aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-08-27 00:01:56 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2019-08-27 00:01:56 +0000
commitb2e60773c6b015f06fcd71510cd20a91eb43bcaa (patch)
tree7e88792669a12b900d38f75be531ec5f19459f8b /sys/netinet/ip_output.c
parenta70e17eecad468b652f0e201bf47c4dd65cddfc5 (diff)
Notes
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 223262003086..085040f25e64 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_ipsec.h"
+#include "opt_kern_tls.h"
#include "opt_mbuf_stress_test.h"
#include "opt_mpath.h"
#include "opt_ratelimit.h"
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/ktls.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -212,14 +214,39 @@ static int
ip_output_send(struct inpcb *inp, struct ifnet *ifp, struct mbuf *m,
const struct sockaddr_in *gw, struct route *ro)
{
+#ifdef KERN_TLS
+ struct ktls_session *tls = NULL;
+#endif
struct m_snd_tag *mst;
int error;
MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0);
mst = NULL;
+#ifdef KERN_TLS
+ /*
+ * If this is an unencrypted TLS record, save a reference to
+ * the record. This local reference is used to call
+ * ktls_output_eagain after the mbuf has been freed (thus
+ * dropping the mbuf's reference) in if_output.
+ */
+ if (m->m_next != NULL && mbuf_has_tls_session(m->m_next)) {
+ tls = ktls_hold(m->m_next->m_ext.ext_pgs->tls);
+ mst = tls->snd_tag;
+
+ /*
+ * If a TLS session doesn't have a valid tag, it must
+ * have had an earlier ifp mismatch, so drop this
+ * packet.
+ */
+ if (mst == NULL) {
+ error = EAGAIN;
+ goto done;
+ }
+ }
+#endif
#ifdef RATELIMIT
- if (inp != NULL) {
+ if (inp != NULL && mst == NULL) {
if ((inp->inp_flags2 & INP_RATE_LIMIT_CHANGED) != 0 ||
(inp->inp_snd_tag != NULL &&
inp->inp_snd_tag->ifp != ifp))
@@ -246,6 +273,13 @@ ip_output_send(struct inpcb *inp, struct ifnet *ifp, struct mbuf *m,
done:
/* Check for route change invalidating send tags. */
+#ifdef KERN_TLS
+ if (tls != NULL) {
+ if (error == EAGAIN)
+ error = ktls_output_eagain(inp, tls);
+ ktls_free(tls);
+ }
+#endif
#ifdef RATELIMIT
if (error == EAGAIN)
in_pcboutput_eagain(inp);