aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_output.c
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2015-04-05 22:19:04 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 15:25:55 -0400
commit7026b1ddb6b8d4e6ee33dc2bd06c0ca8746fa7ab (patch)
tree3e11ed0f186ea6066a3f7efecb88d85bc732ee51 /net/xfrm/xfrm_output.c
parent1c984f8a5df085bcf35364a8a870bd4db4da4ed3 (diff)
netfilter: Pass socket pointer down through okfn().
On the output paths in particular, we have to sometimes deal with two socket contexts. First, and usually skb->sk, is the local socket that generated the frame. And second, is potentially the socket used to control a tunneling socket, such as one the encapsulates using UDP. We do not want to disassociate skb->sk when encapsulating in order to fix this, because that would break socket memory accounting. The most extreme case where this can cause huge problems is an AF_PACKET socket transmitting over a vxlan device. We hit code paths doing checks that assume they are dealing with an ipv4 socket, but are actually operating upon the AF_PACKET one. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_output.c')
-rw-r--r--net/xfrm/xfrm_output.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 7c532856b398..fbcedbe33190 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -19,7 +19,7 @@
19#include <net/dst.h> 19#include <net/dst.h>
20#include <net/xfrm.h> 20#include <net/xfrm.h>
21 21
22static int xfrm_output2(struct sk_buff *skb); 22static int xfrm_output2(struct sock *sk, struct sk_buff *skb);
23 23
24static int xfrm_skb_check_space(struct sk_buff *skb) 24static int xfrm_skb_check_space(struct sk_buff *skb)
25{ 25{
@@ -130,7 +130,7 @@ int xfrm_output_resume(struct sk_buff *skb, int err)
130 return dst_output(skb); 130 return dst_output(skb);
131 131
132 err = nf_hook(skb_dst(skb)->ops->family, 132 err = nf_hook(skb_dst(skb)->ops->family,
133 NF_INET_POST_ROUTING, skb, 133 NF_INET_POST_ROUTING, skb->sk, skb,
134 NULL, skb_dst(skb)->dev, xfrm_output2); 134 NULL, skb_dst(skb)->dev, xfrm_output2);
135 if (unlikely(err != 1)) 135 if (unlikely(err != 1))
136 goto out; 136 goto out;
@@ -144,12 +144,12 @@ out:
144} 144}
145EXPORT_SYMBOL_GPL(xfrm_output_resume); 145EXPORT_SYMBOL_GPL(xfrm_output_resume);
146 146
147static int xfrm_output2(struct sk_buff *skb) 147static int xfrm_output2(struct sock *sk, struct sk_buff *skb)
148{ 148{
149 return xfrm_output_resume(skb, 1); 149 return xfrm_output_resume(skb, 1);
150} 150}
151 151
152static int xfrm_output_gso(struct sk_buff *skb) 152static int xfrm_output_gso(struct sock *sk, struct sk_buff *skb)
153{ 153{
154 struct sk_buff *segs; 154 struct sk_buff *segs;
155 155
@@ -165,7 +165,7 @@ static int xfrm_output_gso(struct sk_buff *skb)
165 int err; 165 int err;
166 166
167 segs->next = NULL; 167 segs->next = NULL;
168 err = xfrm_output2(segs); 168 err = xfrm_output2(sk, segs);
169 169
170 if (unlikely(err)) { 170 if (unlikely(err)) {
171 kfree_skb_list(nskb); 171 kfree_skb_list(nskb);
@@ -178,13 +178,13 @@ static int xfrm_output_gso(struct sk_buff *skb)
178 return 0; 178 return 0;
179} 179}
180 180
181int xfrm_output(struct sk_buff *skb) 181int xfrm_output(struct sock *sk, struct sk_buff *skb)
182{ 182{
183 struct net *net = dev_net(skb_dst(skb)->dev); 183 struct net *net = dev_net(skb_dst(skb)->dev);
184 int err; 184 int err;
185 185
186 if (skb_is_gso(skb)) 186 if (skb_is_gso(skb))
187 return xfrm_output_gso(skb); 187 return xfrm_output_gso(sk, skb);
188 188
189 if (skb->ip_summed == CHECKSUM_PARTIAL) { 189 if (skb->ip_summed == CHECKSUM_PARTIAL) {
190 err = skb_checksum_help(skb); 190 err = skb_checksum_help(skb);
@@ -195,7 +195,7 @@ int xfrm_output(struct sk_buff *skb)
195 } 195 }
196 } 196 }
197 197
198 return xfrm_output2(skb); 198 return xfrm_output2(sk, skb);
199} 199}
200EXPORT_SYMBOL_GPL(xfrm_output); 200EXPORT_SYMBOL_GPL(xfrm_output);
201 201