mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
ipsec_offload: handle TSO if supported
Allow for TSO to operate if network interface supports ipsec inline offload and supports TSO over it. Reviewed by: tuexen Sponsored by: NVIDIA networking Differential revision: https://reviews.freebsd.org/D44222
This commit is contained in:
parent
9d269938e3
commit
b6919741b7
4 changed files with 17 additions and 11 deletions
|
|
@ -3979,6 +3979,8 @@ tcp_mss(struct tcpcb *tp, int offer)
|
|||
tp->t_tsomax = cap.tsomax;
|
||||
tp->t_tsomaxsegcount = cap.tsomaxsegcount;
|
||||
tp->t_tsomaxsegsize = cap.tsomaxsegsize;
|
||||
if (cap.ipsec_tso)
|
||||
tp->t_flags2 |= TF2_IPSEC_TSO;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,9 +201,7 @@ tcp_default_output(struct tcpcb *tp)
|
|||
struct tcphdr *th;
|
||||
u_char opt[TCP_MAXOLEN];
|
||||
unsigned ipoptlen, optlen, hdrlen, ulen;
|
||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
|
||||
unsigned ipsec_optlen = 0;
|
||||
#endif
|
||||
int idle, sendalot, curticks;
|
||||
int sack_rxmit, sack_bytes_rxmt;
|
||||
struct sackhole *p;
|
||||
|
|
@ -553,15 +551,15 @@ after_sack_rexmit:
|
|||
offsetof(struct ipoption, ipopt_list);
|
||||
else
|
||||
ipoptlen = 0;
|
||||
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
|
||||
ipoptlen += ipsec_optlen;
|
||||
#endif
|
||||
|
||||
if ((tp->t_flags & TF_TSO) && V_tcp_do_tso && len > tp->t_maxseg &&
|
||||
(tp->t_port == 0) &&
|
||||
((tp->t_flags & TF_SIGNATURE) == 0) &&
|
||||
tp->rcv_numsacks == 0 && ((sack_rxmit == 0) || V_tcp_sack_tso) &&
|
||||
ipoptlen == 0 && !(flags & TH_SYN))
|
||||
(ipoptlen == 0 || (ipoptlen == ipsec_optlen &&
|
||||
(tp->t_flags2 & TF2_IPSEC_TSO) != 0)) &&
|
||||
!(flags & TH_SYN))
|
||||
tso = 1;
|
||||
|
||||
if (SEQ_LT((sack_rxmit ? p->rxmit : tp->snd_nxt) + len,
|
||||
|
|
@ -917,7 +915,7 @@ send:
|
|||
* overflowing or exceeding the maximum length
|
||||
* allowed by the network interface:
|
||||
*/
|
||||
KASSERT(ipoptlen == 0,
|
||||
KASSERT(ipoptlen == ipsec_optlen,
|
||||
("%s: TSO can't do IP options", __func__));
|
||||
|
||||
/*
|
||||
|
|
@ -926,8 +924,8 @@ send:
|
|||
*/
|
||||
if (if_hw_tsomax != 0) {
|
||||
/* compute maximum TSO length */
|
||||
max_len = (if_hw_tsomax - hdrlen -
|
||||
max_linkhdr);
|
||||
max_len = if_hw_tsomax - hdrlen -
|
||||
ipsec_optlen - max_linkhdr;
|
||||
if (max_len <= 0) {
|
||||
len = 0;
|
||||
} else if (len > max_len) {
|
||||
|
|
@ -941,7 +939,7 @@ send:
|
|||
* fractional unless the send sockbuf can be
|
||||
* emptied:
|
||||
*/
|
||||
max_len = (tp->t_maxseg - optlen);
|
||||
max_len = tp->t_maxseg - optlen - ipsec_optlen;
|
||||
if (((uint32_t)off + (uint32_t)len) <
|
||||
sbavail(&so->so_snd)) {
|
||||
moff = len % max_len;
|
||||
|
|
@ -1393,10 +1391,10 @@ send:
|
|||
* The TCP pseudo header checksum is always provided.
|
||||
*/
|
||||
if (tso) {
|
||||
KASSERT(len > tp->t_maxseg - optlen,
|
||||
KASSERT(len > tp->t_maxseg - optlen - ipsec_optlen,
|
||||
("%s: len <= tso_segsz", __func__));
|
||||
m->m_pkthdr.csum_flags |= CSUM_TSO;
|
||||
m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen;
|
||||
m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen - ipsec_optlen;
|
||||
}
|
||||
|
||||
KASSERT(len + hdrlen == m_length(m, NULL),
|
||||
|
|
|
|||
|
|
@ -3349,6 +3349,9 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap)
|
|||
cap->tsomax = ifp->if_hw_tsomax;
|
||||
cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount;
|
||||
cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize;
|
||||
/* XXXKIB IFCAP2_IPSEC_OFFLOAD_TSO */
|
||||
cap->ipsec_tso = (ifp->if_capenable2 &
|
||||
IFCAP2_BIT(IFCAP2_IPSEC_OFFLOAD)) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3388,6 +3391,7 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap)
|
|||
cap->tsomax = ifp->if_hw_tsomax;
|
||||
cap->tsomaxsegcount = ifp->if_hw_tsomaxsegcount;
|
||||
cap->tsomaxsegsize = ifp->if_hw_tsomaxsegsize;
|
||||
cap->ipsec_tso = false; /* XXXKIB */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -844,6 +844,7 @@ tcp_packets_this_ack(struct tcpcb *tp, tcp_seq ack)
|
|||
#define TF2_DONT_SACK_QUEUE 0x00040000 /* Don't wake on sack */
|
||||
#define TF2_CANNOT_DO_ECN 0x00080000 /* The stack does not do ECN */
|
||||
#define TF2_PROC_SACK_PROHIBIT 0x00100000 /* Due to small MSS size do not process sack's */
|
||||
#define TF2_IPSEC_TSO 0x00200000 /* IPSEC + TSO supported */
|
||||
|
||||
/*
|
||||
* Structure to hold TCP options that are only used during segment
|
||||
|
|
@ -1430,6 +1431,7 @@ struct tcp_ifcap {
|
|||
u_int tsomax;
|
||||
u_int tsomaxsegcount;
|
||||
u_int tsomaxsegsize;
|
||||
bool ipsec_tso;
|
||||
};
|
||||
uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
|
||||
uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
|
||||
|
|
|
|||
Loading…
Reference in a new issue