/*
 * Kernel routing table updates by routing socket.
 * 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 "if.h"
#include "prefix.h"
#include "sockunion.h"
#include "log.h"
#include "str.h"
#include "privs.h"

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

extern struct zebra_privs_t zserv_privs;

/* kernel socket export */
extern int rtm_write (int message, union sockunion *dest,
                      union sockunion *mask, union sockunion *gate,
                      unsigned int index, int zebra_flags, int metric);

/* Adjust netmask socket length. Return value is a adjusted sin_len
   value. */
static int
sin_masklen (struct in_addr mask)
{
  char *p, *lim;
  int len;
  struct sockaddr_in sin;

  if (mask.s_addr == 0) 
    return sizeof (long);

  sin.sin_addr = mask;
  len = sizeof (struct sockaddr_in);

  lim = (char *) &sin.sin_addr;
  p = lim + sizeof (sin.sin_addr);

  while (*--p == 0 && p >= lim) 
    len--;
  return len;
}

/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)

{
  struct sockaddr_in *mask = NULL;
  struct sockaddr_in sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop, *tnexthop;
  int recursing;
  int nexthop_num = 0;
  unsigned int ifindex = 0;
  int gate = 0;
  int error;
  char prefix_buf[INET_ADDRSTRLEN];

  if (IS_ZEBRA_DEBUG_RIB)
    inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
  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;

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

  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 */

  /* Make gateway. */
  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
    {
      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
        continue;

      gate = 0;
      char gate_buf[INET_ADDRSTRLEN] = "NULL";

      /*
       * XXX We need to refrain from kernel operations in some cases,
       * but this if statement seems overly cautious - what about
       * other than ADD and DELETE?
       */
      if ((cmd == RTM_ADD
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == RTM_DELETE
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
	      ))
	{
	  if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
	      nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
	    {
	      sin_gate.sin_addr = nexthop->gate.ipv4;
	      gate = 1;
	    }
	  if (nexthop->type == NEXTHOP_TYPE_IFINDEX
	      || nexthop->type == NEXTHOP_TYPE_IFNAME
	      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
	    ifindex = nexthop->ifindex;
	  if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
	    {
	      struct in_addr loopback;
	      loopback.s_addr = htonl (INADDR_LOOPBACK);
	      sin_gate.sin_addr = loopback;
	      gate = 1;
	    }

	  if (gate && p->prefixlen == 32)
	    mask = NULL;
	  else
	    {
	      masklen2ip (p->prefixlen, &sin_mask.sin_addr);
	      sin_mask.sin_family = AF_INET;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
	      sin_mask.sin_len = sin_masklen (sin_mask.sin_addr);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
	      mask = &sin_mask;
	    }

	  error = rtm_write (cmd,
			     (union sockunion *)&sin_dest, 
			     (union sockunion *)mask, 
			     gate ? (union sockunion *)&sin_gate : NULL,
			     ifindex,
			     rib->flags,
			     rib->metric);

           if (IS_ZEBRA_DEBUG_RIB)
           {
             if (!gate)
             {
               zlog_debug ("%s: %s/%d: attention! gate not found for rib %p",
                 __func__, prefix_buf, p->prefixlen, rib);
               rib_dump (__func__, (struct prefix_ipv4 *)p, rib);
             }
             else
               inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN);
           }
 
           switch (error)
           {
             /* We only flag nexthops as being in FIB if rtm_write() did its work. */
             case ZEBRA_ERR_NOERROR:
               nexthop_num++;
               if (IS_ZEBRA_DEBUG_RIB)
                 zlog_debug ("%s: %s/%d: successfully did NH %s",
                   __func__, prefix_buf, p->prefixlen, gate_buf);
               if (cmd == RTM_ADD)
                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
               break;
 
             /* The only valid case for this error is kernel's failure to install
              * a multipath route, which is common for FreeBSD. This should be
              * ignored silently, but logged as an error otherwise.
              */
             case ZEBRA_ERR_RTEXIST:
               if (cmd != RTM_ADD)
                 zlog_err ("%s: rtm_write() returned %d for command %d",
                   __func__, error, cmd);
               continue;
               break;
 
             /* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't
              * normal to get any other messages in ANY case.
              */
             case ZEBRA_ERR_RTNOEXIST:
             case ZEBRA_ERR_RTUNREACH:
             default:
               /* This point is reachable regardless of debugging mode. */
               if (!IS_ZEBRA_DEBUG_RIB)
                 inet_ntop (AF_INET, &p->u.prefix, prefix_buf, INET_ADDRSTRLEN);
               zlog_err ("%s: %s/%d: rtm_write() unexpectedly returned %d for command %s",
                 __func__, prefix_buf, p->prefixlen, error, lookup (rtm_type_str, cmd));
               break;
           }
         } /* if (cmd and flags make sense) */
       else
         if (IS_ZEBRA_DEBUG_RIB)
           zlog_debug ("%s: odd command %s for flags %d",
             __func__, lookup (rtm_type_str, cmd), nexthop->flags);
     } /* for (ALL_NEXTHOPS_RO(...))*/
 
   /* If there was no useful nexthop, then complain. */
   if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
     zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib);

  return 0; /*XXX*/
}

int
kernel_add_ipv4 (struct prefix *p, struct rib *rib)
{
  int route;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET);
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}

int
kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
{
  int route;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET);
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}

#ifdef HAVE_IPV6

/* Calculate sin6_len value for netmask socket value. */
static int
sin6_masklen (struct in6_addr mask)
{
  struct sockaddr_in6 sin6;
  char *p, *lim;
  int len;

#if defined (INRIA)
  if (IN_ANYADDR6 (mask)) 
    return sizeof (long);
#else /* ! INRIA */
  if (IN6_IS_ADDR_UNSPECIFIED (&mask)) 
    return sizeof (long);
#endif /* ! INRIA */

  sin6.sin6_addr = mask;
  len = sizeof (struct sockaddr_in6);

  lim = (char *) & sin6.sin6_addr;
  p = lim + sizeof (sin6.sin6_addr);

  while (*--p == 0 && p >= lim) 
    len--;

  return len;
}

/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv6 (int message, struct prefix_ipv6 *dest,
		 struct in6_addr *gate, int index, int flags)
{
  struct sockaddr_in6 *mask;
  struct sockaddr_in6 sin_dest, sin_mask, sin_gate;

  memset (&sin_dest, 0, sizeof (struct sockaddr_in6));
  sin_dest.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  sin_dest.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */

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

  memset (&sin_gate, 0, sizeof (struct sockaddr_in6));
  sin_gate.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  sin_gate.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */

  sin_dest.sin6_addr = dest->prefix;

  if (gate)
    memcpy (&sin_gate.sin6_addr, gate, sizeof (struct in6_addr));

  /* Under kame set interface index to link local address. */
#ifdef KAME

#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
  do { \
    (a).s6_addr[2] = ((i) >> 8) & 0xff; \
    (a).s6_addr[3] = (i) & 0xff; \
  } while (0)

  if (gate && IN6_IS_ADDR_LINKLOCAL(gate))
    SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, index);
#endif /* KAME */

  if (gate && dest->prefixlen == 128)
    mask = NULL;
  else
    {
      masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);
      sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN
      sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
#endif /* SIN6_LEN */
      mask = &sin_mask;
    }

  return rtm_write (message, 
		    (union sockunion *) &sin_dest,
		    (union sockunion *) mask,
		    gate ? (union sockunion *)&sin_gate : NULL,
		    index,
		    flags,
		    0);
}

/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
			   int family)
{
  struct sockaddr_in6 *mask;
  struct sockaddr_in6 sin_dest, sin_mask, sin_gate;
  struct nexthop *nexthop, *tnexthop;
  int recursing;
  int nexthop_num = 0;
  unsigned int ifindex = 0;
  int gate = 0;
  int error;

  memset (&sin_dest, 0, sizeof (struct sockaddr_in6));
  sin_dest.sin6_family = AF_INET6;
#ifdef SIN6_LEN
  sin_dest.sin6_len = sizeof (struct sockaddr_in6);
#endif /* SIN6_LEN */
  sin_dest.sin6_addr = p->u.prefix6;

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

  memset (&sin_gate, 0, sizeof (struct sockaddr_in6));
  sin_gate.sin6_family = AF_INET6;
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  sin_gate.sin6_len = sizeof (struct sockaddr_in6);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */

  /* Make gateway. */
  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing))
    {
      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
	continue;

      gate = 0;

      if ((cmd == RTM_ADD
	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
	  || (cmd == RTM_DELETE
#if 0
	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
#endif
	      ))
	{
	  if (nexthop->type == NEXTHOP_TYPE_IPV6
	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
	    {
	      sin_gate.sin6_addr = nexthop->gate.ipv6;
	      gate = 1;
	    }
	  if (nexthop->type == NEXTHOP_TYPE_IFINDEX
	      || nexthop->type == NEXTHOP_TYPE_IFNAME
	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
	    ifindex = nexthop->ifindex;

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

      /* Under kame set interface index to link local address. */
#ifdef KAME

#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \
      do { \
	(a).s6_addr[2] = ((i) >> 8) & 0xff; \
	(a).s6_addr[3] = (i) & 0xff; \
      } while (0)

      if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr))
	SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, ifindex);
#endif /* KAME */

      if (gate && p->prefixlen == 128)
	mask = NULL;
      else
	{
	  masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr);
	  sin_mask.sin6_family = AF_INET6;
#ifdef SIN6_LEN
	  sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
#endif /* SIN6_LEN */
	  mask = &sin_mask;
	}

      error = rtm_write (cmd,
			(union sockunion *) &sin_dest,
			(union sockunion *) mask,
			gate ? (union sockunion *)&sin_gate : NULL,
			ifindex,
			rib->flags,
			rib->metric);

#if 0
      if (error)
	{
	  zlog_info ("kernel_rtm_ipv6_multipath(): nexthop %d add error=%d.",
	    nexthop_num, error);
	}
#endif

      nexthop_num++;
    }

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

  return 0; /*XXX*/
}

int
kernel_add_ipv6 (struct prefix *p, struct rib *rib)
{
  int route;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  route =  kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6);
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}

int
kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
{
  int route;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  route =  kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6);
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}

/* 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)
{
  int route;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");
  route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags);
  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}
#endif /* HAVE_IPV6 */
