@@ -86,6 +86,97 @@ static struct sk_buff **esp6_gro_receive(struct sk_buff **head,
8686 return NULL ;
8787}
8888
89+ static void esp6_gso_encap (struct xfrm_state * x , struct sk_buff * skb )
90+ {
91+ struct ip_esp_hdr * esph ;
92+ struct ipv6hdr * iph = ipv6_hdr (skb );
93+ struct xfrm_offload * xo = xfrm_offload (skb );
94+ int proto = iph -> nexthdr ;
95+
96+ skb_push (skb , - skb_network_offset (skb ));
97+ esph = ip_esp_hdr (skb );
98+ * skb_mac_header (skb ) = IPPROTO_ESP ;
99+
100+ esph -> spi = x -> id .spi ;
101+ esph -> seq_no = htonl (XFRM_SKB_CB (skb )-> seq .output .low );
102+
103+ xo -> proto = proto ;
104+ }
105+
106+ static struct sk_buff * esp6_gso_segment (struct sk_buff * skb ,
107+ netdev_features_t features )
108+ {
109+ __u32 seq ;
110+ int err = 0 ;
111+ struct sk_buff * skb2 ;
112+ struct xfrm_state * x ;
113+ struct ip_esp_hdr * esph ;
114+ struct crypto_aead * aead ;
115+ struct sk_buff * segs = ERR_PTR (- EINVAL );
116+ netdev_features_t esp_features = features ;
117+ struct xfrm_offload * xo = xfrm_offload (skb );
118+
119+ if (xo )
120+ goto out ;
121+
122+ seq = xo -> seq .low ;
123+
124+ x = skb -> sp -> xvec [skb -> sp -> len - 1 ];
125+ aead = x -> data ;
126+ esph = ip_esp_hdr (skb );
127+
128+ if (esph -> spi != x -> id .spi )
129+ goto out ;
130+
131+ if (!pskb_may_pull (skb , sizeof (* esph ) + crypto_aead_ivsize (aead )))
132+ goto out ;
133+
134+ __skb_pull (skb , sizeof (* esph ) + crypto_aead_ivsize (aead ));
135+
136+ skb -> encap_hdr_csum = 1 ;
137+
138+ if (!(features & NETIF_F_HW_ESP ))
139+ esp_features = features & ~(NETIF_F_SG | NETIF_F_CSUM_MASK );
140+
141+ segs = x -> outer_mode -> gso_segment (x , skb , esp_features );
142+ if (IS_ERR_OR_NULL (segs ))
143+ goto out ;
144+
145+ __skb_pull (skb , skb -> data - skb_mac_header (skb ));
146+
147+ skb2 = segs ;
148+ do {
149+ struct sk_buff * nskb = skb2 -> next ;
150+
151+ xo = xfrm_offload (skb2 );
152+ xo -> flags |= XFRM_GSO_SEGMENT ;
153+ xo -> seq .low = seq ;
154+ xo -> seq .hi = xfrm_replay_seqhi (x , seq );
155+
156+ if (!(features & NETIF_F_HW_ESP ))
157+ xo -> flags |= CRYPTO_FALLBACK ;
158+
159+ x -> outer_mode -> xmit (x , skb2 );
160+
161+ err = x -> type_offload -> xmit (x , skb2 , esp_features );
162+ if (err ) {
163+ kfree_skb_list (segs );
164+ return ERR_PTR (err );
165+ }
166+
167+ if (!skb_is_gso (skb2 ))
168+ seq ++ ;
169+ else
170+ seq += skb_shinfo (skb2 )-> gso_segs ;
171+
172+ skb_push (skb2 , skb2 -> mac_len );
173+ skb2 = nskb ;
174+ } while (skb2 );
175+
176+ out :
177+ return segs ;
178+ }
179+
89180static int esp6_input_tail (struct xfrm_state * x , struct sk_buff * skb )
90181{
91182 struct crypto_aead * aead = x -> data ;
@@ -176,6 +267,7 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb, netdev_features
176267static const struct net_offload esp6_offload = {
177268 .callbacks = {
178269 .gro_receive = esp6_gro_receive ,
270+ .gso_segment = esp6_gso_segment ,
179271 },
180272};
181273
@@ -185,6 +277,7 @@ static const struct xfrm_type_offload esp6_type_offload = {
185277 .proto = IPPROTO_ESP ,
186278 .input_tail = esp6_input_tail ,
187279 .xmit = esp6_xmit ,
280+ .encap = esp6_gso_encap ,
188281};
189282
190283static int __init esp6_offload_init (void )
0 commit comments