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