diff options
author | Patrick McHardy <kaber@trash.net> | 2006-01-05 15:20:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-01-05 15:20:59 -0500 |
commit | 1bd9bef6f9fe06dd0c628ac877c85b6b36aca062 (patch) | |
tree | 60b4bfdd06efc0ab5cf297c470a273f470b7c1f5 /net/ipv4/ip_output.c | |
parent | abbcc73982445c1457901c7fc1d0d110e7a587e3 (diff) |
[NETFILTER]: Call POST_ROUTING hook before fragmentation
Call POST_ROUTING hook before fragmentation to get rid of the okfn use
in ip_refrag and save the useless fragmentation/defragmentation step
when NAT is used.
The patch introduces one user-visible change, the POSTROUTING chain
in the mangle table gets entire packets, not fragments, which should
simplify use of the MARK and CLASSIFY targets for queueing as a nice
side-effect.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r-- | net/ipv4/ip_output.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 2a830de3a699..71da31818cfc 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -202,13 +202,11 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
202 | 202 | ||
203 | static inline int ip_finish_output(struct sk_buff *skb) | 203 | static inline int ip_finish_output(struct sk_buff *skb) |
204 | { | 204 | { |
205 | struct net_device *dev = skb->dst->dev; | 205 | if (skb->len > dst_mtu(skb->dst) && |
206 | 206 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | |
207 | skb->dev = dev; | 207 | return ip_fragment(skb, ip_finish_output2); |
208 | skb->protocol = htons(ETH_P_IP); | 208 | else |
209 | 209 | return ip_finish_output2(skb); | |
210 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, | ||
211 | ip_finish_output2); | ||
212 | } | 210 | } |
213 | 211 | ||
214 | int ip_mc_output(struct sk_buff *skb) | 212 | int ip_mc_output(struct sk_buff *skb) |
@@ -265,21 +263,21 @@ int ip_mc_output(struct sk_buff *skb) | |||
265 | newskb->dev, ip_dev_loopback_xmit); | 263 | newskb->dev, ip_dev_loopback_xmit); |
266 | } | 264 | } |
267 | 265 | ||
268 | if (skb->len > dst_mtu(&rt->u.dst)) | 266 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, |
269 | return ip_fragment(skb, ip_finish_output); | 267 | ip_finish_output); |
270 | else | ||
271 | return ip_finish_output(skb); | ||
272 | } | 268 | } |
273 | 269 | ||
274 | int ip_output(struct sk_buff *skb) | 270 | int ip_output(struct sk_buff *skb) |
275 | { | 271 | { |
272 | struct net_device *dev = skb->dst->dev; | ||
273 | |||
276 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); | 274 | IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS); |
277 | 275 | ||
278 | if (skb->len > dst_mtu(skb->dst) && | 276 | skb->dev = dev; |
279 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | 277 | skb->protocol = htons(ETH_P_IP); |
280 | return ip_fragment(skb, ip_finish_output); | 278 | |
281 | else | 279 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, |
282 | return ip_finish_output(skb); | 280 | ip_finish_output); |
283 | } | 281 | } |
284 | 282 | ||
285 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 283 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) |