/* RIPngd Zebra
 * Copyright (C) 2002 6WIND <vincent.jardin@6wind.com>
 *
 * 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.  
 */

/* This file is required in order to support properly the RIPng nexthop
 * feature.
 */

#include <zebra.h>

/* For struct udphdr. */
#include <netinet/udp.h>

#include "linklist.h"
#include "stream.h"
#include "log.h"
#include "memory.h"
#include "vty.h"
#include "if.h"
#include "prefix.h"

#include "ripngd/ripngd.h"
#include "ripngd/ripng_debug.h"
#include "ripngd/ripng_nexthop.h"

#define DEBUG 1

#define min(a, b) ((a) < (b) ? (a) : (b))

struct ripng_rte_data {
  struct prefix_ipv6 *p;
  struct ripng_info *rinfo;
  struct ripng_aggregate *aggregate;
};

void _ripng_rte_del(struct ripng_rte_data *A);
int _ripng_rte_cmp(struct ripng_rte_data *A, struct ripng_rte_data *B);

#define METRIC_OUT(a) \
    (a->rinfo ?  a->rinfo->metric_out : a->aggregate->metric_out)
#define NEXTHOP_OUT(a) \
    (a->rinfo ?  a->rinfo->nexthop_out : a->aggregate->nexthop_out)
#define TAG_OUT(a) \
    (a->rinfo ?  a->rinfo->tag_out : a->aggregate->tag_out)

struct list *
ripng_rte_new(void) {
  struct list *rte;

  rte = list_new();
  rte->cmp = (int (*)(void *, void *)) _ripng_rte_cmp;
  rte->del = (void (*)(void *)) _ripng_rte_del;

  return rte;
}

void
ripng_rte_free(struct list *ripng_rte_list) {
  list_delete(ripng_rte_list);
}

/* Delete RTE */
void
_ripng_rte_del(struct ripng_rte_data *A) {
  XFREE(MTYPE_RIPNG_RTE_DATA, A);
}

/* Compare RTE:
 *  return +  if A > B
 *         0  if A = B
 *         -  if A < B
 */
int
_ripng_rte_cmp(struct ripng_rte_data *A, struct ripng_rte_data *B) {
  return addr6_cmp(&NEXTHOP_OUT(A), &NEXTHOP_OUT(B));
}

/* Add routing table entry */
void
ripng_rte_add(struct list *ripng_rte_list, struct prefix_ipv6 *p,
              struct ripng_info *rinfo, struct ripng_aggregate *aggregate) {

  struct ripng_rte_data *data;

  /* At least one should not be null */
  assert(!rinfo || !aggregate);

  data = XMALLOC(MTYPE_RIPNG_RTE_DATA, sizeof(*data));
  data->p     = p;
  data->rinfo = rinfo;
  data->aggregate = aggregate;

  listnode_add_sort(ripng_rte_list, data);
} 

/* Send the RTE with the nexthop support
 */
void
ripng_rte_send(struct list *ripng_rte_list, struct interface *ifp,
               struct sockaddr_in6 *to) {

  struct ripng_rte_data *data;
  struct listnode * nn;

  struct in6_addr last_nexthop;
  struct in6_addr myself_nexthop;

  struct stream *s;
  int num;
  int mtu;
  int rtemax;
  int ret;

  /* Most of the time, there is no nexthop */
  memset(&last_nexthop, 0, sizeof(last_nexthop));

  /* Use myself_nexthop if the nexthop is not a link-local address, because
   * we remain a right path without beeing the optimal one.
   */
  memset(&myself_nexthop, 0, sizeof(myself_nexthop));

  /* Output stream get from ripng structre.  XXX this should be
     interface structure. */
  s = ripng->obuf;

  /* Reset stream and RTE counter. */
  stream_reset (s);
  num = 0;

  mtu = ifp->mtu6;
  if (mtu < 0)
    mtu = IFMINMTU;

  rtemax = (min (mtu, RIPNG_MAX_PACKET_SIZE) -
	    IPV6_HDRLEN - 
	    sizeof (struct udphdr) -
	    sizeof (struct ripng_packet) +
	    sizeof (struct rte)) / sizeof (struct rte);

  LIST_LOOP(ripng_rte_list, data, nn) {

    /* (2.1) Next hop support */
    if (!IPV6_ADDR_SAME(&last_nexthop, &NEXTHOP_OUT(data))) {

      /* A nexthop entry should be at least followed by 1 RTE */
      if (num == (rtemax-1)) {
	ret = ripng_send_packet (STREAM_DATA (s), stream_get_endp (s),
				 to, ifp);

        if (ret >= 0 && IS_RIPNG_DEBUG_SEND)
          ripng_packet_dump((struct ripng_packet *)STREAM_DATA (s),
			    stream_get_endp(s), "SEND");
        num = 0;
        stream_reset (s);
      }

      /* Add the nexthop (2.1) */

      /* If the received next hop address is not a link-local address,
       * it should be treated as 0:0:0:0:0:0:0:0.
       */
      if (!IN6_IS_ADDR_LINKLOCAL(&NEXTHOP_OUT(data)))
        last_nexthop = myself_nexthop;
      else
	last_nexthop = NEXTHOP_OUT(data);

      num = ripng_write_rte(num, s, NULL, &last_nexthop, 0, RIPNG_METRIC_NEXTHOP);
    } else {
      /* Rewrite the nexthop for each new packet */
      if ((num == 0) && !IPV6_ADDR_SAME(&last_nexthop, &myself_nexthop))
        num = ripng_write_rte(num, s, NULL, &last_nexthop, 0, RIPNG_METRIC_NEXTHOP);
    }
    num = ripng_write_rte(num, s, data->p, NULL,
			  TAG_OUT(data), METRIC_OUT(data));

    if (num == rtemax) {
      ret = ripng_send_packet (STREAM_DATA (s), stream_get_endp (s),
			       to, ifp);

      if (ret >= 0 && IS_RIPNG_DEBUG_SEND)
        ripng_packet_dump((struct ripng_packet *)STREAM_DATA (s),
			  stream_get_endp(s), "SEND");
      num = 0;
      stream_reset (s);
    }
  }

  /* If unwritten RTE exist, flush it. */
  if (num != 0) {
    ret = ripng_send_packet (STREAM_DATA (s), stream_get_endp (s),
			     to, ifp);

    if (ret >= 0 && IS_RIPNG_DEBUG_SEND)
      ripng_packet_dump ((struct ripng_packet *)STREAM_DATA (s),
			 stream_get_endp (s), "SEND");
    num = 0;
    stream_reset (s);
  }
}
