1/* netfilter.c: look after the filters for various protocols. 2 * Heavily influenced by the old firewall.c by David Bonn and Alan Cox. 3 * 4 * Thanks to Rob `CmdrTaco' Malda for not influencing this code in any 5 * way. 6 * 7 * Rusty Russell (C)2000 -- This code is GPL. 8 */ 9#include <linux/kernel.h> 10#include <linux/netfilter.h> 11#include <net/protocol.h> 12#include <linux/init.h> 13#include <linux/skbuff.h> 14#include <linux/wait.h> 15#include <linux/module.h> 16#include <linux/interrupt.h> 17#include <linux/if.h> 18#include <linux/netdevice.h> 19#include <linux/inetdevice.h> 20#include <linux/proc_fs.h> 21#include <linux/mutex.h> 22#include <net/sock.h> 23 24#include "nf_internals.h" 25 26static DEFINE_MUTEX(afinfo_mutex); 27 28struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly; 29EXPORT_SYMBOL(nf_afinfo); 30 31int nf_register_afinfo(struct nf_afinfo *afinfo) 32{ 33 int err; 34 35 err = mutex_lock_interruptible(&afinfo_mutex); 36 if (err < 0) 37 return err; 38 rcu_assign_pointer(nf_afinfo[afinfo->family], afinfo); 39 mutex_unlock(&afinfo_mutex); 40 return 0; 41} 42EXPORT_SYMBOL_GPL(nf_register_afinfo); 43 44void nf_unregister_afinfo(struct nf_afinfo *afinfo) 45{ 46 mutex_lock(&afinfo_mutex); 47 rcu_assign_pointer(nf_afinfo[afinfo->family], NULL); 48 mutex_unlock(&afinfo_mutex); 49 synchronize_rcu(); 50} 51EXPORT_SYMBOL_GPL(nf_unregister_afinfo); 52 53/* In this code, we can be waiting indefinitely for userspace to 54 * service a packet if a hook returns NF_QUEUE. We could keep a count 55 * of skbuffs queued for userspace, and not deregister a hook unless 56 * this is zero, but that sucks. Now, we simply check when the 57 * packets come back: if the hook is gone, the packet is discarded. */ 58struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; 59EXPORT_SYMBOL(nf_hooks); 60static DEFINE_MUTEX(nf_hook_mutex); 61 62int nf_register_hook(struct nf_hook_ops *reg) 63{ 64 struct list_head *i; 65 int err; 66 67 err = mutex_lock_interruptible(&nf_hook_mutex); 68 if (err < 0) 69 return err; 70 list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) { 71 if (reg->priority < ((struct nf_hook_ops *)i)->priority) 72 break; 73 } 74 list_add_rcu(®->list, i->prev); 75 mutex_unlock(&nf_hook_mutex); 76 return 0; 77} 78EXPORT_SYMBOL(nf_register_hook); 79 80void nf_unregister_hook(struct nf_hook_ops *reg) 81{ 82 mutex_lock(&nf_hook_mutex); 83 list_del_rcu(®->list); 84 mutex_unlock(&nf_hook_mutex); 85 86 synchronize_net(); 87} 88EXPORT_SYMBOL(nf_unregister_hook); 89 90int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) 91{ 92 unsigned int i; 93 int err = 0; 94 95 for (i = 0; i < n; i++) { 96 err = nf_register_hook(®[i]); 97 if (err) 98 goto err; 99 } 100 return err; 101 102err: 103 if (i > 0) 104 nf_unregister_hooks(reg, i); 105 return err; 106} 107EXPORT_SYMBOL(nf_register_hooks); 108 109void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) 110{ 111 unsigned int i; 112 113 for (i = 0; i < n; i++) 114 nf_unregister_hook(®[i]); 115} 116EXPORT_SYMBOL(nf_unregister_hooks); 117 118unsigned int nf_iterate(struct list_head *head, 119 struct sk_buff **skb, 120 int hook, 121 const struct net_device *indev, 122 const struct net_device *outdev, 123 struct list_head **i, 124 int (*okfn)(struct sk_buff *), 125 int hook_thresh) 126{ 127 unsigned int verdict; 128 129 /* 130 * The caller must not block between calls to this 131 * function because of risk of continuing from deleted element. 132 */ 133 list_for_each_continue_rcu(*i, head) { 134 struct nf_hook_ops *elem = (struct nf_hook_ops *)*i; 135 136 if (hook_thresh > elem->priority) 137 continue; 138 139 /* Optimization: we don't need to hold module 140 reference here, since function can't sleep. --RR */ 141 verdict = elem->hook(hook, skb, indev, outdev, okfn); 142 if (verdict != NF_ACCEPT) { 143#ifdef CONFIG_NETFILTER_DEBUG 144 if (unlikely((verdict & NF_VERDICT_MASK) 145 > NF_MAX_VERDICT)) { 146 NFDEBUG("Evil return from %p(%u).\n", 147 elem->hook, hook); 148 continue; 149 } 150#endif 151 if (verdict != NF_REPEAT) 152 return verdict; 153 *i = (*i)->prev; 154 } 155 } 156 return NF_ACCEPT; 157} 158 159 160/* Returns 1 if okfn() needs to be executed by the caller, 161 * -EPERM for NF_DROP, 0 otherwise. */ 162int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb, 163 struct net_device *indev, 164 struct net_device *outdev, 165 int (*okfn)(struct sk_buff *), 166 int hook_thresh) 167{ 168 struct list_head *elem; 169 unsigned int verdict; 170 int ret = 0; 171 172 /* We may already have this, but read-locks nest anyway */ 173 rcu_read_lock(); 174 175 elem = &nf_hooks[pf][hook]; 176next_hook: 177 verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev, 178 outdev, &elem, okfn, hook_thresh); 179 if (verdict == NF_ACCEPT || verdict == NF_STOP) { 180 ret = 1; 181 goto unlock; 182 } else if (verdict == NF_DROP) { 183 kfree_skb(*pskb); 184 ret = -EPERM; 185 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { 186 NFDEBUG("nf_hook: Verdict = QUEUE.\n"); 187 if (!nf_queue(*pskb, elem, pf, hook, indev, outdev, okfn, 188 verdict >> NF_VERDICT_BITS)) 189 goto next_hook; 190 } 191unlock: 192 rcu_read_unlock(); 193 return ret; 194} 195EXPORT_SYMBOL(nf_hook_slow); 196 197 198int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len) 199{ 200 struct sk_buff *nskb; 201 202 if (writable_len > (*pskb)->len) 203 return 0; 204 205 /* Not exclusive use of packet? Must copy. */ 206 if (skb_shared(*pskb) || skb_cloned(*pskb)) 207 goto copy_skb; 208 209 return pskb_may_pull(*pskb, writable_len); 210 211copy_skb: 212 nskb = skb_copy(*pskb, GFP_ATOMIC); 213 if (!nskb) 214 return 0; 215 BUG_ON(skb_is_nonlinear(nskb)); 216 217 /* Rest of kernel will get very unhappy if we pass it a 218 suddenly-orphaned skbuff */ 219 if ((*pskb)->sk) 220 skb_set_owner_w(nskb, (*pskb)->sk); 221 kfree_skb(*pskb); 222 *pskb = nskb; 223 return 1; 224} 225EXPORT_SYMBOL(skb_make_writable); 226 227void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, 228 __be32 from, __be32 to, int pseudohdr) 229{ 230 __be32 diff[] = { ~from, to }; 231 if (skb->ip_summed != CHECKSUM_PARTIAL) { 232 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 233 ~csum_unfold(*sum))); 234 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) 235 skb->csum = ~csum_partial((char *)diff, sizeof(diff), 236 ~skb->csum); 237 } else if (pseudohdr) 238 *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff), 239 csum_unfold(*sum))); 240} 241EXPORT_SYMBOL(nf_proto_csum_replace4); 242 243#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 244/* This does not belong here, but locally generated errors need it if connection 245 tracking in use: without this, connection may not be in hash table, and hence 246 manufactured ICMP or RST packets will not be associated with it. */ 247void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *); 248EXPORT_SYMBOL(ip_ct_attach); 249 250void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) 251{ 252 void (*attach)(struct sk_buff *, struct sk_buff *); 253 254 if (skb->nfct) { 255 rcu_read_lock(); 256 attach = rcu_dereference(ip_ct_attach); 257 if (attach) 258 attach(new, skb); 259 rcu_read_unlock(); 260 } 261} 262EXPORT_SYMBOL(nf_ct_attach); 263 264void (*nf_ct_destroy)(struct nf_conntrack *); 265EXPORT_SYMBOL(nf_ct_destroy); 266 267void nf_conntrack_destroy(struct nf_conntrack *nfct) 268{ 269 void (*destroy)(struct nf_conntrack *); 270 271 rcu_read_lock(); 272 destroy = rcu_dereference(nf_ct_destroy); 273 BUG_ON(destroy == NULL); 274 destroy(nfct); 275 rcu_read_unlock(); 276} 277EXPORT_SYMBOL(nf_conntrack_destroy); 278#endif /* CONFIG_NF_CONNTRACK */ 279 280#ifdef CONFIG_PROC_FS 281struct proc_dir_entry *proc_net_netfilter; 282EXPORT_SYMBOL(proc_net_netfilter); 283#endif 284 285void __init netfilter_init(void) 286{ 287 int i, h; 288 for (i = 0; i < NPROTO; i++) { 289 for (h = 0; h < NF_MAX_HOOKS; h++) 290 INIT_LIST_HEAD(&nf_hooks[i][h]); 291 } 292 293#ifdef CONFIG_PROC_FS 294 proc_net_netfilter = proc_mkdir("netfilter", proc_net); 295 if (!proc_net_netfilter) 296 panic("cannot create netfilter proc entry"); 297#endif 298 299 if (netfilter_queue_init() < 0) 300 panic("cannot initialize nf_queue"); 301 if (netfilter_log_init() < 0) 302 panic("cannot initialize nf_log"); 303} 304