Module Name:    src
Committed By:   ozaki-r
Date:           Mon Aug 31 08:02:45 UTC 2015

Modified Files:
        src/sys/kern: init_main.c
        src/sys/net: files.net if.c if.h route.h
        src/sys/netinet: in.c in_selsrc.c in_selsrc.h in_var.h
        src/sys/rump/net/lib/libnet: Makefile net_component.c

Log Message:
Hook up lltable/llentry with the kernel (and rumpkernel)

It is built and initialized on bootup, but there is no user for now.

Most codes in in.c are imported from FreeBSD as well as lltable/llentry.


To generate a diff of this commit:
cvs rdiff -u -r1.467 -r1.468 src/sys/kern/init_main.c
cvs rdiff -u -r1.6 -r1.7 src/sys/net/files.net
cvs rdiff -u -r1.317 -r1.318 src/sys/net/if.c
cvs rdiff -u -r1.190 -r1.191 src/sys/net/if.h
cvs rdiff -u -r1.94 -r1.95 src/sys/net/route.h
cvs rdiff -u -r1.157 -r1.158 src/sys/netinet/in.c
cvs rdiff -u -r1.14 -r1.15 src/sys/netinet/in_selsrc.c
cvs rdiff -u -r1.1 -r1.2 src/sys/netinet/in_selsrc.h
cvs rdiff -u -r1.72 -r1.73 src/sys/netinet/in_var.h
cvs rdiff -u -r1.25 -r1.26 src/sys/rump/net/lib/libnet/Makefile
cvs rdiff -u -r1.3 -r1.4 src/sys/rump/net/lib/libnet/net_component.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.467 src/sys/kern/init_main.c:1.468
--- src/sys/kern/init_main.c:1.467	Wed May  6 15:57:08 2015
+++ src/sys/kern/init_main.c	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.467 2015/05/06 15:57:08 hannken Exp $	*/
+/*	$NetBSD: init_main.c,v 1.468 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.467 2015/05/06 15:57:08 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.468 2015/08/31 08:02:44 ozaki-r Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipsec.h"
@@ -228,6 +228,7 @@ extern void *_binary_splash_image_end;
 #include <net/bpf.h>
 #include <net/if.h>
 #include <net/raw_cb.h>
+#include <net/if_llatbl.h>
 
 #include <prop/proplib.h>
 
@@ -565,6 +566,7 @@ main(void)
 	 */
 	s = splnet();
 	ifinit();
+	lltableinit();
 	domaininit(true);
 	if_attachdomain();
 	splx(s);

Index: src/sys/net/files.net
diff -u src/sys/net/files.net:1.6 src/sys/net/files.net:1.7
--- src/sys/net/files.net:1.6	Mon Jun  1 00:15:07 2015
+++ src/sys/net/files.net	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: files.net,v 1.6 2015/06/01 00:15:07 roy Exp $
+#	$NetBSD: files.net,v 1.7 2015/08/31 08:02:44 ozaki-r Exp $
 
 # XXX CLEANUP
 define	net
@@ -22,6 +22,7 @@ file	net/if_gif.c			gif			needs-flag
 file	net/if_gre.c			gre			needs-flag
 file	net/if_hippisubr.c		hippi			needs-flag
 file	net/if_ieee1394subr.c		ieee1394
+file	net/if_llatbl.c			ether
 file	net/if_loop.c			loop
 file	net/if_media.c			net
 file	net/if_mpls.c			ifmpls			needs-flag

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.317 src/sys/net/if.c:1.318
--- src/sys/net/if.c:1.317	Fri Jul 17 02:21:08 2015
+++ src/sys/net/if.c	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.317 2015/07/17 02:21:08 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.318 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.317 2015/07/17 02:21:08 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.318 2015/08/31 08:02:44 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -615,6 +615,8 @@ if_initialize(ifnet_t *ifp)
 	(void)pfil_run_hooks(if_pfil,
 	    (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
 
+	IF_AFDATA_LOCK_INIT(ifp);
+
 	if_getindex(ifp);
 }
 

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.190 src/sys/net/if.h:1.191
--- src/sys/net/if.h:1.190	Mon May 18 06:38:59 2015
+++ src/sys/net/if.h	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.190 2015/05/18 06:38:59 martin Exp $	*/
+/*	$NetBSD: if.h,v 1.191 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -213,6 +213,7 @@ struct ifnet_lock;
 #include <sys/condvar.h>
 #include <sys/percpu.h>
 #include <sys/callout.h>
+#include <sys/rwlock.h>
 
 struct ifnet_lock {
 	kmutex_t il_lock;	/* Protects the critical section. */
@@ -244,6 +245,7 @@ TAILQ_HEAD(ifnet_head, ifnet);		/* the a
 struct bridge_softc;
 struct bridge_iflist;
 struct callout;
+struct krwlock;
 
 typedef struct ifnet {
 	void	*if_softc;		/* lower-level data for this if */
@@ -345,6 +347,7 @@ typedef struct ifnet {
 #ifdef _KERNEL /* XXX kvm(3) */
 	struct callout *if_slowtimo_ch;
 #endif
+	struct krwlock	*if_afdata_lock;
 } ifnet_t;
  
 #define	if_mtu		if_data.ifi_mtu
@@ -434,6 +437,28 @@ typedef struct ifnet {
 	"\23TSO6"		\
 	"\24LRO"		\
 
+#define	IF_AFDATA_LOCK_INIT(ifp)	\
+	do {(ifp)->if_afdata_lock = rw_obj_alloc();} while (0)
+
+#define	IF_AFDATA_WLOCK(ifp)	rw_enter((ifp)->if_afdata_lock, RW_WRITER)
+#define	IF_AFDATA_RLOCK(ifp)	rw_enter((ifp)->if_afdata_lock, RW_READER)
+#define	IF_AFDATA_WUNLOCK(ifp)	rw_exit((ifp)->if_afdata_lock)
+#define	IF_AFDATA_RUNLOCK(ifp)	rw_exit((ifp)->if_afdata_lock)
+#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
+#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
+#define	IF_AFDATA_TRYLOCK(ifp)	rw_tryenter((ifp)->if_afdata_lock, RW_WRITER)
+#define	IF_AFDATA_DESTROY(ifp)	rw_destroy((ifp)->if_afdata_lock)
+
+#define	IF_AFDATA_LOCK_ASSERT(ifp)	\
+	KASSERT(rw_lock_held((ifp)->if_afdata_lock))
+#define	IF_AFDATA_RLOCK_ASSERT(ifp)	\
+	KASSERT(rw_read_held((ifp)->if_afdata_lock))
+#define	IF_AFDATA_WLOCK_ASSERT(ifp)	\
+	KASSERT(rw_write_held((ifp)->if_afdata_lock))
+#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	\
+	KASSERT(!rw_lock_head((ifp)->if_afdata_lock))
+
+
 #define IFQ_LOCK(_ifq)		if ((_ifq)->ifq_lock) mutex_enter((_ifq)->ifq_lock)
 #define IFQ_UNLOCK(_ifq)	if ((_ifq)->ifq_lock) mutex_exit((_ifq)->ifq_lock)
 

Index: src/sys/net/route.h
diff -u src/sys/net/route.h:1.94 src/sys/net/route.h:1.95
--- src/sys/net/route.h:1.94	Mon Aug 31 06:25:15 2015
+++ src/sys/net/route.h	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: route.h,v 1.94 2015/08/31 06:25:15 ozaki-r Exp $	*/
+/*	$NetBSD: route.h,v 1.95 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -148,6 +148,7 @@ struct ortentry {
 #define RTF_CLONING	0x100		/* generate new routes on use */
 #define RTF_XRESOLVE	0x200		/* external daemon resolves name */
 #define RTF_LLINFO	0x400		/* generated by ARP or NDP */
+#define RTF_LLDATA	0x400		/* used by apps to add/del L2 entries */
 #define RTF_STATIC	0x800		/* manually added */
 #define RTF_BLACKHOLE	0x1000		/* just discard pkts (during updates) */
 #define RTF_CLONED	0x2000		/* this is a cloned route */

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.157 src/sys/netinet/in.c:1.158
--- src/sys/netinet/in.c:1.157	Mon Aug 24 22:21:26 2015
+++ src/sys/netinet/in.c	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.157 2015/08/24 22:21:26 pooka Exp $	*/
+/*	$NetBSD: in.c,v 1.158 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.157 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.158 2015/08/31 08:02:44 ozaki-r Exp $");
 
 #include "arp.h"
 
@@ -113,6 +113,7 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.157
 #include <sys/proc.h>
 #include <sys/syslog.h>
 #include <sys/kauth.h>
+#include <sys/kmem.h>
 
 #include <sys/cprng.h>
 
@@ -121,6 +122,9 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.157
 #include <net/pfil.h>
 
 #include <net/if_ether.h>
+#include <net/if_types.h>
+#include <net/if_llatbl.h>
+#include <net/if_dl.h>
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
@@ -129,6 +133,7 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.157
 #include <netinet/ip_var.h>
 #include <netinet/in_ifattach.h>
 #include <netinet/in_pcb.h>
+#include <netinet/in_selsrc.h>
 #include <netinet/if_inarp.h>
 #include <netinet/ip_mroute.h>
 #include <netinet/igmp_var.h>
@@ -1529,6 +1534,333 @@ in_selectsrc(struct sockaddr_in *sin, st
 	return satosin(&ia->ia_addr);
 }
 
+struct in_llentry {
+	struct llentry		base;
+};
+
+#define	IN_LLTBL_DEFAULT_HSIZE	32
+#define	IN_LLTBL_HASH(k, h) \
+	(((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1))
+
+/*
+ * Do actual deallocation of @lle.
+ * Called by LLE_FREE_LOCKED when number of references
+ * drops to zero.
+ */
+static void
+in_lltable_destroy_lle(struct llentry *lle)
+{
+
+	LLE_WUNLOCK(lle);
+	LLE_LOCK_DESTROY(lle);
+	kmem_intr_free(lle, sizeof(*lle));
+}
+
+static struct llentry *
+in_lltable_new(struct in_addr addr4, u_int flags)
+{
+	struct in_llentry *lle;
+
+	lle = kmem_intr_zalloc(sizeof(*lle), KM_NOSLEEP);
+	if (lle == NULL)		/* NB: caller generates msg */
+		return NULL;
+
+	/*
+	 * For IPv4 this will trigger "arpresolve" to generate
+	 * an ARP request.
+	 */
+	lle->base.la_expire = time_uptime; /* mark expired */
+	lle->base.r_l3addr.addr4 = addr4;
+	lle->base.lle_refcnt = 1;
+	lle->base.lle_free = in_lltable_destroy_lle;
+	LLE_LOCK_INIT(&lle->base);
+	callout_init(&lle->base.la_timer, 1);
+
+	return (&lle->base);
+}
+
+#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m)	(			\
+	    (((ntohl((d).s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
+
+static int
+in_lltable_match_prefix(const struct sockaddr *prefix,
+    const struct sockaddr *mask, u_int flags, struct llentry *lle)
+{
+	const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
+	const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
+
+	/*
+	 * (flags & LLE_STATIC) means deleting all entries
+	 * including static ARP entries.
+	 */
+	if (IN_ARE_MASKED_ADDR_EQUAL(lle->r_l3addr.addr4, pfx, msk) &&
+	    ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
+		return (1);
+
+	return (0);
+}
+
+static void
+in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
+{
+	struct ifnet *ifp;
+	size_t pkts_dropped;
+
+	LLE_WLOCK_ASSERT(lle);
+	KASSERT(llt != NULL);
+
+	/* Unlink entry from table if not already */
+	if ((lle->la_flags & LLE_LINKED) != 0) {
+		ifp = llt->llt_ifp;
+		IF_AFDATA_WLOCK_ASSERT(ifp);
+		lltable_unlink_entry(llt, lle);
+	}
+
+	/* cancel timer */
+	if (callout_stop(&lle->lle_timer))
+		LLE_REMREF(lle);
+
+	/* Drop hold queue */
+	pkts_dropped = llentry_free(lle);
+#ifdef __FreeBSD__
+	ARPSTAT_ADD(dropped, pkts_dropped);
+#else
+	(void) pkts_dropped; /* FIXME */
+#endif
+}
+
+static int
+in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
+{
+	struct rtentry *rt;
+	int error = EINVAL;
+
+	KASSERTMSG(l3addr->sa_family == AF_INET,
+	    "sin_family %d", l3addr->sa_family);
+
+	rt = rtalloc1(l3addr, 0);
+	if (rt == NULL)
+		return error;
+
+	/*
+	 * If the gateway for an existing host route matches the target L3
+	 * address, which is a special route inserted by some implementation
+	 * such as MANET, and the interface is of the correct type, then
+	 * allow for ARP to proceed.
+	 */
+	if (rt->rt_flags & RTF_GATEWAY) {
+		if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
+		    rt->rt_ifp->if_type != IFT_ETHER ||
+#ifdef __FreeBSD__
+		    (rt->rt_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
+#else /* XXX */
+		    (rt->rt_ifp->if_flags & IFF_NOARP) != 0 ||
+#endif
+		    memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
+		    sizeof(in_addr_t)) != 0) {
+			goto error;
+		}
+	}
+
+	/*
+	 * Make sure that at least the destination address is covered
+	 * by the route. This is for handling the case where 2 or more
+	 * interfaces have the same prefix. An incoming packet arrives
+	 * on one interface and the corresponding outgoing packet leaves
+	 * another interface.
+	 */
+	if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
+		const char *sa, *mask, *addr, *lim;
+		int len;
+
+		mask = (const char *)rt_mask(rt);
+		/*
+		 * Just being extra cautious to avoid some custom
+		 * code getting into trouble.
+		 */
+		if (mask == NULL)
+			goto error;
+
+		sa = (const char *)rt_getkey(rt);
+		addr = (const char *)l3addr;
+		len = ((const struct sockaddr_in *)l3addr)->sin_len;
+		lim = addr + len;
+
+		for ( ; addr < lim; sa++, mask++, addr++) {
+			if ((*sa ^ *addr) & *mask) {
+#ifdef DIAGNOSTIC
+				log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
+				    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
+#endif
+				goto error;
+			}
+		}
+	}
+
+	error = 0;
+error:
+#ifdef __FreeBSD__
+	RTFREE_LOCKED(rt);
+#endif
+	return error;
+}
+
+static inline uint32_t
+in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize)
+{
+
+	return (IN_LLTBL_HASH(dst.s_addr, hsize));
+}
+
+static uint32_t
+in_lltable_hash(const struct llentry *lle, uint32_t hsize)
+{
+
+	return (in_lltable_hash_dst(lle->r_l3addr.addr4, hsize));
+}
+
+static void
+in_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
+{
+	struct sockaddr_in *sin;
+
+	sin = (struct sockaddr_in *)sa;
+	memset(sin, 0, sizeof(*sin));
+	sin->sin_family = AF_INET;
+	sin->sin_len = sizeof(*sin);
+	sin->sin_addr = lle->r_l3addr.addr4;
+}
+
+static inline struct llentry *
+in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
+{
+	struct llentry *lle;
+	struct llentries *lleh;
+	u_int hashidx;
+
+	hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
+	lleh = &llt->lle_head[hashidx];
+	LIST_FOREACH(lle, lleh, lle_next) {
+		if (lle->la_flags & LLE_DELETED)
+			continue;
+		if (lle->r_l3addr.addr4.s_addr == dst.s_addr)
+			break;
+	}
+
+	return (lle);
+}
+
+static int
+in_lltable_delete(struct lltable *llt, u_int flags,
+    const struct sockaddr *l3addr)
+{
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
+	struct ifnet *ifp = llt->llt_ifp;
+	struct llentry *lle;
+
+	IF_AFDATA_WLOCK_ASSERT(ifp);
+	KASSERTMSG(l3addr->sa_family == AF_INET,
+	    "sin_family %d", l3addr->sa_family);
+
+	lle = in_lltable_find_dst(llt, sin->sin_addr);
+	if (lle == NULL) {
+#ifdef DIAGNOSTIC
+		log(LOG_INFO, "interface address is missing from cache = %p  in delete\n", lle);
+#endif
+		return (ENOENT);
+	}
+
+	if (!(lle->la_flags & LLE_IFADDR) || (flags & LLE_IFADDR)) {
+		LLE_WLOCK(lle);
+		lle->la_flags |= LLE_DELETED;
+#ifdef __FreeBSD__
+		EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
+#endif
+#ifdef DIAGNOSTIC
+		log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
+#endif
+		if ((lle->la_flags & (LLE_STATIC | LLE_IFADDR)) == LLE_STATIC)
+			llentry_free(lle);
+		else
+			LLE_WUNLOCK(lle);
+	}
+
+	return (0);
+}
+
+static struct llentry *
+in_lltable_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+{
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
+	struct ifnet *ifp = llt->llt_ifp;
+	struct llentry *lle;
+
+	IF_AFDATA_WLOCK_ASSERT(ifp);
+	KASSERTMSG(l3addr->sa_family == AF_INET,
+	    "sin_family %d", l3addr->sa_family);
+
+	lle = in_lltable_find_dst(llt, sin->sin_addr);
+
+	if (lle != NULL) {
+		LLE_WLOCK(lle);
+		return (lle);
+	}
+
+	/* no existing record, we need to create new one */
+
+	/*
+	 * A route that covers the given address must have
+	 * been installed 1st because we are doing a resolution,
+	 * verify this.
+	 */
+	if (!(flags & LLE_IFADDR) &&
+	    in_lltable_rtcheck(ifp, flags, l3addr) != 0)
+		return (NULL);
+
+	lle = in_lltable_new(sin->sin_addr, flags);
+	if (lle == NULL) {
+		log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
+		return (NULL);
+	}
+	lle->la_flags = flags;
+	if ((flags & LLE_IFADDR) == LLE_IFADDR) {
+		memcpy(&lle->ll_addr, CLLADDR(ifp->if_sadl), ifp->if_addrlen);
+		lle->la_flags |= (LLE_VALID | LLE_STATIC);
+	}
+
+	lltable_link_entry(llt, lle);
+	LLE_WLOCK(lle);
+
+	return (lle);
+}
+
+/*
+ * Return NULL if not found or marked for deletion.
+ * If found return lle read locked.
+ */
+static struct llentry *
+in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+{
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
+	struct llentry *lle;
+
+	IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
+	KASSERTMSG(l3addr->sa_family == AF_INET,
+	    "sin_family %d", l3addr->sa_family);
+
+	lle = in_lltable_find_dst(llt, sin->sin_addr);
+
+	if (lle == NULL)
+		return NULL;
+
+	if (flags & LLE_EXCLUSIVE)
+		LLE_WLOCK(lle);
+	else
+		LLE_RLOCK(lle);
+
+	return lle;
+}
+
 static void
 in_sysctl_init(struct sysctllog **clog)
 {
@@ -1561,3 +1893,57 @@ in_sysctl_init(struct sysctllog **clog)
 		       CTL_NET, PF_INET, IPPROTO_IP,
 		       IPCTL_HOSTZEROBROADCAST, CTL_EOL);
 }
+
+static struct lltable *
+in_lltattach(struct ifnet *ifp)
+{
+	struct lltable *llt;
+
+	llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
+	llt->llt_af = AF_INET;
+	llt->llt_ifp = ifp;
+
+	llt->llt_lookup = in_lltable_lookup;
+	llt->llt_create = in_lltable_create;
+	llt->llt_delete = in_lltable_delete;
+#if 0
+	llt->llt_dump_entry = in_lltable_dump_entry;
+#endif
+	llt->llt_hash = in_lltable_hash;
+	llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
+	llt->llt_free_entry = in_lltable_free_entry;
+	llt->llt_match_prefix = in_lltable_match_prefix;
+	lltable_link(llt);
+
+	return (llt);
+}
+
+void *
+in_domifattach(struct ifnet *ifp)
+{
+	struct in_ifinfo *ii;
+
+	ii = kmem_zalloc(sizeof(struct in_ifinfo), KM_SLEEP);
+	KASSERT(ii != NULL);
+
+	ii->ii_llt = in_lltattach(ifp);
+
+#ifdef IPSELSRC
+	ii->ii_selsrc = in_selsrc_domifattach(ifp);
+	KASSERT(ii->ii_selsrc != NULL);
+#endif
+
+	return ii;
+}
+
+void
+in_domifdetach(struct ifnet *ifp, void *aux)
+{
+	struct in_ifinfo *ii = aux;
+
+#ifdef IPSELSRC
+	in_selsrc_domifdetach(ifp, ii->ii_selsrc);
+#endif
+	lltable_free(ii->ii_llt);
+	kmem_free(ii, sizeof(struct in_ifinfo));
+}

Index: src/sys/netinet/in_selsrc.c
diff -u src/sys/netinet/in_selsrc.c:1.14 src/sys/netinet/in_selsrc.c:1.15
--- src/sys/netinet/in_selsrc.c:1.14	Mon Aug 24 22:21:26 2015
+++ src/sys/netinet/in_selsrc.c	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_selsrc.c,v 1.14 2015/08/24 22:21:26 pooka Exp $	*/
+/*	$NetBSD: in_selsrc.c,v 1.15 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 2005 David Young.  All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_selsrc.c,v 1.14 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_selsrc.c,v 1.15 2015/08/31 08:02:44 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -311,7 +311,8 @@ in_getifa(struct ifaddr *ifa, const stru
 	}
 
 	ifp = ifa->ifa_ifp;
-	isc = (struct in_ifsysctl *)ifp->if_afdata[AF_INET];
+	KASSERT(ifp->if_afdata[AF_INET] != NULL);
+	isc = ifp->if_afdata[AF_INET]->ii_selsrc;
 	if (isc != NULL && isc->isc_selsrc != NULL &&
 	    isc->isc_selsrc->iss_score_src[0] != NULL)
 		iss = isc->isc_selsrc;
@@ -544,7 +545,7 @@ err:
 }
 
 void *
-in_domifattach(struct ifnet *ifp)
+in_selsrc_domifattach(struct ifnet *ifp)
 {
 	struct in_ifsysctl *isc;
 	struct in_ifselsrc *iss;
@@ -572,7 +573,7 @@ err:
 }
 
 void
-in_domifdetach(struct ifnet *ifp, void *aux)
+in_selsrc_domifdetach(struct ifnet *ifp, void *aux)
 {
 	struct in_ifsysctl *isc;
 	struct in_ifselsrc *iss;

Index: src/sys/netinet/in_selsrc.h
diff -u src/sys/netinet/in_selsrc.h:1.1 src/sys/netinet/in_selsrc.h:1.2
--- src/sys/netinet/in_selsrc.h:1.1	Mon Nov 13 05:13:42 2006
+++ src/sys/netinet/in_selsrc.h	Mon Aug 31 08:02:44 2015
@@ -27,4 +27,7 @@ enum in_category {
 
 struct ifaddr *in_getifa(struct ifaddr *, const struct sockaddr *);
 
+void	*in_selsrc_domifattach(struct ifnet *ifp);
+void	in_selsrc_domifdetach(struct ifnet *ifp, void *aux);
+
 #endif /* _NETINET_IN_SELSRC_H */

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.72 src/sys/netinet/in_var.h:1.73
--- src/sys/netinet/in_var.h:1.72	Sat May 16 12:12:46 2015
+++ src/sys/netinet/in_var.h	Mon Aug 31 08:02:44 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.72 2015/05/16 12:12:46 roy Exp $	*/
+/*	$NetBSD: in_var.h,v 1.73 2015/08/31 08:02:44 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -204,7 +204,17 @@ extern	const	int	inetctlerrmap[];
 	} \
 	(ia) = ifatoia(ifa); \
 }
-#endif
+
+#include <netinet/in_selsrc.h>
+/*
+ * IPv4 per-interface state.
+ */
+struct in_ifinfo {
+	struct lltable		*ii_llt;	/* ARP state */
+	struct in_ifsysctl	*ii_selsrc;
+};
+
+#endif /* _KERNEL */
 
 /*
  * Internet multicast address structure.  There is one of these for each IP

Index: src/sys/rump/net/lib/libnet/Makefile
diff -u src/sys/rump/net/lib/libnet/Makefile:1.25 src/sys/rump/net/lib/libnet/Makefile:1.26
--- src/sys/rump/net/lib/libnet/Makefile:1.25	Mon Aug 24 23:04:43 2015
+++ src/sys/rump/net/lib/libnet/Makefile	Mon Aug 31 08:02:45 2015
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.25 2015/08/24 23:04:43 pooka Exp $
+#	$NetBSD: Makefile,v 1.26 2015/08/31 08:02:45 ozaki-r Exp $
 #
 
 
@@ -10,6 +10,7 @@ IOCONF=	NET.ioconf
 SRCS=	if.c if_loop.c route.c rtsock.c raw_usrreq.c			\
 	raw_cb.c if_media.c link_proto.c net_stats.c if_ethersubr.c
 SRCS+=	if_43.c pfil.c
+SRCS+=	if_llatbl.c
 SRCS+=	net_component.c
 
 .include <bsd.init.mk>

Index: src/sys/rump/net/lib/libnet/net_component.c
diff -u src/sys/rump/net/lib/libnet/net_component.c:1.3 src/sys/rump/net/lib/libnet/net_component.c:1.4
--- src/sys/rump/net/lib/libnet/net_component.c:1.3	Thu Apr 23 07:55:24 2015
+++ src/sys/rump/net/lib/libnet/net_component.c	Mon Aug 31 08:02:45 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: net_component.c,v 1.3 2015/04/23 07:55:24 pooka Exp $	*/
+/*	$NetBSD: net_component.c,v 1.4 2015/08/31 08:02:45 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -28,13 +28,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: net_component.c,v 1.3 2015/04/23 07:55:24 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: net_component.c,v 1.4 2015/08/31 08:02:45 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/domain.h>
 #include <sys/protosw.h>
 
 #include <net/if.h>
+#include <net/if_llatbl.h>
 #include <net/route.h>
 
 #include "rump_private.h"
@@ -45,6 +46,7 @@ RUMP_COMPONENT(RUMP_COMPONENT_NET)
 
 	ifinit1();
 	ifinit();
+	lltableinit();
 }
 
 RUMP_COMPONENT(RUMP_COMPONENT_NET_ROUTE)

Reply via email to