xfrm_output.c (29a26a56803855a79dbd028cd61abee56237d6e5) xfrm_output.c (0c4b51f0054ce85c0ec578ab818f0631834573eb)
1/*
2 * xfrm_output.c - Common IPsec encapsulation code.
3 *
4 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 5 unchanged lines hidden (view full) ---

14#include <linux/netdevice.h>
15#include <linux/netfilter.h>
16#include <linux/skbuff.h>
17#include <linux/slab.h>
18#include <linux/spinlock.h>
19#include <net/dst.h>
20#include <net/xfrm.h>
21
1/*
2 * xfrm_output.c - Common IPsec encapsulation code.
3 *
4 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version

--- 5 unchanged lines hidden (view full) ---

14#include <linux/netdevice.h>
15#include <linux/netfilter.h>
16#include <linux/skbuff.h>
17#include <linux/slab.h>
18#include <linux/spinlock.h>
19#include <net/dst.h>
20#include <net/xfrm.h>
21
22static int xfrm_output2(struct sock *sk, struct sk_buff *skb);
22static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb);
23
24static int xfrm_skb_check_space(struct sk_buff *skb)
25{
26 struct dst_entry *dst = skb_dst(skb);
27 int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
28 - skb_headroom(skb);
29 int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
30

--- 121 unchanged lines hidden (view full) ---

152 if (err == -EINPROGRESS)
153 err = 0;
154
155out:
156 return err;
157}
158EXPORT_SYMBOL_GPL(xfrm_output_resume);
159
23
24static int xfrm_skb_check_space(struct sk_buff *skb)
25{
26 struct dst_entry *dst = skb_dst(skb);
27 int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
28 - skb_headroom(skb);
29 int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
30

--- 121 unchanged lines hidden (view full) ---

152 if (err == -EINPROGRESS)
153 err = 0;
154
155out:
156 return err;
157}
158EXPORT_SYMBOL_GPL(xfrm_output_resume);
159
160static int xfrm_output2(struct sock *sk, struct sk_buff *skb)
160static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
161{
162 return xfrm_output_resume(skb, 1);
163}
164
161{
162 return xfrm_output_resume(skb, 1);
163}
164
165static int xfrm_output_gso(struct sock *sk, struct sk_buff *skb)
165static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb)
166{
167 struct sk_buff *segs;
168
169 segs = skb_gso_segment(skb, 0);
170 kfree_skb(skb);
171 if (IS_ERR(segs))
172 return PTR_ERR(segs);
173 if (segs == NULL)
174 return -EINVAL;
175
176 do {
177 struct sk_buff *nskb = segs->next;
178 int err;
179
180 segs->next = NULL;
166{
167 struct sk_buff *segs;
168
169 segs = skb_gso_segment(skb, 0);
170 kfree_skb(skb);
171 if (IS_ERR(segs))
172 return PTR_ERR(segs);
173 if (segs == NULL)
174 return -EINVAL;
175
176 do {
177 struct sk_buff *nskb = segs->next;
178 int err;
179
180 segs->next = NULL;
181 err = xfrm_output2(sk, segs);
181 err = xfrm_output2(net, sk, segs);
182
183 if (unlikely(err)) {
184 kfree_skb_list(nskb);
185 return err;
186 }
187
188 segs = nskb;
189 } while (segs);
190
191 return 0;
192}
193
194int xfrm_output(struct sock *sk, struct sk_buff *skb)
195{
196 struct net *net = dev_net(skb_dst(skb)->dev);
197 int err;
198
199 if (skb_is_gso(skb))
182
183 if (unlikely(err)) {
184 kfree_skb_list(nskb);
185 return err;
186 }
187
188 segs = nskb;
189 } while (segs);
190
191 return 0;
192}
193
194int xfrm_output(struct sock *sk, struct sk_buff *skb)
195{
196 struct net *net = dev_net(skb_dst(skb)->dev);
197 int err;
198
199 if (skb_is_gso(skb))
200 return xfrm_output_gso(sk, skb);
200 return xfrm_output_gso(net, sk, skb);
201
202 if (skb->ip_summed == CHECKSUM_PARTIAL) {
203 err = skb_checksum_help(skb);
204 if (err) {
205 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
206 kfree_skb(skb);
207 return err;
208 }
209 }
210
201
202 if (skb->ip_summed == CHECKSUM_PARTIAL) {
203 err = skb_checksum_help(skb);
204 if (err) {
205 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
206 kfree_skb(skb);
207 return err;
208 }
209 }
210
211 return xfrm_output2(sk, skb);
211 return xfrm_output2(net, sk, skb);
212}
213EXPORT_SYMBOL_GPL(xfrm_output);
214
215int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
216{
217 struct xfrm_mode *inner_mode;
218 if (x->sel.family == AF_UNSPEC)
219 inner_mode = xfrm_ip2inner_mode(x,

--- 30 unchanged lines hidden ---
212}
213EXPORT_SYMBOL_GPL(xfrm_output);
214
215int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
216{
217 struct xfrm_mode *inner_mode;
218 if (x->sel.family == AF_UNSPEC)
219 inner_mode = xfrm_ip2inner_mode(x,

--- 30 unchanged lines hidden ---