Module Name: src
Committed By: ozaki-r
Date: Tue Feb 14 03:05:06 UTC 2017
Modified Files:
src/sys/dist/pf/net: pf.c
src/sys/external/bsd/ipf/netinet: ip_fil_netbsd.c
src/sys/net: if_arcsubr.c if_ethersubr.c if_fddisubr.c
if_ieee1394subr.c if_srt.c
src/sys/netinet6: in6_offload.c ip6_forward.c ip6_mroute.c ip6_output.c
ip6_var.h nd6.c nd6.h
Log Message:
Do ND in L2_output in the same manner as arpresolve
The benefits of this change are:
- The flow is consistent with IPv4 (and FreeBSD and OpenBSD)
- old: ip6_output => nd6_output (do ND if needed) => L2_output (lookup a
stored cache)
- new: ip6_output => L2_output (lookup a cache. Do ND if cache not found)
- We can remove some workarounds in nd6_output
- We can move L2 specific operations to their own place
- The performance slightly improves because one cache lookup is reduced
To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sys/dist/pf/net/pf.c
cvs rdiff -u -r1.21 -r1.22 src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
cvs rdiff -u -r1.76 -r1.77 src/sys/net/if_arcsubr.c
cvs rdiff -u -r1.237 -r1.238 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.104 -r1.105 src/sys/net/if_fddisubr.c
cvs rdiff -u -r1.58 -r1.59 src/sys/net/if_ieee1394subr.c
cvs rdiff -u -r1.25 -r1.26 src/sys/net/if_srt.c
cvs rdiff -u -r1.6 -r1.7 src/sys/netinet6/in6_offload.c
cvs rdiff -u -r1.85 -r1.86 src/sys/netinet6/ip6_forward.c
cvs rdiff -u -r1.116 -r1.117 src/sys/netinet6/ip6_mroute.c
cvs rdiff -u -r1.182 -r1.183 src/sys/netinet6/ip6_output.c
cvs rdiff -u -r1.71 -r1.72 src/sys/netinet6/ip6_var.h
cvs rdiff -u -r1.226 -r1.227 src/sys/netinet6/nd6.c
cvs rdiff -u -r1.81 -r1.82 src/sys/netinet6/nd6.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dist/pf/net/pf.c
diff -u src/sys/dist/pf/net/pf.c:1.75 src/sys/dist/pf/net/pf.c:1.76
--- src/sys/dist/pf/net/pf.c:1.75 Thu Dec 8 05:16:33 2016
+++ src/sys/dist/pf/net/pf.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: pf.c,v 1.75 2016/12/08 05:16:33 ozaki-r Exp $ */
+/* $NetBSD: pf.c,v 1.76 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $OpenBSD: pf.c,v 1.552.2.1 2007/11/27 16:37:57 henning Exp $ */
/*
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.75 2016/12/08 05:16:33 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.76 2017/02/14 03:05:06 ozaki-r Exp $");
#include "pflog.h"
@@ -5553,7 +5553,7 @@ pf_route6(struct mbuf **m, struct pf_rul
if (IN6_IS_SCOPE_EMBEDDABLE(&dst.sin6_addr))
dst.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
- (void)nd6_output(ifp, ifp, m0, &dst, NULL);
+ (void)ip6_if_output(ifp, ifp, m0, &dst, NULL);
} else {
in6_ifstat_inc(ifp, ifs6_in_toobig);
if (r->rt != PF_DUPTO)
Index: src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c
diff -u src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.21 src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.22
--- src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c:1.21 Wed Dec 28 19:53:02 2016
+++ src/sys/external/bsd/ipf/netinet/ip_fil_netbsd.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_fil_netbsd.c,v 1.21 2016/12/28 19:53:02 christos Exp $ */
+/* $NetBSD: ip_fil_netbsd.c,v 1.22 2017/02/14 03:05:06 ozaki-r Exp $ */
/*
* Copyright (C) 2012 by Darren Reed.
@@ -8,7 +8,7 @@
#if !defined(lint)
#if defined(__NetBSD__)
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.21 2016/12/28 19:53:02 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_fil_netbsd.c,v 1.22 2017/02/14 03:05:06 ozaki-r Exp $");
#else
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_fil_netbsd.c,v 1.1.1.2 2012/07/22 13:45:17 darrenr Exp";
@@ -1478,7 +1478,7 @@ ipf_fastroute6(struct mbuf *m0, struct m
# endif
if ((error == 0) && (m0->m_pkthdr.len <= mtu)) {
# if __NetBSD_Version__ >= 499001100
- error = nd6_output(ifp, ifp, m0, satocsin6(dst), rt);
+ error = ip6_if_output(ifp, ifp, m0, satocsin6(dst), rt);
# else
error = nd6_output(ifp, ifp, m0, dst6, rt);
# endif
Index: src/sys/net/if_arcsubr.c
diff -u src/sys/net/if_arcsubr.c:1.76 src/sys/net/if_arcsubr.c:1.77
--- src/sys/net/if_arcsubr.c:1.76 Tue Jan 24 18:37:20 2017
+++ src/sys/net/if_arcsubr.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arcsubr.c,v 1.76 2017/01/24 18:37:20 maxv Exp $ */
+/* $NetBSD: if_arcsubr.c,v 1.77 2017/02/14 03:05:06 ozaki-r Exp $ */
/*
* Copyright (c) 1994, 1995 Ignatios Souvatzis
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.76 2017/01/24 18:37:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.77 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -218,8 +218,14 @@ arc_output(struct ifnet *ifp, struct mbu
#endif
#ifdef INET6
case AF_INET6:
- if (!nd6_storelladdr(ifp, rt, m, dst, &adst, sizeof(adst)))
- return (0); /* it must be impossible, but... */
+ if (m->m_flags & M_MCAST) {
+ adst = 0;
+ } else {
+ error = nd6_resolve(ifp, rt, m, dst, &adst,
+ sizeof(adst));
+ if (error != 0)
+ return error == EWOULDBLOCK ? 0 : error;
+ }
atype = htons(ARCTYPE_INET6);
newencoding = 1;
break;
Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.237 src/sys/net/if_ethersubr.c:1.238
--- src/sys/net/if_ethersubr.c:1.237 Sun Feb 12 09:36:05 2017
+++ src/sys/net/if_ethersubr.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.237 2017/02/12 09:36:05 skrll Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.238 2017/02/14 03:05:06 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.237 2017/02/12 09:36:05 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.238 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -303,9 +303,16 @@ ether_output(struct ifnet * const ifp0,
#endif
#ifdef INET6
case AF_INET6:
- if (!nd6_storelladdr(ifp, rt, m, dst, edst, sizeof(edst))){
- /* something bad happened */
- return (0);
+ if (m->m_flags & M_BCAST)
+ (void)memcpy(edst, etherbroadcastaddr, sizeof(edst));
+ else if (m->m_flags & M_MCAST) {
+ ETHER_MAP_IPV6_MULTICAST(&satocsin6(dst)->sin6_addr,
+ edst);
+ } else {
+ error = nd6_resolve(ifp, rt, m, dst, edst,
+ sizeof(edst));
+ if (error != 0)
+ return error == EWOULDBLOCK ? 0 : error;
}
etype = htons(ETHERTYPE_IPV6);
break;
Index: src/sys/net/if_fddisubr.c
diff -u src/sys/net/if_fddisubr.c:1.104 src/sys/net/if_fddisubr.c:1.105
--- src/sys/net/if_fddisubr.c:1.104 Tue Jan 24 18:37:20 2017
+++ src/sys/net/if_fddisubr.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_fddisubr.c,v 1.104 2017/01/24 18:37:20 maxv Exp $ */
+/* $NetBSD: if_fddisubr.c,v 1.105 2017/02/14 03:05:06 ozaki-r Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_fddisubr.c,v 1.104 2017/01/24 18:37:20 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_fddisubr.c,v 1.105 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
@@ -250,9 +250,18 @@ fddi_output(struct ifnet *ifp0, struct m
#endif
#ifdef INET6
case AF_INET6:
- if (!nd6_storelladdr(ifp, rt, m, dst, edst, sizeof(edst))){
- /* something bad happened */
- return (0);
+ if (m->m_flags & M_BCAST)
+ (void)memcpy(edst, fddibroadcastaddr, sizeof(edst));
+ else if (m->m_flags & M_MCAST) {
+ ETHER_MAP_IPV6_MULTICAST(&satocsin6(dst)->sin6_addr,
+ edst);
+ } else {
+ error = nd6_resolve(ifp, rt, m, dst, edst,
+ sizeof(edst));
+ if (error != 0) {
+ error = error == EWOULDBLOCK ? 0 : error;
+ return error;
+ }
}
etype = htons(ETHERTYPE_IPV6);
break;
Index: src/sys/net/if_ieee1394subr.c
diff -u src/sys/net/if_ieee1394subr.c:1.58 src/sys/net/if_ieee1394subr.c:1.59
--- src/sys/net/if_ieee1394subr.c:1.58 Mon Oct 3 11:06:06 2016
+++ src/sys/net/if_ieee1394subr.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ieee1394subr.c,v 1.58 2016/10/03 11:06:06 ozaki-r Exp $ */
+/* $NetBSD: if_ieee1394subr.c,v 1.59 2017/02/14 03:05:06 ozaki-r Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ieee1394subr.c,v 1.58 2016/10/03 11:06:06 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ieee1394subr.c,v 1.59 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -154,10 +154,21 @@ ieee1394_output(struct ifnet *ifp, struc
#endif /* INET */
#ifdef INET6
case AF_INET6:
- if (unicast && (!nd6_storelladdr(ifp, rt, m0, dst,
- hwdst->iha_uid, IEEE1394_ADDR_LEN))) {
- /* something bad happened */
- return 0;
+#if 0
+ /*
+ * XXX This code was in nd6_storelladdr, which was replaced with
+ * nd6_resolve, but it never be used because nd6_storelladdr was
+ * called only if unicast. Should it be enabled?
+ */
+ if (m0->m_flags & M_BCAST)
+ memcpy(hwdst->iha_uid, ifp->if_broadcastaddr,
+ MIN(IEEE1394_ADDR_LEN, ifp->if_addrlen));
+#endif
+ if (unicast) {
+ error = nd6_resolve(ifp, rt, m0, dst, hwdst->iha_uid,
+ IEEE1394_ADDR_LEN);
+ if (error != 0)
+ return error == EWOULDBLOCK ? 0 : error;
}
etype = htons(ETHERTYPE_IPV6);
break;
Index: src/sys/net/if_srt.c
diff -u src/sys/net/if_srt.c:1.25 src/sys/net/if_srt.c:1.26
--- src/sys/net/if_srt.c:1.25 Thu Feb 9 11:43:32 2017
+++ src/sys/net/if_srt.c Tue Feb 14 03:05:06 2017
@@ -1,8 +1,8 @@
-/* $NetBSD: if_srt.c,v 1.25 2017/02/09 11:43:32 kre Exp $ */
+/* $NetBSD: if_srt.c,v 1.26 2017/02/14 03:05:06 ozaki-r Exp $ */
/* This file is in the public domain. */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_srt.c,v 1.25 2017/02/09 11:43:32 kre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_srt.c,v 1.26 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_srt.c,v 1
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet6/in6_var.h>
+#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
#include <netinet6/scope6_var.h>
#include <net/if_types.h>
@@ -240,7 +241,7 @@ srt_if_output(
}
/* XXX is 0 the right last arg here? */
if (to->sa_family == AF_INET6)
- return nd6_output(r->u.dstifp, r->u.dstifp, m, &r->dst.sin6, 0);
+ return ip6_if_output(r->u.dstifp, r->u.dstifp, m, &r->dst.sin6, 0);
return if_output_lock(r->u.dstifp, r->u.dstifp, m, &r->dst.sa, 0);
}
Index: src/sys/netinet6/in6_offload.c
diff -u src/sys/netinet6/in6_offload.c:1.6 src/sys/netinet6/in6_offload.c:1.7
--- src/sys/netinet6/in6_offload.c:1.6 Mon Apr 25 22:07:57 2011
+++ src/sys/netinet6/in6_offload.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_offload.c,v 1.6 2011/04/25 22:07:57 yamt Exp $ */
+/* $NetBSD: in6_offload.c,v 1.7 2017/02/14 03:05:06 ozaki-r Exp $ */
/*-
* Copyright (c)2006 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_offload.c,v 1.6 2011/04/25 22:07:57 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_offload.c,v 1.7 2017/02/14 03:05:06 ozaki-r Exp $");
#include <sys/param.h>
#include <sys/mbuf.h>
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: in6_offload.
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet6/in6_var.h>
+#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
#include <netinet6/in6_offload.h>
@@ -56,7 +57,7 @@ ip6_tso_output_callback(void *vp, struct
{
struct ip6_tso_output_args *args = vp;
- return nd6_output(args->ifp, args->origifp, m, args->dst, args->rt);
+ return ip6_if_output(args->ifp, args->origifp, m, args->dst, args->rt);
}
int
Index: src/sys/netinet6/ip6_forward.c
diff -u src/sys/netinet6/ip6_forward.c:1.85 src/sys/netinet6/ip6_forward.c:1.86
--- src/sys/netinet6/ip6_forward.c:1.85 Mon Jan 16 15:44:47 2017
+++ src/sys/netinet6/ip6_forward.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_forward.c,v 1.85 2017/01/16 15:44:47 christos Exp $ */
+/* $NetBSD: ip6_forward.c,v 1.86 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.85 2017/01/16 15:44:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.86 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_gateway.h"
@@ -401,7 +401,7 @@ ip6_forward(struct mbuf *m, int srcrt)
goto freecopy;
ip6 = mtod(m, struct ip6_hdr *);
- error = nd6_output(rt->rt_ifp, origifp, m, dst, rt);
+ error = ip6_if_output(rt->rt_ifp, origifp, m, dst, rt);
if (error) {
in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
IP6_STATINC(IP6_STAT_CANTFORWARD);
Index: src/sys/netinet6/ip6_mroute.c
diff -u src/sys/netinet6/ip6_mroute.c:1.116 src/sys/netinet6/ip6_mroute.c:1.117
--- src/sys/netinet6/ip6_mroute.c:1.116 Tue Jan 24 07:09:25 2017
+++ src/sys/netinet6/ip6_mroute.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_mroute.c,v 1.116 2017/01/24 07:09:25 ozaki-r Exp $ */
+/* $NetBSD: ip6_mroute.c,v 1.117 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $ */
/*
@@ -117,7 +117,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.116 2017/01/24 07:09:25 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.117 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -1620,12 +1620,7 @@ phyint_send(struct ip6_hdr *ip6, struct
*/
linkmtu = IN6_LINKMTU(ifp);
if (mb_copy->m_pkthdr.len <= linkmtu || linkmtu < IPV6_MMTU) {
- /*
- * We could call if_output directly here, but we use
- * nd6_output on purpose to see if IPv6 operation is allowed
- * on the interface.
- */
- error = nd6_output(ifp, ifp, mb_copy, &dst6, NULL);
+ error = ip6_if_output(ifp, ifp, mb_copy, &dst6, NULL);
#ifdef MRT6DEBUG
if (mrt6debug & DEBUG_XMIT)
log(LOG_DEBUG, "phyint_send on mif %td err %d\n",
Index: src/sys/netinet6/ip6_output.c
diff -u src/sys/netinet6/ip6_output.c:1.182 src/sys/netinet6/ip6_output.c:1.183
--- src/sys/netinet6/ip6_output.c:1.182 Mon Jan 16 15:44:47 2017
+++ src/sys/netinet6/ip6_output.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_output.c,v 1.182 2017/01/16 15:44:47 christos Exp $ */
+/* $NetBSD: ip6_output.c,v 1.183 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.182 2017/01/16 15:44:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.183 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -180,6 +180,31 @@ ip6_handle_rthdr(struct ip6_rthdr *rh, s
}
/*
+ * Send an IP packet to a host.
+ */
+int
+ip6_if_output(struct ifnet * const ifp, struct ifnet * const origifp,
+ struct mbuf * const m,
+ const struct sockaddr_in6 * const dst, const struct rtentry *rt)
+{
+ int error = 0;
+
+ if (rt != NULL) {
+ error = rt_check_reject_route(rt, ifp);
+ if (error != 0) {
+ m_freem(m);
+ return error;
+ }
+ }
+
+ if ((ifp->if_flags & IFF_LOOPBACK) != 0)
+ error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt);
+ else
+ error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt);
+ return error;
+}
+
+/*
* IP6 output. The packet in mbuf chain m contains a skeletal IP6
* header (with pri, len, nxt, hlim, src, dst).
* This function may modify ver and hlim only.
@@ -844,7 +869,7 @@ ip6_output(
KASSERT(dst != NULL);
if (__predict_true(!tso ||
(ifp->if_capenable & IFCAP_TSOv6) != 0)) {
- error = nd6_output(ifp, origifp, m, dst, rt);
+ error = ip6_if_output(ifp, origifp, m, dst, rt);
} else {
error = ip6_tso_output(ifp, origifp, m, dst, rt);
}
@@ -1030,7 +1055,7 @@ sendorfree:
}
pserialize_read_exit(s);
KASSERT(dst != NULL);
- error = nd6_output(ifp, origifp, m, dst, rt);
+ error = ip6_if_output(ifp, origifp, m, dst, rt);
} else
m_freem(m);
}
Index: src/sys/netinet6/ip6_var.h
diff -u src/sys/netinet6/ip6_var.h:1.71 src/sys/netinet6/ip6_var.h:1.72
--- src/sys/netinet6/ip6_var.h:1.71 Thu Dec 8 05:16:34 2016
+++ src/sys/netinet6/ip6_var.h Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_var.h,v 1.71 2016/12/08 05:16:34 ozaki-r Exp $ */
+/* $NetBSD: ip6_var.h,v 1.72 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -353,6 +353,9 @@ int ip6_output(struct mbuf *, struct ip6
struct route *, int,
struct ip6_moptions *, struct socket *,
struct ifnet **);
+int ip6_if_output(struct ifnet * const, struct ifnet * const,
+ struct mbuf * const,
+ const struct sockaddr_in6 * const, const struct rtentry *);
int ip6_ctloutput(int, struct socket *, struct sockopt *);
int ip6_raw_ctloutput(int, struct socket *, struct sockopt *);
void ip6_initpktopts(struct ip6_pktopts *);
Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.226 src/sys/netinet6/nd6.c:1.227
--- src/sys/netinet6/nd6.c:1.226 Mon Jan 16 15:44:47 2017
+++ src/sys/netinet6/nd6.c Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.c,v 1.226 2017/01/16 15:44:47 christos Exp $ */
+/* $NetBSD: nd6.c,v 1.227 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.226 2017/01/16 15:44:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.227 2017/02/14 03:05:06 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -1992,7 +1992,7 @@ nd6_llinfo_release_pkts(struct llentry *
* just set the 2nd argument as the
* 1st one.
*/
- nd6_output(ifp, ifp, m_hold, &sin6, NULL);
+ ip6_if_output(ifp, ifp, m_hold, &sin6, NULL);
}
LLE_WLOCK(ln);
}
@@ -2265,59 +2265,23 @@ nd6_slowtimo(void *ignored_arg)
#endif
}
+/*
+ * Return 0 if a neighbor cache is found. Return EWOULDBLOCK if a cache is not
+ * found and trying to resolve a neighbor; in this case the mbuf is queued in
+ * the list. Otherwise return errno after freeing the mbuf.
+ */
int
-nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m,
- const struct sockaddr_in6 *dst, struct rtentry *rt)
+nd6_resolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m,
+ const struct sockaddr *_dst, uint8_t *lldst, size_t dstsize)
{
-#define senderr(e) { error = (e); goto bad;}
struct llentry *ln = NULL;
- int error = 0;
bool created = false;
+ const struct sockaddr_in6 *dst = satocsin6(_dst);
- if (rt != NULL) {
- error = rt_check_reject_route(rt, ifp);
- if (error != 0) {
- m_freem(m);
- return error;
- }
- }
-
- if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
- goto sendpkt;
-
- if (nd6_need_cache(ifp) == 0)
- goto sendpkt;
-
- if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) != 0) {
- struct sockaddr_in6 *gw6 = satosin6(rt->rt_gateway);
- int s;
-
- /* XXX remain the check to keep the original behavior. */
- /*
- * We skip link-layer address resolution and NUD
- * if the gateway is not a neighbor from ND point
- * of view, regardless of the value of nd_ifinfo.flags.
- * The second condition is a bit tricky; we skip
- * if the gateway is our own address, which is
- * sometimes used to install a route to a p2p link.
- */
- s = pserialize_read_enter();
- if (!nd6_is_addr_neighbor(gw6, ifp) ||
- in6ifa_ifpwithaddr(ifp, &gw6->sin6_addr)) {
- /*
- * We allow this kind of tricky route only
- * when the outgoing interface is p2p.
- * XXX: we may need a more generic rule here.
- */
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
- pserialize_read_exit(s);
- senderr(EHOSTUNREACH);
- }
-
- pserialize_read_exit(s);
- goto sendpkt;
- }
- pserialize_read_exit(s);
+ /* discard the packet if IPv6 operation is disabled on the interface */
+ if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {
+ m_freem(m);
+ return ENETDOWN; /* better error? */
}
/*
@@ -2328,29 +2292,37 @@ nd6_output(struct ifnet *ifp, struct ifn
*/
/* Look up the neighbor cache for the nexthop */
+ ln = nd6_lookup(&dst->sin6_addr, ifp, false);
+
+ if (ln != NULL && (ln->la_flags & LLE_VALID) != 0) {
+ KASSERT(ln->ln_state > ND6_LLINFO_INCOMPLETE);
+ /* Fast path */
+ memcpy(lldst, &ln->ll_addr, MIN(dstsize, ifp->if_addrlen));
+ LLE_RUNLOCK(ln);
+ return 0;
+ }
+ if (ln != NULL)
+ LLE_RUNLOCK(ln);
+
+ /* Slow path */
ln = nd6_lookup(&dst->sin6_addr, ifp, true);
- if ((ln == NULL) && nd6_is_addr_neighbor(dst, ifp)) {
+ if (ln == NULL && nd6_is_addr_neighbor(dst, ifp)) {
/*
* Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
* the condition below is not very efficient. But we believe
* it is tolerable, because this should be a rare case.
*/
ln = nd6_create(&dst->sin6_addr, ifp);
- if (ln != NULL)
- created = true;
- }
-
- if (ln == NULL) {
- if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
- !(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) {
+ if (ln == NULL) {
char ip6buf[INET6_ADDRSTRLEN];
log(LOG_DEBUG,
- "nd6_output: can't allocate llinfo for %s "
- "(ln=%p, rt=%p)\n",
+ "%s: can't allocate llinfo for %s "
+ "(ln=%p, rt=%p)\n", __func__,
IN6_PRINT(ip6buf, &dst->sin6_addr), ln, rt);
- senderr(EIO); /* XXX: good error? */
+ m_freem(m);
+ return ENOBUFS;
}
- goto sendpkt; /* send anyway */
+ created = true;
}
LLE_WLOCK_ASSERT(ln);
@@ -2376,14 +2348,6 @@ nd6_output(struct ifnet *ifp, struct ifn
}
/*
- * If the neighbor cache entry has a state other than INCOMPLETE
- * (i.e. its link-layer address is already resolved), just
- * send the packet.
- */
- if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
- goto sendpkt;
-
- /*
* There is a neighbor cache entry, but no ethernet address
* response yet. Append this latest packet to the end of the
* packet queue in the mbuf, unless the number of the packet
@@ -2432,34 +2396,10 @@ nd6_output(struct ifnet *ifp, struct ifn
LLE_WUNLOCK(ln);
}
- error = 0;
- goto exit;
-
- sendpkt:
- /* discard the packet if IPv6 operation is disabled on the interface */
- if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {
- error = ENETDOWN; /* better error? */
- goto bad;
- }
-
- if (ln != NULL)
- LLE_WUNLOCK(ln);
-
- if ((ifp->if_flags & IFF_LOOPBACK) != 0)
- error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt);
- else
- error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt);
- goto exit;
-
- bad:
- if (m != NULL)
- m_freem(m);
- exit:
if (created)
nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr);
- return error;
-#undef senderr
+ return EWOULDBLOCK;
}
int
@@ -2542,68 +2482,6 @@ nd6_rem_ifa_lle(struct in6_ifaddr *ia)
LLE_STATIC);
}
-int
-nd6_storelladdr(const struct ifnet *ifp, const struct rtentry *rt,
- struct mbuf *m, const struct sockaddr *dst, uint8_t *lldst,
- size_t dstsize)
-{
- struct llentry *ln;
-
- if (m->m_flags & M_MCAST) {
- switch (ifp->if_type) {
- case IFT_ETHER:
- case IFT_FDDI:
- ETHER_MAP_IPV6_MULTICAST(&satocsin6(dst)->sin6_addr,
- lldst);
- return 1;
- case IFT_IEEE1394:
- memcpy(lldst, ifp->if_broadcastaddr,
- MIN(dstsize, ifp->if_addrlen));
- return 1;
- case IFT_ARCNET:
- *lldst = 0;
- return 1;
- default:
- m_freem(m);
- return 0;
- }
- }
-
- /*
- * the entry should have been created in nd6_store_lladdr
- */
- ln = nd6_lookup(&satocsin6(dst)->sin6_addr, ifp, false);
- if ((ln == NULL) || !(ln->la_flags & LLE_VALID)) {
- if (ln != NULL)
- LLE_RUNLOCK(ln);
- /* this could happen, if we could not allocate memory */
- m_freem(m);
- return 0;
- }
-
- /* XXX llentry should have addrlen? */
-#if 0
- sdl = satocsdl(rt->rt_gateway);
- if (sdl->sdl_alen == 0 || sdl->sdl_alen > dstsize) {
- char sbuf[INET6_ADDRSTRLEN];
- char dbuf[LINK_ADDRSTRLEN];
- /* this should be impossible, but we bark here for debugging */
- printf("%s: sdl_alen == %" PRIu8 ", if=%s, dst=%s, sdl=%s\n",
- __func__, sdl->sdl_alen, if_name(ifp),
- IN6_PRINT(sbuf, &satocsin6(dst)->sin6_addr),
- DL_PRINT(dbuf, &sdl->sdl_addr));
- m_freem(m);
- return 0;
- }
-#endif
-
- memcpy(lldst, &ln->ll_addr, MIN(dstsize, ifp->if_addrlen));
-
- LLE_RUNLOCK(ln);
-
- return 1;
-}
-
static void
clear_llinfo_pqueue(struct llentry *ln)
{
Index: src/sys/netinet6/nd6.h
diff -u src/sys/netinet6/nd6.h:1.81 src/sys/netinet6/nd6.h:1.82
--- src/sys/netinet6/nd6.h:1.81 Mon Dec 19 07:51:34 2016
+++ src/sys/netinet6/nd6.h Tue Feb 14 03:05:06 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.h,v 1.81 2016/12/19 07:51:34 ozaki-r Exp $ */
+/* $NetBSD: nd6.h,v 1.82 2017/02/14 03:05:06 ozaki-r Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@@ -438,16 +438,12 @@ void nd6_llinfo_settimer(struct llentry
void nd6_purge(struct ifnet *, struct in6_ifextra *);
void nd6_assert_purged(struct ifnet *);
void nd6_nud_hint(struct rtentry *);
-int nd6_resolve(struct ifnet *, struct rtentry *,
- struct mbuf *, struct sockaddr *, u_char *);
+int nd6_resolve(struct ifnet *, const struct rtentry *, struct mbuf *,
+ const struct sockaddr *, uint8_t *, size_t);
void nd6_rtrequest(int, struct rtentry *, const struct rt_addrinfo *);
int nd6_ioctl(u_long, void *, struct ifnet *);
void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
char *, int, int, int);
-int nd6_output(struct ifnet *, struct ifnet *, struct mbuf *,
- const struct sockaddr_in6 *, struct rtentry *);
-int nd6_storelladdr(const struct ifnet *, const struct rtentry *, struct mbuf *,
- const struct sockaddr *, uint8_t *, size_t);
int nd6_sysctl(int, void *, size_t *, void *, size_t);
int nd6_need_cache(struct ifnet *);
void nd6_llinfo_release_pkts(struct llentry *, struct ifnet *);