aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2014-09-09 01:45:39 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2014-09-09 01:45:39 +0000
commit9d3ddf438402c8e711dd639be6052d51cb45b680 (patch)
tree7a08d9539d5dc0c08bba7869418c535b30644538 /sys/netinet/udp_usrreq.c
parentb174de323a42a678e7204b372818f0425846c9db (diff)
downloadsrc-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.c46
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)