summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/icmp6.h14
-rw-r--r--sys/netinet6/icmp6.c158
-rw-r--r--sys/netinet6/in6_ifattach.c55
-rw-r--r--sys/netinet6/ip6_input.c8
-rw-r--r--sys/netinet6/nd6.c17
-rw-r--r--sys/netinet6/nd6.h8
-rw-r--r--sys/netinet6/nd6_nbr.c212
-rw-r--r--sys/netinet6/nd6_rtr.c68
8 files changed, 314 insertions, 226 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h
index 5a62d382e9a..effaf0f04e0 100644
--- a/sys/netinet/icmp6.h
+++ b/sys/netinet/icmp6.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: icmp6.h,v 1.14 2001/01/22 04:31:21 itojun Exp $ */
-/* $KAME: icmp6.h,v 1.32 2001/01/22 02:26:00 itojun Exp $ */
+/* $OpenBSD: icmp6.h,v 1.15 2001/02/07 11:43:52 itojun Exp $ */
+/* $KAME: icmp6.h,v 1.39 2001/02/06 03:48:06 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -537,6 +537,12 @@ struct icmp6stat {
#define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect
#define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown
u_quad_t icp6s_pmtuchg; /* path MTU changes */
+ u_quad_t icp6s_nd_badopt; /* bad ND options */
+ u_quad_t icp6s_badns; /* bad neighbor solicitation */
+ u_quad_t icp6s_badna; /* bad neighbor advertisement */
+ u_quad_t icp6s_badrs; /* bad router advertisement */
+ u_quad_t icp6s_badra; /* bad router advertisement */
+ u_quad_t icp6s_badredirect; /* bad redirect message */
};
/*
@@ -559,7 +565,8 @@ struct icmp6stat {
#define ICMPV6CTL_ND6_MAXNUDHINT 15
#define ICMPV6CTL_MTUDISC_HIWAT 16
#define ICMPV6CTL_MTUDISC_LOWAT 17
-#define ICMPV6CTL_MAXID 18
+#define ICMPV6CTL_ND6_DEBUG 18
+#define ICMPV6CTL_MAXID 19
#define ICMPV6CTL_NAMES { \
{ 0, 0 }, \
@@ -580,6 +587,7 @@ struct icmp6stat {
{ "nd6_maxnudhint", CTLTYPE_INT }, \
{ "mtudisc_hiwat", CTLTYPE_INT }, \
{ "mtudisc_lowat", CTLTYPE_INT }, \
+ { "nd6_debug", CTLTYPE_INT }, \
}
#define RTF_PROBEMTU RTF_PROTO1
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index d28fd1bea84..68554f5eed1 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: icmp6.c,v 1.29 2001/01/16 06:16:34 itojun Exp $ */
-/* $KAME: icmp6.c,v 1.172 2000/12/11 19:27:06 itojun Exp $ */
+/* $OpenBSD: icmp6.c,v 1.30 2001/02/07 11:43:52 itojun Exp $ */
+/* $KAME: icmp6.c,v 1.191 2001/02/07 08:07:38 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -340,7 +340,7 @@ icmp6_error(m, type, code, param)
if (m && m->m_len < preplen)
m = m_pullup(m, preplen);
if (m == NULL) {
- printf("ENOBUFS in icmp6_error %d\n", __LINE__);
+ nd6log((LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__));
return;
}
@@ -417,11 +417,9 @@ icmp6_input(mp, offp, proto)
code = icmp6->icmp6_code;
if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) {
-#ifdef ND6_DEBUG
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 checksum error(%d|%x) %s\n",
- icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src));
-#endif
+ icmp6->icmp6_type, sum, ip6_sprintf(&ip6->ip6_src)));
icmp6stat.icp6s_checksum++;
goto freeit;
}
@@ -552,9 +550,6 @@ icmp6_input(mp, offp, proto)
* always copy the length we specified.
*/
if (maxlen >= MCLBYTES) {
-#ifdef DIAGNOSTIC
- printf("MCLBYTES too small\n");
-#endif
/* Give up remote */
m_freem(n0);
break;
@@ -673,9 +668,6 @@ icmp6_input(mp, offp, proto)
goto badcode;
maxlen = sizeof(*nip6) + sizeof(*nicmp6) + 4;
if (maxlen >= MCLBYTES) {
-#ifdef DIAGNOSTIC
- printf("MCLBYTES too small\n");
-#endif
/* Give up remote */
break;
}
@@ -815,10 +807,11 @@ icmp6_input(mp, offp, proto)
break;
default:
- printf("icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n",
- icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src),
- ip6_sprintf(&ip6->ip6_dst),
- m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0);
+ nd6log((LOG_DEBUG,
+ "icmp6_input: unknown type %d(src=%s, dst=%s, ifid=%d)\n",
+ icmp6->icmp6_type, ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst),
+ m->m_pkthdr.rcvif ? m->m_pkthdr.rcvif->if_index : 0));
if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) {
/* ICMPv6 error: MUST deliver it by spec... */
code = PRC_NCMDS;
@@ -987,7 +980,7 @@ icmp6_input(mp, offp, proto)
goto notify;
}
}
- notify:
+ notify:
#ifndef PULLDOWN_TEST
icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
#else
@@ -1199,8 +1192,8 @@ ni6_input(m, off)
/*
* Validate Subject address.
*
- * Not sure what exactly does "address belongs to the
- * node" mean in the spec, is it just unicast, or what?
+ * Not sure what exactly "address belongs to the node"
+ * means in the spec, is it just unicast, or what?
*
* At this moment we consider Subject address as
* "belong to the node" if the Subject address equals
@@ -1319,10 +1312,10 @@ ni6_input(m, off)
M_COPY_PKTHDR(n, m); /* just for recvif */
if (replylen > MHLEN) {
if (replylen > MCLBYTES) {
- /*
- * XXX: should we try to allocate more? But MCLBYTES
- * is probably much larger than IPV6_MMTU...
- */
+ /*
+ * XXX: should we try to allocate more? But MCLBYTES
+ * is probably much larger than IPV6_MMTU...
+ */
goto bad;
}
MCLGET(n, M_DONTWAIT);
@@ -1574,9 +1567,9 @@ ni6_addrs(ni6, m, ifpp, subj)
struct ifnet **ifpp;
char *subj;
{
- register struct ifnet *ifp;
- register struct in6_ifaddr *ifa6;
- register struct ifaddr *ifa;
+ struct ifnet *ifp;
+ struct in6_ifaddr *ifa6;
+ struct ifaddr *ifa;
struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */
int addrs = 0, addrsofif, iffound = 0;
int niflags = ni6->ni_flags;
@@ -1625,18 +1618,15 @@ ni6_addrs(ni6, m, ifpp, subj)
/* What do we have to do about ::1? */
switch(in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
case IPV6_ADDR_SCOPE_LINKLOCAL:
- if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
continue;
break;
case IPV6_ADDR_SCOPE_SITELOCAL:
- if ((niflags & NI_NODEADDR_FLAG_SITELOCAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
continue;
break;
case IPV6_ADDR_SCOPE_GLOBAL:
- if ((niflags & NI_NODEADDR_FLAG_GLOBAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
continue;
break;
default:
@@ -1670,9 +1660,9 @@ ni6_store_addrs(ni6, nni6, ifp0, resid)
struct ifnet *ifp0;
int resid;
{
- register struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
- register struct in6_ifaddr *ifa6;
- register struct ifaddr *ifa;
+ struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&ifnet);
+ struct in6_ifaddr *ifa6;
+ struct ifaddr *ifa;
struct ifnet *ifp_dep = NULL;
int copied = 0, allow_deprecated = 0;
u_char *cp = (u_char *)(nni6 + 1);
@@ -1714,18 +1704,15 @@ ni6_store_addrs(ni6, nni6, ifp0, resid)
/* What do we have to do about ::1? */
switch(in6_addrscope(&ifa6->ia_addr.sin6_addr)) {
case IPV6_ADDR_SCOPE_LINKLOCAL:
- if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0)
continue;
break;
case IPV6_ADDR_SCOPE_SITELOCAL:
- if ((niflags & NI_NODEADDR_FLAG_SITELOCAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0)
continue;
break;
case IPV6_ADDR_SCOPE_GLOBAL:
- if ((niflags & NI_NODEADDR_FLAG_GLOBAL)
- == 0)
+ if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0)
continue;
break;
default:
@@ -1829,9 +1816,10 @@ icmp6_reflect(m, off)
/* too short to reflect */
if (off < sizeof(struct ip6_hdr)) {
- printf("sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n",
- (u_long)off, (u_long)sizeof(struct ip6_hdr),
- __FILE__, __LINE__);
+ nd6log((LOG_DEBUG,
+ "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n",
+ (u_long)off, (u_long)sizeof(struct ip6_hdr),
+ __FILE__, __LINE__));
goto bad;
}
@@ -2012,7 +2000,7 @@ icmp6_redirect_diag(src6, dst6, tgt6)
void
icmp6_redirect_input(m, off)
- register struct mbuf *m;
+ struct mbuf *m;
int off;
{
struct ifnet *ifp = m->m_pkthdr.rcvif;
@@ -2060,17 +2048,17 @@ icmp6_redirect_input(m, off)
/* validation */
if (!IN6_IS_ADDR_LINKLOCAL(&src6)) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect sent from %s rejected; "
- "must be from linklocal\n", ip6_sprintf(&src6));
- goto freeit;
+ "must be from linklocal\n", ip6_sprintf(&src6)));
+ goto bad;
}
if (ip6->ip6_hlim != 255) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect sent from %s rejected; "
"hlim=%d (must be 255)\n",
- ip6_sprintf(&src6), ip6->ip6_hlim);
- goto freeit;
+ ip6_sprintf(&src6), ip6->ip6_hlim));
+ goto bad;
}
{
/* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */
@@ -2085,41 +2073,41 @@ icmp6_redirect_input(m, off)
if (rt) {
if (rt->rt_gateway == NULL ||
rt->rt_gateway->sa_family != AF_INET6) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect rejected; no route "
"with inet6 gateway found for redirect dst: %s\n",
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
RTFREE(rt);
- goto freeit;
+ goto bad;
}
gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr);
if (bcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect rejected; "
"not equal to gw-for-src=%s (must be same): "
"%s\n",
ip6_sprintf(gw6),
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
RTFREE(rt);
- goto freeit;
+ goto bad;
}
} else {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect rejected; "
"no route found for redirect dst: %s\n",
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
- goto freeit;
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
+ goto bad;
}
RTFREE(rt);
rt = NULL;
}
if (IN6_IS_ADDR_MULTICAST(&reddst6)) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect rejected; "
"redirect dst must be unicast: %s\n",
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
- goto freeit;
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
+ goto bad;
}
is_router = is_onlink = 0;
@@ -2128,20 +2116,21 @@ icmp6_redirect_input(m, off)
if (bcmp(&redtgt6, &reddst6, sizeof(redtgt6)) == 0)
is_onlink = 1; /* on-link destination case */
if (!is_router && !is_onlink) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"ICMP6 redirect rejected; "
"neither router case nor onlink case: %s\n",
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
- goto freeit;
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
+ goto bad;
}
/* validation passed */
icmp6len -= sizeof(*nd_rd);
nd6_option_init(nd_rd + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
- log(LOG_INFO, "icmp6_redirect_input: "
+ nd6log((LOG_INFO, "icmp6_redirect_input: "
"invalid ND option, rejected: %s\n",
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
+ /* nd6_options have incremented stats */
goto freeit;
}
@@ -2156,11 +2145,12 @@ icmp6_redirect_input(m, off)
}
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"icmp6_redirect_input: lladdrlen mismatch for %s "
"(if %d, icmp6 packet %d): %s\n",
ip6_sprintf(&redtgt6), ifp->if_addrlen, lladdrlen - 2,
- icmp6_redirect_diag(&src6, &reddst6, &redtgt6));
+ icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
+ goto bad;
}
/* RFC 2461 8.3 */
@@ -2191,31 +2181,12 @@ icmp6_redirect_input(m, off)
/* finally update cached route in each socket via pfctlinput */
{
struct sockaddr_in6 sdst;
-#if 1
-#else
- struct ip6protosw *pr;
-#endif
bzero(&sdst, sizeof(sdst));
sdst.sin6_family = AF_INET6;
sdst.sin6_len = sizeof(struct sockaddr_in6);
bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr));
-#if 1
pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&sdst);
-#else
- /*
- * do not use pfctlinput() here, we have different prototype for
- * xx_ctlinput() in ip6proto.
- */
- for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
- pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW;
- pr++) {
- if (pr->pr_ctlinput) {
- (*pr->pr_ctlinput)(PRC_REDIRECT_HOST,
- (struct sockaddr *)&sdst, NULL, NULL, 0);
- }
- }
-#endif
#ifdef IPSEC
key_sa_routechange((struct sockaddr *)&sdst);
#endif
@@ -2223,6 +2194,11 @@ icmp6_redirect_input(m, off)
freeit:
m_freem(m);
+ return;
+
+ bad:
+ icmp6stat.icp6s_badredirect++;
+ m_freem(m);
}
void
@@ -2641,6 +2617,8 @@ icmp6_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
case ICMPV6CTL_MTUDISC_LOWAT:
return sysctl_int(oldp, oldlenp, newp, newlen,
&icmp6_mtudisc_lowat);
+ case ICMPV6CTL_ND6_DEBUG:
+ return sysctl_int(oldp, oldlenp, newp, newlen, &nd6_debug);
default:
return ENOPROTOOPT;
}
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 09e48542cf4..a5fd6d5028d 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: in6_ifattach.c,v 1.14 2001/01/18 06:48:25 itojun Exp $ */
-/* $KAME: in6_ifattach.c,v 1.68 2000/10/18 18:44:24 itojun Exp $ */
+/* $OpenBSD: in6_ifattach.c,v 1.15 2001/02/07 11:43:53 itojun Exp $ */
+/* $KAME: in6_ifattach.c,v 1.102 2001/02/07 11:01:29 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -36,6 +36,7 @@
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/kernel.h>
+#include <sys/syslog.h>
#include <sys/md5k.h>
#include <net/if.h>
@@ -214,7 +215,7 @@ found:
case IFT_STF:
#endif
/*
- * mech-06 says: "SHOULD use IPv4 address as ifid source".
+ * RFC2893 says: "SHOULD use IPv4 address as ifid source".
* however, IPv4 address is not very suitable as unique
* identifier source (can be renumbered).
* we don't do this.
@@ -259,19 +260,15 @@ get_ifid(ifp0, altifp, in6)
/* first, try to get it from the interface itself */
if (get_hw_ifid(ifp0, in6) == 0) {
-#ifdef ND6_DEBUG
- printf("%s: got interface identifier from itself\n",
- if_name(ifp0));
-#endif
+ nd6log((LOG_DEBUG, "%s: got interface identifier from itself\n",
+ if_name(ifp0)));
goto success;
}
/* try secondary EUI64 source. this basically is for ATM PVC */
if (altifp && get_hw_ifid(altifp, in6) == 0) {
-#ifdef ND6_DEBUG
- printf("%s: got interface identifier from %s\n",
- if_name(ifp0), if_name(altifp));
-#endif
+ nd6log((LOG_DEBUG, "%s: got interface identifier from %s\n",
+ if_name(ifp0), if_name(altifp)));
goto success;
}
@@ -288,21 +285,18 @@ get_ifid(ifp0, altifp, in6)
* globally unique
*/
if (IFID_UNIVERSAL(in6)) {
-
-#ifdef ND6_DEBUG
- printf("%s: borrow interface identifier from %s\n",
- if_name(ifp0), if_name(ifp));
-#endif
+ nd6log((LOG_DEBUG,
+ "%s: borrow interface identifier from %s\n",
+ if_name(ifp0), if_name(ifp)));
goto success;
}
}
/* last resort: get from random number source */
if (get_rand_ifid(ifp, in6) == 0) {
-#ifdef ND6_DEBUG
- printf("%s: interface identifier generated by random number\n",
- if_name(ifp0));
-#endif
+ nd6log((LOG_DEBUG,
+ "%s: interface identifier generated by random number\n",
+ if_name(ifp0)));
goto success;
}
@@ -310,15 +304,13 @@ get_ifid(ifp0, altifp, in6)
return -1;
success:
-#ifdef ND6_DEBUG
- printf("%s: ifid: "
+ nd6log((LOG_INFO, "%s: ifid: "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
if_name(ifp0),
in6->s6_addr[8], in6->s6_addr[9],
in6->s6_addr[10], in6->s6_addr[11],
in6->s6_addr[12], in6->s6_addr[13],
- in6->s6_addr[14], in6->s6_addr[15]);
-#endif
+ in6->s6_addr[14], in6->s6_addr[15]));
return 0;
}
@@ -500,9 +492,8 @@ in6_ifattach_linklocal(ifp, altifp)
ia->ia_addr.sin6_addr.s6_addr32[3] = htonl(1);
} else {
if (get_ifid(ifp, altifp, &ia->ia_addr.sin6_addr) != 0) {
-#ifdef ND6_DEBUG
- printf("%s: no ifid available\n", if_name(ifp));
-#endif
+ nd6log((LOG_ERR,
+ "%s: no ifid available\n", if_name(ifp)));
free(ia, M_IFADDR);
return -1;
}
@@ -867,11 +858,11 @@ in6_ifdetach(ifp)
ia = ia->ia_next;
if (ia->ia_next)
ia->ia_next = oia->ia_next;
-#ifdef ND6_DEBUG
- else
- printf("%s: didn't unlink in6ifaddr from "
- "list\n", if_name(ifp));
-#endif
+ else {
+ nd6log((LOG_ERR,
+ "%s: didn't unlink in6ifaddr from "
+ "list\n", if_name(ifp)));
+ }
}
IFAFREE(&oia->ia_ifa);
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 4cc9d3424bd..67de254f5c1 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ip6_input.c,v 1.20 2001/02/06 00:22:23 mickey Exp $ */
-/* $KAME: ip6_input.c,v 1.121 2000/08/31 06:07:29 itojun Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.21 2001/02/07 11:43:53 itojun Exp $ */
+/* $KAME: ip6_input.c,v 1.170 2001/02/07 07:50:02 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -484,10 +484,10 @@ ip6_input(m)
goto hbhcheck;
} else {
/* address is not ready, so discard the packet. */
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"ip6_input: packet to an unready address %s->%s\n",
ip6_sprintf(&ip6->ip6_src),
- ip6_sprintf(&ip6->ip6_dst));
+ ip6_sprintf(&ip6->ip6_dst)));
goto bad;
}
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 230902af6ab..c7abb5797c0 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: nd6.c,v 1.21 2001/02/06 00:22:23 mickey Exp $ */
-/* $KAME: nd6.c,v 1.75 2000/10/15 15:23:11 itojun Exp $ */
+/* $OpenBSD: nd6.c,v 1.22 2001/02/07 11:43:54 itojun Exp $ */
+/* $KAME: nd6.c,v 1.110 2001/02/06 09:14:38 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -89,6 +89,12 @@ int nd6_maxndopt = 10; /* max # of ND options allowed */
int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */
+#ifdef ND6_DEBUG
+int nd6_debug = 1;
+#else
+int nd6_debug = 0;
+#endif
+
/* for debugging? */
static int nd6_inuse, nd6_allocated;
@@ -307,6 +313,7 @@ nd6_options(ndopts)
* Message validation requires that all included
* options have a length that is greater than zero.
*/
+ icmp6stat.icp6s_nd_badopt++;
bzero(ndopts, sizeof(*ndopts));
return -1;
}
@@ -341,16 +348,16 @@ nd6_options(ndopts)
* Unknown options must be silently ignored,
* to accomodate future extension to the protocol.
*/
- log(LOG_DEBUG,
+ nd6log((LOG_DEBUG,
"nd6_options: unsupported option %d - "
- "option ignored\n", nd_opt->nd_opt_type);
+ "option ignored\n", nd_opt->nd_opt_type));
}
skip1:
i++;
if (i > nd6_maxndopt) {
icmp6stat.icp6s_nd_toomanyopt++;
- printf("too many loop in nd opt\n");
+ nd6log((LOG_INFO, "too many loop in nd opt\n"));
break;
}
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 3e44d94db02..62851f3ac48 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: nd6.h,v 1.9 2001/01/19 06:37:38 itojun Exp $ */
-/* $KAME: nd6.h,v 1.23 2000/06/04 12:54:57 itojun Exp $ */
+/* $OpenBSD: nd6.h,v 1.10 2001/02/07 11:43:54 itojun Exp $ */
+/* $KAME: nd6.h,v 1.42 2001/02/06 09:14:39 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -236,6 +236,9 @@ extern struct llinfo_nd6 llinfo_nd6;
extern struct nd_ifinfo *nd_ifinfo;
extern struct nd_drhead nd_defrouter;
extern struct nd_prhead nd_prefix;
+extern int nd6_debug;
+
+#define nd6log(x) do { if (nd6_debug) log x; } while (0)
/* nd6_rtr.c */
extern struct ifnet *nd6_defifp; /* XXXYYY */
@@ -302,6 +305,7 @@ void nd6_ns_output __P((struct ifnet *, struct in6_addr *,
struct in6_addr *, struct llinfo_nd6 *, int));
caddr_t nd6_ifptomac __P((struct ifnet *));
void nd6_dad_start __P((struct ifaddr *, int *));
+void nd6_dad_stop __P((struct ifaddr *));
void nd6_dad_duplicated __P((struct ifaddr *));
/* nd6_rtr.c */
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 24a41a4d30e..f55551520a6 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: nd6_nbr.c,v 1.11 2001/01/18 04:57:05 itojun Exp $ */
-/* $KAME: nd6_nbr.c,v 1.36 2000/05/17 12:35:59 jinmei Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.12 2001/02/07 11:43:54 itojun Exp $ */
+/* $KAME: nd6_nbr.c,v 1.57 2001/02/07 08:18:21 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -64,6 +64,8 @@
struct dadq;
static struct dadq *nd6_dad_find __P((struct ifaddr *));
+static void nd6_dad_starttimer __P((struct dadq *, int));
+static void nd6_dad_stoptimer __P((struct dadq *));
static void nd6_dad_timer __P((struct ifaddr *));
static void nd6_dad_ns_output __P((struct dadq *, struct ifaddr *));
static void nd6_dad_ns_input __P((struct ifaddr *));
@@ -98,12 +100,25 @@ nd6_ns_input(m, off, icmp6len)
union nd_opts ndopts;
struct sockaddr_dl *proxydl = NULL;
- if (ip6->ip6_hlim != 255) {
-#ifdef ND6_DEBUG
- log(LOG_ERR,
- "nd6_ns_input: invalid hlim %d\n", ip6->ip6_hlim);
+#ifndef PULLDOWN_TEST
+ IP6_EXTHDR_CHECK(m, off, icmp6len,);
+ nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
+#else
+ IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
+ if (nd_ns == NULL) {
+ icmp6stat.icp6s_tooshort++;
+ return;
+ }
#endif
- goto freeit;
+ ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
+ taddr6 = nd_ns->nd_ns_target;
+
+ if (ip6->ip6_hlim != 255) {
+ nd6log((LOG_ERR,
+ "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
+ ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
+ goto bad;
}
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
@@ -115,26 +130,14 @@ nd6_ns_input(m, off, icmp6len)
&& daddr6.s6_addr8[12] == 0xff) {
; /*good*/
} else {
- log(LOG_INFO, "nd6_ns_input: bad DAD packet "
- "(wrong ip6 dst)\n");
+ nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
+ "(wrong ip6 dst)\n"));
goto bad;
}
}
-#ifndef PULLDOWN_TEST
- IP6_EXTHDR_CHECK(m, off, icmp6len,);
- nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
-#else
- IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
- if (nd_ns == NULL) {
- icmp6stat.icp6s_tooshort++;
- return;
- }
-#endif
- taddr6 = nd_ns->nd_ns_target;
-
if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
- log(LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n");
+ nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
goto bad;
}
@@ -144,8 +147,10 @@ nd6_ns_input(m, off, icmp6len)
icmp6len -= sizeof(*nd_ns);
nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
- log(LOG_INFO, "nd6_ns_input: invalid ND option, ignored\n");
- goto bad;
+ nd6log((LOG_INFO,
+ "nd6_ns_input: invalid ND option, ignored\n"));
+ /* nd6_options have incremented stats */
+ goto freeit;
}
if (ndopts.nd_opts_src_lladdr) {
@@ -154,8 +159,8 @@ nd6_ns_input(m, off, icmp6len)
}
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
- log(LOG_INFO, "nd6_ns_input: bad DAD packet "
- "(link-layer address option)\n");
+ nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
+ "(link-layer address option)\n"));
goto bad;
}
@@ -217,7 +222,7 @@ nd6_ns_input(m, off, icmp6len)
}
if (!ifa) {
/*
- * We've got a NS packet, and we don't have that adddress
+ * We've got an NS packet, and we don't have that adddress
* assigned for us. We MUST silently ignore it.
* See RFC2461 7.2.3.
*/
@@ -230,10 +235,11 @@ nd6_ns_input(m, off, icmp6len)
goto freeit;
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"nd6_ns_input: lladdrlen mismatch for %s "
"(if %d, NS packet %d)\n",
- ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2);
+ ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
+ goto bad;
}
if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
@@ -300,9 +306,10 @@ nd6_ns_input(m, off, icmp6len)
return;
bad:
- log(LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6));
- log(LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6));
- log(LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6));
+ nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6)));
+ nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6)));
+ nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6)));
+ icmp6stat.icp6s_badns++;
m_freem(m);
}
@@ -531,11 +538,11 @@ nd6_na_input(m, off, icmp6len)
union nd_opts ndopts;
if (ip6->ip6_hlim != 255) {
-#ifdef ND6_DEBUG
- log(LOG_ERR,
- "nd6_na_input: invalid hlim %d\n", ip6->ip6_hlim);
-#endif
- goto freeit;
+ nd6log((LOG_ERR,
+ "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
+ ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
+ goto bad;
}
#ifndef PULLDOWN_TEST
@@ -558,22 +565,24 @@ nd6_na_input(m, off, icmp6len)
taddr6.s6_addr16[1] = htons(ifp->if_index);
if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"nd6_na_input: invalid target address %s\n",
- ip6_sprintf(&taddr6));
- goto freeit;
+ ip6_sprintf(&taddr6)));
+ goto bad;
}
if (IN6_IS_ADDR_MULTICAST(&daddr6))
if (is_solicited) {
- log(LOG_ERR,
- "nd6_na_input: a solicited adv is multicasted\n");
- goto freeit;
+ nd6log((LOG_ERR,
+ "nd6_na_input: a solicited adv is multicasted\n"));
+ goto bad;
}
icmp6len -= sizeof(*nd_na);
nd6_option_init(nd_na + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
- log(LOG_INFO, "nd6_na_input: invalid ND option, ignored\n");
+ nd6log((LOG_INFO,
+ "nd6_na_input: invalid ND option, ignored\n"));
+ /* nd6_options have incremented stats */
goto freeit;
}
@@ -608,10 +617,11 @@ nd6_na_input(m, off, icmp6len)
}
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"nd6_na_input: lladdrlen mismatch for %s "
"(if %d, NA packet %d)\n",
- ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2);
+ ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
+ goto bad;
}
/*
@@ -766,6 +776,11 @@ nd6_na_input(m, off, icmp6len)
freeit:
m_freem(m);
+ return;
+
+ bad:
+ icmp6stat.icp6s_badna++;
+ m_freem(m);
}
/*
@@ -942,6 +957,7 @@ struct dadq {
};
static struct dadq_head dadq;
+static int dad_init = 0;
static struct dadq *
nd6_dad_find(ifa)
@@ -956,6 +972,40 @@ nd6_dad_find(ifa)
return NULL;
}
+static void
+nd6_dad_starttimer(dp, ticks)
+ struct dadq *dp;
+ int ticks;
+{
+
+#ifdef __NetBSD__
+ callout_reset(&dp->dad_timer_ch, ticks,
+ (void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa);
+#else
+#if defined(__FreeBSD__) && __FreeBSD__ >= 3
+ dp->dad_timer =
+#endif
+ timeout((void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa,
+ ticks);
+#endif
+}
+
+static void
+nd6_dad_stoptimer(dp)
+ struct dadq *dp;
+{
+
+#ifdef __NetBSD__
+ callout_stop(&dp->dad_timer_ch);
+#else
+ untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa
+#if defined(__FreeBSD__) && __FreeBSD__ >= 3
+ , dp->dad_timer
+#endif
+ );
+#endif
+}
+
/*
* Start Duplicated Address Detection (DAD) for specified interface address.
*/
@@ -966,7 +1016,6 @@ nd6_dad_start(ifa, tick)
{
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
struct dadq *dp;
- static int dad_init = 0;
if (!dad_init) {
TAILQ_INIT(&dadq);
@@ -1015,10 +1064,8 @@ nd6_dad_start(ifa, tick)
bzero(dp, sizeof(*dp));
TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
-#ifdef DEBUG
- log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
- ip6_sprintf(&ia->ia_addr.sin6_addr));
-#endif
+ nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
+ ip6_sprintf(&ia->ia_addr.sin6_addr)));
/*
* Send NS packet for DAD, ip6_dad_count times.
@@ -1033,19 +1080,49 @@ nd6_dad_start(ifa, tick)
dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
if (!tick) {
nd6_dad_ns_output(dp, ifa);
- timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
- nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
+ nd6_dad_starttimer(dp,
+ nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
} else {
int ntick;
+#ifdef __OpenBSD__
+#define random arc4random
+#endif
if (*tick == 0)
- ntick = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
+ ntick = random() % (MAX_RTR_SOLICITATION_DELAY * hz);
else
- ntick = *tick + arc4random() % (hz / 2);
+ ntick = *tick + random() % (hz / 2);
+#ifdef __OpenBSD__
+#undef random
+#endif
*tick = ntick;
- timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
- ntick);
+ nd6_dad_starttimer(dp, ntick);
+ }
+}
+
+/*
+ * terminate DAD unconditionally. used for address removals.
+ */
+void
+nd6_dad_stop(ifa)
+ struct ifaddr *ifa;
+{
+ struct dadq *dp;
+
+ if (!dad_init)
+ return;
+ dp = nd6_dad_find(ifa);
+ if (!dp) {
+ /* DAD wasn't started yet */
+ return;
}
+
+ nd6_dad_stoptimer(dp);
+
+ TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
+ free(dp, M_IP6NDP);
+ dp = NULL;
+ IFAFREE(ifa);
}
static void
@@ -1085,8 +1162,8 @@ nd6_dad_timer(ifa)
/* timeouted with IFF_{RUNNING,UP} check */
if (dp->dad_ns_tcount > dad_maxtry) {
- log(LOG_ERR, "%s: could not run DAD, driver problem?\n",
- if_name(ifa->ifa_ifp));
+ nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n",
+ if_name(ifa->ifa_ifp)));
TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
free(dp, M_IP6NDP);
@@ -1101,8 +1178,8 @@ nd6_dad_timer(ifa)
* We have more NS to go. Send NS packet for DAD.
*/
nd6_dad_ns_output(dp, ifa);
- timeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa,
- nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
+ nd6_dad_starttimer(dp,
+ nd_ifinfo[ifa->ifa_ifp->if_index].retrans * hz / 1000);
} else {
/*
* We have transmitted sufficient number of DAD packets.
@@ -1161,12 +1238,10 @@ nd6_dad_timer(ifa)
*/
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
-#ifdef DEBUG
- log(LOG_INFO,
+ nd6log((LOG_DEBUG,
"%s: DAD complete for %s - no duplicates found\n",
if_name(ifa->ifa_ifp),
- ip6_sprintf(&ia->ia_addr.sin6_addr));
-#endif
+ ip6_sprintf(&ia->ia_addr.sin6_addr)));
TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
free(dp, M_IP6NDP);
@@ -1201,7 +1276,7 @@ nd6_dad_duplicated(ifa)
ia->ia6_flags |= IN6_IFF_DUPLICATED;
/* We are done with DAD, with duplicated address found. (failure) */
- untimeout((void (*) __P((void *)))nd6_dad_timer, (void *)ifa);
+ nd6_dad_stoptimer(dp);
log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr));
@@ -1267,9 +1342,10 @@ nd6_dad_ns_input(ifa)
/* Quickhack - completely ignore DAD NS packets */
if (dad_ignore_ns) {
- log(LOG_INFO, "nd6_dad_ns_input: ignoring DAD NS packet for "
+ nd6log((LOG_INFO,
+ "nd6_dad_ns_input: ignoring DAD NS packet for "
"address %s(%s)\n", ip6_sprintf(taddr6),
- if_name(ifa->ifa_ifp));
+ if_name(ifa->ifa_ifp)));
return;
}
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 735b15b2bb8..d3018656c7e 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: nd6_rtr.c,v 1.7 2000/06/13 04:12:40 itojun Exp $ */
-/* $KAME: nd6_rtr.c,v 1.40 2000/06/13 03:02:29 jinmei Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.8 2001/02/07 11:43:55 itojun Exp $ */
+/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -120,9 +120,11 @@ nd6_rs_input(m, off, icmp6len)
/* Sanity checks */
if (ip6->ip6_hlim != 255) {
- log(LOG_ERR,
- "nd6_rs_input: invalid hlim %d\n", ip6->ip6_hlim);
- goto freeit;
+ nd6log((LOG_ERR,
+ "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
+ ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
+ goto bad;
}
/*
@@ -146,7 +148,9 @@ nd6_rs_input(m, off, icmp6len)
icmp6len -= sizeof(*nd_rs);
nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
- log(LOG_INFO, "nd6_rs_input: invalid ND option, ignored\n");
+ nd6log((LOG_INFO,
+ "nd6_rs_input: invalid ND option, ignored\n"));
+ /* nd6_options have incremented stats */
goto freeit;
}
@@ -156,16 +160,22 @@ nd6_rs_input(m, off, icmp6len)
}
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"nd6_rs_input: lladdrlen mismatch for %s "
"(if %d, RS packet %d)\n",
- ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2);
+ ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
+ goto bad;
}
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0);
freeit:
m_freem(m);
+ return;
+
+ bad:
+ icmp6stat.icp6s_badrs++;
+ m_freem(m);
}
/*
@@ -198,16 +208,18 @@ nd6_ra_input(m, off, icmp6len)
goto freeit;
if (ip6->ip6_hlim != 255) {
- log(LOG_ERR,
- "nd6_ra_input: invalid hlim %d\n", ip6->ip6_hlim);
- goto freeit;
+ nd6log((LOG_ERR,
+ "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
+ ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
+ ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
+ goto bad;
}
if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
- log(LOG_ERR,
+ nd6log((LOG_ERR,
"nd6_ra_input: src %s is not link-local\n",
- ip6_sprintf(&saddr6));
- goto freeit;
+ ip6_sprintf(&saddr6)));
+ goto bad;
}
#ifndef PULLDOWN_TEST
@@ -224,7 +236,9 @@ nd6_ra_input(m, off, icmp6len)
icmp6len -= sizeof(*nd_ra);
nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
if (nd6_options(&ndopts) < 0) {
- log(LOG_INFO, "nd6_ra_input: invalid ND option, ignored\n");
+ nd6log((LOG_INFO,
+ "nd6_ra_input: invalid ND option, ignored\n"));
+ /* nd6_options have incremented stats */
goto freeit;
}
@@ -377,10 +391,11 @@ nd6_ra_input(m, off, icmp6len)
}
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
- log(LOG_INFO,
+ nd6log((LOG_INFO,
"nd6_ra_input: lladdrlen mismatch for %s "
"(if %d, RA packet %d)\n",
- ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2);
+ ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
+ goto bad;
}
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_ADVERT, 0);
@@ -393,7 +408,12 @@ nd6_ra_input(m, off, icmp6len)
pfxlist_onlink_check();
}
-freeit:
+ freeit:
+ m_freem(m);
+ return;
+
+ bad:
+ icmp6stat.icp6s_badra++;
m_freem(m);
}
@@ -611,13 +631,17 @@ defrouter_select()
/*
* Install a route to the default interface
* as default route.
+ * XXX: we enable this for host only, because
+ * this may override a default route installed
+ * a user process (e.g. routing daemon) in a
+ * router case.
*/
defrouter_addifreq(nd6_defifp);
- }
- else /* noisy log? */
- log(LOG_INFO, "defrouter_select: "
+ } else {
+ nd6log((LOG_INFO, "defrouter_select: "
"there's no default router and no default"
- " interface\n");
+ " interface\n"));
+ }
}
}