Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141996323
D6262.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D6262.diff
View Options
Index: head/sys/net/flowtable.c
===================================================================
--- head/sys/net/flowtable.c
+++ head/sys/net/flowtable.c
@@ -696,13 +696,8 @@
ro->ro_rt = fle->f_rt;
ro->ro_flags |= RT_NORTREF;
lle = fle->f_lle;
- if (lle != NULL && (lle->la_flags & LLE_VALID)) {
- ro->ro_prepend = lle->r_linkdata;
- ro->ro_plen = lle->r_hdrlen;
- ro->ro_flags |= RT_MAY_LOOP;
- if (lle->la_flags & LLE_IFADDR)
- ro->ro_flags |= RT_L2_ME;
- }
+ if (lle != NULL && (lle->la_flags & LLE_VALID))
+ ro->ro_lle = lle; /* share ref with fle->f_lle */
return (0);
}
Index: head/sys/net/if_arcsubr.c
===================================================================
--- head/sys/net/if_arcsubr.c
+++ head/sys/net/if_arcsubr.c
@@ -129,7 +129,8 @@
else if (ifp->if_flags & IFF_NOARP)
adst = ntohl(SIN(dst)->sin_addr.s_addr) & 0xFF;
else {
- error = arpresolve(ifp, is_gw, m, dst, &adst, NULL);
+ error = arpresolve(ifp, is_gw, m, dst, &adst, NULL,
+ NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
@@ -170,7 +171,8 @@
if ((m->m_flags & M_MCAST) != 0)
adst = arcbroadcastaddr; /* ARCnet broadcast address */
else {
- error = nd6_resolve(ifp, is_gw, m, dst, &adst, NULL);
+ error = nd6_resolve(ifp, is_gw, m, dst, &adst, NULL,
+ NULL);
if (error != 0)
return (error == EWOULDBLOCK ? 0 : error);
}
Index: head/sys/net/if_ethersubr.c
===================================================================
--- head/sys/net/if_ethersubr.c
+++ head/sys/net/if_ethersubr.c
@@ -199,7 +199,7 @@
static int
ether_resolve_addr(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro, u_char *phdr,
- uint32_t *pflags)
+ uint32_t *pflags, struct llentry **plle)
{
struct ether_header *eh;
uint32_t lleflags = 0;
@@ -208,13 +208,16 @@
uint16_t etype;
#endif
+ if (plle)
+ *plle = NULL;
eh = (struct ether_header *)phdr;
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
if ((m->m_flags & (M_BCAST | M_MCAST)) == 0)
- error = arpresolve(ifp, 0, m, dst, phdr, &lleflags);
+ error = arpresolve(ifp, 0, m, dst, phdr, &lleflags,
+ plle);
else {
if (m->m_flags & M_BCAST)
memcpy(eh->ether_dhost, ifp->if_broadcastaddr,
@@ -233,7 +236,8 @@
#ifdef INET6
case AF_INET6:
if ((m->m_flags & M_MCAST) == 0)
- error = nd6_resolve(ifp, 0, m, dst, phdr, &lleflags);
+ error = nd6_resolve(ifp, 0, m, dst, phdr, &lleflags,
+ plle);
else {
const struct in6_addr *a6;
a6 = &(((const struct sockaddr_in6 *)dst)->sin6_addr);
@@ -283,14 +287,40 @@
int loop_copy = 1;
int hlen; /* link layer header length */
uint32_t pflags;
+ struct llentry *lle = NULL;
+ struct rtentry *rt0 = NULL;
+ int addref = 0;
phdr = NULL;
pflags = 0;
if (ro != NULL) {
- phdr = ro->ro_prepend;
- hlen = ro->ro_plen;
- pflags = ro->ro_flags;
+ /* XXX BPF uses ro_prepend */
+ if (ro->ro_prepend != NULL) {
+ phdr = ro->ro_prepend;
+ hlen = ro->ro_plen;
+ } else if (!(m->m_flags & (M_BCAST | M_MCAST))) {
+ if ((ro->ro_flags & RT_LLE_CACHE) != 0) {
+ lle = ro->ro_lle;
+ if (lle != NULL &&
+ (lle->la_flags & LLE_VALID) == 0) {
+ LLE_FREE(lle);
+ lle = NULL; /* redundant */
+ ro->ro_lle = NULL;
+ }
+ if (lle == NULL) {
+ /* if we lookup, keep cache */
+ addref = 1;
+ }
+ }
+ if (lle != NULL) {
+ phdr = lle->r_linkdata;
+ hlen = lle->r_hdrlen;
+ pflags = lle->r_flags;
+ }
+ }
+ rt0 = ro->ro_rt;
}
+
#ifdef MAC
error = mac_ifnet_check_transmit(ifp, m);
if (error)
@@ -308,7 +338,10 @@
/* No prepend data supplied. Try to calculate ourselves. */
phdr = linkhdr;
hlen = ETHER_HDR_LEN;
- error = ether_resolve_addr(ifp, m, dst, ro, phdr, &pflags);
+ error = ether_resolve_addr(ifp, m, dst, ro, phdr, &pflags,
+ addref ? &lle : NULL);
+ if (addref && lle != NULL)
+ ro->ro_lle = lle;
if (error != 0)
return (error == EWOULDBLOCK ? 0 : error);
}
Index: head/sys/net/if_fddisubr.c
===================================================================
--- head/sys/net/if_fddisubr.c
+++ head/sys/net/if_fddisubr.c
@@ -126,7 +126,7 @@
switch (dst->sa_family) {
#ifdef INET
case AF_INET: {
- error = arpresolve(ifp, is_gw, m, dst, edst, NULL);
+ error = arpresolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IP);
@@ -162,7 +162,7 @@
#endif /* INET */
#ifdef INET6
case AF_INET6:
- error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL);
+ error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
type = htons(ETHERTYPE_IPV6);
Index: head/sys/net/if_fwsubr.c
===================================================================
--- head/sys/net/if_fwsubr.c
+++ head/sys/net/if_fwsubr.c
@@ -144,7 +144,8 @@
* doesn't fit into the arp model.
*/
if (unicast) {
- error = arpresolve(ifp, is_gw, m, dst, (u_char *) destfw, NULL);
+ error = arpresolve(ifp, is_gw, m, dst,
+ (u_char *) destfw, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
@@ -174,7 +175,7 @@
case AF_INET6:
if (unicast) {
error = nd6_resolve(fc->fc_ifp, is_gw, m, dst,
- (u_char *) destfw, NULL);
+ (u_char *) destfw, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
}
Index: head/sys/net/if_iso88025subr.c
===================================================================
--- head/sys/net/if_iso88025subr.c
+++ head/sys/net/if_iso88025subr.c
@@ -254,7 +254,7 @@
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
- error = arpresolve(ifp, is_gw, m, dst, edst, NULL);
+ error = arpresolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
snap_type = ETHERTYPE_IP;
@@ -289,7 +289,7 @@
#endif /* INET */
#ifdef INET6
case AF_INET6:
- error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL);
+ error = nd6_resolve(ifp, is_gw, m, dst, edst, NULL, NULL);
if (error)
return (error == EWOULDBLOCK ? 0 : error);
snap_type = ETHERTYPE_IPV6;
Index: head/sys/net/if_llatbl.h
===================================================================
--- head/sys/net/if_llatbl.h
+++ head/sys/net/if_llatbl.h
@@ -138,7 +138,6 @@
LLE_FREE_LOCKED(lle); \
} while (0)
-
typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
const struct sockaddr *l3addr);
typedef struct llentry *(llt_alloc_t)(struct lltable *, u_int flags,
Index: head/sys/net/route.h
===================================================================
--- head/sys/net/route.h
+++ head/sys/net/route.h
@@ -50,6 +50,11 @@
*/
struct route {
struct rtentry *ro_rt;
+ struct llentry *ro_lle;
+ /*
+ * ro_prepend and ro_plen are only used for bpf to pass in a
+ * preformed header. They are not cacheable.
+ */
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
@@ -71,6 +76,7 @@
#define RT_REJECT 0x0020 /* Destination is reject */
#define RT_BLACKHOLE 0x0040 /* Destination is blackhole */
#define RT_HAS_GW 0x0080 /* Destination has GW */
+#define RT_LLE_CACHE 0x0100 /* Cache link layer */
struct rt_metrics {
u_long rmx_locks; /* Kernel must leave these values alone */
@@ -399,6 +405,7 @@
if ((_ro)->ro_flags & RT_NORTREF) { \
(_ro)->ro_flags &= ~RT_NORTREF; \
(_ro)->ro_rt = NULL; \
+ (_ro)->ro_lle = NULL; \
} else { \
RT_LOCK((_ro)->ro_rt); \
RTFREE_LOCKED((_ro)->ro_rt); \
@@ -413,9 +420,11 @@
*/
#define RT_VALIDATE(ro, cookiep, fibnum) do { \
rt_gen_t cookie = RT_GEN(fibnum, (ro)->ro_dst.sa_family); \
- if (*(cookiep) != cookie && (ro)->ro_rt != NULL) { \
- RTFREE((ro)->ro_rt); \
- (ro)->ro_rt = NULL; \
+ if (*(cookiep) != cookie) { \
+ if ((ro)->ro_rt != NULL) { \
+ RTFREE((ro)->ro_rt); \
+ (ro)->ro_rt = NULL; \
+ } \
*(cookiep) = cookie; \
} \
} while (0)
Index: head/sys/net/route.c
===================================================================
--- head/sys/net/route.c
+++ head/sys/net/route.c
@@ -207,6 +207,8 @@
struct rib_head *rnh;
rnh = *rt_tables_get_rnh_ptr(table, fam);
+ KASSERT(rnh != NULL, ("%s: NULL rib_head pointer table %d fam %d",
+ __func__, table, fam));
return (rnh->rnh_gen);
}
Index: head/sys/netinet/if_ether.h
===================================================================
--- head/sys/netinet/if_ether.h
+++ head/sys/netinet/if_ether.h
@@ -113,11 +113,14 @@
extern u_char ether_ipmulticast_max[ETHER_ADDR_LEN];
struct ifaddr;
+struct llentry;
int arpresolve_addr(struct ifnet *ifp, int flags,
- const struct sockaddr *dst, char *desten, uint32_t *pflags);
+ const struct sockaddr *dst, char *desten, uint32_t *pflags,
+ struct llentry **plle);
int arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
- const struct sockaddr *dst, u_char *desten, uint32_t *pflags);
+ const struct sockaddr *dst, u_char *desten, uint32_t *pflags,
+ struct llentry **plle);
void arprequest(struct ifnet *, const struct in_addr *,
const struct in_addr *, u_char *);
void arp_ifinit(struct ifnet *, struct ifaddr *);
Index: head/sys/netinet/if_ether.c
===================================================================
--- head/sys/netinet/if_ether.c
+++ head/sys/netinet/if_ether.c
@@ -420,7 +420,8 @@
*/
static int
arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
- const struct sockaddr *dst, u_char *desten, uint32_t *pflags)
+ const struct sockaddr *dst, u_char *desten, uint32_t *pflags,
+ struct llentry **plle)
{
struct llentry *la = NULL, *la_tmp;
struct mbuf *curr = NULL;
@@ -431,6 +432,8 @@
if (pflags != NULL)
*pflags = 0;
+ if (plle != NULL)
+ *plle = NULL;
if ((flags & LLE_CREATE) == 0) {
IF_AFDATA_RLOCK(ifp);
@@ -483,6 +486,10 @@
}
if (pflags != NULL)
*pflags = la->la_flags & (LLE_VALID|LLE_IFADDR);
+ if (plle) {
+ LLE_ADDREF(la);
+ *plle = la;
+ }
LLE_WUNLOCK(la);
return (0);
}
@@ -548,12 +555,12 @@
*/
int
arpresolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
- char *desten, uint32_t *pflags)
+ char *desten, uint32_t *pflags, struct llentry **plle)
{
int error;
flags |= LLE_ADDRONLY;
- error = arpresolve_full(ifp, 0, flags, NULL, dst, desten, pflags);
+ error = arpresolve_full(ifp, 0, flags, NULL, dst, desten, pflags, plle);
return (error);
}
@@ -576,12 +583,15 @@
*/
int
arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
- const struct sockaddr *dst, u_char *desten, uint32_t *pflags)
+ const struct sockaddr *dst, u_char *desten, uint32_t *pflags,
+ struct llentry **plle)
{
struct llentry *la = NULL;
if (pflags != NULL)
*pflags = 0;
+ if (plle != NULL)
+ *plle = NULL;
if (m != NULL) {
if (m->m_flags & M_BCAST) {
@@ -616,7 +626,7 @@
IF_AFDATA_RUNLOCK(ifp);
return (arpresolve_full(ifp, is_gw, la == NULL ? LLE_CREATE : 0, m, dst,
- desten, pflags));
+ desten, pflags, plle));
}
/*
Index: head/sys/netinet/in_pcb.c
===================================================================
--- head/sys/netinet/in_pcb.c
+++ head/sys/netinet/in_pcb.c
@@ -73,6 +73,7 @@
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_types.h>
+#include <net/if_llatbl.h>
#include <net/route.h>
#include <net/rss_config.h>
#include <net/vnet.h>
@@ -1302,6 +1303,8 @@
RTFREE(inp->inp_route.ro_rt);
inp->inp_route.ro_rt = (struct rtentry *)NULL;
}
+ if (inp->inp_route.ro_lle)
+ LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
inp->inp_vflag = 0;
inp->inp_flags2 |= INP_FREED;
@@ -2243,6 +2246,8 @@
RTFREE(inp->inp_route.ro_rt);
inp->inp_route.ro_rt = (struct rtentry *)NULL;
}
+ if (inp->inp_route.ro_lle)
+ LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
return;
}
Index: head/sys/netinet/ip_output.c
===================================================================
--- head/sys/netinet/ip_output.c
+++ head/sys/netinet/ip_output.c
@@ -245,7 +245,8 @@
if (ro == NULL) {
ro = &iproute;
bzero(ro, sizeof (*ro));
- }
+ } else
+ ro->ro_flags |= RT_LLE_CACHE;
#ifdef FLOWTABLE
if (ro->ro_rt == NULL)
@@ -311,6 +312,9 @@
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
RTFREE(rte);
rte = ro->ro_rt = (struct rtentry *)NULL;
+ if (ro->ro_lle)
+ LLE_FREE(ro->ro_lle); /* zeros ro_lle */
+ ro->ro_lle = (struct llentry *)NULL;
}
ia = NULL;
have_ia_ref = 0;
Index: head/sys/netinet/toecore.c
===================================================================
--- head/sys/netinet/toecore.c
+++ head/sys/netinet/toecore.c
@@ -451,12 +451,12 @@
switch (sa->sa_family) {
#ifdef INET
case AF_INET:
- rc = arpresolve(ifp, 0, NULL, sa, lladdr, NULL);
+ rc = arpresolve(ifp, 0, NULL, sa, lladdr, NULL, NULL);
break;
#endif
#ifdef INET6
case AF_INET6:
- rc = nd6_resolve(ifp, 0, NULL, sa, lladdr, NULL);
+ rc = nd6_resolve(ifp, 0, NULL, sa, lladdr, NULL, NULL);
break;
#endif
default:
Index: head/sys/netinet6/in6.h
===================================================================
--- head/sys/netinet6/in6.h
+++ head/sys/netinet6/in6.h
@@ -375,6 +375,11 @@
#if __BSD_VISIBLE
struct route_in6 {
struct rtentry *ro_rt;
+ struct llentry *ro_lle;
+ /*
+ * ro_prepend and ro_plen are only used for bpf to pass in a
+ * preformed header. They are not cacheable.
+ */
char *ro_prepend;
uint16_t ro_plen;
uint16_t ro_flags;
Index: head/sys/netinet6/in6_pcb.c
===================================================================
--- head/sys/netinet6/in6_pcb.c
+++ head/sys/netinet6/in6_pcb.c
@@ -92,6 +92,7 @@
#include <net/if.h>
#include <net/if_var.h>
+#include <net/if_llatbl.h>
#include <net/if_types.h>
#include <net/route.h>
@@ -831,6 +832,8 @@
RTFREE(in6p->inp_route6.ro_rt);
in6p->inp_route6.ro_rt = (struct rtentry *)NULL;
}
+ if (in6p->inp_route.ro_lle)
+ LLE_FREE(in6p->inp_route.ro_lle); /* zeros ro_lle */
return;
}
@@ -846,6 +849,8 @@
RTFREE(inp->inp_route6.ro_rt);
inp->inp_route6.ro_rt = (struct rtentry *)NULL;
}
+ if (inp->inp_route.ro_lle)
+ LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */
return inp;
}
Index: head/sys/netinet6/ip6_output.c
===================================================================
--- head/sys/netinet6/ip6_output.c
+++ head/sys/netinet6/ip6_output.c
@@ -500,7 +500,8 @@
if (ro == NULL) {
ro = &ip6route;
bzero((caddr_t)ro, sizeof(*ro));
- }
+ } else
+ ro->ro_flags |= RT_LLE_CACHE;
ro_pmtu = ro;
if (opt && opt->ip6po_rthdr)
ro = &opt->ip6po_route;
Index: head/sys/netinet6/nd6.h
===================================================================
--- head/sys/netinet6/nd6.h
+++ head/sys/netinet6/nd6.h
@@ -428,7 +428,7 @@
int nd6_resolve_addr(struct ifnet *ifp, int flags, const struct sockaddr *dst,
char *desten, uint32_t *pflags);
int nd6_resolve(struct ifnet *, int, struct mbuf *,
- const struct sockaddr *, u_char *, uint32_t *);
+ const struct sockaddr *, u_char *, uint32_t *, struct llentry **);
int nd6_ioctl(u_long, caddr_t, struct ifnet *);
void nd6_cache_lladdr(struct ifnet *, struct in6_addr *,
char *, int, int, int);
Index: head/sys/netinet6/nd6.c
===================================================================
--- head/sys/netinet6/nd6.c
+++ head/sys/netinet6/nd6.c
@@ -136,7 +136,7 @@
static void clear_llinfo_pqueue(struct llentry *);
static void nd6_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
static int nd6_resolve_slow(struct ifnet *, int, struct mbuf *,
- const struct sockaddr_in6 *, u_char *, uint32_t *);
+ const struct sockaddr_in6 *, u_char *, uint32_t *, struct llentry **);
static int nd6_need_cache(struct ifnet *);
@@ -2175,7 +2175,8 @@
*/
int
nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
- const struct sockaddr *sa_dst, u_char *desten, uint32_t *pflags)
+ const struct sockaddr *sa_dst, u_char *desten, uint32_t *pflags,
+ struct llentry **plle)
{
struct llentry *ln = NULL;
const struct sockaddr_in6 *dst6;
@@ -2227,7 +2228,7 @@
}
IF_AFDATA_RUNLOCK(ifp);
- return (nd6_resolve_slow(ifp, 0, m, dst6, desten, pflags));
+ return (nd6_resolve_slow(ifp, 0, m, dst6, desten, pflags, plle));
}
@@ -2244,7 +2245,8 @@
*/
static __noinline int
nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
- const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags)
+ const struct sockaddr_in6 *dst, u_char *desten, uint32_t *pflags,
+ struct llentry **plle)
{
struct llentry *lle = NULL, *lle_tmp;
struct in6_addr *psrc, src;
@@ -2331,6 +2333,10 @@
bcopy(lladdr, desten, ll_len);
if (pflags != NULL)
*pflags = lle->la_flags;
+ if (plle) {
+ LLE_ADDREF(lle);
+ *plle = lle;
+ }
LLE_WUNLOCK(lle);
return (0);
}
@@ -2405,7 +2411,7 @@
flags |= LLE_ADDRONLY;
error = nd6_resolve_slow(ifp, flags, NULL,
- (const struct sockaddr_in6 *)dst, desten, pflags);
+ (const struct sockaddr_in6 *)dst, desten, pflags, NULL);
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 15, 4:16 PM (5 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27653073
Default Alt Text
D6262.diff (16 KB)
Attached To
Mode
D6262: Implement L2 lookup caching for TCP and UDP
Attached
Detach File
Event Timeline
Log In to Comment