@@ -698,11 +698,90 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
698
698
}
699
699
}
700
700
701
+ /**
702
+ * ixgbe_ipsec_offload_ok - can this packet use the xfrm hw offload
703
+ * @skb: current data packet
704
+ * @xs: pointer to transformer state struct
705
+ **/
706
+ static bool ixgbe_ipsec_offload_ok (struct sk_buff * skb , struct xfrm_state * xs )
707
+ {
708
+ if (xs -> props .family == AF_INET ) {
709
+ /* Offload with IPv4 options is not supported yet */
710
+ if (ip_hdr (skb )-> ihl != 5 )
711
+ return false;
712
+ } else {
713
+ /* Offload with IPv6 extension headers is not support yet */
714
+ if (ipv6_ext_hdr (ipv6_hdr (skb )-> nexthdr ))
715
+ return false;
716
+ }
717
+
718
+ return true;
719
+ }
720
+
701
721
static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
702
722
.xdo_dev_state_add = ixgbe_ipsec_add_sa ,
703
723
.xdo_dev_state_delete = ixgbe_ipsec_del_sa ,
724
+ .xdo_dev_offload_ok = ixgbe_ipsec_offload_ok ,
704
725
};
705
726
727
+ /**
728
+ * ixgbe_ipsec_tx - setup Tx flags for ipsec offload
729
+ * @tx_ring: outgoing context
730
+ * @first: current data packet
731
+ * @itd: ipsec Tx data for later use in building context descriptor
732
+ **/
733
+ int ixgbe_ipsec_tx (struct ixgbe_ring * tx_ring ,
734
+ struct ixgbe_tx_buffer * first ,
735
+ struct ixgbe_ipsec_tx_data * itd )
736
+ {
737
+ struct ixgbe_adapter * adapter = netdev_priv (tx_ring -> netdev );
738
+ struct ixgbe_ipsec * ipsec = adapter -> ipsec ;
739
+ struct xfrm_state * xs ;
740
+ struct tx_sa * tsa ;
741
+
742
+ if (unlikely (!first -> skb -> sp -> len )) {
743
+ netdev_err (tx_ring -> netdev , "%s: no xfrm state len = %d\n" ,
744
+ __func__ , first -> skb -> sp -> len );
745
+ return 0 ;
746
+ }
747
+
748
+ xs = xfrm_input_state (first -> skb );
749
+ if (unlikely (!xs )) {
750
+ netdev_err (tx_ring -> netdev , "%s: no xfrm_input_state() xs = %p\n" ,
751
+ __func__ , xs );
752
+ return 0 ;
753
+ }
754
+
755
+ itd -> sa_idx = xs -> xso .offload_handle - IXGBE_IPSEC_BASE_TX_INDEX ;
756
+ if (unlikely (itd -> sa_idx > IXGBE_IPSEC_MAX_SA_COUNT )) {
757
+ netdev_err (tx_ring -> netdev , "%s: bad sa_idx=%d handle=%lu\n" ,
758
+ __func__ , itd -> sa_idx , xs -> xso .offload_handle );
759
+ return 0 ;
760
+ }
761
+
762
+ tsa = & ipsec -> tx_tbl [itd -> sa_idx ];
763
+ if (unlikely (!tsa -> used )) {
764
+ netdev_err (tx_ring -> netdev , "%s: unused sa_idx=%d\n" ,
765
+ __func__ , itd -> sa_idx );
766
+ return 0 ;
767
+ }
768
+
769
+ first -> tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC ;
770
+
771
+ itd -> flags = 0 ;
772
+ if (xs -> id .proto == IPPROTO_ESP ) {
773
+ itd -> flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
774
+ IXGBE_ADVTXD_TUCMD_L4T_TCP ;
775
+ if (first -> protocol == htons (ETH_P_IP ))
776
+ itd -> flags |= IXGBE_ADVTXD_TUCMD_IPV4 ;
777
+ itd -> trailer_len = xs -> props .trailer_len ;
778
+ }
779
+ if (tsa -> encrypt )
780
+ itd -> flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN ;
781
+
782
+ return 1 ;
783
+ }
784
+
706
785
/**
707
786
* ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
708
787
* @rx_ring: receiving ring
0 commit comments