Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/net/ipv4/netfilter/nf_nat_standalone.c (Version 2.6.25) and /linux/net/ipv4/netfilter/nf_nat_standalone.c (Version 2.6.11.8)


  1 /* (C) 1999-2001 Paul `Rusty' Russell               1 
  2  * (C) 2002-2006 Netfilter Core Team <coreteam    
  3  *                                                
  4  * This program is free software; you can redi    
  5  * it under the terms of the GNU General Publi    
  6  * published by the Free Software Foundation.     
  7  */                                               
  8 #include <linux/types.h>                          
  9 #include <linux/icmp.h>                           
 10 #include <linux/ip.h>                             
 11 #include <linux/netfilter.h>                      
 12 #include <linux/netfilter_ipv4.h>                 
 13 #include <linux/module.h>                         
 14 #include <linux/skbuff.h>                         
 15 #include <linux/proc_fs.h>                        
 16 #include <net/ip.h>                               
 17 #include <net/checksum.h>                         
 18 #include <linux/spinlock.h>                       
 19                                                   
 20 #include <net/netfilter/nf_conntrack.h>           
 21 #include <net/netfilter/nf_conntrack_core.h>      
 22 #include <net/netfilter/nf_conntrack_extend.h>    
 23 #include <net/netfilter/nf_nat.h>                 
 24 #include <net/netfilter/nf_nat_rule.h>            
 25 #include <net/netfilter/nf_nat_protocol.h>        
 26 #include <net/netfilter/nf_nat_core.h>            
 27 #include <net/netfilter/nf_nat_helper.h>          
 28 #include <linux/netfilter_ipv4/ip_tables.h>       
 29                                                   
 30 #ifdef CONFIG_XFRM                                
 31 static void nat_decode_session(struct sk_buff     
 32 {                                                 
 33         struct nf_conn *ct;                       
 34         struct nf_conntrack_tuple *t;             
 35         enum ip_conntrack_info ctinfo;            
 36         enum ip_conntrack_dir dir;                
 37         unsigned long statusbit;                  
 38                                                   
 39         ct = nf_ct_get(skb, &ctinfo);             
 40         if (ct == NULL)                           
 41                 return;                           
 42         dir = CTINFO2DIR(ctinfo);                 
 43         t = &ct->tuplehash[dir].tuple;            
 44                                                   
 45         if (dir == IP_CT_DIR_ORIGINAL)            
 46                 statusbit = IPS_DST_NAT;          
 47         else                                      
 48                 statusbit = IPS_SRC_NAT;          
 49                                                   
 50         if (ct->status & statusbit) {             
 51                 fl->fl4_dst = t->dst.u3.ip;       
 52                 if (t->dst.protonum == IPPROTO    
 53                     t->dst.protonum == IPPROTO    
 54                         fl->fl_ip_dport = t->d    
 55         }                                         
 56                                                   
 57         statusbit ^= IPS_NAT_MASK;                
 58                                                   
 59         if (ct->status & statusbit) {             
 60                 fl->fl4_src = t->src.u3.ip;       
 61                 if (t->dst.protonum == IPPROTO    
 62                     t->dst.protonum == IPPROTO    
 63                         fl->fl_ip_sport = t->s    
 64         }                                         
 65 }                                                 
 66 #endif                                            
 67                                                   
 68 static unsigned int                               
 69 nf_nat_fn(unsigned int hooknum,                   
 70           struct sk_buff *skb,                    
 71           const struct net_device *in,            
 72           const struct net_device *out,           
 73           int (*okfn)(struct sk_buff *))          
 74 {                                                 
 75         struct nf_conn *ct;                       
 76         enum ip_conntrack_info ctinfo;            
 77         struct nf_conn_nat *nat;                  
 78         /* maniptype == SRC for postrouting. *    
 79         enum nf_nat_manip_type maniptype = HOO    
 80                                                   
 81         /* We never see fragments: conntrack d    
 82            and local-out, and nf_nat_out prote    
 83         NF_CT_ASSERT(!(ip_hdr(skb)->frag_off &    
 84                                                   
 85         ct = nf_ct_get(skb, &ctinfo);             
 86         /* Can't track?  It's not due to stres    
 87            have dropped it.  Hence it's the us    
 88            packet filter it out, or implement     
 89            protocol. 8) --RR */                   
 90         if (!ct) {                                
 91                 /* Exception: ICMP redirect to    
 92                    hash table yet).  We must n    
 93                    case we're doing NAT to the    
 94                 if (ip_hdr(skb)->protocol == I    
 95                         struct icmphdr _hdr, *    
 96                                                   
 97                         hp = skb_header_pointe    
 98                                                   
 99                         if (hp != NULL &&         
100                             hp->type == ICMP_R    
101                                 return NF_DROP    
102                 }                                 
103                 return NF_ACCEPT;                 
104         }                                         
105                                                   
106         /* Don't try to NAT if this packet is     
107         if (ct == &nf_conntrack_untracked)        
108                 return NF_ACCEPT;                 
109                                                   
110         nat = nfct_nat(ct);                       
111         if (!nat) {                               
112                 nat = nf_ct_ext_add(ct, NF_CT_    
113                 if (nat == NULL) {                
114                         pr_debug("failed to ad    
115                         return NF_ACCEPT;         
116                 }                                 
117         }                                         
118                                                   
119         switch (ctinfo) {                         
120         case IP_CT_RELATED:                       
121         case IP_CT_RELATED+IP_CT_IS_REPLY:        
122                 if (ip_hdr(skb)->protocol == I    
123                         if (!nf_nat_icmp_reply    
124                                                   
125                                 return NF_DROP    
126                         else                      
127                                 return NF_ACCE    
128                 }                                 
129                 /* Fall thru... (Only ICMPs ca    
130         case IP_CT_NEW:                           
131                                                   
132                 /* Seen it before?  This can h    
133                    or local packets.. */          
134                 if (!nf_nat_initialized(ct, ma    
135                         unsigned int ret;         
136                                                   
137                         if (unlikely(nf_ct_is_    
138                                 /* NAT module     
139                                 ret = alloc_nu    
140                         else if (hooknum == NF    
141                                 /* LOCAL_IN ho    
142                                 ret = alloc_nu    
143                         else                      
144                                 ret = nf_nat_r    
145                                                   
146                                                   
147                         if (ret != NF_ACCEPT)     
148                                 return ret;       
149                         }                         
150                 } else                            
151                         pr_debug("Already setu    
152                                  maniptype ==     
153                                  ct);             
154                 break;                            
155                                                   
156         default:                                  
157                 /* ESTABLISHED */                 
158                 NF_CT_ASSERT(ctinfo == IP_CT_E    
159                              ctinfo == (IP_CT_    
160         }                                         
161                                                   
162         return nf_nat_packet(ct, ctinfo, hookn    
163 }                                                 
164                                                   
165 static unsigned int                               
166 nf_nat_in(unsigned int hooknum,                   
167           struct sk_buff *skb,                    
168           const struct net_device *in,            
169           const struct net_device *out,           
170           int (*okfn)(struct sk_buff *))          
171 {                                                 
172         unsigned int ret;                         
173         __be32 daddr = ip_hdr(skb)->daddr;        
174                                                   
175         ret = nf_nat_fn(hooknum, skb, in, out,    
176         if (ret != NF_DROP && ret != NF_STOLEN    
177             daddr != ip_hdr(skb)->daddr) {        
178                 dst_release(skb->dst);            
179                 skb->dst = NULL;                  
180         }                                         
181         return ret;                               
182 }                                                 
183                                                   
184 static unsigned int                               
185 nf_nat_out(unsigned int hooknum,                  
186            struct sk_buff *skb,                   
187            const struct net_device *in,           
188            const struct net_device *out,          
189            int (*okfn)(struct sk_buff *))         
190 {                                                 
191 #ifdef CONFIG_XFRM                                
192         struct nf_conn *ct;                       
193         enum ip_conntrack_info ctinfo;            
194 #endif                                            
195         unsigned int ret;                         
196                                                   
197         /* root is playing with raw sockets. *    
198         if (skb->len < sizeof(struct iphdr) ||    
199             ip_hdrlen(skb) < sizeof(struct iph    
200                 return NF_ACCEPT;                 
201                                                   
202         ret = nf_nat_fn(hooknum, skb, in, out,    
203 #ifdef CONFIG_XFRM                                
204         if (ret != NF_DROP && ret != NF_STOLEN    
205             (ct = nf_ct_get(skb, &ctinfo)) !=     
206                 enum ip_conntrack_dir dir = CT    
207                                                   
208                 if (ct->tuplehash[dir].tuple.s    
209                     ct->tuplehash[!dir].tuple.    
210                     || ct->tuplehash[dir].tupl    
211                        ct->tuplehash[!dir].tup    
212                     )                             
213                         return ip_xfrm_me_hard    
214         }                                         
215 #endif                                            
216         return ret;                               
217 }                                                 
218                                                   
219 static unsigned int                               
220 nf_nat_local_fn(unsigned int hooknum,             
221                 struct sk_buff *skb,              
222                 const struct net_device *in,      
223                 const struct net_device *out,     
224                 int (*okfn)(struct sk_buff *))    
225 {                                                 
226         struct nf_conn *ct;                       
227         enum ip_conntrack_info ctinfo;            
228         unsigned int ret;                         
229                                                   
230         /* root is playing with raw sockets. *    
231         if (skb->len < sizeof(struct iphdr) ||    
232             ip_hdrlen(skb) < sizeof(struct iph    
233                 return NF_ACCEPT;                 
234                                                   
235         ret = nf_nat_fn(hooknum, skb, in, out,    
236         if (ret != NF_DROP && ret != NF_STOLEN    
237             (ct = nf_ct_get(skb, &ctinfo)) !=     
238                 enum ip_conntrack_dir dir = CT    
239                                                   
240                 if (ct->tuplehash[dir].tuple.d    
241                     ct->tuplehash[!dir].tuple.    
242                         if (ip_route_me_harder    
243                                 ret = NF_DROP;    
244                 }                                 
245 #ifdef CONFIG_XFRM                                
246                 else if (ct->tuplehash[dir].tu    
247                          ct->tuplehash[!dir].t    
248                         if (ip_xfrm_me_harder(    
249                                 ret = NF_DROP;    
250 #endif                                            
251         }                                         
252         return ret;                               
253 }                                                 
254                                                   
255 static unsigned int                               
256 nf_nat_adjust(unsigned int hooknum,               
257               struct sk_buff *skb,                
258               const struct net_device *in,        
259               const struct net_device *out,       
260               int (*okfn)(struct sk_buff *))      
261 {                                                 
262         struct nf_conn *ct;                       
263         enum ip_conntrack_info ctinfo;            
264                                                   
265         ct = nf_ct_get(skb, &ctinfo);             
266         if (ct && test_bit(IPS_SEQ_ADJUST_BIT,    
267                 pr_debug("nf_nat_standalone: a    
268                 if (!nf_nat_seq_adjust(skb, ct    
269                         return NF_DROP;           
270         }                                         
271         return NF_ACCEPT;                         
272 }                                                 
273                                                   
274 /* We must be after connection tracking and be    
275                                                   
276 static struct nf_hook_ops nf_nat_ops[] __read_    
277         /* Before packet filtering, change des    
278         {                                         
279                 .hook           = nf_nat_in,      
280                 .owner          = THIS_MODULE,    
281                 .pf             = PF_INET,        
282                 .hooknum        = NF_INET_PRE_    
283                 .priority       = NF_IP_PRI_NA    
284         },                                        
285         /* After packet filtering, change sour    
286         {                                         
287                 .hook           = nf_nat_out,     
288                 .owner          = THIS_MODULE,    
289                 .pf             = PF_INET,        
290                 .hooknum        = NF_INET_POST    
291                 .priority       = NF_IP_PRI_NA    
292         },                                        
293         /* After conntrack, adjust sequence nu    
294         {                                         
295                 .hook           = nf_nat_adjus    
296                 .owner          = THIS_MODULE,    
297                 .pf             = PF_INET,        
298                 .hooknum        = NF_INET_POST    
299                 .priority       = NF_IP_PRI_NA    
300         },                                        
301         /* Before packet filtering, change des    
302         {                                         
303                 .hook           = nf_nat_local    
304                 .owner          = THIS_MODULE,    
305                 .pf             = PF_INET,        
306                 .hooknum        = NF_INET_LOCA    
307                 .priority       = NF_IP_PRI_NA    
308         },                                        
309         /* After packet filtering, change sour    
310         {                                         
311                 .hook           = nf_nat_fn,      
312                 .owner          = THIS_MODULE,    
313                 .pf             = PF_INET,        
314                 .hooknum        = NF_INET_LOCA    
315                 .priority       = NF_IP_PRI_NA    
316         },                                        
317         /* After conntrack, adjust sequence nu    
318         {                                         
319                 .hook           = nf_nat_adjus    
320                 .owner          = THIS_MODULE,    
321                 .pf             = PF_INET,        
322                 .hooknum        = NF_INET_LOCA    
323                 .priority       = NF_IP_PRI_NA    
324         },                                        
325 };                                                
326                                                   
327 static int __init nf_nat_standalone_init(void)    
328 {                                                 
329         int ret = 0;                              
330                                                   
331         need_ipv4_conntrack();                    
332                                                   
333 #ifdef CONFIG_XFRM                                
334         BUG_ON(ip_nat_decode_session != NULL);    
335         rcu_assign_pointer(ip_nat_decode_sessi    
336 #endif                                            
337         ret = nf_nat_rule_init();                 
338         if (ret < 0) {                            
339                 printk("nf_nat_init: can't set    
340                 goto cleanup_decode_session;      
341         }                                         
342         ret = nf_register_hooks(nf_nat_ops, AR    
343         if (ret < 0) {                            
344                 printk("nf_nat_init: can't reg    
345                 goto cleanup_rule_init;           
346         }                                         
347         return ret;                               
348                                                   
349  cleanup_rule_init:                               
350         nf_nat_rule_cleanup();                    
351  cleanup_decode_session:                          
352 #ifdef CONFIG_XFRM                                
353         rcu_assign_pointer(ip_nat_decode_sessi    
354         synchronize_net();                        
355 #endif                                            
356         return ret;                               
357 }                                                 
358                                                   
359 static void __exit nf_nat_standalone_fini(void    
360 {                                                 
361         nf_unregister_hooks(nf_nat_ops, ARRAY_    
362         nf_nat_rule_cleanup();                    
363 #ifdef CONFIG_XFRM                                
364         rcu_assign_pointer(ip_nat_decode_sessi    
365         synchronize_net();                        
366 #endif                                            
367         /* Conntrack caches are unregistered i    
368 }                                                 
369                                                   
370 module_init(nf_nat_standalone_init);              
371 module_exit(nf_nat_standalone_fini);              
372                                                   
373 MODULE_LICENSE("GPL");                            
374 MODULE_ALIAS("ip_nat");                           
375                                                   
  This page was automatically generated by the LXR engine.