/*
 * Address linked list routine.
 * 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 "prefix.h"
#include "linklist.h"
#include "if.h"
#include "table.h"
#include "rib.h"
#include "table.h"
#include "log.h"
#include "memory.h"

#include "zebra/zserv.h"
#include "zebra/redistribute.h"
#include "zebra/interface.h"
#include "zebra/connected.h"
extern struct zebra_t zebrad;

/* communicate the withdrawal of a connected address */
static void
connected_withdraw (struct connected *ifc)
{
  if (! ifc)
    return;

  /* Update interface address information to protocol daemon. */
  if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    {
      zebra_interface_address_delete_update (ifc->ifp, ifc);

      if (ifc->address->family == AF_INET)
        if_subnet_delete (ifc->ifp, ifc);

      if (ifc->address->family == AF_INET)
        connected_down_ipv4 (ifc->ifp, ifc);
#ifdef HAVE_IPV6
      else
        connected_down_ipv6 (ifc->ifp, ifc);
#endif

      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
    }

  /* The address is not in the kernel anymore, so clear the flag */
  UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);

  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
    {
      listnode_delete (ifc->ifp->connected, ifc);
      connected_free (ifc);
    }
}

static void
connected_announce (struct interface *ifp, struct connected *ifc)
{
  if (!ifc)
    return;
  
  listnode_add (ifp->connected, ifc);

  /* Update interface address information to protocol daemon. */
  if (ifc->address->family == AF_INET)
    if_subnet_add (ifp, ifc);

  zebra_interface_address_add_update (ifp, ifc);

  if (if_is_operative(ifp))
    {
      if (ifc->address->family == AF_INET)
        connected_up_ipv4 (ifp, ifc);
#ifdef HAVE_IPV6
      else
        connected_up_ipv6 (ifp, ifc);
#endif
    }
}

/* If same interface address is already exist... */
struct connected *
connected_check (struct interface *ifp, struct prefix *p)
{
  struct connected *ifc;
  struct listnode *node;

  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
    if (prefix_same (ifc->address, p))
      return ifc;

  return NULL;
}

/* Check if two ifc's describe the same address in the same state */
static int
connected_same (struct connected *ifc1, struct connected *ifc2)
{
  if (ifc1->ifp != ifc2->ifp)
    return 0;
  
  if (ifc1->destination)
    if (!ifc2->destination)
      return 0;
  if (ifc2->destination)
    if (!ifc1->destination)
      return 0;
  
  if (ifc1->destination && ifc2->destination)
    if (!prefix_same (ifc1->destination, ifc2->destination))
      return 0;

  if (ifc1->flags != ifc2->flags)
    return 0;

  if (ifc1->conf != ifc2->conf)
    return 0;
  
  return 1;
}

/* Handle changes to addresses and send the neccesary announcements
 * to clients. */
static void
connected_update(struct interface *ifp, struct connected *ifc)
{
  struct connected *current;
  
  /* Check same connected route. */
  if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
    {
      if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
        SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
	
      /* Avoid spurious withdraws, this might be just the kernel 'reflecting'
       * back an address we have already added.
       */
      if (connected_same (current, ifc))
        {
          /* nothing to do */
          connected_free (ifc);
          return;
        }

      /* Clear the configured flag on the old ifc, so it will be freed by
       * connected withdraw. */
      UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
      connected_withdraw (current); /* implicit withdraw - freebsd does this */
    }

  /* If the connected is new or has changed, announce it, if it is usable */
  if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
    connected_announce(ifp, ifc);
}

/* Called from if_up(). */
void
connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv4 p;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));

  /* Apply mask to the network. */
  apply_mask_ipv4 (&p);

  /* In case of connected address is 0.0.0.0/0 we treat it tunnel
     address. */
  if (prefix_ipv4_any (&p))
    return;

  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
	RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);

  rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
	RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);

  rib_update ();
}

/* Add connected IPv4 route to the interface. */
void
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, 
		    u_char prefixlen, struct in_addr *broad, 
		    const char *label)
{
  struct prefix_ipv4 *p;
  struct connected *ifc;

  /* Make connected structure. */
  ifc = connected_new ();
  ifc->ifp = ifp;
  ifc->flags = flags;
  /* If we get a notification from the kernel,
   * we can safely assume the address is known to the kernel */
  SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);

  /* Allocate new connected address. */
  p = prefix_ipv4_new ();
  p->family = AF_INET;
  p->prefix = *addr;
  p->prefixlen = prefixlen;
  ifc->address = (struct prefix *) p;
  
  /* If there is broadcast or peer address. */
  if (broad)
    {
      p = prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = *broad;
      p->prefixlen = prefixlen;
      ifc->destination = (struct prefix *) p;

      /* validate the destination address */
      if (CONNECTED_PEER(ifc))
        {
	  if (IPV4_ADDR_SAME(addr,broad))
	    zlog_warn("warning: interface %s has same local and peer "
		      "address %s, routing protocols may malfunction",
		      ifp->name,inet_ntoa(*addr));
        }
      else
        {
	  if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen))
	    {
	      char buf[2][INET_ADDRSTRLEN];
	      struct in_addr bcalc;
	      bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen);
	      zlog_warn("warning: interface %s broadcast addr %s/%d != "
	       		"calculated %s, routing protocols may malfunction",
	    		ifp->name,
			inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])),
			prefixlen,
			inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1])));
	    }
        }

    }
  else
    {
      if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
        {
	  zlog_warn("warning: %s called for interface %s "
		    "with peer flag set, but no peer address supplied",
		    __func__, ifp->name);
	  UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
	}

      /* no broadcast or destination address was supplied */
      if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
	zlog_warn("warning: PtP interface %s with addr %s/%d needs a "
		  "peer address",ifp->name,inet_ntoa(*addr),prefixlen);
    }

  /* Label of this address. */
  if (label)
    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);

  /* For all that I know an IPv4 address is always ready when we receive
   * the notification. So it should be safe to set the REAL flag here. */
  SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);

  connected_update(ifp, ifc);
}

void
connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv4 p;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));

  /* Apply mask to the network. */
  apply_mask_ipv4 (&p);

  /* In case of connected address is 0.0.0.0/0 we treat it tunnel
     address. */
  if (prefix_ipv4_any (&p))
    return;

  /* Same logic as for connected_up_ipv4(): push the changes into the head. */
  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);

  rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);

  rib_update ();
}

/* Delete connected IPv4 route to the interface. */
void
connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
		       u_char prefixlen, struct in_addr *broad)
{
  struct prefix_ipv4 p;
  struct connected *ifc;

  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefix = *addr;
  p.prefixlen = prefixlen;

  ifc = connected_check (ifp, (struct prefix *) &p);
  if (! ifc)
    return;
    
  connected_withdraw (ifc);

  rib_update();
}

#ifdef HAVE_IPV6
void
connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));

  /* Apply mask to the network. */
  apply_mask_ipv6 (&p);

#if ! defined (MUSICA) && ! defined (LINUX)
  /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;
#endif

  rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
                ifp->metric, 0, SAFI_UNICAST);

  rib_update ();
}

/* Add connected IPv6 route to the interface. */
void
connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr,
		    u_char prefixlen, struct in6_addr *broad,
		    const char *label)
{
  struct prefix_ipv6 *p;
  struct connected *ifc;

  /* Make connected structure. */
  ifc = connected_new ();
  ifc->ifp = ifp;
  ifc->flags = flags;
  /* If we get a notification from the kernel,
   * we can safely assume the address is known to the kernel */
  SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);

  /* Allocate new connected address. */
  p = prefix_ipv6_new ();
  p->family = AF_INET6;
  IPV6_ADDR_COPY (&p->prefix, addr);
  p->prefixlen = prefixlen;
  ifc->address = (struct prefix *) p;

  /* If there is broadcast or peer address. */
  if (broad)
    {
      if (IN6_IS_ADDR_UNSPECIFIED(broad))
	zlog_warn("warning: %s called for interface %s with unspecified "
		  "destination address; ignoring!", __func__, ifp->name);
      else
	{
	  p = prefix_ipv6_new ();
	  p->family = AF_INET6;
	  IPV6_ADDR_COPY (&p->prefix, broad);
	  p->prefixlen = prefixlen;
	  ifc->destination = (struct prefix *) p;
	}
    }
  if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination)
    {
      zlog_warn("warning: %s called for interface %s "
		"with peer flag set, but no peer address supplied",
		__func__, ifp->name);
      UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
    }

  /* Label of this address. */
  if (label)
    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);

  /* On Linux, we only get here when DAD is complete, therefore we can set
   * ZEBRA_IFC_REAL.
   *
   * On BSD, there currently doesn't seem to be a way to check for completion of
   * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL, although DAD
   * might still be running.
   */
  SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
  connected_update(ifp, ifc);
}

void
connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
{
  struct prefix_ipv6 p;

  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
    return;

  PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));

  apply_mask_ipv6 (&p);

  if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
    return;

  rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);

  rib_update ();
}

void
connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
		       u_char prefixlen, struct in6_addr *broad)
{
  struct prefix_ipv6 p;
  struct connected *ifc;
  
  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  memcpy (&p.prefix, address, sizeof (struct in6_addr));
  p.prefixlen = prefixlen;

  ifc = connected_check (ifp, (struct prefix *) &p);
  if (! ifc)
    return;

  connected_withdraw (ifc);

  rib_update();
}
#endif /* HAVE_IPV6 */
