Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145847856
D44204.id135380.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D44204.id135380.diff
View Options
Index: FreeBSD/sys/netinet6/ip6_output.c
===================================================================
--- FreeBSD/sys/netinet6/ip6_output.c
+++ FreeBSD/sys/netinet6/ip6_output.c
@@ -431,6 +431,7 @@
uint32_t fibnum;
struct m_tag *fwd_tag = NULL;
uint32_t id;
+ uint32_t optvalid;
NET_EPOCH_ASSERT();
@@ -491,14 +492,17 @@
* Keep the length of the unfragmentable part for fragmentation.
*/
bzero(&exthdrs, sizeof(exthdrs));
- optlen = 0;
+ optlen = optvalid = 0;
unfragpartlen = sizeof(struct ip6_hdr);
if (opt) {
+ optvalid = opt->ip6po_valid;
+
/* Hop-by-Hop options header. */
- MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh, optlen);
+ if ((optvalid & IP6PO_VALID_HBH) != 0)
+ MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh, optlen);
/* Destination options header (1st part). */
- if (opt->ip6po_rthdr) {
+ if ((optvalid & IP6PO_VALID_RHINFO) != 0) {
#ifndef RTHDR_SUPPORT_IMPLEMENTED
/*
* If there is a routing header, discard the packet
@@ -524,11 +528,13 @@
* options, which might automatically be inserted in
* the kernel.
*/
- MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1,
- optlen);
+ if ((optvalid & IP6PO_VALID_DEST1) != 0)
+ MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1,
+ optlen);
}
/* Routing header. */
- MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr, optlen);
+ if ((optvalid & IP6PO_VALID_RHINFO) != 0)
+ MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr, optlen);
unfragpartlen += optlen;
@@ -538,7 +544,8 @@
*/
/* Destination options header (2nd part). */
- MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2, optlen);
+ if ((optvalid & IP6PO_VALID_DEST2) != 0)
+ MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2, optlen);
}
/*
@@ -627,7 +634,7 @@
/* Route packet. */
ro_pmtu = ro;
- if (opt && opt->ip6po_rthdr)
+ if ((optvalid & IP6PO_VALID_RHINFO) != 0)
ro = &opt->ip6po_route;
if (ro != NULL)
dst = (struct sockaddr_in6 *)&ro->ro_dst;
@@ -641,7 +648,7 @@
* Do not override if a non-zero value is already set.
* We check the diffserv field and the ECN field separately.
*/
- if (opt && opt->ip6po_tclass >= 0) {
+ if ((optvalid & IP6PO_VALID_TC) != 0){
int mask = 0;
if (IPV6_DSCP(ip6) == 0)
@@ -653,7 +660,7 @@
}
/* Fill in or override the hop limit field, if necessary. */
- if (opt && opt->ip6po_hlim != -1)
+ if ((optvalid & IP6PO_VALID_HLIM) != 0)
ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
if (im6o != NULL)
@@ -855,7 +862,7 @@
/* All scope ID checks are successful. */
if (nh && !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
- if (opt && opt->ip6po_nextroute.ro_nh) {
+ if ((optvalid & IP6PO_VALID_NHINFO) != 0) {
/*
* The nexthop is explicitly specified by the
* application. We assume the next hop is an IPv6
@@ -2648,10 +2655,14 @@
free(pktopt->ip6po_pktinfo, M_IP6OPT);
pktopt->ip6po_pktinfo = NULL;
}
- if (optname == -1 || optname == IPV6_HOPLIMIT)
+ if (optname == -1 || optname == IPV6_HOPLIMIT) {
pktopt->ip6po_hlim = -1;
- if (optname == -1 || optname == IPV6_TCLASS)
+ pktopt->ip6po_valid &= ~IP6PO_VALID_HLIM;
+ }
+ if (optname == -1 || optname == IPV6_TCLASS) {
pktopt->ip6po_tclass = -1;
+ pktopt->ip6po_valid &= ~IP6PO_VALID_TC;
+ }
if (optname == -1 || optname == IPV6_NEXTHOP) {
if (pktopt->ip6po_nextroute.ro_nh) {
NH_FREE(pktopt->ip6po_nextroute.ro_nh);
@@ -2660,16 +2671,19 @@
if (pktopt->ip6po_nexthop)
free(pktopt->ip6po_nexthop, M_IP6OPT);
pktopt->ip6po_nexthop = NULL;
+ pktopt->ip6po_valid &= ~IP6PO_VALID_NHINFO;
}
if (optname == -1 || optname == IPV6_HOPOPTS) {
if (pktopt->ip6po_hbh)
free(pktopt->ip6po_hbh, M_IP6OPT);
pktopt->ip6po_hbh = NULL;
+ pktopt->ip6po_valid &= ~IP6PO_VALID_HBH;
}
if (optname == -1 || optname == IPV6_RTHDRDSTOPTS) {
if (pktopt->ip6po_dest1)
free(pktopt->ip6po_dest1, M_IP6OPT);
pktopt->ip6po_dest1 = NULL;
+ pktopt->ip6po_valid &= ~IP6PO_VALID_DEST1;
}
if (optname == -1 || optname == IPV6_RTHDR) {
if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
@@ -2679,11 +2693,13 @@
NH_FREE(pktopt->ip6po_route.ro_nh);
pktopt->ip6po_route.ro_nh = NULL;
}
+ pktopt->ip6po_valid &= ~IP6PO_VALID_RHINFO;
}
if (optname == -1 || optname == IPV6_DSTOPTS) {
if (pktopt->ip6po_dest2)
free(pktopt->ip6po_dest2, M_IP6OPT);
pktopt->ip6po_dest2 = NULL;
+ pktopt->ip6po_valid &= ~IP6PO_VALID_DEST2;
}
}
@@ -2730,6 +2746,7 @@
PKTOPT_EXTHDRCPY(ip6po_dest1);
PKTOPT_EXTHDRCPY(ip6po_dest2);
PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
+ dst->ip6po_valid = src->ip6po_valid;
return (0);
bad:
@@ -2959,6 +2976,7 @@
return (ENOBUFS);
}
bcopy(pktinfo, opt->ip6po_pktinfo, sizeof(*pktinfo));
+ opt->ip6po_valid |= IP6PO_VALID_PKTINFO;
break;
}
@@ -2981,6 +2999,7 @@
return (EINVAL);
opt->ip6po_hlim = *hlimp;
+ opt->ip6po_valid |= IP6PO_VALID_HLIM;
break;
}
@@ -2995,6 +3014,7 @@
return (EINVAL);
opt->ip6po_tclass = tclass;
+ opt->ip6po_valid |= IP6PO_VALID_TC;
break;
}
@@ -3045,6 +3065,7 @@
if (opt->ip6po_nexthop == NULL)
return (ENOBUFS);
bcopy(buf, opt->ip6po_nexthop, *buf);
+ opt->ip6po_valid |= IP6PO_VALID_NHINFO;
break;
case IPV6_2292HOPOPTS:
@@ -3083,6 +3104,7 @@
if (opt->ip6po_hbh == NULL)
return (ENOBUFS);
bcopy(hbh, opt->ip6po_hbh, hbhlen);
+ opt->ip6po_valid |= IP6PO_VALID_HBH;
break;
}
@@ -3150,6 +3172,10 @@
if (*newdest == NULL)
return (ENOBUFS);
bcopy(dest, *newdest, destlen);
+ if (newdest == &opt->ip6po_dest1)
+ opt->ip6po_valid |= IP6PO_VALID_DEST1;
+ else
+ opt->ip6po_valid |= IP6PO_VALID_DEST2;
break;
}
@@ -3192,6 +3218,7 @@
if (opt->ip6po_rthdr == NULL)
return (ENOBUFS);
bcopy(rth, opt->ip6po_rthdr, rthlen);
+ opt->ip6po_valid |= IP6PO_VALID_RHINFO;
break;
}
Index: FreeBSD/sys/netinet6/ip6_var.h
===================================================================
--- FreeBSD/sys/netinet6/ip6_var.h
+++ FreeBSD/sys/netinet6/ip6_var.h
@@ -131,26 +131,17 @@
#define ip6po_nextroute ip6po_nhinfo.ip6po_nhi_route
struct ip6_pktopts {
- struct mbuf *ip6po_m; /* Pointer to mbuf storing the data */
- int ip6po_hlim; /* Hoplimit for outgoing packets */
-
- /* Outgoing IF/address information */
- struct in6_pktinfo *ip6po_pktinfo;
-
- /* Next-hop address information */
- struct ip6po_nhinfo ip6po_nhinfo;
-
- struct ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
-
- /* Destination options header (before a routing header) */
- struct ip6_dest *ip6po_dest1;
-
- /* Routing header related info. */
- struct ip6po_rhinfo ip6po_rhinfo;
-
- /* Destination options header (after a routing header) */
- struct ip6_dest *ip6po_dest2;
+ uint32_t ip6po_valid;
+#define IP6PO_VALID_HLIM 0x0001
+#define IP6PO_VALID_PKTINFO 0x0002
+#define IP6PO_VALID_NHINFO 0x0004
+#define IP6PO_VALID_HBH 0x0008
+#define IP6PO_VALID_DEST1 0x0010
+#define IP6PO_VALID_RHINFO 0x0020
+#define IP6PO_VALID_DEST2 0x0040
+#define IP6PO_VALID_TC 0x0080
+ int ip6po_hlim; /* Hoplimit for outgoing packets */
int ip6po_tclass; /* traffic class */
int ip6po_minmtu; /* fragment vs PMTU discovery policy */
@@ -171,6 +162,25 @@
#endif
#define IP6PO_DONTFRAG 0x04 /* disable fragmentation (IPV6_DONTFRAG) */
#define IP6PO_USECOA 0x08 /* use care of address */
+
+ struct mbuf *ip6po_m; /* Pointer to mbuf storing the data */
+
+ /* Outgoing IF/address information */
+ struct in6_pktinfo *ip6po_pktinfo;
+
+ /* Next-hop address information */
+ struct ip6po_nhinfo ip6po_nhinfo;
+
+ struct ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
+
+ /* Destination options header (before a routing header) */
+ struct ip6_dest *ip6po_dest1;
+
+ /* Routing header related info. */
+ struct ip6po_rhinfo ip6po_rhinfo;
+
+ /* Destination options header (after a routing header) */
+ struct ip6_dest *ip6po_dest2;
};
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 26, 4:59 AM (12 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29000994
Default Alt Text
D44204.id135380.diff (7 KB)
Attached To
Mode
D44204: ip6_output: Reduce cache misses on pktopts
Attached
Detach File
Event Timeline
Log In to Comment