==== //depot/vendor/freebsd/src/sys/net/if.c#162 (text+ko) - //depot/projects/ethng/src/sys/net/if.c#5 (text+ko) ==== content @@ -2680,6 +2680,15 @@ return (retval); } +int +if_mq_start(struct ifnet *ifp, struct mbuf *m) +{ + + KASSERT((ifp->if_flags & IFF_NEEDSGIANT) == 0, ("IFF_NEEDSGIANT set on multi queue interface")); + + return (*(ifp)->if_mq_start)(ifp, m); +} + /* * When an interface is marked IFF_NEEDSGIANT, its if_start() routine cannot * be called without Giant. However, we often can't acquire the Giant lock ==== //depot/vendor/freebsd/src/sys/net/if.h#46 (text+ko) - //depot/projects/ethng/src/sys/net/if.h#2 (text+ko) ==== content @@ -150,6 +150,7 @@ #define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */ #define IFF_STATICARP 0x80000 /* (n) static ARP */ #define IFF_NEEDSGIANT 0x100000 /* (i) hold Giant over if_start calls */ +#define IFF_MULTIQ 0x200000 /* (i) driver has multiple queues and manages them privately */ /* * Old names for driver flags so that user space tools can continue to use ==== //depot/vendor/freebsd/src/sys/net/if_arp.h#10 (text+ko) - //depot/projects/ethng/src/sys/net/if_arp.h#2 (text+ko) ==== content @@ -44,12 +44,14 @@ * specified. Field names used correspond to RFC 826. */ struct arphdr { - u_short ar_hrd; /* format of hardware address */ -#define ARPHRD_ETHER 1 /* ethernet hardware format */ -#define ARPHRD_IEEE802 6 /* token-ring hardware format */ -#define ARPHRD_ARCNET 7 /* arcnet hardware format */ -#define ARPHRD_FRELAY 15 /* frame relay hardware format */ -#define ARPHRD_IEEE1394 24 /* firewire hardware format */ + u_short ar_hrd; /* format of hardware address */ +#define ARPHRD_ETHER 1 /* ethernet hardware format */ +#define ARPHRD_IEEE802 6 /* token-ring hardware format */ +#define ARPHRD_ARCNET 7 /* arcnet hardware format */ +#define ARPHRD_FRELAY 15 /* frame relay hardware format */ +#define ARPHRD_IEEE1394 24 /* firewire hardware format */ +#define ARPHRD_INFINIBAND 32 /* InfiniBand */ + u_short ar_pro; /* format of protocol address */ u_char ar_hln; /* length of hardware address */ u_char ar_pln; /* length of protocol address */ ==== //depot/vendor/freebsd/src/sys/net/if_ethersubr.c#146 (text+ko) - //depot/projects/ethng/src/sys/net/if_ethersubr.c#6 (text+ko) ==== content @@ -512,44 +512,36 @@ struct ether_header *eh; u_short etype; - if ((ifp->if_flags & IFF_UP) == 0) { - m_freem(m); - return; - } + if ((ifp->if_flags & IFF_UP) == 0) + goto out; + #ifdef DIAGNOSTIC if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { if_printf(ifp, "discard frame at !IFF_DRV_RUNNING\n"); - m_freem(m); - return; + goto out; } #endif /* * Do consistency checks to verify assumptions * made by code past this point. */ - if ((m->m_flags & M_PKTHDR) == 0) { - if_printf(ifp, "discard frame w/o packet header\n"); - ifp->if_ierrors++; - m_freem(m); - return; - } - if (m->m_len < ETHER_HDR_LEN) { - /* XXX maybe should pullup? */ - if_printf(ifp, "discard frame w/o leading ethernet " - "header (len %u pkt len %u)\n", - m->m_len, m->m_pkthdr.len); - ifp->if_ierrors++; - m_freem(m); - return; - } + if ((m->m_flags & M_PKTHDR) == 0) + goto err_out_print; + if (m->m_len < ETHER_HDR_LEN) + goto err_out_print; + eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); - if (m->m_pkthdr.rcvif == NULL) { - if_printf(ifp, "discard frame w/o interface pointer\n"); - ifp->if_ierrors++; - m_freem(m); - return; - } +#ifdef DIAGNOSTIC + if (m->m_pkthdr.len > + ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS) && + (ifp->if_capenable & IFCAP_LRO) == 0) + goto err_out_print +#endif + + if (m->m_pkthdr.rcvif == NULL) + goto err_out_print; + #ifdef DIAGNOSTIC if (m->m_pkthdr.rcvif != ifp) { if_printf(ifp, "Warning, frame marked as received on %s\n", @@ -591,10 +583,8 @@ ifp->if_ibytes += m->m_pkthdr.len; /* Allow monitor mode to claim this frame, after stats are updated. */ - if (ifp->if_flags & IFF_MONITOR) { - m_freem(m); - return; - } + if (ifp->if_flags & IFF_MONITOR) + goto out; /* Handle input from a lagg(4) port */ if (ifp->if_type == IFT_IEEE8023ADLAG) { @@ -621,9 +611,7 @@ #ifdef DIAGNOSTIC if_printf(ifp, "cannot pullup VLAN header\n"); #endif - ifp->if_ierrors++; - m_freem(m); - return; + goto err_out; } evl = mtod(m, struct ether_vlan_header *); @@ -690,6 +678,33 @@ random_harvest(m, 16, 3, 0, RANDOM_NET); ether_demux(ifp, m); + return; +err_out_print: + eh = mtod(m, struct ether_header *); + etype = ntohs(eh->ether_type); + + if ((m->m_flags & M_PKTHDR) == 0) + if_printf(ifp, "discard frame w/o packet header\n"); + if (m->m_len < ETHER_HDR_LEN) + if_printf(ifp, "discard frame w/o leading ethernet " + "header (len %u pkt len %u)\n", + m->m_len, m->m_pkthdr.len); +#ifdef DIAGNOSTIC + if (m->m_pkthdr.len > + ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS) && + (ifp->if_capenable & IFCAP_LRO) == 0) + if_printf(ifp, "discard oversize frame " + "(ether type %x flags %x len %u > max %lu)\n", + etype, m->m_flags, m->m_pkthdr.len, + ETHER_MAX_FRAME(ifp, etype, + m->m_flags & M_HASFCS)); +#endif + if (m->m_pkthdr.rcvif == NULL) + if_printf(ifp, "discard frame w/o interface pointer\n"); +err_out: + ifp->if_ierrors++; +out: + m_freem(m); } /* ==== //depot/vendor/freebsd/src/sys/net/if_var.h#82 (text+ko) - //depot/projects/ethng/src/sys/net/if_var.h#7 (text+ko) ==== content @@ -80,12 +80,16 @@ #endif /* _KERNEL */ #include /* XXX */ #include /* XXX */ +#include /* XXX */ #include /* XXX */ #include #define IF_DUNIT_NONE -1 #include +#ifdef IFNET_MULTIQUEUE +#include +#endif TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ @@ -152,6 +156,8 @@ (struct ifnet *, struct mbuf *); void (*if_start) /* initiate output routine */ (struct ifnet *); + int (*if_mq_start) /* initiate output routine with immediate */ + (struct ifnet *, struct mbuf *); int (*if_ioctl) /* ioctl routine */ (struct ifnet *, u_long, caddr_t); void (*if_watchdog) /* timer routine */ @@ -187,6 +193,8 @@ /* protected by if_addr_mtx */ void *if_pf_kif; void *if_lagg; /* lagg glue */ +#ifdef IFNET_MULTIQUEUE +#endif }; typedef void if_init_f_t(void *); @@ -378,6 +386,13 @@ if_handoff((struct ifqueue *)ifq, m, ifp, adj) void if_start(struct ifnet *); +#ifdef IFNET_MULTIQUEUE +int if_mq_start(struct ifnet *, struct mbuf *); +int if_mq_enqueue_packet(struct ifnet *, struct mbuf *); +int32_t if_mq_get_cookie(struct ifnet *ifp, struct in6_addr *lip, uint16_t lport, struct in6_addr *rip, uint16_t rport, int ipv6); +#endif +extern int ifnet_multiqueue; /* allow driver module to confirm that multiqueue is supported */ + #define IFQ_ENQUEUE(ifq, m, err) \ do { \ @@ -459,14 +474,56 @@ #define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) #define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) + +#ifdef IFNET_MULTIQUEUE +#define IFQ_HANDOFF_ADJ_MQ(ifp, m, adj, err, cookie) \ +do { \ + int len; \ + short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + err = if_mq_start((ifp), m); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len + (adj); \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + } \ +} while (0) +#define IFQ_HANDOFF_MQ(ifp, m, err, cookie) \ + IFQ_HANDOFF_ADJ_MQ(ifp, m, 0, err, cookie) +#endif + /* * The IFF_DRV_OACTIVE test should really occur in the device driver, not in * the handoff logic, as that flag is locked by the device driver. */ +#ifdef IFNET_MULTIQUEUE #define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ do { \ int len; \ short mflags; \ + \ + len = (m)->m_pkthdr.len; \ + mflags = (m)->m_flags; \ + if ((ifp)->if_flags & IFF_MULTIQ) \ + err = if_mq_start((ifp), m); \ + else \ + IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ + if ((err) == 0) { \ + (ifp)->if_obytes += len + (adj); \ + if (mflags & M_MCAST) \ + (ifp)->if_omcasts++; \ + if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0 && \ + ((ifp)->if_flags & IFF_MULTIQ) == 0) \ + if_start(ifp); \ + } \ +} while (0) +#else +#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ +do { \ + int len; \ + short mflags; \ \ len = (m)->m_pkthdr.len; \ mflags = (m)->m_flags; \ @@ -479,6 +536,7 @@ if_start(ifp); \ } \ } while (0) +#endif #define IFQ_HANDOFF(ifp, m, err) \ IFQ_HANDOFF_ADJ(ifp, m, 0, err) ==== //depot/vendor/freebsd/src/sys/net/radix.c#17 (text+ko) - //depot/projects/ethng/src/sys/net/radix.c#2 (text+ko) ==== content @@ -37,7 +37,7 @@ #include #ifdef _KERNEL #include -#include +#include #include #include #include ==== //depot/vendor/freebsd/src/sys/net/radix.h#10 (text+ko) - //depot/projects/ethng/src/sys/net/radix.h#4 (text+ko) ==== content @@ -35,7 +35,7 @@ #ifdef _KERNEL #include -#include +#include #endif #ifdef MALLOC_DECLARE @@ -131,7 +131,7 @@ (struct radix_node *rn, struct radix_node_head *head); struct radix_node rnh_nodes[3]; /* empty tree for common case */ #ifdef _KERNEL - struct mtx rnh_mtx; /* locks entire radix tree */ + struct rwlock rnh_lock; /* locks entire radix tree */ #endif }; @@ -145,11 +145,26 @@ #define Free(p) free((caddr_t)p, M_RTABLE); #define RADIX_NODE_HEAD_LOCK_INIT(rnh) \ - mtx_init(&(rnh)->rnh_mtx, "radix node head", NULL, MTX_DEF | MTX_RECURSE) -#define RADIX_NODE_HEAD_LOCK(rnh) mtx_lock(&(rnh)->rnh_mtx) -#define RADIX_NODE_HEAD_UNLOCK(rnh) mtx_unlock(&(rnh)->rnh_mtx) -#define RADIX_NODE_HEAD_DESTROY(rnh) mtx_destroy(&(rnh)->rnh_mtx) -#define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) mtx_assert(&(rnh)->rnh_mtx, MA_OWNED) + rw_init_flags(&(rnh)->rnh_lock, "radix node head", RW_RECURSE) +#define RADIX_NODE_HEAD_LOCK(rnh) rw_wlock(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_UNLOCK(rnh) rw_wunlock(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_LOCK_DOWNGRADE(rnh) rw_downgrade(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_LOCK_TRY_UPGRADE(rnh) rw_try_upgrade(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_LOCK_SHARED(rnh) \ + do { \ + if (!rw_wowned(&(rnh)->rnh_lock)) \ + rw_rlock(&(rnh)->rnh_lock); \ + } while (0) + +#define RADIX_NODE_HEAD_UNLOCK_SHARED(rnh) \ + do { \ + if (!rw_wowned(&(rnh)->rnh_lock)) \ + rw_runlock(&(rnh)->rnh_lock); \ + } while (0) + +#define RADIX_NODE_HEAD_DESTROY(rnh) rw_destroy(&(rnh)->rnh_lock) +#define RADIX_NODE_HEAD_LOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_LOCKED) +#define RADIX_NODE_HEAD_UNLOCK_ASSERT(rnh) rw_assert(&(rnh)->rnh_lock, RA_UNLOCKED) #endif /* _KERNEL */ void rn_init(void); ==== //depot/vendor/freebsd/src/sys/net/route.c#60 (text+ko) - //depot/projects/ethng/src/sys/net/route.c#8 (text+ko) ==== content @@ -114,9 +114,7 @@ RTFREE(rt); ro->ro_rt = NULL; } - ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore); - if (ro->ro_rt) - RT_UNLOCK(ro->ro_rt); + ro->ro_rt = rtalloc2(&ro->ro_dst, 1, ignore); } /* @@ -144,7 +142,7 @@ rtstat.rts_unreach++; goto miss2; } - RADIX_NODE_HEAD_LOCK(rnh); + RADIX_NODE_HEAD_LOCK_SHARED(rnh); if ((rn = rnh->rnh_matchaddr(dst, rnh)) && (rn->rn_flags & RNF_ROOT) == 0) { /* @@ -154,6 +152,8 @@ newrt = rt = RNTORT(rn); nflags = rt->rt_flags & ~ignflags; if (report && (nflags & RTF_CLONING)) { + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); + RADIX_NODE_HEAD_LOCK(rnh); /* * We are apparently adding (report = 0 in delete). * If it requires that it be cloned, do so. @@ -162,24 +162,31 @@ err = rtrequest(RTM_RESOLVE, dst, NULL, NULL, 0, &newrt); if (err) { + if (!((rn = rnh->rnh_matchaddr(dst, rnh)) && + (rn->rn_flags & RNF_ROOT) == 0)) { + RADIX_NODE_HEAD_UNLOCK(rnh); + goto miss2; + } /* * If the cloning didn't succeed, maybe * what we have will do. Return that. */ newrt = rt; /* existing route */ RT_LOCK(newrt); + RADIX_NODE_HEAD_UNLOCK(rnh); RT_ADDREF(newrt); - goto miss; + goto miss2; } KASSERT(newrt, ("no route and no error")); RT_LOCK(newrt); + RADIX_NODE_HEAD_UNLOCK(rnh); if (newrt->rt_flags & RTF_XRESOLVE) { /* * If the new route specifies it be * externally resolved, then go do that. */ msgtype = RTM_RESOLVE; - goto miss; + goto miss2; } /* Inform listeners of the new route. */ bzero(&info, sizeof(info)); @@ -195,9 +202,9 @@ } else { KASSERT(rt == newrt, ("locking wrong route")); RT_LOCK(newrt); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); RT_ADDREF(newrt); } - RADIX_NODE_HEAD_UNLOCK(rnh); } else { /* * Either we hit the root or couldn't find any match, @@ -205,8 +212,7 @@ * "caint get there frm here" */ rtstat.rts_unreach++; - miss: - RADIX_NODE_HEAD_UNLOCK(rnh); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); miss2: if (report) { /* * If required, report the failure to the supervising @@ -224,6 +230,122 @@ } /* + * Look up the route that matches the address given + * Or, at least try.. Create a cloned route if needed. + * + * The returned route, if any, is locked. + */ +struct rtentry * +rtalloc2(struct sockaddr *dst, int report, u_long ignflags) +{ + struct radix_node_head *rnh = rt_tables[dst->sa_family]; + struct rtentry *rt; + struct radix_node *rn; + struct rtentry *newrt; + struct rt_addrinfo info; + u_long nflags; + int err = 0, msgtype = RTM_MISS; + + newrt = NULL; + /* + * Look up the address in the table for that Address Family + */ + if (rnh == NULL) { + rtstat.rts_unreach++; + goto miss2; + } + RADIX_NODE_HEAD_LOCK_SHARED(rnh); + if ((rn = rnh->rnh_matchaddr(dst, rnh)) && + (rn->rn_flags & RNF_ROOT) == 0) { + /* + * If we find it and it's not the root node, then + * get a reference on the rtentry associated. + */ + newrt = rt = RNTORT(rn); + nflags = rt->rt_flags & ~ignflags; + if (report && (nflags & RTF_CLONING)) { + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); + RADIX_NODE_HEAD_LOCK(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(RTM_RESOLVE, dst, NULL, + NULL, 0, &newrt); + if (err) { + if (!((rn = rnh->rnh_matchaddr(dst, rnh)) && + (rn->rn_flags & RNF_ROOT) == 0)) { + RADIX_NODE_HEAD_UNLOCK(rnh); + goto miss2; + } + /* + * If the cloning didn't succeed, maybe + * what we have will do. Return that. + */ + newrt = rt; /* existing route */ + RT_LOCK(newrt); + RADIX_NODE_HEAD_UNLOCK(rnh); + RT_ADDREF(newrt); + RT_LOCK_DOWNGRADE(newrt); + goto miss2; + } + RT_LOCK_SHARED(newrt); + RADIX_NODE_HEAD_UNLOCK(rnh); + KASSERT(newrt, ("no route and no error")); + if (newrt->rt_flags & RTF_XRESOLVE) { + /* + * If the new route specifies it be + * externally resolved, then go do that. + */ + msgtype = RTM_RESOLVE; + goto miss2; + } + /* 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); + } else { + KASSERT(rt == newrt, ("locking wrong route")); + RT_LOCK(newrt); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); + RT_ADDREF(newrt); + RT_LOCK_DOWNGRADE(newrt); + } + } else { + /* + * Either we hit the root or couldn't find any match, + * Which basically means + * "caint get there frm here" + */ + rtstat.rts_unreach++; + RADIX_NODE_HEAD_UNLOCK_SHARED(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); + } + } + if (newrt) { + RT_LOCK_ASSERT(newrt); + RT_UNLOCK_SHARED(newrt); + } + return (newrt); +} + +/* * Remove a reference count from an rtentry. * If the count gets low enough, take it out of the routing table */ @@ -297,6 +419,7 @@ /* * and the rtentry itself of course */ + RT_UNLOCK(rt); RT_LOCK_DESTROY(rt); uma_zfree(rtzone, rt); return; @@ -738,7 +861,12 @@ * when RTFREE(rt) is eventually called. */ rttrash++; - + /* + * If inpcbs hold a reference to this route + * they need to be notified that it is no longer valid + */ + rt->rt_rmx.rmx_expire = time_uptime; + /* * If the caller wants it, then it can have it, * but it's up to it to free the rtentry as we won't be @@ -1190,12 +1318,12 @@ */ if ((rnh = rt_tables[dst->sa_family]) == NULL) goto bad; - RADIX_NODE_HEAD_LOCK(rnh); + RADIX_NODE_HEAD_LOCK_SHARED(rnh); error = ((rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL || (rn->rn_flags & RNF_ROOT) || RNTORT(rn)->rt_ifa != ifa || !sa_equal((struct sockaddr *)rn->rn_key, dst)); - RADIX_NODE_HEAD_UNLOCK(rnh); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); if (error) { bad: if (m) ==== //depot/vendor/freebsd/src/sys/net/route.h#29 (text+ko) - //depot/projects/ethng/src/sys/net/route.h#4 (text+ko) ==== content @@ -119,7 +119,7 @@ struct rtentry *rt_parent; /* cloning parent of this route */ #ifdef _KERNEL /* XXX ugly, user apps use this definition but don't have a mtx def */ - struct mtx rt_mtx; /* mutex for routing entry */ + struct rwlock rt_lock; /* mutex for routing entry */ #endif }; @@ -287,11 +287,15 @@ #ifdef _KERNEL #define RT_LOCK_INIT(_rt) \ - mtx_init(&(_rt)->rt_mtx, "rtentry", NULL, MTX_DEF | MTX_DUPOK) -#define RT_LOCK(_rt) mtx_lock(&(_rt)->rt_mtx) -#define RT_UNLOCK(_rt) mtx_unlock(&(_rt)->rt_mtx) -#define RT_LOCK_DESTROY(_rt) mtx_destroy(&(_rt)->rt_mtx) -#define RT_LOCK_ASSERT(_rt) mtx_assert(&(_rt)->rt_mtx, MA_OWNED) + rw_init_flags(&(_rt)->rt_lock, "rtentry", RW_DUPOK) +#define RT_LOCK(_rt) rw_wlock(&(_rt)->rt_lock) +#define RT_UNLOCK(_rt) rw_wunlock(&(_rt)->rt_lock) +#define RT_LOCK_SHARED(_rt) rw_rlock(&(_rt)->rt_lock) +#define RT_UNLOCK_SHARED(_rt) rw_runlock(&(_rt)->rt_lock) +#define RT_LOCK_DOWNGRADE(_rt) rw_downgrade(&(_rt)->rt_lock) +#define RT_LOCK_DESTROY(_rt) rw_destroy(&(_rt)->rt_lock) +#define RT_LOCK_ASSERT(_rt) rw_assert(&(_rt)->rt_lock, RA_LOCKED) +#define RT_UNLOCK_ASSERT(_rt) rw_assert(&(_rt)->rt_lock, RA_UNLOCKED) #define RT_ADDREF(_rt) do { \ RT_LOCK_ASSERT(_rt); \ @@ -349,6 +353,7 @@ void rtalloc_ign(struct route *ro, u_long ignflags); void rtalloc(struct route *ro); /* XXX deprecated, use rtalloc_ign(ro, 0) */ struct rtentry *rtalloc1(struct sockaddr *, int, u_long); +struct rtentry *rtalloc2(struct sockaddr *, int, u_long); int rtexpunge(struct rtentry *); void rtfree(struct rtentry *); int rtinit(struct ifaddr *, int, int); ==== //depot/vendor/freebsd/src/sys/net/rtsock.c#88 (text+ko) - //depot/projects/ethng/src/sys/net/rtsock.c#3 (text+ko) ==== content @@ -413,16 +413,16 @@ rnh = rt_tables[info.rti_info[RTAX_DST]->sa_family]; if (rnh == NULL) senderr(EAFNOSUPPORT); - RADIX_NODE_HEAD_LOCK(rnh); + RADIX_NODE_HEAD_LOCK_SHARED(rnh); rt = (struct rtentry *) rnh->rnh_lookup(info.rti_info[RTAX_DST], info.rti_info[RTAX_NETMASK], rnh); if (rt == NULL) { /* XXX looks bogus */ - RADIX_NODE_HEAD_UNLOCK(rnh); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); senderr(ESRCH); } RT_LOCK(rt); RT_ADDREF(rt); - RADIX_NODE_HEAD_UNLOCK(rnh); + RADIX_NODE_HEAD_UNLOCK_SHARED(rnh); /* * Fix for PR: 82974