*: merge branch stable/0.99.23

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index fc1bef8..1bd2dd8 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -78,7 +78,7 @@
 	  c = com->size -i -1;
 
 	  if (c > 0)
-	    memcpy (com->val + i, com->val + (i + 1), c * sizeof (*val));
+	    memmove (com->val + i, com->val + (i + 1), c * sizeof (*val));
 
 	  com->size--;
 
diff --git a/configure.ac b/configure.ac
index 220124a..f1df482 100755
--- a/configure.ac
+++ b/configure.ac
@@ -442,7 +442,7 @@
 dnl -------------------------
 AC_CHECK_HEADERS([stropts.h sys/ksym.h sys/times.h sys/select.h \
 	sys/types.h linux/version.h netdb.h asm/types.h \
-	sys/param.h limits.h signal.h \
+	sys/cdefs.h sys/param.h limits.h signal.h \
 	sys/socket.h netinet/in.h time.h sys/time.h])
 
 dnl Utility macro to avoid retyping includes all the time
@@ -1204,21 +1204,22 @@
   if test "$zebra_cv_linux_ipv6" = "yes";then
     AC_MSG_CHECKING(for GNU libc >= 2.1)
     AC_DEFINE(HAVE_IPV6,1,Linux IPv6)
+    AC_DEFINE(LINUX_IPV6,1,Linux IPv6 stack)
+
     AC_EGREP_CPP(yes, [
 #include <features.h>
 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
   yes
 #endif], 
       [glibc=yes
-       AC_DEFINE(LINUX_IPV6,1,Linux IPv6 stack)
        AC_MSG_RESULT(yes)], 
       AC_MSG_RESULT(no)
     )
     RIPNGD="ripngd"
     OSPF6D="ospf6d"
     if test "$glibc" != "yes"; then
-      INCLUDES="-I/usr/inet6/include"
       if test x`ls /usr/inet6/lib/libinet6.a 2>/dev/null` != x;then
+         INCLUDES="-I/usr/inet6/include"
          LIB_IPV6="-L/usr/inet6/lib -linet6"
       fi
     fi
diff --git a/isisd/include-netbsd/iso.h b/isisd/include-netbsd/iso.h
index 1a80aec..42b9bc8 100644
--- a/isisd/include-netbsd/iso.h
+++ b/isisd/include-netbsd/iso.h
@@ -192,7 +192,7 @@
 #else
 /* user utilities definitions from the iso library */
 
-#ifdef SUNOS_5
+#ifndef HAVE_SYS_CDEFS_H
 #define	__P(x)	x
 #define	__BEGIN_DECLS
 #define	__END_DECLS
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 8a92789..e0208fa 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -402,6 +402,7 @@
   u_int32_t expected = 0, found = 0, auth_tlv_offset = 0;
   uint16_t pdu_len;
   struct tlvs tlvs;
+  int v4_usable = 0, v6_usable = 0;
 
   if (isis->debugs & DEBUG_ADJ_PACKETS)
     {
@@ -518,11 +519,44 @@
   /*
    * check if it's own interface ip match iih ip addrs
    */
-  if ((found & TLVFLAG_IPV4_ADDR) == 0 ||
-      ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0)
+  if (found & TLVFLAG_IPV4_ADDR)
     {
-      zlog_warn ("ISIS-Adj: No usable IP interface addresses "
-                 "in LAN IIH from %s\n", circuit->interface->name);
+      if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
+	v4_usable = 1;
+      else
+	zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
+		   "in P2P IIH from %s\n", circuit->interface->name);
+    }
+#ifndef HAVE_IPV6
+  else /* !(found & TLVFLAG_IPV4_ADDR) */
+    zlog_warn ("ISIS-Adj: no IPv4 in P2P IIH from %s "
+	       "(this isisd has no IPv6)\n", circuit->interface->name);
+
+#else
+  if (found & TLVFLAG_IPV6_ADDR)
+    {
+      /* TBA: check that we have a linklocal ourselves? */
+      struct listnode *node;
+      struct in6_addr *ip;
+      for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip))
+	if (IN6_IS_ADDR_LINKLOCAL (ip))
+	  {
+	    v6_usable = 1;
+	    break;
+	  }
+
+      if (!v6_usable)
+	zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local "
+		   "in P2P IIH from %s\n", circuit->interface->name);
+    }
+
+  if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
+    zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in P2P IIH from %s\n",
+	       circuit->interface->name);
+#endif
+
+  if (!v6_usable && !v4_usable)
+    {
       free_tlvs (&tlvs);
       return ISIS_WARNING;
     }
@@ -859,6 +893,7 @@
   struct tlvs tlvs;
   u_char *snpa;
   struct listnode *node;
+  int v4_usable = 0, v6_usable = 0;
 
   if (isis->debugs & DEBUG_ADJ_PACKETS)
     {
@@ -1045,14 +1080,48 @@
   /*
    * check if it's own interface ip match iih ip addrs
    */
-  if ((found & TLVFLAG_IPV4_ADDR) == 0 ||
-      ip_match (circuit->ip_addrs, tlvs.ipv4_addrs) == 0)
+  if (found & TLVFLAG_IPV4_ADDR)
     {
-      zlog_debug ("ISIS-Adj: No usable IP interface addresses "
-                  "in LAN IIH from %s\n", circuit->interface->name);
-      retval = ISIS_WARNING;
-      goto out;
+      if (ip_match (circuit->ip_addrs, tlvs.ipv4_addrs))
+	v4_usable = 1;
+      else
+	zlog_warn ("ISIS-Adj: IPv4 addresses present but no overlap "
+		   "in LAN IIH from %s\n", circuit->interface->name);
     }
+#ifndef HAVE_IPV6
+  else /* !(found & TLVFLAG_IPV4_ADDR) */
+    zlog_warn ("ISIS-Adj: no IPv4 in LAN IIH from %s "
+	       "(this isisd has no IPv6)\n", circuit->interface->name);
+
+#else
+  if (found & TLVFLAG_IPV6_ADDR)
+    {
+      /* TBA: check that we have a linklocal ourselves? */
+      struct listnode *node;
+      struct in6_addr *ip;
+      for (ALL_LIST_ELEMENTS_RO (tlvs.ipv6_addrs, node, ip))
+	if (IN6_IS_ADDR_LINKLOCAL (ip))
+	  {
+	    v6_usable = 1;
+	    break;
+	  }
+
+      if (!v6_usable)
+	zlog_warn ("ISIS-Adj: IPv6 addresses present but no link-local "
+		   "in LAN IIH from %s\n", circuit->interface->name);
+    }
+
+  if (!(found & (TLVFLAG_IPV4_ADDR | TLVFLAG_IPV6_ADDR)))
+    zlog_warn ("ISIS-Adj: neither IPv4 nor IPv6 addr in LAN IIH from %s\n",
+	       circuit->interface->name);
+#endif
+
+  if (!v6_usable && !v4_usable)
+    {
+      free_tlvs (&tlvs);
+      return ISIS_WARNING;
+    }
+
 
   adj = isis_adj_lookup (hdr.source_id, circuit->u.bc.adjdb[level - 1]);
   if ((adj == NULL) || (memcmp(adj->snpa, ssnpa, ETH_ALEN)) ||
diff --git a/lib/queue.h b/lib/queue.h
index 70cffab..48b363e 100644
--- a/lib/queue.h
+++ b/lib/queue.h
@@ -33,8 +33,6 @@
 #ifndef _SYS_QUEUE_H_
 #define	_SYS_QUEUE_H_
 
-#include <sys/cdefs.h>
-
 /*
  * This file defines four types of data structures: singly-linked lists,
  * singly-linked tail queues, lists and tail queues.
diff --git a/lib/zclient.c b/lib/zclient.c
index 20188f6..3b5477e 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -805,6 +805,16 @@
 	   ifc->flags = ifc_flags;
 	   if (ifc->destination)
 	     ifc->destination->prefixlen = ifc->address->prefixlen;
+	   else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
+	     {
+	       /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
+	       char buf[BUFSIZ];
+	       prefix2str (ifc->address, buf, sizeof(buf));
+	       zlog_warn("warning: interface %s address %s "
+		    "with peer flag set, but no peer address!",
+		    ifp->name, buf);
+	       UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
+	     }
 	 }
     }
   else
diff --git a/tests/bgp_mp_attr_test.c b/tests/bgp_mp_attr_test.c
index 177c1ad..aa8e485 100644
--- a/tests/bgp_mp_attr_test.c
+++ b/tests/bgp_mp_attr_test.c
@@ -478,7 +478,7 @@
   
   printf ("parsed?: %s\n", ret ? "no" : "yes");
   
-  if (ret != t->parses)
+  if ((ret == 0) != (t->parses == 0))
     failed++;
   
   if (tty)
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 452ea64..95a82fd 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -282,9 +282,17 @@
   while (1)
     {
       char buf[NL_PKT_BUF_SIZE];
-      struct iovec iov = { buf, sizeof buf };
+      struct iovec iov = {
+        .iov_base = buf,
+        .iov_len = sizeof buf
+      };
       struct sockaddr_nl snl;
-      struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
+      struct msghdr msg = {
+        .msg_name = (void *) &snl,
+        .msg_namelen = sizeof snl,
+        .msg_iov = &iov,
+        .msg_iovlen = 1
+      };
       struct nlmsghdr *h;
 
       status = recvmsg (nl->sock, &msg, 0);
@@ -1312,8 +1320,16 @@
 {
   int status;
   struct sockaddr_nl snl;
-  struct iovec iov = { (void *) n, n->nlmsg_len };
-  struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
+  struct iovec iov = {
+    .iov_base = (void *) n,
+    .iov_len = n->nlmsg_len
+  };
+  struct msghdr msg = {
+    .msg_name = (void *) &snl,
+    .msg_namelen = sizeof snl,
+    .msg_iov = &iov,
+    .msg_iovlen = 1,
+  };
   int save_errno;
 
   memset (&snl, 0, sizeof snl);