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

网络

开发平台:

Unix_Linux

  1. /* Kernel communication using routing socket.
  2.  * Copyright (C) 1999 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. #include "if.h"
  23. #include "prefix.h"
  24. #include "sockunion.h"
  25. #include "connected.h"
  26. #include "memory.h"
  27. #include "ioctl.h"
  28. #include "log.h"
  29. #include "str.h"
  30. #include "table.h"
  31. #include "rib.h"
  32. #include "zebra/interface.h"
  33. #include "zebra/zserv.h"
  34. #include "zebra/debug.h"
  35. /* Socket length roundup function. */
  36. #define ROUNDUP(a) 
  37.   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
  38. /* And this macro is wrapper for handling sa_len. */
  39. #ifdef HAVE_SA_LEN
  40. #define WRAPUP(X)   ROUNDUP(((struct sockaddr *)(X))->sa_len)
  41. #else
  42. #define WRAPUP(X)   ROUNDUP(sizeof (struct sockaddr))
  43. #endif /* HAVE_SA_LEN */
  44. /* Routing socket message types. */
  45. struct message rtm_type_str[] =
  46. {
  47.   {RTM_ADD,      "RTM_ADD"},
  48.   {RTM_DELETE,   "RTM_DELETE"},
  49.   {RTM_CHANGE,   "RTM_CHANGE"},
  50.   {RTM_GET,      "RTM_GET"},
  51.   {RTM_LOSING,   "RTM_LOSING"},
  52.   {RTM_REDIRECT, "RTM_REDIRECT"},
  53.   {RTM_MISS,     "RTM_MISS"},
  54.   {RTM_LOCK,     "RTM_LOCK"},
  55.   {RTM_OLDADD,   "RTM_OLDADD"},
  56.   {RTM_OLDDEL,   "RTM_OLDDEL"},
  57.   {RTM_RESOLVE,  "RTM_RESOLVE"},
  58.   {RTM_NEWADDR,  "RTM_NEWADDR"},
  59.   {RTM_DELADDR,  "RTM_DELADDR"},
  60.   {RTM_IFINFO,   "RTM_IFINFO"},
  61. #ifdef RTM_OIFINFO
  62.   {RTM_OIFINFO,   "RTM_OIFINFO"},
  63. #endif /* RTM_OIFINFO */
  64. #ifdef RTM_NEWMADDR
  65.   {RTM_NEWMADDR, "RTM_NEWMADDR"},
  66. #endif /* RTM_NEWMADDR */
  67. #ifdef RTM_DELMADDR
  68.   {RTM_DELMADDR, "RTM_DELMADDR"},
  69. #endif /* RTM_DELMADDR */
  70. #ifdef RTM_IFANNOUNCE
  71.   {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"},
  72. #endif /* RTM_IFANNOUNCE */
  73.   {0,            NULL}
  74. };
  75. struct message rtm_flag_str[] =
  76. {
  77.   {RTF_UP,        "UP"},
  78.   {RTF_GATEWAY,   "GATEWAY"},
  79.   {RTF_HOST,      "HOST"},
  80.   {RTF_REJECT,    "REJECT"},
  81.   {RTF_DYNAMIC,   "DYNAMIC"},
  82.   {RTF_MODIFIED,  "MODIFIED"},
  83.   {RTF_DONE,      "DONE"},
  84. #ifdef RTF_MASK
  85.   {RTF_MASK,      "MASK"},
  86. #endif /* RTF_MASK */
  87.   {RTF_CLONING,   "CLONING"},
  88.   {RTF_XRESOLVE,  "XRESOLVE"},
  89.   {RTF_LLINFO,    "LLINFO"},
  90.   {RTF_STATIC,    "STATIC"},
  91.   {RTF_BLACKHOLE, "BLACKHOLE"},
  92.   {RTF_PROTO1,    "PROTO1"},
  93.   {RTF_PROTO2,    "PROTO2"},
  94. #ifdef RTF_PRCLONING
  95.   {RTF_PRCLONING, "PRCLONING"},
  96. #endif /* RTF_PRCLONING */
  97. #ifdef RTF_WASCLONED
  98.   {RTF_WASCLONED, "WASCLONED"},
  99. #endif /* RTF_WASCLONED */
  100. #ifdef RTF_PROTO3
  101.   {RTF_PROTO3,    "PROTO3"},
  102. #endif /* RTF_PROTO3 */
  103. #ifdef RTF_PINNED
  104.   {RTF_PINNED,    "PINNED"},
  105. #endif /* RTF_PINNED */
  106. #ifdef RTF_LOCAL
  107.   {RTF_LOCAL,    "LOCAL"},
  108. #endif /* RTF_LOCAL */
  109. #ifdef RTF_BROADCAST
  110.   {RTF_BROADCAST, "BROADCAST"},
  111. #endif /* RTF_BROADCAST */
  112. #ifdef RTF_MULTICAST
  113.   {RTF_MULTICAST, "MULTICAST"},
  114. #endif /* RTF_MULTICAST */
  115.   {0,             NULL}
  116. };
  117. /* Kernel routing update socket. */
  118. int routing_sock = -1;
  119. /* Yes I'm checking ugly routing socket behavior. */
  120. /* #define DEBUG */
  121. /* Supported address family check. */
  122. static int
  123. af_check (int family)
  124. {
  125.   if (family == AF_INET)
  126.     return 1;
  127. #ifdef HAVE_IPV6
  128.   if (family == AF_INET6)
  129.     return 1;
  130. #endif /* HAVE_IPV6 */
  131.   return 0;
  132. }
  133. /* Dump routing table flag for debug purpose. */
  134. void
  135. rtm_flag_dump (int flag)
  136. {
  137.   struct message *mes;
  138.   static char buf[BUFSIZ];
  139.   buf[0] = '0';
  140.   for (mes = rtm_flag_str; mes->key != 0; mes++)
  141.     {
  142.       if (mes->key & flag)
  143. {
  144.   strlcat (buf, mes->str, BUFSIZ);
  145.   strlcat (buf, " ", BUFSIZ);
  146. }
  147.     }
  148.   zlog_info ("Kernel: %s", buf);
  149. }
  150. #ifdef RTM_IFANNOUNCE
  151. /* Interface adding function */
  152. int
  153. ifan_read (struct if_announcemsghdr *ifan)
  154. {
  155.   struct interface *ifp;
  156.   ifp = if_lookup_by_index (ifan->ifan_index);
  157.   if (ifp == NULL && ifan->ifan_what == IFAN_ARRIVAL)
  158.     {
  159.       /* Create Interface */
  160.       ifp = if_get_by_name (ifan->ifan_name);
  161.       ifp->ifindex = ifan->ifan_index;
  162.       if_add_update (ifp);
  163.     }
  164.   else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE)
  165.     {
  166.       if_delete_update (ifp);
  167.       if_delete (ifp);
  168.     }
  169.   if_get_flags (ifp);
  170.   if_get_mtu (ifp);
  171.   if_get_metric (ifp);
  172.   if (IS_ZEBRA_DEBUG_KERNEL)
  173.     zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);
  174.   return 0;
  175. }
  176. #endif /* RTM_IFANNOUNCE */
  177. /* Interface adding function called from interface_list. */
  178. int
  179. ifm_read (struct if_msghdr *ifm)
  180. {
  181.   struct interface *ifp;
  182.   struct sockaddr_dl *sdl = NULL;
  183.   sdl = (struct sockaddr_dl *)(ifm + 1);
  184.   /* Use sdl index. */
  185.   ifp = if_lookup_by_index (ifm->ifm_index);
  186.   if (ifp == NULL)
  187.     {
  188.       /* Check interface's address.*/
  189.       if (! (ifm->ifm_addrs & RTA_IFP))
  190. {
  191.   zlog_warn ("There must be RTA_IFP address for ifindex %dn",
  192.      ifm->ifm_index);
  193.   return -1;
  194. }
  195.       ifp = if_create ();
  196.       strncpy (ifp->name, sdl->sdl_data, sdl->sdl_nlen);
  197.       ifp->ifindex = ifm->ifm_index;
  198.       ifp->flags = ifm->ifm_flags;
  199. #if defined(__bsdi__)
  200.       if_kvm_get_mtu (ifp);
  201. #else
  202.       if_get_mtu (ifp);
  203. #endif /* __bsdi__ */
  204.       if_get_metric (ifp);
  205.       /* Fetch hardware address. */
  206.       if (sdl->sdl_family != AF_LINK)
  207. {
  208.   zlog_warn ("sockaddr_dl->sdl_family is not AF_LINK");
  209.   return -1;
  210. }
  211.       memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));
  212.       if_add_update (ifp);
  213.     }
  214.   else
  215.     {
  216.       /* There is a case of promisc, allmulti flag modification. */
  217.       if (if_is_up (ifp))
  218. {
  219.   ifp->flags = ifm->ifm_flags;
  220.   if (! if_is_up (ifp))
  221.     if_down (ifp);
  222. }
  223.       else
  224. {
  225.   ifp->flags = ifm->ifm_flags;
  226.   if (if_is_up (ifp))
  227.     if_up (ifp);
  228. }
  229.     }
  230.   
  231. #ifdef HAVE_NET_RT_IFLIST
  232.   ifp->stats = ifm->ifm_data;
  233. #endif /* HAVE_NET_RT_IFLIST */
  234.   if (IS_ZEBRA_DEBUG_KERNEL)
  235.     zlog_info ("interface %s index %d", ifp->name, ifp->ifindex);
  236.   return 0;
  237. }
  238. /* Address read from struct ifa_msghdr. */
  239. void
  240. ifam_read_mesg (struct ifa_msghdr *ifm,
  241. union sockunion *addr,
  242. union sockunion *mask,
  243. union sockunion *dest)
  244. {
  245.   caddr_t pnt, end;
  246.   pnt = (caddr_t)(ifm + 1);
  247.   end = ((caddr_t)ifm) + ifm->ifam_msglen;
  248. #define IFAMADDRGET(X,R) 
  249.     if (ifm->ifam_addrs & (R)) 
  250.       { 
  251.         int len = WRAPUP(pnt); 
  252.         if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) 
  253.           memcpy ((caddr_t)(X), pnt, len); 
  254.         pnt += len; 
  255.       }
  256. #define IFAMMASKGET(X,R) 
  257.     if (ifm->ifam_addrs & (R)) 
  258.       { 
  259. int len = WRAPUP(pnt); 
  260.         if ((X) != NULL) 
  261.   memcpy ((caddr_t)(X), pnt, len); 
  262. pnt += len; 
  263.       }
  264.   /* Be sure structure is cleared */
  265.   memset (mask, 0, sizeof (union sockunion));
  266.   memset (addr, 0, sizeof (union sockunion));
  267.   memset (dest, 0, sizeof (union sockunion));
  268.   /* We fetch each socket variable into sockunion. */
  269.   IFAMADDRGET (NULL, RTA_DST);
  270.   IFAMADDRGET (NULL, RTA_GATEWAY);
  271.   IFAMMASKGET (mask, RTA_NETMASK);
  272.   IFAMADDRGET (NULL, RTA_GENMASK);
  273.   IFAMADDRGET (NULL, RTA_IFP);
  274.   IFAMADDRGET (addr, RTA_IFA);
  275.   IFAMADDRGET (NULL, RTA_AUTHOR);
  276.   IFAMADDRGET (dest, RTA_BRD);
  277.   /* Assert read up end point matches to end point */
  278.   if (pnt != end)
  279.     zlog_warn ("ifam_read() doesn't read all socket data");
  280. }
  281. /* Interface's address information get. */
  282. int
  283. ifam_read (struct ifa_msghdr *ifam)
  284. {
  285.   struct interface *ifp;
  286.   union sockunion addr, mask, gate;
  287.   /* Check does this interface exist or not. */
  288.   ifp = if_lookup_by_index (ifam->ifam_index);
  289.   if (ifp == NULL) 
  290.     {
  291.       zlog_warn ("no interface for index %d", ifam->ifam_index); 
  292.       return -1;
  293.     }
  294.   /* Allocate and read address information. */
  295.   ifam_read_mesg (ifam, &addr, &mask, &gate);
  296.   /* Check interface flag for implicit up of the interface. */
  297.   if_refresh (ifp);
  298.   /* Add connected address. */
  299.   switch (sockunion_family (&addr))
  300.     {
  301.     case AF_INET:
  302.       if (ifam->ifam_type == RTM_NEWADDR)
  303. connected_add_ipv4 (ifp, 0, &addr.sin.sin_addr, 
  304.     ip_masklen (mask.sin.sin_addr),
  305.     &gate.sin.sin_addr, NULL);
  306.       else
  307. connected_delete_ipv4 (ifp, 0, &addr.sin.sin_addr, 
  308.        ip_masklen (mask.sin.sin_addr),
  309.        &gate.sin.sin_addr, NULL);
  310.       break;
  311. #ifdef HAVE_IPV6
  312.     case AF_INET6:
  313.       /* Unset interface index from link-local address when IPv6 stack
  314.  is KAME. */
  315.       if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr))
  316. SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0);
  317.       if (ifam->ifam_type == RTM_NEWADDR)
  318. connected_add_ipv6 (ifp,
  319.     &addr.sin6.sin6_addr, 
  320.     ip6_masklen (mask.sin6.sin6_addr),
  321.     &gate.sin6.sin6_addr);
  322.       else
  323. connected_delete_ipv6 (ifp,
  324.        &addr.sin6.sin6_addr, 
  325.        ip6_masklen (mask.sin6.sin6_addr),
  326.        &gate.sin6.sin6_addr);
  327.       break;
  328. #endif /* HAVE_IPV6 */
  329.     default:
  330.       /* Unsupported family silently ignore... */
  331.       break;
  332.     }
  333.   return 0;
  334. }
  335. /* Interface function for reading kernel routing table information. */
  336. int
  337. rtm_read_mesg (struct rt_msghdr *rtm,
  338.        union sockunion *dest,
  339.        union sockunion *mask,
  340.        union sockunion *gate)
  341. {
  342.   caddr_t pnt, end;
  343.   /* Pnt points out socket data start point. */
  344.   pnt = (caddr_t)(rtm + 1);
  345.   end = ((caddr_t)rtm) + rtm->rtm_msglen;
  346.   /* rt_msghdr version check. */
  347.   if (rtm->rtm_version != RTM_VERSION) 
  348.       zlog (NULL, LOG_WARNING,
  349.       "Routing message version different %d should be %d."
  350.       "This may cause problemn", rtm->rtm_version, RTM_VERSION);
  351. #define RTMADDRGET(X,R) 
  352.     if (rtm->rtm_addrs & (R)) 
  353.       { 
  354. int len = WRAPUP (pnt); 
  355.         if (((X) != NULL) && af_check (((struct sockaddr *)pnt)->sa_family)) 
  356.   memcpy ((caddr_t)(X), pnt, len); 
  357. pnt += len; 
  358.       }
  359. #define RTMMASKGET(X,R) 
  360.     if (rtm->rtm_addrs & (R)) 
  361.       { 
  362. int len = WRAPUP (pnt); 
  363.         if ((X) != NULL) 
  364.   memcpy ((caddr_t)(X), pnt, len); 
  365. pnt += len; 
  366.       }
  367.   /* Be sure structure is cleared */
  368.   memset (dest, 0, sizeof (union sockunion));
  369.   memset (gate, 0, sizeof (union sockunion));
  370.   memset (mask, 0, sizeof (union sockunion));
  371.   /* We fetch each socket variable into sockunion. */
  372.   RTMADDRGET (dest, RTA_DST);
  373.   RTMADDRGET (gate, RTA_GATEWAY);
  374.   RTMMASKGET (mask, RTA_NETMASK);
  375.   RTMADDRGET (NULL, RTA_GENMASK);
  376.   RTMADDRGET (NULL, RTA_IFP);
  377.   RTMADDRGET (NULL, RTA_IFA);
  378.   RTMADDRGET (NULL, RTA_AUTHOR);
  379.   RTMADDRGET (NULL, RTA_BRD);
  380.   /* If there is netmask information set it's family same as
  381.      destination family*/
  382.   if (rtm->rtm_addrs & RTA_NETMASK)
  383.     mask->sa.sa_family = dest->sa.sa_family;
  384.   /* Assert read up to the end of pointer. */
  385.   if (pnt != end) 
  386.       zlog (NULL, LOG_WARNING, "rtm_read() doesn't read all socket data.");
  387.   return rtm->rtm_flags;
  388. }
  389. void
  390. rtm_read (struct rt_msghdr *rtm)
  391. {
  392.   int flags;
  393.   u_char zebra_flags;
  394.   union sockunion dest, mask, gate;
  395.   zebra_flags = 0;
  396.   /* Discard self send message. */
  397.   if (rtm->rtm_type != RTM_GET 
  398.       && (rtm->rtm_pid == pid || rtm->rtm_pid == old_pid))
  399.     return;
  400.   /* Read destination and netmask and gateway from rtm message
  401.      structure. */
  402.   flags = rtm_read_mesg (rtm, &dest, &mask, &gate);
  403. #ifdef RTF_CLONED /*bsdi, netbsd 1.6*/
  404.   if (flags & RTF_CLONED)
  405.     return;
  406. #endif
  407. #ifdef RTF_WASCLONED /*freebsd*/
  408.   if (flags & RTF_WASCLONED)
  409.     return;
  410. #endif
  411.   if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))
  412.     return;
  413.   /* This is connected route. */
  414.   if (! (flags & RTF_GATEWAY))
  415.       return;
  416.   if (flags & RTF_PROTO1)
  417.     SET_FLAG (zebra_flags, ZEBRA_FLAG_SELFROUTE);
  418.   /* This is persistent route. */
  419.   if (flags & RTF_STATIC)
  420.     SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC);
  421.   if (dest.sa.sa_family == AF_INET)
  422.     {
  423.       struct prefix_ipv4 p;
  424.       p.family = AF_INET;
  425.       p.prefix = dest.sin.sin_addr;
  426.       if (flags & RTF_HOST)
  427. p.prefixlen = IPV4_MAX_PREFIXLEN;
  428.       else
  429. p.prefixlen = ip_masklen (mask.sin.sin_addr);
  430.       if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
  431. rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
  432.       &p, &gate.sin.sin_addr, 0, 0, 0, 0);
  433.       else
  434. rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, 
  435.       &p, &gate.sin.sin_addr, 0, 0);
  436.     }
  437. #ifdef HAVE_IPV6
  438.   if (dest.sa.sa_family == AF_INET6)
  439.     {
  440.       struct prefix_ipv6 p;
  441.       unsigned int ifindex = 0;
  442.       p.family = AF_INET6;
  443.       p.prefix = dest.sin6.sin6_addr;
  444.       if (flags & RTF_HOST)
  445. p.prefixlen = IPV6_MAX_PREFIXLEN;
  446.       else
  447. p.prefixlen = ip6_masklen (mask.sin6.sin6_addr);
  448. #ifdef KAME
  449.       if (IN6_IS_ADDR_LINKLOCAL (&gate.sin6.sin6_addr))
  450. {
  451.   ifindex = IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr);
  452.   SET_IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr, 0);
  453. }
  454. #endif /* KAME */
  455.       if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD)
  456. rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
  457.       &p, &gate.sin6.sin6_addr, ifindex, 0);
  458.       else
  459. rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
  460.  &p, &gate.sin6.sin6_addr, ifindex, 0);
  461.     }
  462. #endif /* HAVE_IPV6 */
  463. }
  464. /* Interface function for the kernel routing table updates.  Support
  465.    for RTM_CHANGE will be needed. */
  466. int
  467. rtm_write (int message,
  468.    union sockunion *dest,
  469.    union sockunion *mask,
  470.    union sockunion *gate,
  471.    unsigned int index,
  472.    int zebra_flags,
  473.    int metric)
  474. {
  475.   int ret;
  476.   caddr_t pnt;
  477.   struct interface *ifp;
  478.   struct sockaddr_in tmp_gate;
  479. #ifdef HAVE_IPV6
  480.   struct sockaddr_in6 tmp_gate6;
  481. #endif /* HAVE_IPV6 */
  482.   /* Sequencial number of routing message. */
  483.   static int msg_seq = 0;
  484.   /* Struct of rt_msghdr and buffer for storing socket's data. */
  485.   struct 
  486.   {
  487.     struct rt_msghdr rtm;
  488.     char buf[512];
  489.   } msg;
  490.   
  491.   memset (&tmp_gate, 0, sizeof (struct sockaddr_in));
  492.   tmp_gate.sin_family = AF_INET;
  493. #ifdef HAVE_SIN_LEN
  494.   tmp_gate.sin_len = sizeof (struct sockaddr_in);
  495. #endif /* HAVE_SIN_LEN */
  496. #ifdef HAVE_IPV6
  497.   memset (&tmp_gate6, 0, sizeof (struct sockaddr_in6));
  498.   tmp_gate6.sin6_family = AF_INET6;
  499. #ifdef SIN6_LEN
  500.   tmp_gate6.sin6_len = sizeof (struct sockaddr_in6);
  501. #endif /* SIN6_LEN */
  502. #endif /* HAVE_IPV6 */
  503.   if (routing_sock < 0)
  504.     return ZEBRA_ERR_EPERM;
  505.   /* Clear and set rt_msghdr values */
  506.   memset (&msg, 0, sizeof (struct rt_msghdr));
  507.   msg.rtm.rtm_version = RTM_VERSION;
  508.   msg.rtm.rtm_type = message;
  509.   msg.rtm.rtm_seq = msg_seq++;
  510.   msg.rtm.rtm_addrs = RTA_DST;
  511.   msg.rtm.rtm_addrs |= RTA_GATEWAY;
  512.   msg.rtm.rtm_flags = RTF_UP;
  513.   msg.rtm.rtm_index = index;
  514.   if (metric != 0)
  515.     {
  516.       msg.rtm.rtm_rmx.rmx_hopcount = metric;
  517.       msg.rtm.rtm_inits |= RTV_HOPCOUNT;
  518.     }
  519.   ifp = if_lookup_by_index (index);
  520.   if (gate && message == RTM_ADD)
  521.     msg.rtm.rtm_flags |= RTF_GATEWAY;
  522.   if (! gate && message == RTM_ADD && ifp &&
  523.       (ifp->flags & IFF_POINTOPOINT) == 0)
  524.     msg.rtm.rtm_flags |= RTF_CLONING;
  525.   /* If no protocol specific gateway is specified, use link
  526.      address for gateway. */
  527.   if (! gate)
  528.     {
  529.       if (!ifp)
  530.         {
  531.           zlog_warn ("no gateway found for interface index %d", index);
  532.           return -1;
  533.         }
  534.       gate = (union sockunion *) & ifp->sdl;
  535.     }
  536.   if (mask)
  537.     msg.rtm.rtm_addrs |= RTA_NETMASK;
  538.   else if (message == RTM_ADD) 
  539.     msg.rtm.rtm_flags |= RTF_HOST;
  540.   /* Tagging route with flags */
  541.   msg.rtm.rtm_flags |= (RTF_PROTO1);
  542.   /* Additional flags. */
  543.   if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
  544.     msg.rtm.rtm_flags |= RTF_BLACKHOLE;
  545. #ifdef HAVE_SIN_LEN
  546. #define SOCKADDRSET(X,R) 
  547.   if (msg.rtm.rtm_addrs & (R)) 
  548.     { 
  549.       int len = ROUNDUP ((X)->sa.sa_len); 
  550.       memcpy (pnt, (caddr_t)(X), len); 
  551.       pnt += len; 
  552.     }
  553. #else 
  554. #define SOCKADDRSET(X,R) 
  555.   if (msg.rtm.rtm_addrs & (R)) 
  556.     { 
  557.       int len = ROUNDUP (sizeof((X)->sa)); 
  558.       memcpy (pnt, (caddr_t)(X), len); 
  559.       pnt += len; 
  560.     }
  561. #endif /* HAVE_SIN_LEN */
  562.   pnt = (caddr_t) msg.buf;
  563.   /* Write each socket data into rtm message buffer */
  564.   SOCKADDRSET (dest, RTA_DST);
  565.   SOCKADDRSET (gate, RTA_GATEWAY);
  566.   SOCKADDRSET (mask, RTA_NETMASK);
  567.   msg.rtm.rtm_msglen = pnt - (caddr_t) &msg;
  568.   ret = write (routing_sock, &msg, msg.rtm.rtm_msglen);
  569.   if (ret != msg.rtm.rtm_msglen) 
  570.     {
  571.       if (errno == EEXIST) 
  572. return ZEBRA_ERR_RTEXIST;
  573.       if (errno == ENETUNREACH)
  574. return ZEBRA_ERR_RTUNREACH;
  575.       
  576.       zlog_warn ("write : %s (%d)", strerror (errno), errno);
  577.       return -1;
  578.     }
  579.   return 0;
  580. }
  581. #include "thread.h"
  582. #include "zebra/zserv.h"
  583. extern struct thread_master *master;
  584. /* For debug purpose. */
  585. void
  586. rtmsg_debug (struct rt_msghdr *rtm)
  587. {
  588.   char *type = "Unknown";
  589.   struct message *mes;
  590.   for (mes = rtm_type_str; mes->str; mes++)
  591.     if (mes->key == rtm->rtm_type)
  592.       {
  593. type = mes->str;
  594. break;
  595.       }
  596.   zlog_info ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, type);
  597.   rtm_flag_dump (rtm->rtm_flags);
  598.   zlog_info ("Kernel: message seq %d", rtm->rtm_seq);
  599.   zlog_info ("Kernel: pid %d", rtm->rtm_pid);
  600. }
  601. /* This is pretty gross, better suggestions welcome -- mhandler */
  602. #ifndef RTAX_MAX
  603. #ifdef RTA_NUMBITS
  604. #define RTAX_MAX RTA_NUMBITS
  605. #else
  606. #define RTAX_MAX 8
  607. #endif /* RTA_NUMBITS */
  608. #endif /* RTAX_MAX */
  609. /* Kernel routing table and interface updates via routing socket. */
  610. int
  611. kernel_read (struct thread *thread)
  612. {
  613.   int sock;
  614.   int nbytes;
  615.   struct rt_msghdr *rtm;
  616.   union 
  617.   {
  618.     /* Routing information. */
  619.     struct 
  620.     {
  621.       struct rt_msghdr rtm;
  622.       struct sockaddr addr[RTAX_MAX];
  623.     } r;
  624.     /* Interface information. */
  625.     struct
  626.     {
  627.       struct if_msghdr ifm;
  628.       struct sockaddr addr[RTAX_MAX];
  629.     } im;
  630.     /* Interface address information. */
  631.     struct
  632.     {
  633.       struct ifa_msghdr ifa;
  634.       struct sockaddr addr[RTAX_MAX];
  635.     } ia;
  636. #ifdef RTM_IFANNOUNCE
  637.     /* Interface arrival/departure */
  638.     struct
  639.     {
  640.       struct if_announcemsghdr ifan;
  641.       struct sockaddr addr[RTAX_MAX];
  642.     } ian;
  643. #endif /* RTM_IFANNOUNCE */
  644.   } buf;
  645.   /* Fetch routing socket. */
  646.   sock = THREAD_FD (thread);
  647.   nbytes= read (sock, &buf, sizeof buf);
  648.   if (nbytes <= 0)
  649.     {
  650.       if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
  651. zlog_warn ("routing socket error: %s", strerror (errno));
  652.       return 0;
  653.     }
  654.   thread_add_read (master, kernel_read, NULL, sock);
  655. #ifdef DEBUG
  656.   rtmsg_debug (&buf.r.rtm);
  657. #endif /* DEBUG */
  658.   rtm = &buf.r.rtm;
  659.   switch (rtm->rtm_type)
  660.     {
  661.     case RTM_ADD:
  662.     case RTM_DELETE:
  663.       rtm_read (rtm);
  664.       break;
  665.     case RTM_IFINFO:
  666.       ifm_read (&buf.im.ifm);
  667.       break;
  668.     case RTM_NEWADDR:
  669.     case RTM_DELADDR:
  670.       ifam_read (&buf.ia.ifa);
  671.       break;
  672. #ifdef RTM_IFANNOUNCE
  673.     case RTM_IFANNOUNCE:
  674.       ifan_read (&buf.ian.ifan);
  675.       break;
  676. #endif /* RTM_IFANNOUNCE */
  677.     default:
  678.       break;
  679.     }
  680.   return 0;
  681. }
  682. /* Make routing socket. */
  683. void
  684. routing_socket ()
  685. {
  686.   routing_sock = socket (AF_ROUTE, SOCK_RAW, 0);
  687.   if (routing_sock < 0) 
  688.     {
  689.       zlog_warn ("Can't init kernel routing socket");
  690.       return;
  691.     }
  692.   if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) 
  693.     zlog_warn ("Can't set O_NONBLOCK to routing socket");
  694.   /* kernel_read needs rewrite. */
  695.   thread_add_read (master, kernel_read, NULL, routing_sock);
  696. }
  697. /* Exported interface function.  This function simply calls
  698.    routing_socket (). */
  699. void
  700. kernel_init ()
  701. {
  702.   routing_socket ();
  703. }