netdev
[Top] [All Lists]

[PATCH] packet fragmentation after POST_ROUTING netfilter hook

To: netdev@xxxxxxxxxxx
Subject: [PATCH] packet fragmentation after POST_ROUTING netfilter hook
From: Paul Rusty Russell <Paul.Russell@xxxxxxxxxxxxxxxx>
Date: Tue, 30 Nov 1999 21:59:15 +1100
Sender: owner-netdev@xxxxxxxxxxx
At the moment, a fragment comes in, must be defragmented for
connection tracking.  It is then forwarded, fragmented, then must be
defragemented AGAIN for NAT in POST_ROUTING hook.  Ick.

This patch defers fragmentation to past the hook, by effectively
reversing ip_send and ip_finish_output (renaming ip_finish_output
because it's EXPORTed), and making everyone use ip_send (it's harmless
to set skb->dev and skb->protocol AFAICT).

I think this also means that the fragment: part in ip_queue_xmit2 can
be reduced, since skb->dst->output() will now do fragmenting.

This is a patch mainly to how much Alexey hates it. 8-)

Rusty.
PS.  Alexey; I saw your photograph in Linux Magazine: very
     disappointed!  I hope, at least, that *your* head? 8-)

diff -ur linux-2.3-official/include/net/ip.h linux-2.3-mangled/include/net/ip.h
--- linux-2.3-official/include/net/ip.h Tue Nov 30 19:08:08 1999
+++ linux-2.3-mangled/include/net/ip.h  Tue Nov 30 21:43:10 1999
@@ -29,6 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/in_route.h>
+#include <linux/netfilter_ipv4.h>
 #include <net/route.h>
 #include <net/arp.h>
 
@@ -138,7 +139,7 @@
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg 
*arg,
                   unsigned int len); 
 
-extern __inline__ int ip_finish_output(struct sk_buff *skb);
+extern int ip_finish_output_and_frag(struct sk_buff *skb);
 
 struct ipv4_config
 {
@@ -156,10 +157,13 @@
 #ifdef CONFIG_INET
 extern __inline__ int ip_send(struct sk_buff *skb)
 {
-       if (skb->len > skb->dst->pmtu)
-               return ip_fragment(skb, ip_finish_output);
-       else
-               return ip_finish_output(skb);
+       struct net_device *dev = skb->dst->dev;
+
+       skb->dev = dev;
+       skb->protocol = __constant_htons(ETH_P_IP);
+
+       return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+                      ip_finish_output_and_frag);
 }
 
 extern __inline__
diff -ur linux-2.3-official/net/ipv4/ip_output.c 
linux-2.3-mangled/net/ipv4/ip_output.c
--- linux-2.3-official/net/ipv4/ip_output.c     Tue Nov 30 17:58:59 1999
+++ linux-2.3-mangled/net/ipv4/ip_output.c      Tue Nov 30 21:45:38 1999
@@ -209,22 +209,18 @@
        return -EINVAL;
 }
 
-__inline__ int ip_finish_output(struct sk_buff *skb)
+int ip_finish_output_and_frag(struct sk_buff *skb)
 {
-       struct net_device *dev = skb->dst->dev;
-
-       skb->dev = dev;
-       skb->protocol = __constant_htons(ETH_P_IP);
-
-       return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
-                      ip_finish_output2);
+       if (skb->len > skb->dst->pmtu)
+               return ip_fragment(skb, ip_finish_output2);
+       else
+               return ip_finish_output2(skb);
 }
 
 int ip_mc_output(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
        struct rtable *rt = (struct rtable*)skb->dst;
-       struct net_device *dev = rt->u.dst.dev;
 
        /*
         *      If the indicated interface is up and running, send the packet.
@@ -235,9 +231,6 @@
                ip_do_nat(skb);
 #endif
 
-       skb->dev = dev;
-       skb->protocol = __constant_htons(ETH_P_IP);
-
        /*
         *      Multicasts are looped back for other local users
         */
@@ -277,7 +270,7 @@
                                newskb->dev, ip_dev_loopback_xmit);
        }
 
-       return ip_finish_output(skb);
+       return ip_send(skb);
 }
 
 int ip_output(struct sk_buff *skb)
@@ -293,7 +286,7 @@
                ip_do_nat(skb);
 #endif
 
-       return ip_finish_output(skb);
+       return ip_send(skb);
 }
 
 /* Queues a packet to be sent, and starts the transmitter if necessary.  
@@ -837,6 +830,8 @@
 
                skb2->pkt_type = skb->pkt_type;
                skb2->priority = skb->priority;
+               skb2->dev = skb->dev;
+               skb2->protocol = skb->protocol;
                skb_reserve(skb2, (dev->hard_header_len+15)&~15);
                skb_put(skb2, len + hlen);
                skb2->nh.raw = skb2->data;
diff -ur linux-2.3-official/net/netsyms.c linux-2.3-mangled/net/netsyms.c
--- linux-2.3-official/net/netsyms.c    Tue Nov 30 17:58:59 1999
+++ linux-2.3-mangled/net/netsyms.c     Tue Nov 30 21:36:48 1999
@@ -239,7 +239,7 @@
 EXPORT_SYMBOL(in_aton);
 EXPORT_SYMBOL(ip_mc_inc_group);
 EXPORT_SYMBOL(ip_mc_dec_group);
-EXPORT_SYMBOL(ip_finish_output);
+EXPORT_SYMBOL(ip_finish_output_and_frag);
 EXPORT_SYMBOL(inet_dgram_ops);
 EXPORT_SYMBOL(ip_cmsg_recv);
 EXPORT_SYMBOL(inet_addr_type); 

--
Hacking time.

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] packet fragmentation after POST_ROUTING netfilter hook, Paul Rusty Russell <=