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

#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
/* 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;
}
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_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[PREFIX_STRLEN];

  if (IS_ZEBRA_DEBUG_RIB)
    prefix2str (p, prefix_buf, sizeof(prefix_buf));
  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: attention! gate not found for rib %p",
                 __func__, prefix_buf, rib);
               rib_dump (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: successfully did NH %s",
                   __func__, prefix_buf, 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:
               zlog_err ("%s: %s: rtm_write() unexpectedly returned %d for command %s",
                 __func__, prefix2str(p, prefix_buf, sizeof(prefix_buf)),
                 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*/
}

#ifdef HAVE_IPV6

#ifdef SIN6_LEN
/* 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 (IN6_IS_ADDR_UNSPECIFIED (&mask)) 
    return sizeof (long);

  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;
}
#endif /* SIN6_LEN */

/* Interface between zebra message and rtm message. */
static int
kernel_rtm_ipv6 (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(): nexthop %d add error=%d.",
	    nexthop_num, error);
	}
#else
      (void)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(): No useful nexthop.");
      return 0;
    }

  return 0; /*XXX*/
}

#endif

int
kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new)
{
  struct rib *rib;
  int route = 0, cmd;

  if (!old && new)
    cmd = RTM_ADD;
  else if (old && !new)
    cmd = RTM_DELETE;
  else
    cmd = RTM_CHANGE;

  rib = new ? new : old;

  if (zserv_privs.change(ZPRIVS_RAISE))
    zlog (NULL, LOG_ERR, "Can't raise privileges");

  switch (PREFIX_FAMILY(p))
    {
    case AF_INET:
      route = kernel_rtm_ipv4 (cmd, p, rib, AF_INET);
      break;
    case AF_INET6:
      route = kernel_rtm_ipv6 (cmd, p, rib, AF_INET6);
      break;
    }

  if (zserv_privs.change(ZPRIVS_LOWER))
    zlog (NULL, LOG_ERR, "Can't lower privileges");

  return route;
}
