diff options
author | Adrian Chadd <adrian@FreeBSD.org> | 2014-09-09 01:45:39 +0000 |
---|---|---|
committer | Adrian Chadd <adrian@FreeBSD.org> | 2014-09-09 01:45:39 +0000 |
commit | 9d3ddf438402c8e711dd639be6052d51cb45b680 (patch) | |
tree | 7a08d9539d5dc0c08bba7869418c535b30644538 /sys/netinet/udp_usrreq.c | |
parent | b174de323a42a678e7204b372818f0425846c9db (diff) | |
download | src-9d3ddf438402c8e711dd639be6052d51cb45b680.tar.gz src-9d3ddf438402c8e711dd639be6052d51cb45b680.zip |
Add support for receiving and setting flowtype, flowid and RSS bucket
information as part of recvmsg().
This is primarily used for debugging/verification of the various
processing paths in the IP, PCB and driver layers.
Unfortunately the current implementation of the control message path
results in a ~10% or so drop in UDP frame throughput when it's used.
Differential Revision: https://reviews.freebsd.org/D527
Reviewed by: grehan
Notes
Notes:
svn path=/head/; revision=271293
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 5860c579e749..ecb7aec8d889 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" #include "opt_ipsec.h" +#include "opt_rss.h" #include <sys/param.h> #include <sys/domain.h> @@ -1084,6 +1085,9 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, u_char tos; uint8_t pr; uint16_t cscov = 0; + uint32_t flowid = 0; + int flowid_type = 0; + int use_flowid = 0; /* * udp_output() may need to temporarily bind or connect the current @@ -1147,6 +1151,32 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, tos = *(u_char *)CMSG_DATA(cm); break; + case IP_FLOWID: + if (cm->cmsg_len != CMSG_LEN(sizeof(uint32_t))) { + error = EINVAL; + break; + } + flowid = *(uint32_t *) CMSG_DATA(cm); + break; + + case IP_FLOWTYPE: + if (cm->cmsg_len != CMSG_LEN(sizeof(uint32_t))) { + error = EINVAL; + break; + } + flowid_type = *(uint32_t *) CMSG_DATA(cm); + use_flowid = 1; + break; + +#ifdef RSS + case IP_RSSBUCKETID: + if (cm->cmsg_len != CMSG_LEN(sizeof(uint32_t))) { + error = EINVAL; + break; + } + /* This is just a placeholder for now */ + break; +#endif /* RSS */ default: error = ENOPROTOOPT; break; @@ -1395,6 +1425,22 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, ((struct ip *)ui)->ip_tos = tos; /* XXX */ UDPSTAT_INC(udps_opackets); + /* + * Setup flowid / RSS information for outbound socket. + * + * Once the UDP code decides to set a flowid some other way, + * this allows the flowid to be overridden by userland. + */ + if (use_flowid) { + m->m_flags |= M_FLOWID; + m->m_pkthdr.flowid = flowid; + M_HASHTYPE_SET(m, flowid_type); + } + +#ifdef RSS + ipflags |= IP_NODEFAULTFLOWID; +#endif /* RSS */ + if (unlock_udbinfo == UH_WLOCKED) INP_HASH_WUNLOCK(pcbinfo); else if (unlock_udbinfo == UH_RLOCKED) |