/*
 * kernel routing table update by ioctl().
 * Copyright (C) 1997, 98 Kunihiro Ishiguro
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.  
 */

#include <zebra.h>

#include "prefix.h"
#include "log.h"
#include "if.h"

#include "zebra/zserv.h"
#include "zebra/rib.h"
#include "zebra/debug.h"
#include "zebra/rt.h"

/* Initialize of kernel interface.  There is no kernel communication
   support under ioctl().  So this is dummy stub function. */
void
kernel_init (void)
{
  return;
}

/* Dummy function of routing socket. */
static void
kernel_read (int sock)
{
  return;
}

#if 0
/* Initialization prototype of struct sockaddr_in. */
static struct sockaddr_in sin_proto =
{
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  sizeof (struct sockaddr_in), 
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
  AF_INET, 0, {0}, {0}
};
#endif /* 0 */

/* Solaris has ortentry. */
#ifdef HAVE_OLD_RTENTRY
#define rtentry ortentry
#endif /* HAVE_OLD_RTENTRY */

/* Interface to ioctl route message. */
int
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));

  /* Make destination. */
  memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  sin_dest.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  sin_dest.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
  sin_dest.sin_addr = dest->prefix;

  /* Make gateway. */
  if (gate)
    {
      memset (&sin_gate, 0, sizeof (struct sockaddr_in));
      sin_gate.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
      sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
      sin_gate.sin_addr = *gate;
    }

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));
  sin_mask.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
      sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
  masklen2ip (dest->prefixlen, &sin_mask.sin_addr);

  /* Set destination address, mask and gateway.*/
  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 /* SUNOS_5 */

  /* Routing entry flag set. */
  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;

  /* Additional flags */
  rtentry.rt_flags |= flags;


  /* For tagging route. */
  /* rtentry.rt_flags |= RTF_DYNAMIC; */

  /* Open socket for ioctl. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message by ioctl(). */
  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)", safe_strerror (errno), errno);
      return 1;
    }
  close (sock);

  return ret;
}

/* Interface to ioctl route message. */
static int
kernel_ioctl_ipv4 (u_long cmd, struct prefix *p, struct rib *rib, int family)
{
  int ret;
  int sock;
  struct rtentry rtentry;
  struct sockaddr_in sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop;
  int nexthop_num = 0;
  struct interface *ifp;

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

  /* Make destination. */
  memset (&sin_dest, 0, sizeof (struct sockaddr_in));
  sin_dest.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  sin_dest.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
  sin_dest.sin_addr = p->u.prefix4;

  if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
    {
      SET_FLAG (rtentry.rt_flags, RTF_REJECT);

      if (cmd == SIOCADDRT)
	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
	  SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

      goto skip;
    }

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

  /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
    {
      if ((cmd == SIOCADDRT 
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == SIOCDELRT
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
	{
	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
	    {
	      if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
		  nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		  sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
		  sin_gate.sin_addr = nexthop->rgate.ipv4;
		  rtentry.rt_flags |= RTF_GATEWAY;
		}
	      if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
		  || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
		{
		  ifp = if_lookup_by_index (nexthop->rifindex);
		  if (ifp)
		    rtentry.rt_dev = ifp->name;
		  else
		    return -1;
		}
	    }
	  else
	    {
	      if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
		  nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
		{
		  sin_gate.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
		  sin_gate.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
		  sin_gate.sin_addr = nexthop->gate.ipv4;
		  rtentry.rt_flags |= RTF_GATEWAY;
		}
	      if (nexthop->type == NEXTHOP_TYPE_IFINDEX
		  || nexthop->type == NEXTHOP_TYPE_IFNAME)
		{
		  ifp = if_lookup_by_index (nexthop->ifindex);
		  if (ifp)
		    rtentry.rt_dev = ifp->name;
		  else
		    return -1;
		}
	    }

	  if (cmd == SIOCADDRT)
	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

	  nexthop_num++;
	  break;
	}
    }

  /* If there is no useful nexthop then return. */
  if (nexthop_num == 0)
    {
      if (IS_ZEBRA_DEBUG_KERNEL)
	zlog_debug ("netlink_route_multipath(): No useful nexthop.");
      return 0;
    }

 skip:

  memset (&sin_mask, 0, sizeof (struct sockaddr_in));
  sin_mask.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  sin_mask.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
  masklen2ip (p->prefixlen, &sin_mask.sin_addr);

  /* Set destination address, mask and gateway.*/
  memcpy (&rtentry.rt_dst, &sin_dest, sizeof (struct sockaddr_in));

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

#ifndef SUNOS_5
  memcpy (&rtentry.rt_genmask, &sin_mask, sizeof (struct sockaddr_in));
#endif /* SUNOS_5 */

  /* Metric.  It seems metric minus one value is installed... */
  rtentry.rt_metric = rib->metric;

  /* Routing entry flag set. */
  if (p->prefixlen == 32)
    rtentry.rt_flags |= RTF_HOST;

  rtentry.rt_flags |= RTF_UP;

  /* Additional flags */
  /* rtentry.rt_flags |= flags; */

  /* For tagging route. */
  /* rtentry.rt_flags |= RTF_DYNAMIC; */

  /* Open socket for ioctl. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message by ioctl(). */
  ret = ioctl (sock, cmd, &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)", safe_strerror (errno), errno);
      return ret;
    }
  close (sock);

  return ret;
}

int
kernel_add_ipv4 (struct prefix *p, struct rib *rib)
{
  return kernel_ioctl_ipv4 (SIOCADDRT, p, rib, AF_INET);
}

int
kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
{
  return kernel_ioctl_ipv4 (SIOCDELRT, p, rib, AF_INET);
}

#ifdef HAVE_IPV6

/* Below is hack for GNU libc definition and Linux 2.1.X header. */
#undef RTF_DEFAULT
#undef RTF_ADDRCONF

#include <asm/types.h>

#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
/* struct in6_rtmsg will be declared in net/route.h. */
#else
#include <linux/ipv6_route.h>
#endif

static int
kernel_ioctl_ipv6 (u_long type, struct prefix_ipv6 *dest, struct in6_addr *gate,
		   int index, int flags)
{
  int ret;
  int sock;
  struct in6_rtmsg rtm;
    
  memset (&rtm, 0, sizeof (struct in6_rtmsg));

  rtm.rtmsg_flags |= RTF_UP;
  rtm.rtmsg_metric = 1;
  memcpy (&rtm.rtmsg_dst, &dest->prefix, sizeof (struct in6_addr));
  rtm.rtmsg_dst_len = dest->prefixlen;

  /* We need link local index. But this should be done caller...
  if (IN6_IS_ADDR_LINKLOCAL(&rtm.rtmsg_gateway))
    {
      index = if_index_address (&rtm.rtmsg_gateway);
      rtm.rtmsg_ifindex = index;
    }
  else
    rtm.rtmsg_ifindex = 0;
  */

  rtm.rtmsg_flags |= RTF_GATEWAY;

  /* For tagging route. */
  /* rtm.rtmsg_flags |= RTF_DYNAMIC; */

  memcpy (&rtm.rtmsg_gateway, gate, sizeof (struct in6_addr));

  if (index)
    rtm.rtmsg_ifindex = index;
  else
    rtm.rtmsg_ifindex = 0;

  rtm.rtmsg_metric = 1;
  
  sock = socket (AF_INET6, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message via ioctl. */
  ret = ioctl (sock, type, &rtm);
  if (ret < 0)
    {
      zlog_warn ("can't %s ipv6 route: %s\n", type == SIOCADDRT ? "add" : "delete", 
	   safe_strerror(errno));
      ret = errno;
      close (sock);
      return ret;
    }
  close (sock);

  return ret;
}

static int
kernel_ioctl_ipv6_multipath (u_long cmd, struct prefix *p, struct rib *rib,
			     int family)
{
  int ret;
  int sock;
  struct in6_rtmsg rtm;
  struct nexthop *nexthop;
  int nexthop_num = 0;
    
  memset (&rtm, 0, sizeof (struct in6_rtmsg));

  rtm.rtmsg_flags |= RTF_UP;
  rtm.rtmsg_metric = rib->metric;
  memcpy (&rtm.rtmsg_dst, &p->u.prefix, sizeof (struct in6_addr));
  rtm.rtmsg_dst_len = p->prefixlen;

  /* We need link local index. But this should be done caller...
  if (IN6_IS_ADDR_LINKLOCAL(&rtm.rtmsg_gateway))
    {
      index = if_index_address (&rtm.rtmsg_gateway);
      rtm.rtmsg_ifindex = index;
    }
  else
    rtm.rtmsg_ifindex = 0;
  */

  rtm.rtmsg_flags |= RTF_GATEWAY;

  /* For tagging route. */
  /* rtm.rtmsg_flags |= RTF_DYNAMIC; */

  /* Make gateway. */
  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
    {
      if ((cmd == SIOCADDRT 
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == SIOCDELRT
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
	{
	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
	    {
	      if (nexthop->rtype == NEXTHOP_TYPE_IPV6
		  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
		  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
		{
		  memcpy (&rtm.rtmsg_gateway, &nexthop->rgate.ipv6,
			  sizeof (struct in6_addr));
		}
	      if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
		  || nexthop->rtype == NEXTHOP_TYPE_IFNAME
		  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
		  || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
		rtm.rtmsg_ifindex = nexthop->rifindex;
	      else
		rtm.rtmsg_ifindex = 0;
	      
	    }
	  else
	    {
	      if (nexthop->type == NEXTHOP_TYPE_IPV6
		  || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
		  || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
		{
		  memcpy (&rtm.rtmsg_gateway, &nexthop->gate.ipv6,
			  sizeof (struct in6_addr));
		}
	      if (nexthop->type == NEXTHOP_TYPE_IFINDEX
		  || nexthop->type == NEXTHOP_TYPE_IFNAME
		  || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
		  || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
		rtm.rtmsg_ifindex = nexthop->ifindex;
	      else
		rtm.rtmsg_ifindex = 0;
	    }

	  if (cmd == SIOCADDRT)
	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);

	  nexthop_num++;
	  break;
	}
    }

  /* If there is no useful nexthop then return. */
  if (nexthop_num == 0)
    {
      if (IS_ZEBRA_DEBUG_KERNEL)
	zlog_debug ("netlink_route_multipath(): No useful nexthop.");
      return 0;
    }

  sock = socket (AF_INET6, SOCK_DGRAM, 0);
  if (sock < 0)
    {
      zlog_warn ("can't make socket\n");
      return -1;
    }

  /* Send message via ioctl. */
  ret = ioctl (sock, cmd, &rtm);
  if (ret < 0)
    {
      zlog_warn ("can't %s ipv6 route: %s\n",
		 cmd == SIOCADDRT ? "add" : "delete", 
	   safe_strerror(errno));
      ret = errno;
      close (sock);
      return ret;
    }
  close (sock);

  return ret;
}

int
kernel_add_ipv6 (struct prefix *p, struct rib *rib)
{
  return kernel_ioctl_ipv6_multipath (SIOCADDRT, p, rib, AF_INET6);
}

int
kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
{
  return kernel_ioctl_ipv6_multipath (SIOCDELRT, p, rib, AF_INET6);
}

/* Delete IPv6 route from the kernel. */
int
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
		    unsigned int index, int flags, int table)
{
  return kernel_ioctl_ipv6 (SIOCDELRT, dest, gate, index, flags);
}
#endif /* HAVE_IPV6 */
