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