aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-01-05 15:20:59 -0500
committerDavid S. Miller <davem@davemloft.net>2006-01-05 15:20:59 -0500
commit1bd9bef6f9fe06dd0c628ac877c85b6b36aca062 (patch)
tree60b4bfdd06efc0ab5cf297c470a273f470b7c1f5 /net/ipv4/ip_output.c
parentabbcc73982445c1457901c7fc1d0d110e7a587e3 (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.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 2a830de3a69..71da31818cf 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
203static inline int ip_finish_output(struct sk_buff *skb) 203static 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
214int ip_mc_output(struct sk_buff *skb) 212int 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
274int ip_output(struct sk_buff *skb) 270int 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
285int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 283int ip_queue_xmit(struct sk_buff *skb, int ipfragok)