天天看點

add route

kernel_add_route (struct prefix_ipv4 *dest, struct in_addr *gate,

                  int index, int flags)

{

  int ret;

  int sock;

  struct rtentry rtentry;

  struct sockaddr_in sin_dest, sin_mask, sin_gate;

  memset (&rtentry, 0, sizeof (struct rtentry));

  memset (&sin_dest, 0, sizeof (struct sockaddr_in));

  sin_dest.sin_family = AF_INET;

#ifdef HAVE_SIN_LEN

  sin_dest.sin_len = sizeof (struct sockaddr_in);

#endif

  sin_dest.sin_addr = dest->prefix;

  if (gate)

    {

      memset (&sin_gate, 0, sizeof (struct sockaddr_in));

      sin_gate.sin_family = AF_INET;

#ifdef HAVE_SIN_LEN

      sin_gate.sin_len = sizeof (struct sockaddr_in);

#endif

      sin_gate.sin_addr = *gate;

    }

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));

  sin_mask.sin_family = AF_INET;

#ifdef HAVE_SIN_LEN

      sin_gate.sin_len = sizeof (struct sockaddr_in);

#endif

  masklen2ip (dest->prefixlen, &sin_mask.sin_addr);

  memcpy (&rtentry.rt_dst, &sin_dest, sizeof (struct sockaddr_in));

  if (gate)

    memcpy (&rtentry.rt_gateway, &sin_gate, sizeof (struct sockaddr_in));

#ifndef SUNOS_5

  memcpy (&rtentry.rt_genmask, &sin_mask, sizeof (struct sockaddr_in));

#endif

  if (dest->prefixlen == 32)

    rtentry.rt_flags |= RTF_HOST;

  if (gate && gate->s_addr != INADDR_ANY)

    rtentry.rt_flags |= RTF_GATEWAY;

  rtentry.rt_flags |= RTF_UP;

  rtentry.rt_flags |= flags;

  sock = socket (AF_INET, SOCK_DGRAM, 0);

  if (sock < 0)

    {

      zlog_warn ("can't make socket/n");

      return -1;

    }

  ret = ioctl (sock, SIOCADDRT, &rtentry);

  if (ret < 0)

    {

      switch (errno)

        {

        case EEXIST:

          close (sock);

          return ZEBRA_ERR_RTEXIST;

          break;

        case ENETUNREACH:

          close (sock);

          return ZEBRA_ERR_RTUNREACH;

          break;

        case EPERM:

          close (sock);

          return ZEBRA_ERR_EPERM;

          break;

        }

      close (sock);

      zlog_warn ("write : %s (%d)", strerror (errno), errno);

      return 1;

    }

  close (sock);

  return ret;

}

繼續閱讀