svn commit: r185598 - in user/kmacy/head_arpv2: lib/libstand
sys/conf sys/contrib/rdma sys/dev/cxgb/ulp/tom sys/net
sys/netinet sys/netinet6 usr.sbin/arp usr.sbin/ndp
Kip Macy
kmacy at FreeBSD.org
Wed Dec 3 18:23:03 PST 2008
Author: kmacy
Date: Thu Dec 4 02:23:01 2008
New Revision: 185598
URL: http://svn.freebsd.org/changeset/base/185598
Log:
Integrate arp-v2 patch along with a few compile fixes
Added:
user/kmacy/head_arpv2/sys/net/if_llatbl.c (contents, props changed)
user/kmacy/head_arpv2/sys/net/if_llatbl.h (contents, props changed)
Modified:
user/kmacy/head_arpv2/lib/libstand/if_ether.h
user/kmacy/head_arpv2/sys/conf/files
user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c
user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
user/kmacy/head_arpv2/sys/net/if.c
user/kmacy/head_arpv2/sys/net/if_arcsubr.c
user/kmacy/head_arpv2/sys/net/if_ethersubr.c
user/kmacy/head_arpv2/sys/net/if_fddisubr.c
user/kmacy/head_arpv2/sys/net/if_fwsubr.c
user/kmacy/head_arpv2/sys/net/if_iso88025subr.c
user/kmacy/head_arpv2/sys/net/if_var.h
user/kmacy/head_arpv2/sys/net/route.c
user/kmacy/head_arpv2/sys/net/rtsock.c
user/kmacy/head_arpv2/sys/netinet/if_ether.c
user/kmacy/head_arpv2/sys/netinet/if_ether.h
user/kmacy/head_arpv2/sys/netinet/in.c
user/kmacy/head_arpv2/sys/netinet/in_proto.c
user/kmacy/head_arpv2/sys/netinet/in_var.h
user/kmacy/head_arpv2/sys/netinet/ip_output.c
user/kmacy/head_arpv2/sys/netinet6/icmp6.c
user/kmacy/head_arpv2/sys/netinet6/in6.c
user/kmacy/head_arpv2/sys/netinet6/in6_var.h
user/kmacy/head_arpv2/sys/netinet6/ip6_forward.c
user/kmacy/head_arpv2/sys/netinet6/ip6_input.c
user/kmacy/head_arpv2/sys/netinet6/ip6_mroute.c
user/kmacy/head_arpv2/sys/netinet6/ip6_output.c
user/kmacy/head_arpv2/sys/netinet6/nd6.c
user/kmacy/head_arpv2/sys/netinet6/nd6.h
user/kmacy/head_arpv2/sys/netinet6/nd6_nbr.c
user/kmacy/head_arpv2/sys/netinet6/nd6_rtr.c
user/kmacy/head_arpv2/sys/netinet6/vinet6.h
user/kmacy/head_arpv2/usr.sbin/arp/arp.c
user/kmacy/head_arpv2/usr.sbin/ndp/ndp.c
Modified: user/kmacy/head_arpv2/lib/libstand/if_ether.h
==============================================================================
--- user/kmacy/head_arpv2/lib/libstand/if_ether.h Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/lib/libstand/if_ether.h Thu Dec 4 02:23:01 2008 (r185598)
@@ -156,7 +156,7 @@ struct ifqueue arpintrq;
void arpwhohas(struct arpcom *, struct in_addr *);
void arpintr(void);
int arpresolve(struct arpcom *,
- struct rtentry *, struct mbuf *, struct sockaddr *, u_char *);
+ struct rtentry *, struct mbuf *, struct sockaddr *, u_char *, struct llentry **);
void arp_ifinit(struct arpcom *, struct ifaddr *);
void arp_rtrequest(int, struct rtentry *, struct sockaddr *);
@@ -233,7 +233,7 @@ struct ether_multistep {
#ifdef _KERNEL
void arp_rtrequest(int, struct rtentry *, struct sockaddr *);
int arpresolve(struct arpcom *, struct rtentry *, struct mbuf *,
- struct sockaddr *, u_char *);
+ struct sockaddr *, u_char *, struct llentry **);
void arpintr(void);
int arpioctl(u_long, caddr_t);
void arp_ifinit(struct arpcom *, struct ifaddr *);
Modified: user/kmacy/head_arpv2/sys/conf/files
==============================================================================
--- user/kmacy/head_arpv2/sys/conf/files Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/conf/files Thu Dec 4 02:23:01 2008 (r185598)
@@ -2171,6 +2171,7 @@ net/if_gre.c optional gre
net/if_iso88025subr.c optional token
net/if_lagg.c optional lagg
net/if_loop.c optional loop
+net/if_llatbl.c standard
net/if_media.c standard
net/if_mib.c standard
net/if_ppp.c optional ppp
Modified: user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/contrib/rdma/rdma_addr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -163,6 +163,7 @@ static void addr_send_arp(struct sockadd
struct route iproute;
struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst;
char dmac[ETHER_ADDR_LEN];
+ struct llentry *lle;
bzero(&iproute, sizeof iproute);
*dst = *dst_in;
@@ -172,7 +173,7 @@ static void addr_send_arp(struct sockadd
return;
arpresolve(iproute.ro_rt->rt_ifp, iproute.ro_rt, NULL,
- rt_key(iproute.ro_rt), dmac);
+ rt_key(iproute.ro_rt), dmac, &lle);
RTFREE(iproute.ro_rt);
}
@@ -186,6 +187,7 @@ static int addr_resolve_remote(struct so
struct route iproute;
struct sockaddr_in *dst = (struct sockaddr_in *)&iproute.ro_dst;
char dmac[ETHER_ADDR_LEN];
+ struct llentry *lle;
bzero(&iproute, sizeof iproute);
*dst = *dst_in;
@@ -202,7 +204,7 @@ static int addr_resolve_remote(struct so
goto put;
}
ret = arpresolve(iproute.ro_rt->rt_ifp, iproute.ro_rt, NULL,
- rt_key(iproute.ro_rt), dmac);
+ rt_key(iproute.ro_rt), dmac, &lle);
if (ret) {
goto put;
}
Modified: user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c
==============================================================================
--- user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -166,6 +166,7 @@ t3_l2t_send_slow(struct t3cdev *dev, str
{
struct rtentry *rt = e->neigh;
struct sockaddr_in sin;
+ struct llentry *lle;
bzero(&sin, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
@@ -177,7 +178,7 @@ again:
switch (e->state) {
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
arpresolve(rt->rt_ifp, rt, NULL,
- (struct sockaddr *)&sin, e->dmac);
+ (struct sockaddr *)&sin, e->dmac, &lle);
mtx_lock(&e->lock);
if (e->state == L2T_STATE_STALE)
e->state = L2T_STATE_VALID;
@@ -201,7 +202,7 @@ again:
* entries when there's no memory.
*/
if (arpresolve(rt->rt_ifp, rt, NULL,
- (struct sockaddr *)&sin, e->dmac) == 0) {
+ (struct sockaddr *)&sin, e->dmac, &lle) == 0) {
CTR6(KTR_CXGB, "mac=%x:%x:%x:%x:%x:%x\n",
e->dmac[0], e->dmac[1], e->dmac[2], e->dmac[3], e->dmac[4], e->dmac[5]);
@@ -228,6 +229,7 @@ t3_l2t_send_event(struct t3cdev *dev, st
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_addr.s_addr = e->addr;
+ struct llentry *lle;
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
return;
@@ -237,7 +239,7 @@ again:
switch (e->state) {
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
arpresolve(rt->rt_ifp, rt, NULL,
- (struct sockaddr *)&sin, e->dmac);
+ (struct sockaddr *)&sin, e->dmac, &lle);
mtx_lock(&e->lock);
if (e->state == L2T_STATE_STALE) {
e->state = L2T_STATE_VALID;
@@ -263,7 +265,7 @@ again:
* entries when there's no memory.
*/
arpresolve(rt->rt_ifp, rt, NULL,
- (struct sockaddr *)&sin, e->dmac);
+ (struct sockaddr *)&sin, e->dmac, &lle);
}
return;
Modified: user/kmacy/head_arpv2/sys/net/if.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -58,6 +58,7 @@
#include <sys/jail.h>
#include <sys/vimage.h>
#include <machine/stdarg.h>
+#include <vm/uma.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -1342,6 +1343,7 @@ done:
}
#include <net/route.h>
+#include <net/if_llatbl.h>
/*
* Default action when installing a route with a Link Level gateway.
Modified: user/kmacy/head_arpv2/sys/net/if_arcsubr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_arcsubr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_arcsubr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -64,6 +64,7 @@
#include <net/if_arc.h>
#include <net/if_arp.h>
#include <net/bpf.h>
+#include <net/if_llatbl.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
@@ -108,6 +109,7 @@ arc_output(struct ifnet *ifp, struct mbu
u_int8_t atype, adst;
int loop_copy = 0;
int isphds;
+ struct llentry *lle;
if (!((ifp->if_flags & IFF_UP) &&
(ifp->if_drv_flags & IFF_DRV_RUNNING)))
@@ -127,7 +129,7 @@ arc_output(struct ifnet *ifp, struct mbu
else if (ifp->if_flags & IFF_NOARP)
adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF;
else {
- error = arpresolve(ifp, rt0, m, dst, &adst);
+ error = arpresolve(ifp, rt0, m, dst, &adst, &lle);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
@@ -165,7 +167,7 @@ arc_output(struct ifnet *ifp, struct mbu
#endif
#ifdef INET6
case AF_INET6:
- error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)&adst);
+ error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)&adst, &lle);
if (error)
return (error);
atype = ARCTYPE_INET6;
Modified: user/kmacy/head_arpv2/sys/net/if_ethersubr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_ethersubr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_ethersubr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -62,6 +62,7 @@
#include <net/ethernet.h>
#include <net/if_bridgevar.h>
#include <net/if_vlan_var.h>
+#include <net/if_llatbl.h>
#include <net/pf_mtag.h>
#include <net/vnet.h>
@@ -148,6 +149,8 @@ static int ether_ipfw;
#endif
#endif
+extern int useloopback;
+
/*
* Ethernet output routine.
* Encapsulate a packet of type family for the local net.
@@ -161,6 +164,7 @@ ether_output(struct ifnet *ifp, struct m
short type;
int error, hdrcmplt = 0;
u_char esrc[ETHER_ADDR_LEN], edst[ETHER_ADDR_LEN];
+ struct llentry *lle = NULL;
struct ether_header *eh;
struct pf_mtag *t;
int loop_copy = 1;
@@ -183,7 +187,7 @@ ether_output(struct ifnet *ifp, struct m
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
- error = arpresolve(ifp, rt0, m, dst, edst);
+ error = arpresolve(ifp, rt0, m, dst, edst, &lle);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IP);
@@ -218,7 +222,7 @@ ether_output(struct ifnet *ifp, struct m
#endif
#ifdef INET6
case AF_INET6:
- error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst);
+ error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle);
if (error)
return error;
type = htons(ETHERTYPE_IPV6);
@@ -286,6 +290,9 @@ ether_output(struct ifnet *ifp, struct m
senderr(EAFNOSUPPORT);
}
+ if (lle && (lle->la_flags & LLE_IFADDR) && useloopback)
+ return (if_simloop(ifp, m, dst->sa_family, 0));
+
/*
* Add local net header. If no space in first mbuf,
* allocate another.
Modified: user/kmacy/head_arpv2/sys/net/if_fddisubr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_fddisubr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_fddisubr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -55,6 +55,7 @@
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/if_types.h>
+#include <net/if_llatbl.h>
#include <net/ethernet.h>
#include <net/netisr.h>
@@ -120,6 +121,7 @@ fddi_output(ifp, m, dst, rt0)
int loop_copy = 0, error = 0, hdrcmplt = 0;
u_char esrc[FDDI_ADDR_LEN], edst[FDDI_ADDR_LEN];
struct fddi_header *fh;
+ struct llentry *lle;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
@@ -137,7 +139,7 @@ fddi_output(ifp, m, dst, rt0)
switch (dst->sa_family) {
#ifdef INET
case AF_INET: {
- error = arpresolve(ifp, rt0, m, dst, edst);
+ error = arpresolve(ifp, rt0, m, dst, edst, &lle);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IP);
@@ -173,7 +175,7 @@ fddi_output(ifp, m, dst, rt0)
#endif /* INET */
#ifdef INET6
case AF_INET6:
- error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst);
+ error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle);
if (error)
return (error); /* Something bad happened */
type = htons(ETHERTYPE_IPV6);
Modified: user/kmacy/head_arpv2/sys/net/if_fwsubr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_fwsubr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_fwsubr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -51,6 +51,7 @@
#include <net/if_types.h>
#include <net/bpf.h>
#include <net/firewire.h>
+#include <net/if_llatbl.h>
#if defined(INET) || defined(INET6)
#include <netinet/in.h>
@@ -89,6 +90,7 @@ firewire_output(struct ifnet *ifp, struc
struct mbuf *mtail;
int unicast, dgl, foff;
static int next_dgl;
+ struct llentry *lle;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
@@ -144,7 +146,7 @@ firewire_output(struct ifnet *ifp, struc
* doesn't fit into the arp model.
*/
if (unicast) {
- error = arpresolve(ifp, rt, m, dst, (u_char *) destfw);
+ error = arpresolve(ifp, rt, m, dst, (u_char *) destfw, &lle);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
@@ -174,7 +176,7 @@ firewire_output(struct ifnet *ifp, struc
case AF_INET6:
if (unicast) {
error = nd6_storelladdr(fc->fc_ifp, rt, m, dst,
- (u_char *) destfw);
+ (u_char *) destfw, &lle);
if (error)
return (error);
}
Modified: user/kmacy/head_arpv2/sys/net/if_iso88025subr.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_iso88025subr.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_iso88025subr.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -59,6 +59,7 @@
#include <net/if_dl.h>
#include <net/if_llc.h>
#include <net/if_types.h>
+#include <net/if_llatbl.h>
#include <net/ethernet.h>
#include <net/netisr.h>
@@ -244,6 +245,7 @@ iso88025_output(ifp, m, dst, rt0)
struct iso88025_header gen_th;
struct sockaddr_dl *sdl = NULL;
struct rtentry *rt = NULL;
+ struct llentry *lle;
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
@@ -289,7 +291,7 @@ iso88025_output(ifp, m, dst, rt0)
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
- error = arpresolve(ifp, rt0, m, dst, edst);
+ error = arpresolve(ifp, rt0, m, dst, edst, &lle);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
snap_type = ETHERTYPE_IP;
@@ -324,7 +326,7 @@ iso88025_output(ifp, m, dst, rt0)
#endif /* INET */
#ifdef INET6
case AF_INET6:
- error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst);
+ error = nd6_storelladdr(ifp, rt0, m, dst, (u_char *)edst, &lle);
if (error)
return (error);
snap_type = ETHERTYPE_IPV6;
Added: user/kmacy/head_arpv2/sys/net/if_llatbl.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/kmacy/head_arpv2/sys/net/if_llatbl.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2007 Qing Li, Luigi Rizzo, Alessandro Cerri. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/syslog.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <sys/kernel.h>
+#include <sys/mutex.h>
+#include <sys/vimage.h>
+
+#include <vm/uma.h>
+
+#include <netinet/in.h>
+#include <net/if_llatbl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_var.h>
+#include <net/route.h>
+#include <netinet/if_ether.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+
+MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
+
+static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
+
+extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
+ u_char *);
+
+/*
+ * Dump arp state for a specific address family.
+ */
+int
+lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
+{
+ struct lltable *llt;
+ int error = 0;
+
+ IFNET_RLOCK();
+ SLIST_FOREACH(llt, &lltables, llt_link) {
+ if (llt->llt_af == af) {
+ error = llt->llt_dump(llt, wr);
+ if (error != 0)
+ goto done;
+ }
+ }
+done:
+ IFNET_RUNLOCK();
+ return (error);
+}
+
+/*
+ * Deletes an address from the address table.
+ * This function is called by the timer functions
+ * such as arptimer() and nd6_llinfo_timer(), and
+ * the caller does the locking.
+ */
+void
+llentry_free(struct llentry *lle)
+{
+ struct lltable *llt = lle->lle_tbl;
+
+ LIST_REMOVE(lle, lle_next);
+
+ if (lle->la_hold != NULL)
+ m_freem(lle->la_hold);
+ llt->llt_free(llt, lle);
+}
+
+/*
+ * Free all entries from given table and free itself.
+ * Since lltables collects from all of the intefaces,
+ * the caller of this function must acquire IFNET_WLOCK().
+ */
+void
+lltable_free(struct lltable *llt)
+{
+ struct llentry *lle, *next;
+ int i;
+
+ KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
+
+ IFNET_WLOCK();
+ SLIST_REMOVE(&lltables, llt, lltable, llt_link);
+ IFNET_WUNLOCK();
+
+ for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+ LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+ callout_drain(&lle->la_timer);
+ llentry_free(lle);
+ }
+ }
+
+ free(llt, M_LLTABLE);
+}
+
+void
+lltable_drain(int af)
+{
+ struct lltable *llt;
+ struct llentry *lle;
+ register int i;
+
+ IFNET_RLOCK();
+ SLIST_FOREACH(llt, &lltables, llt_link) {
+ if (llt->llt_af != af)
+ continue;
+
+ for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+ LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
+ if (lle->la_hold) {
+ m_freem(lle->la_hold);
+ lle->la_hold = NULL;
+ }
+ }
+ }
+ }
+ IFNET_RUNLOCK();
+}
+
+/*
+ * Create a new lltable.
+ */
+struct lltable *
+lltable_init(struct ifnet *ifp, int af)
+{
+ struct lltable *llt;
+ register int i;
+
+ llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK);
+ if (llt == NULL)
+ return (NULL);
+
+ llt->llt_af = af;
+ llt->llt_ifp = ifp;
+ for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
+ LIST_INIT(&llt->lle_head[i]);
+
+ IFNET_WLOCK();
+ SLIST_INSERT_HEAD(&lltables, llt, llt_link);
+ IFNET_WUNLOCK();
+
+ return (llt);
+}
+
+/*
+ * Called in route_output when adding/deleting a route to an interface.
+ */
+int
+lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
+{
+ struct sockaddr_dl *dl =
+ (struct sockaddr_dl *)info->rti_info[RTAX_GATEWAY];
+ struct sockaddr *dst = (struct sockaddr *)info->rti_info[RTAX_DST];
+ struct ifnet *ifp;
+ struct lltable *llt;
+ struct llentry *lle;
+ u_int flags = 0;
+
+ if (dl == NULL || dl->sdl_family != AF_LINK) {
+ log(LOG_INFO, "%s: invalid dl\n", __func__);
+ return EINVAL;
+ }
+ ifp = ifnet_byindex(dl->sdl_index);
+ if (ifp == NULL) {
+ log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n",
+ __func__, dl->sdl_index);
+ return EINVAL;
+ }
+
+ switch (rtm->rtm_type) {
+ case RTM_ADD:
+ if (rtm->rtm_flags & RTF_ANNOUNCE) {
+ flags |= LLE_PUB;
+#ifdef INET
+ if (dst->sa_family == AF_INET &&
+ ((struct sockaddr_inarp *)dst)->sin_other != 0) {
+ struct rtentry *rt = rtalloc1(dst, 0, 0);
+ if (rt == NULL || !(rt->rt_flags & RTF_HOST)) {
+ log(LOG_INFO, "%s: RTM_ADD publish "
+ "(proxy only) is invalid\n",
+ __func__);
+ rtfree(rt);
+ return EINVAL;
+ }
+ rtfree(rt);
+
+ flags |= LLE_PROXY;
+ }
+#endif
+ }
+ flags |= LLE_CREATE;
+ break;
+
+ case RTM_DELETE:
+ flags |= LLE_DELETE;
+ break;
+
+ case RTM_CHANGE:
+ break;
+
+ default:
+ return EINVAL; /* XXX not implemented yet */
+ }
+
+ /*
+ * XXXXXXXX:
+ * REVISE this approach if possible.
+ */
+ IFNET_WLOCK();
+ SLIST_FOREACH(llt, &lltables, llt_link) {
+ if (llt->llt_af == dst->sa_family &&
+ llt->llt_ifp == ifp)
+ break;
+ }
+ IFNET_WUNLOCK();
+ KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
+
+ IF_AFDATA_LOCK(ifp);
+ lle = lla_lookup(llt, flags, dst);
+ if (lle != NULL) {
+ if (flags & LLE_CREATE) {
+ /* qing: if we delay the delete, then if a subsequent
+ * "arp add" on the same host should look up this entry,
+ * reset the LLE_DELETED flag, and reset the expiration timer
+ */
+ bcopy(LLADDR(dl), &lle->ll_addr, ifp->if_addrlen);
+ lle->la_flags |= LLE_VALID;
+ lle->la_flags &= ~LLE_DELETED;
+#ifdef INET6
+ /*
+ * ND6
+ */
+ if (dst->sa_family == AF_INET6)
+ lle->ln_state = ND6_LLINFO_REACHABLE;
+#endif
+ /*
+ * "arp" and "ndp" always sets the (RTF_STATIC | RTF_HOST) flags
+ */
+ if (rtm->rtm_rmx.rmx_expire == 0) {
+ lle->la_flags |= LLE_STATIC;
+ lle->la_expire = 0;
+ } else
+ lle->la_expire = rtm->rtm_rmx.rmx_expire;
+#ifdef INET
+ /* gratuious ARP */
+ if ((lle->la_flags & LLE_PUB) &&
+ dst->sa_family == AF_INET) {
+ arprequest(ifp,
+ &((struct sockaddr_in *)dst)->sin_addr,
+ &((struct sockaddr_in *)dst)->sin_addr,
+ ((lle->la_flags & LLE_PROXY) ?
+ (u_char *)IF_LLADDR(ifp) :
+ (u_char *)LLADDR(dl)));
+ }
+#endif
+ }
+ } else {
+ if (flags & LLE_DELETE) {
+ IF_AFDATA_UNLOCK(ifp);
+ return EINVAL;
+ }
+ }
+
+ IF_AFDATA_UNLOCK(ifp);
+ return 0;
+}
Added: user/kmacy/head_arpv2/sys/net/if_llatbl.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/kmacy/head_arpv2/sys/net/if_llatbl.h Thu Dec 4 02:23:01 2008 (r185598)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2007 Qing Li, Luigi Rizzo, Alessandro Cerri. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifndef _NET_IF_LLATBL_H_
+#define _NET_IF_LLATBL_H_
+
+#include <netinet/in.h>
+
+struct ifnet;
+struct sysctl_req;
+struct rt_msghdr;
+struct rt_addrinfo;
+
+struct llentry;
+LIST_HEAD(llentries, llentry);
+
+struct llentry {
+ LIST_ENTRY(llentry) lle_next;
+ struct lltable *lle_tbl;
+ struct llentries *lle_head;
+ struct mbuf *la_hold;
+ time_t la_expire;
+ uint16_t la_flags;
+ uint16_t la_asked;
+ uint16_t la_preempt;
+ uint16_t ln_byhint;
+ int16_t ln_state; /* IPv6 has ND6_LLINFO_NOSTATE == -2 */
+ uint16_t ln_router;
+ time_t ln_ntick;
+ union {
+ uint64_t mac_aligned;
+ uint16_t mac16[3];
+ } ll_addr;
+
+ /* XXX af-private? */
+ union {
+ struct callout ln_timer_ch;
+ struct callout la_timer;
+ } lle_timer;
+ /* NB: struct sockaddr must immediately follow */
+};
+
+#define ln_timer_ch lle_timer.ln_timer_ch
+#define la_timer lle_timer.la_timer
+
+/* XXX bad name */
+#define L3_ADDR(lle) ((struct sockaddr *)(&lle[1]))
+#define L3_ADDR_LEN(lle) (((struct sockaddr *)(&lle[1]))->sa_len)
+
+#ifndef LLTBL_HASHTBL_SIZE
+#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
+#endif
+
+#ifndef LLTBL_HASHMASK
+#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1)
+#endif
+
+struct lltable {
+ SLIST_ENTRY(lltable) llt_link;
+ struct llentries lle_head[LLTBL_HASHTBL_SIZE];
+ int llt_af;
+ struct ifnet *llt_ifp;
+
+ struct llentry * (*llt_new)(const struct sockaddr *, u_int);
+ void (*llt_free)(struct lltable *, struct llentry *);
+ struct llentry * (*llt_lookup)(struct lltable *, u_int flags,
+ const struct sockaddr *l3addr);
+ int (*llt_rtcheck)(struct ifnet *,
+ const struct sockaddr *);
+ int (*llt_dump)(struct lltable *,
+ struct sysctl_req *);
+};
+MALLOC_DECLARE(M_LLTABLE);
+
+/*
+ * flags to be passed to arplookup.
+ */
+#define LLE_DELETED 0x0001 /* entry must be deleted */
+#define LLE_STATIC 0x0002 /* entry is static */
+#define LLE_IFADDR 0x0004 /* entry is interface addr */
+#define LLE_VALID 0x0008 /* ll_addr is valid */
+#define LLE_PROXY 0x0010 /* proxy entry ??? */
+#define LLE_PUB 0x0020 /* publish entry ??? */
+#define LLE_CREATE 0x8000 /* create on a lookup miss */
+#define LLE_DELETE 0x4000 /* delete on a lookup - match LLE_IFADDR */
+
+#define LLATBL_HASH(key, mask) \
+ (((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
+
+struct lltable *lltable_init(struct ifnet *, int);
+void lltable_free(struct lltable *);
+void lltable_drain(int);
+int lltable_sysctl_dumparp(int, struct sysctl_req *);
+
+void llentry_free(struct llentry *);
+
+/*
+ * Generic link layer address lookup function.
+ */
+static __inline struct llentry *
+lla_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
+{
+ return llt->llt_lookup(llt, flags, l3addr);
+}
+
+int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
+#endif /* _NET_IF_LLATBL_H_ */
Modified: user/kmacy/head_arpv2/sys/net/if_var.h
==============================================================================
--- user/kmacy/head_arpv2/sys/net/if_var.h Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/if_var.h Thu Dec 4 02:23:01 2008 (r185598)
@@ -68,6 +68,7 @@ struct rtentry;
struct rt_addrinfo;
struct socket;
struct ether_header;
+struct lltable;
struct carp_if;
struct ifvlantrunk;
#endif
@@ -169,8 +170,6 @@ struct ifnet {
void *if_bridge; /* bridge glue */
- struct lltable *lltables; /* list of L3-L2 resolution tables */
-
struct label *if_label; /* interface MAC label */
/* these are only used by IPv6 */
@@ -181,6 +180,7 @@ struct ifnet {
struct task if_starttask; /* task for IFF_NEEDSGIANT */
struct task if_linktask; /* task for link change events */
struct mtx if_addr_mtx; /* mutex to protect address lists */
+
LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */
TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
/* protected by if_addr_mtx */
@@ -359,7 +359,8 @@ typedef void (*group_change_event_handle
EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
#define IF_AFDATA_LOCK_INIT(ifp) \
- mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
+ mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, \
+ (MTX_DEF | MTX_RECURSE))
#define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx)
#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx)
#define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx)
Modified: user/kmacy/head_arpv2/sys/net/route.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/route.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/route.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -41,6 +41,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
@@ -52,6 +53,7 @@
#include <sys/vimage.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/route.h>
#ifdef RADIX_MPATH
@@ -383,7 +385,7 @@ rtfree(struct rtentry *rt)
*/
RT_REMREF(rt);
if (rt->rt_refcnt > 0) {
- printf("%s: %p has %lu refs\n", __func__, rt, rt->rt_refcnt);
+ log(LOG_DEBUG, "%s: %p has %lu refs\t", __func__, rt, rt->rt_refcnt);
goto done;
}
@@ -1452,6 +1454,7 @@ rtinit1(struct ifaddr *ifa, int cmd, int
char tempbuf[_SOCKADDR_TMPSIZE];
int didwork = 0;
int a_failure = 0;
+ static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
if (flags & RTF_HOST) {
dst = ifa->ifa_dstaddr;
@@ -1556,7 +1559,14 @@ rtinit1(struct ifaddr *ifa, int cmd, int
info.rti_ifa = ifa;
info.rti_flags = flags | ifa->ifa_flags;
info.rti_info[RTAX_DST] = dst;
- info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
+ /*
+ * doing this for compatibility reasons
+ */
+ if (cmd == RTM_ADD)
+ info.rti_info[RTAX_GATEWAY] =
+ (struct sockaddr *)&null_sdl;
+ else
+ info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
info.rti_info[RTAX_NETMASK] = netmask;
error = rtrequest1_fib(cmd, &info, &rt, fibnum);
if (error == 0 && rt != NULL) {
@@ -1580,6 +1590,15 @@ rtinit1(struct ifaddr *ifa, int cmd, int
rt->rt_ifa = ifa;
}
#endif
+ /*
+ * doing this for compatibility reasons
+ */
+ if (cmd == RTM_ADD) {
+ ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
+ rt->rt_ifp->if_type;
+ ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
+ rt->rt_ifp->if_index;
+ }
rt_newaddrmsg(cmd, ifa, error, rt);
if (cmd == RTM_DELETE) {
/*
Modified: user/kmacy/head_arpv2/sys/net/rtsock.c
==============================================================================
--- user/kmacy/head_arpv2/sys/net/rtsock.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/net/rtsock.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -51,6 +51,7 @@
#include <sys/vimage.h>
#include <net/if.h>
+#include <net/if_llatbl.h>
#include <net/netisr.h>
#include <net/raw_cb.h>
#include <net/route.h>
@@ -524,6 +525,11 @@ route_output(struct mbuf *m, struct sock
if (info.rti_info[RTAX_GATEWAY] == NULL)
senderr(EINVAL);
saved_nrt = NULL;
+ /* support for new ARP code */
+ if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) {
+ error = lla_rt_output(rtm, &info);
+ break;
+ }
error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt,
so->so_fibnum);
if (error == 0 && saved_nrt) {
@@ -539,6 +545,12 @@ route_output(struct mbuf *m, struct sock
case RTM_DELETE:
saved_nrt = NULL;
+ /* support for new ARP code */
+ if (info.rti_info[RTAX_GATEWAY] &&
+ (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)) {
+ error = lla_rt_output(rtm, &info);
+ break;
+ }
error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt,
so->so_fibnum);
if (error == 0) {
@@ -1430,6 +1442,11 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
RADIX_NODE_HEAD_UNLOCK(rnh);
} else if (af != 0)
error = EAFNOSUPPORT;
+ /*
+ * take care of llinfo entries
+ */
+ if (w.w_op == NET_RT_FLAGS && (RTF_LLINFO & w.w_arg))
+ error = lltable_sysctl_dumparp(af, w.w_req);
break;
case NET_RT_IFLIST:
Modified: user/kmacy/head_arpv2/sys/netinet/if_ether.c
==============================================================================
--- user/kmacy/head_arpv2/sys/netinet/if_ether.c Thu Dec 4 02:16:53 2008 (r185597)
+++ user/kmacy/head_arpv2/sys/netinet/if_ether.c Thu Dec 4 02:23:01 2008 (r185598)
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <net/if_llatbl.h>
#include <netinet/if_ether.h>
#include <netinet/vinet.h>
@@ -79,6 +80,7 @@ __FBSDID("$FreeBSD$");
#define SIN(s) ((struct sockaddr_in *)s)
#define SDL(s) ((struct sockaddr_dl *)s)
+#define LLTABLE(ifp) ((struct lltable *)(ifp)->if_afdata[AF_INET])
SYSCTL_DECL(_net_link_ether);
SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, "");
@@ -87,7 +89,7 @@ SYSCTL_NODE(_net_link_ether, PF_INET, in
#ifdef VIMAGE_GLOBALS
static int arpt_keep; /* once resolved, good for 20 more minutes */
static int arp_maxtries;
-static int useloopback; /* use loopback interface for local traffic */
+int useloopback; /* use loopback interface for local traffic */
static int arp_proxyall;
#endif
@@ -96,14 +98,6 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_link
#define rt_expire rt_rmx.rmx_expire
-struct llinfo_arp {
- struct callout la_timer;
- struct rtentry *la_rt;
- struct mbuf *la_hold; /* last packet until resolved/timeout */
- u_short la_preempt; /* countdown for pre-expiry arps */
- u_short la_asked; /* # requests sent */
-};
-
static struct ifqueue arpintrq;
SYSCTL_V_INT(V_NET, vnet_inet, _net_link_ether_inet, OID_AUTO, maxtries,
@@ -117,212 +111,104 @@ SYSCTL_V_INT(V_NET, vnet_inet, _net_link
"Enable proxy ARP for all suitable requests");
static void arp_init(void);
-static void arp_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
-static void arprequest(struct ifnet *,
+void arprequest(struct ifnet *,
struct in_addr *, struct in_addr *, u_char *);
static void arpintr(struct mbuf *);
static void arptimer(void *);
-static struct rtentry
- *arplookup(u_long, int, int, int);
#ifdef INET
static void in_arpinput(struct mbuf *);
#endif
+#ifdef AF_INET
+void arp_ifscrub(struct ifnet *ifp, uint32_t addr);
+
/*
- * Timeout routine.
+ * called by in_ifscrub to remove entry from the table when
+ * the interface goes away
*/
-static void
-arptimer(void *arg)
+void
+arp_ifscrub(struct ifnet *ifp, uint32_t addr)
{
- struct rtentry *rt = (struct rtentry *)arg;
+ struct sockaddr_in addr4;
+ struct llentry *lle;
- RT_LOCK_ASSERT(rt);
- /*
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-user
mailing list