at v2.6.18-rc5 316 lines 7.0 kB view raw
1#include <linux/kernel.h> 2#include <linux/init.h> 3#include <linux/module.h> 4#include <linux/proc_fs.h> 5#include <linux/skbuff.h> 6#include <linux/netfilter.h> 7#include <linux/seq_file.h> 8#include <linux/rcupdate.h> 9#include <net/protocol.h> 10 11#include "nf_internals.h" 12 13/* 14 * A queue handler may be registered for each protocol. Each is protected by 15 * long term mutex. The handler must provide an an outfn() to accept packets 16 * for queueing and must reinject all packets it receives, no matter what. 17 */ 18static struct nf_queue_handler *queue_handler[NPROTO]; 19 20static DEFINE_RWLOCK(queue_handler_lock); 21 22/* return EBUSY when somebody else is registered, return EEXIST if the 23 * same handler is registered, return 0 in case of success. */ 24int nf_register_queue_handler(int pf, struct nf_queue_handler *qh) 25{ 26 int ret; 27 28 if (pf >= NPROTO) 29 return -EINVAL; 30 31 write_lock_bh(&queue_handler_lock); 32 if (queue_handler[pf] == qh) 33 ret = -EEXIST; 34 else if (queue_handler[pf]) 35 ret = -EBUSY; 36 else { 37 queue_handler[pf] = qh; 38 ret = 0; 39 } 40 write_unlock_bh(&queue_handler_lock); 41 42 return ret; 43} 44EXPORT_SYMBOL(nf_register_queue_handler); 45 46/* The caller must flush their queue before this */ 47int nf_unregister_queue_handler(int pf) 48{ 49 if (pf >= NPROTO) 50 return -EINVAL; 51 52 write_lock_bh(&queue_handler_lock); 53 queue_handler[pf] = NULL; 54 write_unlock_bh(&queue_handler_lock); 55 56 return 0; 57} 58EXPORT_SYMBOL(nf_unregister_queue_handler); 59 60void nf_unregister_queue_handlers(struct nf_queue_handler *qh) 61{ 62 int pf; 63 64 write_lock_bh(&queue_handler_lock); 65 for (pf = 0; pf < NPROTO; pf++) { 66 if (queue_handler[pf] == qh) 67 queue_handler[pf] = NULL; 68 } 69 write_unlock_bh(&queue_handler_lock); 70} 71EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); 72 73/* 74 * Any packet that leaves via this function must come back 75 * through nf_reinject(). 76 */ 77int nf_queue(struct sk_buff **skb, 78 struct list_head *elem, 79 int pf, unsigned int hook, 80 struct net_device *indev, 81 struct net_device *outdev, 82 int (*okfn)(struct sk_buff *), 83 unsigned int queuenum) 84{ 85 int status; 86 struct nf_info *info; 87#ifdef CONFIG_BRIDGE_NETFILTER 88 struct net_device *physindev = NULL; 89 struct net_device *physoutdev = NULL; 90#endif 91 struct nf_afinfo *afinfo; 92 93 /* QUEUE == DROP if noone is waiting, to be safe. */ 94 read_lock(&queue_handler_lock); 95 if (!queue_handler[pf]) { 96 read_unlock(&queue_handler_lock); 97 kfree_skb(*skb); 98 return 1; 99 } 100 101 afinfo = nf_get_afinfo(pf); 102 if (!afinfo) { 103 read_unlock(&queue_handler_lock); 104 kfree_skb(*skb); 105 return 1; 106 } 107 108 info = kmalloc(sizeof(*info) + afinfo->route_key_size, GFP_ATOMIC); 109 if (!info) { 110 if (net_ratelimit()) 111 printk(KERN_ERR "OOM queueing packet %p\n", 112 *skb); 113 read_unlock(&queue_handler_lock); 114 kfree_skb(*skb); 115 return 1; 116 } 117 118 *info = (struct nf_info) { 119 (struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn }; 120 121 /* If it's going away, ignore hook. */ 122 if (!try_module_get(info->elem->owner)) { 123 read_unlock(&queue_handler_lock); 124 kfree(info); 125 return 0; 126 } 127 128 /* Bump dev refs so they don't vanish while packet is out */ 129 if (indev) dev_hold(indev); 130 if (outdev) dev_hold(outdev); 131 132#ifdef CONFIG_BRIDGE_NETFILTER 133 if ((*skb)->nf_bridge) { 134 physindev = (*skb)->nf_bridge->physindev; 135 if (physindev) dev_hold(physindev); 136 physoutdev = (*skb)->nf_bridge->physoutdev; 137 if (physoutdev) dev_hold(physoutdev); 138 } 139#endif 140 afinfo->saveroute(*skb, info); 141 status = queue_handler[pf]->outfn(*skb, info, queuenum, 142 queue_handler[pf]->data); 143 144 read_unlock(&queue_handler_lock); 145 146 if (status < 0) { 147 /* James M doesn't say fuck enough. */ 148 if (indev) dev_put(indev); 149 if (outdev) dev_put(outdev); 150#ifdef CONFIG_BRIDGE_NETFILTER 151 if (physindev) dev_put(physindev); 152 if (physoutdev) dev_put(physoutdev); 153#endif 154 module_put(info->elem->owner); 155 kfree(info); 156 kfree_skb(*skb); 157 158 return 1; 159 } 160 161 return 1; 162} 163 164void nf_reinject(struct sk_buff *skb, struct nf_info *info, 165 unsigned int verdict) 166{ 167 struct list_head *elem = &info->elem->list; 168 struct list_head *i; 169 struct nf_afinfo *afinfo; 170 171 rcu_read_lock(); 172 173 /* Release those devices we held, or Alexey will kill me. */ 174 if (info->indev) dev_put(info->indev); 175 if (info->outdev) dev_put(info->outdev); 176#ifdef CONFIG_BRIDGE_NETFILTER 177 if (skb->nf_bridge) { 178 if (skb->nf_bridge->physindev) 179 dev_put(skb->nf_bridge->physindev); 180 if (skb->nf_bridge->physoutdev) 181 dev_put(skb->nf_bridge->physoutdev); 182 } 183#endif 184 185 /* Drop reference to owner of hook which queued us. */ 186 module_put(info->elem->owner); 187 188 list_for_each_rcu(i, &nf_hooks[info->pf][info->hook]) { 189 if (i == elem) 190 break; 191 } 192 193 if (i == &nf_hooks[info->pf][info->hook]) { 194 /* The module which sent it to userspace is gone. */ 195 NFDEBUG("%s: module disappeared, dropping packet.\n", 196 __FUNCTION__); 197 verdict = NF_DROP; 198 } 199 200 /* Continue traversal iff userspace said ok... */ 201 if (verdict == NF_REPEAT) { 202 elem = elem->prev; 203 verdict = NF_ACCEPT; 204 } 205 206 if (verdict == NF_ACCEPT) { 207 afinfo = nf_get_afinfo(info->pf); 208 if (!afinfo || afinfo->reroute(&skb, info) < 0) 209 verdict = NF_DROP; 210 } 211 212 if (verdict == NF_ACCEPT) { 213 next_hook: 214 verdict = nf_iterate(&nf_hooks[info->pf][info->hook], 215 &skb, info->hook, 216 info->indev, info->outdev, &elem, 217 info->okfn, INT_MIN); 218 } 219 220 switch (verdict & NF_VERDICT_MASK) { 221 case NF_ACCEPT: 222 case NF_STOP: 223 info->okfn(skb); 224 case NF_STOLEN: 225 break; 226 case NF_QUEUE: 227 if (!nf_queue(&skb, elem, info->pf, info->hook, 228 info->indev, info->outdev, info->okfn, 229 verdict >> NF_VERDICT_BITS)) 230 goto next_hook; 231 break; 232 default: 233 kfree_skb(skb); 234 } 235 rcu_read_unlock(); 236 kfree(info); 237 return; 238} 239EXPORT_SYMBOL(nf_reinject); 240 241#ifdef CONFIG_PROC_FS 242static void *seq_start(struct seq_file *seq, loff_t *pos) 243{ 244 if (*pos >= NPROTO) 245 return NULL; 246 247 return pos; 248} 249 250static void *seq_next(struct seq_file *s, void *v, loff_t *pos) 251{ 252 (*pos)++; 253 254 if (*pos >= NPROTO) 255 return NULL; 256 257 return pos; 258} 259 260static void seq_stop(struct seq_file *s, void *v) 261{ 262 263} 264 265static int seq_show(struct seq_file *s, void *v) 266{ 267 int ret; 268 loff_t *pos = v; 269 struct nf_queue_handler *qh; 270 271 read_lock_bh(&queue_handler_lock); 272 qh = queue_handler[*pos]; 273 if (!qh) 274 ret = seq_printf(s, "%2lld NONE\n", *pos); 275 else 276 ret = seq_printf(s, "%2lld %s\n", *pos, qh->name); 277 read_unlock_bh(&queue_handler_lock); 278 279 return ret; 280} 281 282static struct seq_operations nfqueue_seq_ops = { 283 .start = seq_start, 284 .next = seq_next, 285 .stop = seq_stop, 286 .show = seq_show, 287}; 288 289static int nfqueue_open(struct inode *inode, struct file *file) 290{ 291 return seq_open(file, &nfqueue_seq_ops); 292} 293 294static struct file_operations nfqueue_file_ops = { 295 .owner = THIS_MODULE, 296 .open = nfqueue_open, 297 .read = seq_read, 298 .llseek = seq_lseek, 299 .release = seq_release, 300}; 301#endif /* PROC_FS */ 302 303 304int __init netfilter_queue_init(void) 305{ 306#ifdef CONFIG_PROC_FS 307 struct proc_dir_entry *pde; 308 309 pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter); 310 if (!pde) 311 return -1; 312 pde->proc_fops = &nfqueue_file_ops; 313#endif 314 return 0; 315} 316