From owner-svn-src-user@FreeBSD.ORG Thu Dec 11 06:53:54 2008 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A24FD106564A; Thu, 11 Dec 2008 06:53:54 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 901C08FC2A; Thu, 11 Dec 2008 06:53:54 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mBB6rsvT056920; Thu, 11 Dec 2008 06:53:54 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mBB6rrJk056905; Thu, 11 Dec 2008 06:53:53 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <200812110653.mBB6rrJk056905@svn.freebsd.org> From: Kip Macy Date: Thu, 11 Dec 2008 06:53:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r185911 - in user/kmacy/HEAD_fast_multi_xmit/sys: conf contrib/rdma dev/cxgb/ulp/tom net netinet netinet6 X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Dec 2008 06:53:54 -0000 Author: kmacy Date: Thu Dec 11 06:53:53 2008 New Revision: 185911 URL: http://svn.freebsd.org/changeset/base/185911 Log: merge arpv2 and garbage collection of cloning Modified: user/kmacy/HEAD_fast_multi_xmit/sys/conf/files user/kmacy/HEAD_fast_multi_xmit/sys/contrib/rdma/rdma_addr.c user/kmacy/HEAD_fast_multi_xmit/sys/dev/cxgb/ulp/tom/cxgb_l2t.c user/kmacy/HEAD_fast_multi_xmit/sys/net/flowtable.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_arcsubr.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_ethersubr.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fddisubr.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fwsubr.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_iso88025subr.c user/kmacy/HEAD_fast_multi_xmit/sys/net/if_var.h user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h user/kmacy/HEAD_fast_multi_xmit/sys/net/rtsock.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/if_ether.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/if_ether.h user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in_mcast.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in_pcb.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in_proto.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in_rmx.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/in_var.h user/kmacy/HEAD_fast_multi_xmit/sys/netinet/ip_fastfwd.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/ip_input.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/ip_output.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet/tcp_subr.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/icmp6.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/in6.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/in6_rmx.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/in6_src.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/in6_var.h user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/ip6_forward.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/ip6_input.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/ip6_output.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/ip6_var.h user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/nd6.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/nd6.h user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/nd6_nbr.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/nd6_rtr.c user/kmacy/HEAD_fast_multi_xmit/sys/netinet6/vinet6.h Modified: user/kmacy/HEAD_fast_multi_xmit/sys/conf/files ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/conf/files Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/conf/files Thu Dec 11 06:53:53 2008 (r185911) @@ -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_fast_multi_xmit/sys/contrib/rdma/rdma_addr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/contrib/rdma/rdma_addr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/contrib/rdma/rdma_addr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -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_fast_multi_xmit/sys/dev/cxgb/ulp/tom/cxgb_l2t.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/dev/cxgb/ulp/tom/cxgb_l2t.c Thu Dec 11 06:53:53 2008 (r185911) @@ -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_fast_multi_xmit/sys/net/flowtable.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/flowtable.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/flowtable.c Thu Dec 11 06:53:53 2008 (r185911) @@ -34,22 +34,6 @@ #define calloc(count, size) malloc((count)*(size), M_DEVBUF, M_WAITOK|M_ZERO) - - -#if defined (__GNUC__) - #if #cpu(i386) || defined __i386 || defined i386 || defined __i386__ || #cpu(x86_64) || defined __x86_64__ - #define mb() __asm__ __volatile__ ("mfence;": : :"memory") - #elif #cpu(sparc64) || defined sparc64 || defined __sparcv9 - #define mb() __asm__ __volatile__ ("membar #MemIssue": : :"memory") - #elif #cpu(sparc) || defined sparc || defined __sparc__ - #define mb() __asm__ __volatile__ ("stbar;": : :"memory") - #else - #define mb() /* XXX just to make this compile */ - #endif -#else - #error "unknown compiler" -#endif - /* * Taken from http://burtleburtle.net/bob/c/lookup3.c */ @@ -301,7 +285,7 @@ static void in_rtalloc_ign_wrapper(struct route *ro, uint32_t hash, u_int fib) { - in_rtalloc_ign(ro, RTF_CLONING, fib); + in_rtalloc_ign(ro, 0, fib); } #endif @@ -463,12 +447,12 @@ flow_stale(struct flowtable *ft, struct if ((fle->f_fhash == 0) || ((fle->f_rt->rt_flags & RTF_HOST) && - ((fle->f_rt->rt_flags & (RTF_UP|RTF_LLINFO)) - != (RTF_UP|RTF_LLINFO))) + ((fle->f_rt->rt_flags & (RTF_UP)) + != (RTF_UP))) || (fle->f_uptime <= fle->f_rt->rt_llinfo_uptime) || ((fle->f_rt->rt_flags & RTF_GATEWAY) && - ((fle->f_rt->rt_gwroute->rt_flags & (RTF_UP|RTF_LLINFO)) - != (RTF_UP|RTF_LLINFO))) + ((fle->f_rt->rt_gwroute->rt_flags & (RTF_UP)) + != (RTF_UP))) || (fle->f_rt->rt_ifp == NULL)) return (1); @@ -677,13 +661,14 @@ uncached: error = ENETUNREACH; else { int finsert; - + struct llentry *lle; + if (ro.ro_rt->rt_flags & RTF_GATEWAY) error = arpresolve(ro.ro_rt->rt_ifp, ro.ro_rt, - NULL, ro.ro_rt->rt_gateway, desten); + NULL, ro.ro_rt->rt_gateway, desten, &lle); else error = arpresolve(ro.ro_rt->rt_ifp, ro.ro_rt, - NULL, &ro.ro_dst, desten); + NULL, &ro.ro_dst, desten, &lle); #ifdef DIAGNOSTICS if (error) log(LOG_WARNING, "dst=%s gw=%s proto=%d hash=%x " @@ -704,8 +689,8 @@ uncached: #endif route_to_rtentry_info(&ro, error ? NULL : desten, ri); ro.ro_rt->rt_rmx.rmx_pksent++; - finsert = (error == 0 && cache - && !(ro.ro_rt->rt_flags & RTF_CLONING)); + finsert = ((error == 0) && cache); + if (finsert) error = flowtable_insert(ft, hash, key, proto, Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/if.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if.c Thu Dec 11 06:53:53 2008 (r185911) @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -1343,6 +1344,9 @@ done: return (ifa); } +#include +#include + /* * Default action when installing a route with a Link Level gateway. * Lookup an appropriate real ifa to point to. Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/if_arcsubr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_arcsubr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_arcsubr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -64,6 +64,7 @@ #include #include #include +#include #if defined(INET) || defined(INET6) #include @@ -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_fast_multi_xmit/sys/net/if_ethersubr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_ethersubr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_ethersubr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -149,6 +150,8 @@ static int ether_ipfw; #endif #endif +extern int useloopback; + /* * Ethernet output routine. * Encapsulate a packet of type family for the local net. @@ -162,6 +165,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; struct rtentry_info *ri = NULL; @@ -200,7 +204,7 @@ ether_output(struct ifnet *ifp, struct m if (riset && (ri->ri_flags && RTF_DESTEN_VALID)) memcpy(edst, ri->ri_desten, ETHER_ADDR_LEN); else - 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); @@ -235,7 +239,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); @@ -303,6 +307,17 @@ ether_output(struct ifnet *ifp, struct m senderr(EAFNOSUPPORT); } + if (lle && (lle->la_flags & LLE_IFADDR) && useloopback) { + int csum_flags = 0; + if (m->m_pkthdr.csum_flags & CSUM_IP) + csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); + if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) + csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); + m->m_pkthdr.csum_flags |= csum_flags; + m->m_pkthdr.csum_data = 0xffff; + 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_fast_multi_xmit/sys/net/if_fddisubr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fddisubr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fddisubr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -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_fast_multi_xmit/sys/net/if_fwsubr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fwsubr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_fwsubr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -51,6 +51,7 @@ #include #include #include +#include #if defined(INET) || defined(INET6) #include @@ -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_fast_multi_xmit/sys/net/if_iso88025subr.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_iso88025subr.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_iso88025subr.c Thu Dec 11 06:53:53 2008 (r185911) @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -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; Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/if_var.h ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/if_var.h Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/if_var.h Thu Dec 11 06:53:53 2008 (r185911) @@ -68,6 +68,7 @@ struct rtentry; struct rt_addrinfo; struct socket; struct ether_header; +struct lltable; struct carp_if; struct ifvlantrunk; #endif @@ -170,8 +171,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 */ @@ -182,6 +181,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 */ @@ -366,6 +366,9 @@ EVENTHANDLER_DECLARE(group_change_event, #define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx) #define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx) +#define IF_AFDATA_LOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_mtx, MA_OWNED) +#define IF_AFDATA_UNLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_mtx, MA_NOTOWNED) + #define IFF_LOCKGIANT(ifp) do { \ if ((ifp)->if_flags & IFF_NEEDSGIANT) \ mtx_lock(&Giant); \ Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/radix_mpath.c Thu Dec 11 06:53:53 2008 (r185911) @@ -271,8 +271,8 @@ rtalloc_mpath_fib(struct route *ro, u_in * be done for sendto(3) case? */ if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP)) - return; /* XXX */ - ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, RTF_CLONING, fibnum); + return; + ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, 0, fibnum); /* if the route does not exist or it is not multipath, don't care */ if (ro->ro_rt == NULL) Modified: user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/route.c Thu Dec 11 06:53:53 2008 (r185911) @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include +#include #include #ifdef RADIX_MPATH @@ -269,8 +271,7 @@ rtalloc1_fib(struct sockaddr *dst, int r struct radix_node *rn; struct rtentry *newrt; struct rt_addrinfo info; - u_long nflags; - int needresolve = 0, err = 0, msgtype = RTM_MISS; + int err = 0, msgtype = RTM_MISS; int needlock; KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum")); @@ -283,10 +284,9 @@ rtalloc1_fib(struct sockaddr *dst, int r */ if (rnh == NULL) { V_rtstat.rts_unreach++; - goto miss2; + goto miss; } needlock = !(ignflags & RTF_RNH_LOCKED); -retry: if (needlock) RADIX_NODE_HEAD_RLOCK(rnh); #ifdef INVARIANTS @@ -295,103 +295,33 @@ retry: #endif rn = rnh->rnh_matchaddr(dst, rnh); if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) { - newrt = rt = RNTORT(rn); - nflags = rt->rt_flags & ~ignflags; - if (report && (nflags & RTF_CLONING)) { - if (needlock && !RADIX_NODE_HEAD_LOCK_TRY_UPGRADE(rnh)) { - RADIX_NODE_HEAD_RUNLOCK(rnh); - RADIX_NODE_HEAD_LOCK(rnh); - /* - * lookup again to make sure it wasn't changed - */ - rn = rnh->rnh_matchaddr(dst, rnh); - if (!(rn && ((rn->rn_flags & RNF_ROOT) == 0))) { - RADIX_NODE_HEAD_UNLOCK(rnh); - needresolve = 0; - log(LOG_INFO, "retrying route lookup ...\n"); - goto retry; - } - } - needresolve = 1; - } else { - RT_LOCK(newrt); - RT_ADDREF(newrt); - if (needlock) - RADIX_NODE_HEAD_RUNLOCK(rnh); - goto done; - } - } - /* - * if needresolve is set then we have the exclusive lock - * and we need to keep it held for the benefit of rtrequest_fib - */ - if (!needresolve && needlock) - RADIX_NODE_HEAD_RUNLOCK(rnh); - - if (needresolve) { - RADIX_NODE_HEAD_WLOCK_ASSERT(rnh); - /* - * We are apparently adding (report = 0 in delete). - * If it requires that it be cloned, do so. - * (This implies it wasn't a HOST route.) - */ - err = rtrequest_fib(RTM_RESOLVE, dst, NULL, - NULL, RTF_RNH_LOCKED, &newrt, fibnum); - if (err) { - /* - * If the cloning didn't succeed, maybe - * what we have will do. Return that. - */ - newrt = rt; /* existing route */ - RT_LOCK(newrt); - RT_ADDREF(newrt); - goto miss; - } - KASSERT(newrt, ("no route and no error")); RT_LOCK(newrt); - if (newrt->rt_flags & RTF_XRESOLVE) { - /* - * If the new route specifies it be - * externally resolved, then go do that. - */ - msgtype = RTM_RESOLVE; - goto miss; - } - /* Inform listeners of the new route. */ - bzero(&info, sizeof(info)); - info.rti_info[RTAX_DST] = rt_key(newrt); - info.rti_info[RTAX_NETMASK] = rt_mask(newrt); - info.rti_info[RTAX_GATEWAY] = newrt->rt_gateway; - if (newrt->rt_ifp != NULL) { - info.rti_info[RTAX_IFP] = - newrt->rt_ifp->if_addr->ifa_addr; - info.rti_info[RTAX_IFA] = newrt->rt_ifa->ifa_addr; - } - rt_missmsg(RTM_ADD, &info, newrt->rt_flags, 0); + RT_ADDREF(newrt); if (needlock) - RADIX_NODE_HEAD_UNLOCK(rnh); - } else { - /* - * Either we hit the root or couldn't find any match, - * Which basically means - * "caint get there frm here" + RADIX_NODE_HEAD_RUNLOCK(rnh); + goto done; + + } else if (needlock) + RADIX_NODE_HEAD_RUNLOCK(rnh); + + /* + * Either we hit the root or couldn't find any match, + * Which basically means + * "caint get there frm here" + */ + V_rtstat.rts_unreach++; +miss: + if (report) { + /* + * If required, report the failure to the supervising + * Authorities. + * For a delete, this is not an error. (report == 0) */ - V_rtstat.rts_unreach++; - miss: - if (needlock && needresolve) - RADIX_NODE_HEAD_UNLOCK(rnh); - miss2: if (report) { - /* - * If required, report the failure to the supervising - * Authorities. - * For a delete, this is not an error. (report == 0) - */ - bzero(&info, sizeof(info)); - info.rti_info[RTAX_DST] = dst; - rt_missmsg(msgtype, &info, 0, err); - } - } + bzero(&info, sizeof(info)); + info.rti_info[RTAX_DST] = dst; + rt_missmsg(msgtype, &info, 0, err); + } done: if (newrt) RT_LOCK_ASSERT(newrt); @@ -420,7 +350,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; } @@ -715,14 +645,6 @@ ifa_ifwithroute_fib(int flags, struct so return (ifa); } -static walktree_f_t rt_fixdelete; -static walktree_f_t rt_fixchange; - -struct rtfc_arg { - struct rtentry *rt0; - struct radix_node_head *rnh; -}; - /* * Do appropriate manipulations of a routing tree given * all the bits of info needed @@ -862,14 +784,6 @@ rtexpunge(struct rtentry *rt) rt->rt_flags &= ~RTF_UP; /* - * Now search what's left of the subtree for any cloned - * routes which might have been formed from this node. - */ - if ((rt->rt_flags & RTF_CLONING) && rt_mask(rt)) - rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt), - rt_fixdelete, rt); - - /* * Remove any external references we may have. * This might result in another rtentry being freed if * we held its last reference. @@ -1032,10 +946,9 @@ rtrequest1_fib(int req, struct rt_addrin * If we are adding a host route then we don't want to put * a netmask in the tree, nor do we want to clone it. */ - if (flags & RTF_HOST) { + if (flags & RTF_HOST) netmask = NULL; - flags &= ~RTF_CLONING; - } + switch (req) { case RTM_DELETE: #ifdef RADIX_MPATH @@ -1064,16 +977,6 @@ rtrequest1_fib(int req, struct rt_addrin RT_ADDREF(rt); rt->rt_flags &= ~RTF_UP; /* - * Now search what's left of the subtree for any cloned - * routes which might have been formed from this node. - */ - if ((rt->rt_flags & RTF_CLONING) && - rt_mask(rt)) { - rnh->rnh_walktree_from(rnh, dst, rt_mask(rt), - rt_fixdelete, rt); - } - - /* * Remove any external references we may have. * This might result in another rtentry being freed if * we held its last reference. @@ -1107,20 +1010,12 @@ rtrequest1_fib(int req, struct rt_addrin } else RTFREE_LOCKED(rt); break; - case RTM_RESOLVE: - if (ret_nrt == NULL || (rt = *ret_nrt) == NULL) - senderr(EINVAL); - ifa = rt->rt_ifa; - /* XXX locking? */ - flags = rt->rt_flags & - ~(RTF_CLONING | RTF_STATIC); - flags |= RTF_WASCLONED; - gateway = rt->rt_gateway; - if ((netmask = rt->rt_genmask) == NULL) - flags |= RTF_HOST; - goto makeroute; - + /* + * resolve is only used for route cloning + * + */ + senderr(EINVAL); case RTM_ADD: if ((flags & RTF_GATEWAY) && !gateway) senderr(EINVAL); @@ -1131,8 +1026,6 @@ rtrequest1_fib(int req, struct rt_addrin if (info->rti_ifa == NULL && (error = rt_getifa_fib(info, fibnum))) senderr(error); ifa = info->rti_ifa; - - makeroute: rt = uma_zalloc(rtzone, M_NOWAIT | M_ZERO); if (rt == NULL) senderr(ENOBUFS); @@ -1190,26 +1083,6 @@ rtrequest1_fib(int req, struct rt_addrin /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes); - if (rn == NULL) { - struct rtentry *rt2; - /* - * Uh-oh, we already have one of these in the tree. - * We do a special hack: if the route that's already - * there was generated by the cloning mechanism - * then we just blow it away and retry the insertion - * of the new one. - */ - rt2 = rtalloc1_fib(dst, 0, 0, fibnum); - if (rt2 && rt2->rt_parent) { - rtexpunge(rt2); - RT_UNLOCK(rt2); - rn = rnh->rnh_addaddr(ndst, netmask, - rnh, rt->rt_nodes); - } else if (rt2) { - /* undo the extra ref we got */ - RTFREE_LOCKED(rt2); - } - } /* * If it still failed to go into the tree, @@ -1227,32 +1100,6 @@ rtrequest1_fib(int req, struct rt_addrin } rt->rt_parent = NULL; - - /* - * If we got here from RESOLVE, then we are cloning - * so clone the rest, and note that we - * are a clone (and increment the parent's references) - */ - if (req == RTM_RESOLVE) { - KASSERT(ret_nrt && *ret_nrt, - ("no route to clone from")); - rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ - rt->rt_rmx.rmx_pksent = 0; /* reset packet counter */ - if ((*ret_nrt)->rt_flags & RTF_CLONING) { - /* - * NB: We do not bump the refcnt on the parent - * entry under the assumption that it will - * remain so long as we do. This is - * important when deleting the parent route - * as this operation requires traversing - * the tree to delete all clones and futzing - * with refcnts requires us to double-lock - * parent through this back reference. - */ - rt->rt_parent = *ret_nrt; - } - } - /* * If this protocol has something to add to this then * allow it to do that as well. @@ -1261,20 +1108,6 @@ rtrequest1_fib(int req, struct rt_addrin ifa->ifa_rtrequest(req, rt, info); /* - * We repeat the same procedure from rt_setgate() here because - * it doesn't fire when we call it there because the node - * hasn't been added to the tree yet. - */ - if (req == RTM_ADD && - !(rt->rt_flags & RTF_HOST) && rt_mask(rt) != NULL) { - struct rtfc_arg arg; - arg.rnh = rnh; - arg.rt0 = rt; - rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt), - rt_fixchange, &arg); - } - - /* * actually return a resultant rtentry and * give the caller a single reference. */ @@ -1301,90 +1134,6 @@ bad: #undef ifpaddr #undef flags -/* - * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' - * (i.e., the routes related to it by the operation of cloning). This - * routine is iterated over all potential former-child-routes by way of - * rnh->rnh_walktree_from() above, and those that actually are children of - * the late parent (passed in as VP here) are themselves deleted. - */ -static int -rt_fixdelete(struct radix_node *rn, void *vp) -{ - struct rtentry *rt = RNTORT(rn); - struct rtentry *rt0 = vp; - - if (rt->rt_parent == rt0 && - !(rt->rt_flags & (RTF_PINNED | RTF_CLONING))) { - return rtrequest_fib(RTM_DELETE, rt_key(rt), NULL, rt_mask(rt), - rt->rt_flags|RTF_RNH_LOCKED, NULL, rt->rt_fibnum); - } - return 0; -} - -/* - * This routine is called from rt_setgate() to do the analogous thing for - * adds and changes. There is the added complication in this case of a - * middle insert; i.e., insertion of a new network route between an older - * network route and (cloned) host routes. For this reason, a simple check - * of rt->rt_parent is insufficient; each candidate route must be tested - * against the (mask, value) of the new route (passed as before in vp) - * to see if the new route matches it. - * - * XXX - it may be possible to do fixdelete() for changes and reserve this - * routine just for adds. I'm not sure why I thought it was necessary to do - * changes this way. - */ - -static int -rt_fixchange(struct radix_node *rn, void *vp) -{ - struct rtentry *rt = RNTORT(rn); - struct rtfc_arg *ap = vp; - struct rtentry *rt0 = ap->rt0; - struct radix_node_head *rnh = ap->rnh; - u_char *xk1, *xm1, *xk2, *xmp; - int i, len, mlen; - - /* make sure we have a parent, and route is not pinned or cloning */ - if (!rt->rt_parent || - (rt->rt_flags & (RTF_PINNED | RTF_CLONING))) - return 0; - - if (rt->rt_parent == rt0) /* parent match */ - goto delete_rt; - /* - * There probably is a function somewhere which does this... - * if not, there should be. - */ - len = imin(rt_key(rt0)->sa_len, rt_key(rt)->sa_len); - - xk1 = (u_char *)rt_key(rt0); - xm1 = (u_char *)rt_mask(rt0); - xk2 = (u_char *)rt_key(rt); - - /* avoid applying a less specific route */ - xmp = (u_char *)rt_mask(rt->rt_parent); - mlen = rt_key(rt->rt_parent)->sa_len; - if (mlen > rt_key(rt0)->sa_len) /* less specific route */ - return 0; - for (i = rnh->rnh_treetop->rn_offset; i < mlen; i++) - if ((xmp[i] & ~(xmp[i] ^ xm1[i])) != xmp[i]) - return 0; /* less specific route */ - - for (i = rnh->rnh_treetop->rn_offset; i < len; i++) - if ((xk2[i] & xm1[i]) != xk1[i]) - return 0; /* no match */ - - /* - * OK, this node is a clone, and matches the node currently being - * changed/added under the node's mask. So, get rid of it. - */ -delete_rt: - return rtrequest_fib(RTM_DELETE, rt_key(rt), NULL, - rt_mask(rt), rt->rt_flags, NULL, rt->rt_fibnum); -} - int rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate) { @@ -1399,24 +1148,6 @@ again: RADIX_NODE_HEAD_LOCK_ASSERT(rnh); /* - * A host route with the destination equal to the gateway - * will interfere with keeping LLINFO in the routing - * table, so disallow it. - */ - if (((rt->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) == - (RTF_HOST|RTF_GATEWAY)) && - dst->sa_len == gate->sa_len && - bcmp(dst, gate, dst->sa_len) == 0) { - /* - * The route might already exist if this is an RTM_CHANGE - * or a routing redirect, so try to delete it. - */ - if (rt_key(rt)) - rtexpunge(rt); - return EADDRNOTAVAIL; - } - - /* * Cloning loop avoidance in case of bad configuration. */ if (rt->rt_flags & RTF_GATEWAY) { @@ -1484,21 +1215,7 @@ again: */ bcopy(gate, rt->rt_gateway, glen); - /* - * This isn't going to do anything useful for host routes, so - * don't bother. Also make sure we have a reasonable mask - * (we don't yet have one during adds). - */ - if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) { - struct rtfc_arg arg; - - arg.rnh = rnh; - arg.rt0 = rt; - rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt), - rt_fixchange, &arg); - } - - return 0; + return (0); } static void @@ -1538,6 +1255,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; @@ -1642,7 +1360,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) { @@ -1666,6 +1391,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_fast_multi_xmit/sys/net/route.h ============================================================================== --- user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h Thu Dec 11 06:27:18 2008 (r185910) +++ user/kmacy/HEAD_fast_multi_xmit/sys/net/route.h Thu Dec 11 06:53:53 2008 (r185911) @@ -143,7 +143,7 @@ struct rtentry { struct sockaddr *rt_genmask; /* for generation of cloned routes */ caddr_t rt_llinfo; /* pointer to link level info cache */ struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ - struct rtentry *rt_parent; /* cloning parent of this route */ + struct rtentry *rt_parent; /* cloning parent - UNUSED */ u_int rt_fibnum; /* which FIB */ #ifdef _KERNEL /* XXX ugly, user apps use this definition but don't have a mtx def */ @@ -176,9 +176,9 @@ struct ortentry { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***