|
@@ -789,11 +789,33 @@ int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
|
|
|
|
|
|
itd->flags = 0;
|
|
|
if (xs->id.proto == IPPROTO_ESP) {
|
|
|
+ struct sk_buff *skb = first->skb;
|
|
|
+ int ret, authlen, trailerlen;
|
|
|
+ u8 padlen;
|
|
|
+
|
|
|
itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
|
|
|
IXGBE_ADVTXD_TUCMD_L4T_TCP;
|
|
|
if (first->protocol == htons(ETH_P_IP))
|
|
|
itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
|
|
|
- itd->trailer_len = xs->props.trailer_len;
|
|
|
+
|
|
|
+ /* The actual trailer length is authlen (16 bytes) plus
|
|
|
+ * 2 bytes for the proto and the padlen values, plus
|
|
|
+ * padlen bytes of padding. This ends up not the same
|
|
|
+ * as the static value found in xs->props.trailer_len (21).
|
|
|
+ *
|
|
|
+ * The "correct" way to get the auth length would be to use
|
|
|
+ * authlen = crypto_aead_authsize(xs->data);
|
|
|
+ * but since we know we only have one size to worry about
|
|
|
+ * we can let the compiler use the constant and save us a
|
|
|
+ * few CPU cycles.
|
|
|
+ */
|
|
|
+ authlen = IXGBE_IPSEC_AUTH_BITS / 8;
|
|
|
+
|
|
|
+ ret = skb_copy_bits(skb, skb->len - (authlen + 2), &padlen, 1);
|
|
|
+ if (unlikely(ret))
|
|
|
+ return 0;
|
|
|
+ trailerlen = authlen + 2 + padlen;
|
|
|
+ itd->trailer_len = trailerlen;
|
|
|
}
|
|
|
if (tsa->encrypt)
|
|
|
itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
|