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 <linux/slab.h> 23#include <net/net_namespace.h> 24#include <net/sock.h> 25 26#include "nf_internals.h" 27 28#include <typedefs.h> 29#include <bcmdefs.h> 30 31#ifdef CONFIG_IP_NF_LFP 32typedef int (*lfpHitHook)(int pf, unsigned int hook, struct sk_buff *skb); 33extern lfpHitHook lfp_hit_hook; 34#endif 35 36static DEFINE_MUTEX(afinfo_mutex); 37 38const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; 39EXPORT_SYMBOL(nf_afinfo); 40 41int nf_register_afinfo(const struct nf_afinfo *afinfo) 42{ 43 int err; 44 45 err = mutex_lock_interruptible(&afinfo_mutex); 46 if (err < 0) 47 return err; 48 rcu_assign_pointer(nf_afinfo[afinfo->family], afinfo); 49 mutex_unlock(&afinfo_mutex); 50 return 0; 51} 52EXPORT_SYMBOL_GPL(nf_register_afinfo); 53 54void nf_unregister_afinfo(const struct nf_afinfo *afinfo) 55{ 56 mutex_lock(&afinfo_mutex); 57 rcu_assign_pointer(nf_afinfo[afinfo->family], NULL); 58 mutex_unlock(&afinfo_mutex); 59 synchronize_rcu(); 60} 61EXPORT_SYMBOL_GPL(nf_unregister_afinfo); 62 63struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; 64EXPORT_SYMBOL(nf_hooks); 65static DEFINE_MUTEX(nf_hook_mutex); 66 67int nf_register_hook(struct nf_hook_ops *reg) 68{ 69 struct nf_hook_ops *elem; 70 int err; 71 72 err = mutex_lock_interruptible(&nf_hook_mutex); 73 if (err < 0) 74 return err; 75 list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) { 76 if (reg->priority < elem->priority) 77 break; 78 } 79 list_add_rcu(®->list, elem->list.prev); 80 mutex_unlock(&nf_hook_mutex); 81 return 0; 82} 83EXPORT_SYMBOL(nf_register_hook); 84 85void nf_unregister_hook(struct nf_hook_ops *reg) 86{ 87 mutex_lock(&nf_hook_mutex); 88 list_del_rcu(®->list); 89 mutex_unlock(&nf_hook_mutex); 90 91 synchronize_net(); 92} 93EXPORT_SYMBOL(nf_unregister_hook); 94 95int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) 96{ 97 unsigned int i; 98 int err = 0; 99 100 for (i = 0; i < n; i++) { 101 err = nf_register_hook(®[i]); 102 if (err) 103 goto err; 104 } 105 return err; 106 107err: 108 if (i > 0) 109 nf_unregister_hooks(reg, i); 110 return err; 111} 112EXPORT_SYMBOL(nf_register_hooks); 113 114void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) 115{ 116 unsigned int i; 117 118 for (i = 0; i < n; i++) 119 nf_unregister_hook(®[i]); 120} 121EXPORT_SYMBOL(nf_unregister_hooks); 122 123unsigned int BCMFASTPATH_HOST nf_iterate(struct list_head *head, 124 struct sk_buff *skb, 125 unsigned int hook, 126 const struct net_device *indev, 127 const struct net_device *outdev, 128 struct list_head **i, 129 int (*okfn)(struct sk_buff *), 130 int hook_thresh) 131{ 132 unsigned int verdict; 133 134 /* 135 * The caller must not block between calls to this 136 * function because of risk of continuing from deleted element. 137 */ 138 list_for_each_continue_rcu(*i, head) { 139 struct nf_hook_ops *elem = (struct nf_hook_ops *)*i; 140 141 if (hook_thresh > elem->priority) 142 continue; 143 144 /* Optimization: we don't need to hold module 145 reference here, since function can't sleep. --RR */ 146 verdict = elem->hook(hook, skb, indev, outdev, okfn); 147 if (verdict != NF_ACCEPT) { 148#ifdef CONFIG_NETFILTER_DEBUG 149 if (unlikely((verdict & NF_VERDICT_MASK) 150 > NF_MAX_VERDICT)) { 151 NFDEBUG("Evil return from %p(%u).\n", 152 elem->hook, hook); 153 continue; 154 } 155#endif 156 if (verdict != NF_REPEAT) 157 return verdict; 158 *i = (*i)->prev; 159 } 160 } 161 return NF_ACCEPT; 162} 163 164 165/* Returns 1 if okfn() needs to be executed by the caller, 166 * -EPERM for NF_DROP, 0 otherwise. */ 167int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, 168 struct net_device *indev, 169 struct net_device *outdev, 170 int (*okfn)(struct sk_buff *), 171 int hook_thresh) 172{ 173 struct list_head *elem; 174 unsigned int verdict; 175 int ret = 0; 176 177 /* We may already have this, but read-locks nest anyway */ 178 rcu_read_lock(); 179 180#ifdef CONFIG_IP_NF_LFP 181 if(likely(lfp_hit_hook)) { 182 ret = lfp_hit_hook(pf, hook, skb); 183 if(unlikely(ret)) goto unlock; 184 } 185#endif 186 187 elem = &nf_hooks[pf][hook]; 188next_hook: 189 verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, 190 outdev, &elem, okfn, hook_thresh); 191 if (verdict == NF_ACCEPT || verdict == NF_STOP) { 192 ret = 1; 193 } else if (verdict == NF_DROP) { 194 kfree_skb(skb); 195 ret = -EPERM; 196 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { 197 int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn, 198 verdict >> NF_VERDICT_QBITS); 199 if (err < 0) { 200 if (err == -ECANCELED) 201 goto next_hook; 202 if (err == -ESRCH && 203 (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) 204 goto next_hook; 205 kfree_skb(skb); 206 } 207 ret = 0; 208 } 209unlock: 210 rcu_read_unlock(); 211 return ret; 212} 213EXPORT_SYMBOL(nf_hook_slow); 214 215 216int skb_make_writable(struct sk_buff *skb, unsigned int writable_len) 217{ 218 if (writable_len > skb->len) 219 return 0; 220 221 /* Not exclusive use of packet? Must copy. */ 222 if (!skb_cloned(skb)) { 223 if (writable_len <= skb_headlen(skb)) 224 return 1; 225 } else if (skb_clone_writable(skb, writable_len)) 226 return 1; 227 228 if (writable_len <= skb_headlen(skb)) 229 writable_len = 0; 230 else 231 writable_len -= skb_headlen(skb); 232 233 return !!__pskb_pull_tail(skb, writable_len); 234} 235EXPORT_SYMBOL(skb_make_writable); 236 237#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 238/* This does not belong here, but locally generated errors need it if connection 239 tracking in use: without this, connection may not be in hash table, and hence 240 manufactured ICMP or RST packets will not be associated with it. */ 241void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *); 242EXPORT_SYMBOL(ip_ct_attach); 243 244void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) 245{ 246 void (*attach)(struct sk_buff *, struct sk_buff *); 247 248 if (skb->nfct) { 249 rcu_read_lock(); 250 attach = rcu_dereference(ip_ct_attach); 251 if (attach) 252 attach(new, skb); 253 rcu_read_unlock(); 254 } 255} 256EXPORT_SYMBOL(nf_ct_attach); 257 258void (*nf_ct_destroy)(struct nf_conntrack *); 259EXPORT_SYMBOL(nf_ct_destroy); 260 261void nf_conntrack_destroy(struct nf_conntrack *nfct) 262{ 263 void (*destroy)(struct nf_conntrack *); 264 265 rcu_read_lock(); 266 destroy = rcu_dereference(nf_ct_destroy); 267 BUG_ON(destroy == NULL); 268 destroy(nfct); 269 rcu_read_unlock(); 270} 271EXPORT_SYMBOL(nf_conntrack_destroy); 272#endif /* CONFIG_NF_CONNTRACK */ 273 274#ifdef CONFIG_PROC_FS 275struct proc_dir_entry *proc_net_netfilter; 276EXPORT_SYMBOL(proc_net_netfilter); 277#endif 278 279void __init netfilter_init(void) 280{ 281 int i, h; 282 for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) { 283 for (h = 0; h < NF_MAX_HOOKS; h++) 284 INIT_LIST_HEAD(&nf_hooks[i][h]); 285 } 286 287#ifdef CONFIG_PROC_FS 288 proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net); 289 if (!proc_net_netfilter) 290 panic("cannot create netfilter proc entry"); 291#endif 292 293 if (netfilter_queue_init() < 0) 294 panic("cannot initialize nf_queue"); 295 if (netfilter_log_init() < 0) 296 panic("cannot initialize nf_log"); 297} 298 299#ifdef CONFIG_SYSCTL 300struct ctl_path nf_net_netfilter_sysctl_path[] = { 301 { .procname = "net", }, 302 { .procname = "netfilter", }, 303 { } 304}; 305EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path); 306#endif /* CONFIG_SYSCTL */ 307