/*
  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();
  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;
  int nbytes;
  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;
  }
  
  nbytes = stream_read(s, zlookup->sock, length);
  if (nbytes < length) {
    zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d < len=%d",
	     __FILE__, __PRETTY_FUNCTION__, nbytes, length);
    zclient_lookup_failed(zlookup);
    return -3;
  }
  
  if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) {
    zlog_err("%s: socket %d version mismatch, marker %d, version %d",
	     __func__, zlookup->sock, marker, version);
    zclient_lookup_failed(zlookup);
    return -4;
  }
    
  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;
      {
	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_warn("%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) {
      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) {
	/* Report non-recursive success after first lookup */
	char addr_str[100];
	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
	zlog_info("%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;
    }

    {
      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_warn("%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) */

  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;
}
