/*
  PIM for Quagga
  Copyright (C) 2008  Everton da Silva Marques

  This program 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 of the License, or
  (at your option) any later version.

  This program 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 this program; see the file COPYING; if not, write to the
  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  MA 02110-1301 USA
  
  $QuaggaId: $Format:%an, %ai, %h$ $
*/

#include <zebra.h>
#include "zebra/rib.h"

#include "log.h"
#include "prefix.h"
#include "zclient.h"
#include "stream.h"
#include "network.h"
#include "thread.h"

#include "pimd.h"
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_zlookup.h"

extern int zclient_debug;

static void zclient_lookup_sched(struct zclient *zlookup, int delay);

/* Connect to zebra for nexthop lookup. */
static int zclient_lookup_connect(struct thread *t)
{
  struct zclient *zlookup;

  zlookup = THREAD_ARG(t);
  zlookup->t_connect = NULL;

  if (zlookup->sock >= 0) {
    return 0;
  }

  if (zclient_socket_connect(zlookup) < 0) {
    ++zlookup->fail;
    zlog_warn("%s: failure connecting zclient socket: failures=%d",
	      __PRETTY_FUNCTION__, zlookup->fail);
  }
  else {
    zlookup->fail = 0; /* reset counter on connection */
  }

  zassert(!zlookup->t_connect);
  if (zlookup->sock < 0) {
    /* Since last connect failed, retry within 10 secs */
    zclient_lookup_sched(zlookup, 10);
    return -1;
  }

  return 0;
}

/* Schedule connection with delay. */
static void zclient_lookup_sched(struct zclient *zlookup, int delay)
{
  zassert(!zlookup->t_connect);

  THREAD_TIMER_ON(master, zlookup->t_connect,
		  zclient_lookup_connect,
		  zlookup, delay);

  zlog_notice("%s: zclient lookup connection scheduled for %d seconds",
	      __PRETTY_FUNCTION__, delay);
}

/* Schedule connection for now. */
static void zclient_lookup_sched_now(struct zclient *zlookup)
{
  zassert(!zlookup->t_connect);

  zlookup->t_connect = thread_add_event(master, zclient_lookup_connect,
					zlookup, 0);

  zlog_notice("%s: zclient lookup immediate connection scheduled",
	      __PRETTY_FUNCTION__);
}

/* Schedule reconnection, if needed. */
static void zclient_lookup_reconnect(struct zclient *zlookup)
{
  if (zlookup->t_connect) {
    return;
  }

  zclient_lookup_sched_now(zlookup);
}

static void zclient_lookup_failed(struct zclient *zlookup)
{
  if (zlookup->sock >= 0) {
    if (close(zlookup->sock)) {
      zlog_warn("%s: closing fd=%d: errno=%d %s", __func__, zlookup->sock,
		errno, safe_strerror(errno));
    }
    zlookup->sock = -1;
  }

  zclient_lookup_reconnect(zlookup);
}

struct zclient *zclient_lookup_new()
{
  struct zclient *zlookup;

  zlookup = zclient_new (master);
  if (!zlookup) {
    zlog_err("%s: zclient_new() failure",
	     __PRETTY_FUNCTION__);
    return 0;
  }

  zlookup->sock = -1;
  zlookup->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
  zlookup->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
  zlookup->t_connect = 0;

  zclient_lookup_sched_now(zlookup);

  zlog_notice("%s: zclient lookup socket initialized",
	      __PRETTY_FUNCTION__);

  return zlookup;
}

static int zclient_read_nexthop(struct zclient *zlookup,
				struct pim_zlookup_nexthop nexthop_tab[],
				const int tab_size,
				struct in_addr addr)
{
  int num_ifindex = 0;
  struct stream *s;
  const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */
  uint16_t length;
  u_char marker;
  u_char version;
  uint16_t vrf_id;
  uint16_t command;
  struct in_addr raddr;
  uint8_t distance;
  uint32_t metric;
  int nexthop_num;
  int i, err;

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: addr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str);
  }

  s = zlookup->ibuf;
  stream_reset(s);

  err = zclient_read_header (s, zlookup->sock, &length, &marker, &version,
                             &vrf_id, &command);
  if (err < 0) {
    zlog_err("%s %s: zclient_read_header() failed",
	     __FILE__, __PRETTY_FUNCTION__);
    zclient_lookup_failed(zlookup);
    return -1;
  }

  if (length < MIN_LEN) {
    zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
	     __FILE__, __PRETTY_FUNCTION__, length, MIN_LEN);
    zclient_lookup_failed(zlookup);
    return -2;
  }
  
  if (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) {
    zlog_err("%s: socket %d command mismatch: %d",
            __func__, zlookup->sock, command);
    return -5;
  }

  raddr.s_addr = stream_get_ipv4(s);

  if (raddr.s_addr != addr.s_addr) {
    char addr_str[100];
    char raddr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
    zlog_warn("%s: address mismatch: addr=%s raddr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str, raddr_str);
    /* warning only */
  }

  distance = stream_getc(s);
  metric = stream_getl(s);
  nexthop_num = stream_getc(s);

  if (nexthop_num < 1) {
    zlog_err("%s: socket %d bad nexthop_num=%d",
            __func__, zlookup->sock, nexthop_num);
    return -6;
  }

  length -= MIN_LEN;

  for (i = 0; i < nexthop_num; ++i) {
    enum nexthop_types_t nexthop_type;

    if (length < 1) {
      zlog_err("%s: socket %d empty input expecting nexthop_type: len=%d",
	       __func__, zlookup->sock, length);
      return -7;
    }
    
    nexthop_type = stream_getc(s);
    --length;

    switch (nexthop_type) {
    case ZEBRA_NEXTHOP_IFINDEX:
    case ZEBRA_NEXTHOP_IFNAME:
    case ZEBRA_NEXTHOP_IPV4_IFINDEX:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      if (nexthop_type == ZEBRA_NEXTHOP_IPV4_IFINDEX) {
	if (length < 4) {
	  zlog_err("%s: socket %d short input expecting nexthop IPv4-addr: len=%d",
		   __func__, zlookup->sock, length);
	  return -8;
	}
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
	length -= 4;
      }
      else {
	nexthop_tab[num_ifindex].nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
      }
      nexthop_tab[num_ifindex].ifindex           = stream_getl(s);
      nexthop_tab[num_ifindex].protocol_distance = distance;
      nexthop_tab[num_ifindex].route_metric      = metric;
      ++num_ifindex;
      break;
    case ZEBRA_NEXTHOP_IPV4:
      if (num_ifindex >= tab_size) {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		 (num_ifindex + 1), tab_size, addr_str);
	return num_ifindex;
      }
      nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s);
      length -= 4;
      nexthop_tab[num_ifindex].ifindex             = 0;
      nexthop_tab[num_ifindex].protocol_distance   = distance;
      nexthop_tab[num_ifindex].route_metric        = metric;
      if (PIM_DEBUG_ZEBRA) {
	char addr_str[100];
	char nexthop_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	pim_inet4_dump("<nexthop?>", nexthop_tab[num_ifindex].nexthop_addr, nexthop_str, sizeof(nexthop_str));
	zlog_debug("%s %s: zebra returned recursive nexthop %s for address %s",
		   __FILE__, __PRETTY_FUNCTION__,
		   nexthop_str, addr_str);
      }
      ++num_ifindex;
      break;
    default:
      /* do nothing */
      {
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s",
		 __FILE__, __PRETTY_FUNCTION__,
		  nexthop_type, addr_str);
      }
      break;
    }
  }

  return num_ifindex;
}

static int zclient_lookup_nexthop_once(struct zclient *zlookup,
				       struct pim_zlookup_nexthop nexthop_tab[],
				       const int tab_size,
				       struct in_addr addr)
{
  struct stream *s;
  int ret;

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: addr=%s", 
	       __PRETTY_FUNCTION__,
	       addr_str);
  }

  /* Check socket. */
  if (zlookup->sock < 0) {
    zlog_err("%s %s: zclient lookup socket is not connected",
	     __FILE__, __PRETTY_FUNCTION__);
    zclient_lookup_failed(zlookup);
    return -1;
  }
  
  s = zlookup->obuf;
  stream_reset(s);
  zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT);
  stream_put_in_addr(s, &addr);
  stream_putw_at(s, 0, stream_get_endp(s));
  
  ret = writen(zlookup->sock, s->data, stream_get_endp(s));
  if (ret < 0) {
    zlog_err("%s %s: writen() failure writing to zclient lookup socket",
	     __FILE__, __PRETTY_FUNCTION__);
    zclient_lookup_failed(zlookup);
    return -2;
  }
  if (ret == 0) {
    zlog_err("%s %s: connection closed on zclient lookup socket",
	     __FILE__, __PRETTY_FUNCTION__);
    zclient_lookup_failed(zlookup);
    return -3;
  }
  
  return zclient_read_nexthop(zlookup, nexthop_tab,
			      tab_size, addr);
}

int zclient_lookup_nexthop(struct zclient *zlookup,
			   struct pim_zlookup_nexthop nexthop_tab[],
			   const int tab_size,
			   struct in_addr addr,
			   int max_lookup)
{
  int lookup;
  uint32_t route_metric = 0xFFFFFFFF;
  uint8_t  protocol_distance = 0xFF;

  for (lookup = 0; lookup < max_lookup; ++lookup) {
    int num_ifindex;
    int first_ifindex;
    struct in_addr nexthop_addr;

    num_ifindex = zclient_lookup_nexthop_once(qpim_zclient_lookup, nexthop_tab,
					      PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr);
    if ((num_ifindex < 1) && PIM_DEBUG_ZEBRA) {
      char addr_str[100];
      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
      zlog_warn("%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
		__FILE__, __PRETTY_FUNCTION__,
		lookup, max_lookup, addr_str);
      return -1;
    }

    if (lookup < 1) {
      /* this is the non-recursive lookup - save original metric/distance */
      route_metric = nexthop_tab[0].route_metric;
      protocol_distance = nexthop_tab[0].protocol_distance;
    }
    
    /*
      FIXME: Non-recursive nexthop ensured only for first ifindex.
      However, recursive route lookup should really be fixed in zebra daemon.
      See also TODO T24.
     */
    first_ifindex = nexthop_tab[0].ifindex;
    nexthop_addr = nexthop_tab[0].nexthop_addr;
    if (first_ifindex > 0) {
      /* found: first ifindex is non-recursive nexthop */

      if ((lookup > 0) && PIM_DEBUG_ZEBRA) {
	/* Report non-recursive success after first lookup */
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_debug("%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d",
		   __FILE__, __PRETTY_FUNCTION__,
		   lookup, max_lookup, first_ifindex, addr_str,
		   nexthop_tab[0].protocol_distance,
		   nexthop_tab[0].route_metric);

	/* use last address as nexthop address */
	nexthop_tab[0].nexthop_addr = addr;

	/* report original route metric/distance */
	nexthop_tab[0].route_metric = route_metric;
	nexthop_tab[0].protocol_distance = protocol_distance;
      }

      return num_ifindex;
    }

    if (PIM_DEBUG_ZEBRA) {
      char addr_str[100];
      char nexthop_str[100];
      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
      pim_inet4_dump("<nexthop?>", nexthop_addr, nexthop_str, sizeof(nexthop_str));
      zlog_debug("%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d",
		__FILE__, __PRETTY_FUNCTION__,
		lookup, max_lookup, nexthop_str, addr_str,
		nexthop_tab[0].protocol_distance,
		nexthop_tab[0].route_metric);
    }

    addr = nexthop_addr; /* use nexthop addr for recursive lookup */

  } /* for (max_lookup) */

  if (PIM_DEBUG_ZEBRA) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_warn("%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
	      __FILE__, __PRETTY_FUNCTION__,
	      lookup, max_lookup, addr_str);
  }

  return -2;
}
