@@ -373,6 +373,38 @@ static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)
373
373
return - ENOSPC ;
374
374
}
375
375
376
+ /**
377
+ * ixgbe_ipsec_find_rx_state - find the state that matches
378
+ * @ipsec: pointer to ipsec struct
379
+ * @daddr: inbound address to match
380
+ * @proto: protocol to match
381
+ * @spi: SPI to match
382
+ * @ip4: true if using an ipv4 address
383
+ *
384
+ * Returns a pointer to the matching SA state information
385
+ **/
386
+ static struct xfrm_state * ixgbe_ipsec_find_rx_state (struct ixgbe_ipsec * ipsec ,
387
+ __be32 * daddr , u8 proto ,
388
+ __be32 spi , bool ip4 )
389
+ {
390
+ struct rx_sa * rsa ;
391
+ struct xfrm_state * ret = NULL ;
392
+
393
+ rcu_read_lock ();
394
+ hash_for_each_possible_rcu (ipsec -> rx_sa_list , rsa , hlist , spi )
395
+ if (spi == rsa -> xs -> id .spi &&
396
+ ((ip4 && * daddr == rsa -> xs -> id .daddr .a4 ) ||
397
+ (!ip4 && !memcmp (daddr , & rsa -> xs -> id .daddr .a6 ,
398
+ sizeof (rsa -> xs -> id .daddr .a6 )))) &&
399
+ proto == rsa -> xs -> id .proto ) {
400
+ ret = rsa -> xs ;
401
+ xfrm_state_hold (ret );
402
+ break ;
403
+ }
404
+ rcu_read_unlock ();
405
+ return ret ;
406
+ }
407
+
376
408
/**
377
409
* ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
378
410
* @xs: pointer to xfrm_state struct
@@ -476,7 +508,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
476
508
}
477
509
478
510
/* get ip for rx sa table */
479
- if (xs -> xso . flags & XFRM_OFFLOAD_IPV6 )
511
+ if (xs -> props . family == AF_INET6 )
480
512
memcpy (rsa .ipaddr , & xs -> id .daddr .a6 , 16 );
481
513
else
482
514
memcpy (& rsa .ipaddr [3 ], & xs -> id .daddr .a4 , 4 );
@@ -541,7 +573,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
541
573
rsa .mode |= IXGBE_RXMOD_PROTO_ESP ;
542
574
if (rsa .decrypt )
543
575
rsa .mode |= IXGBE_RXMOD_DECRYPT ;
544
- if (rsa .xs -> xso . flags & XFRM_OFFLOAD_IPV6 )
576
+ if (rsa .xs -> props . family == AF_INET6 )
545
577
rsa .mode |= IXGBE_RXMOD_IPV6 ;
546
578
547
579
/* the preparations worked, so save the info */
@@ -671,6 +703,78 @@ static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
671
703
.xdo_dev_state_delete = ixgbe_ipsec_del_sa ,
672
704
};
673
705
706
+ /**
707
+ * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
708
+ * @rx_ring: receiving ring
709
+ * @rx_desc: receive data descriptor
710
+ * @skb: current data packet
711
+ *
712
+ * Determine if there was an ipsec encapsulation noticed, and if so set up
713
+ * the resulting status for later in the receive stack.
714
+ **/
715
+ void ixgbe_ipsec_rx (struct ixgbe_ring * rx_ring ,
716
+ union ixgbe_adv_rx_desc * rx_desc ,
717
+ struct sk_buff * skb )
718
+ {
719
+ struct ixgbe_adapter * adapter = netdev_priv (rx_ring -> netdev );
720
+ __le16 pkt_info = rx_desc -> wb .lower .lo_dword .hs_rss .pkt_info ;
721
+ __le16 ipsec_pkt_types = cpu_to_le16 (IXGBE_RXDADV_PKTTYPE_IPSEC_AH |
722
+ IXGBE_RXDADV_PKTTYPE_IPSEC_ESP );
723
+ struct ixgbe_ipsec * ipsec = adapter -> ipsec ;
724
+ struct xfrm_offload * xo = NULL ;
725
+ struct xfrm_state * xs = NULL ;
726
+ struct ipv6hdr * ip6 = NULL ;
727
+ struct iphdr * ip4 = NULL ;
728
+ void * daddr ;
729
+ __be32 spi ;
730
+ u8 * c_hdr ;
731
+ u8 proto ;
732
+
733
+ /* Find the ip and crypto headers in the data.
734
+ * We can assume no vlan header in the way, b/c the
735
+ * hw won't recognize the IPsec packet and anyway the
736
+ * currently vlan device doesn't support xfrm offload.
737
+ */
738
+ if (pkt_info & cpu_to_le16 (IXGBE_RXDADV_PKTTYPE_IPV4 )) {
739
+ ip4 = (struct iphdr * )(skb -> data + ETH_HLEN );
740
+ daddr = & ip4 -> daddr ;
741
+ c_hdr = (u8 * )ip4 + ip4 -> ihl * 4 ;
742
+ } else if (pkt_info & cpu_to_le16 (IXGBE_RXDADV_PKTTYPE_IPV6 )) {
743
+ ip6 = (struct ipv6hdr * )(skb -> data + ETH_HLEN );
744
+ daddr = & ip6 -> daddr ;
745
+ c_hdr = (u8 * )ip6 + sizeof (struct ipv6hdr );
746
+ } else {
747
+ return ;
748
+ }
749
+
750
+ switch (pkt_info & ipsec_pkt_types ) {
751
+ case cpu_to_le16 (IXGBE_RXDADV_PKTTYPE_IPSEC_AH ):
752
+ spi = ((struct ip_auth_hdr * )c_hdr )-> spi ;
753
+ proto = IPPROTO_AH ;
754
+ break ;
755
+ case cpu_to_le16 (IXGBE_RXDADV_PKTTYPE_IPSEC_ESP ):
756
+ spi = ((struct ip_esp_hdr * )c_hdr )-> spi ;
757
+ proto = IPPROTO_ESP ;
758
+ break ;
759
+ default :
760
+ return ;
761
+ }
762
+
763
+ xs = ixgbe_ipsec_find_rx_state (ipsec , daddr , proto , spi , !!ip4 );
764
+ if (unlikely (!xs ))
765
+ return ;
766
+
767
+ skb -> sp = secpath_dup (skb -> sp );
768
+ if (unlikely (!skb -> sp ))
769
+ return ;
770
+
771
+ skb -> sp -> xvec [skb -> sp -> len ++ ] = xs ;
772
+ skb -> sp -> olen ++ ;
773
+ xo = xfrm_offload (skb );
774
+ xo -> flags = CRYPTO_DONE ;
775
+ xo -> status = CRYPTO_SUCCESS ;
776
+ }
777
+
674
778
/**
675
779
* ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
676
780
* @adapter: board private structure
0 commit comments