at v2.6.24-rc2 367 lines 7.9 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_MUTEX(queue_handler_mutex); 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 mutex_lock(&queue_handler_mutex); 32 if (queue_handler[pf] == qh) 33 ret = -EEXIST; 34 else if (queue_handler[pf]) 35 ret = -EBUSY; 36 else { 37 rcu_assign_pointer(queue_handler[pf], qh); 38 ret = 0; 39 } 40 mutex_unlock(&queue_handler_mutex); 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, struct nf_queue_handler *qh) 48{ 49 if (pf >= NPROTO) 50 return -EINVAL; 51 52 mutex_lock(&queue_handler_mutex); 53 if (queue_handler[pf] != qh) { 54 mutex_unlock(&queue_handler_mutex); 55 return -EINVAL; 56 } 57 58 rcu_assign_pointer(queue_handler[pf], NULL); 59 mutex_unlock(&queue_handler_mutex); 60 61 synchronize_rcu(); 62 63 return 0; 64} 65EXPORT_SYMBOL(nf_unregister_queue_handler); 66 67void nf_unregister_queue_handlers(struct nf_queue_handler *qh) 68{ 69 int pf; 70 71 mutex_lock(&queue_handler_mutex); 72 for (pf = 0; pf < NPROTO; pf++) { 73 if (queue_handler[pf] == qh) 74 rcu_assign_pointer(queue_handler[pf], NULL); 75 } 76 mutex_unlock(&queue_handler_mutex); 77 78 synchronize_rcu(); 79} 80EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); 81 82/* 83 * Any packet that leaves via this function must come back 84 * through nf_reinject(). 85 */ 86static int __nf_queue(struct sk_buff *skb, 87 struct list_head *elem, 88 int pf, unsigned int hook, 89 struct net_device *indev, 90 struct net_device *outdev, 91 int (*okfn)(struct sk_buff *), 92 unsigned int queuenum) 93{ 94 int status; 95 struct nf_info *info; 96#ifdef CONFIG_BRIDGE_NETFILTER 97 struct net_device *physindev = NULL; 98 struct net_device *physoutdev = NULL; 99#endif 100 struct nf_afinfo *afinfo; 101 struct nf_queue_handler *qh; 102 103 /* QUEUE == DROP if noone is waiting, to be safe. */ 104 rcu_read_lock(); 105 106 qh = rcu_dereference(queue_handler[pf]); 107 if (!qh) { 108 rcu_read_unlock(); 109 kfree_skb(skb); 110 return 1; 111 } 112 113 afinfo = nf_get_afinfo(pf); 114 if (!afinfo) { 115 rcu_read_unlock(); 116 kfree_skb(skb); 117 return 1; 118 } 119 120 info = kmalloc(sizeof(*info) + afinfo->route_key_size, GFP_ATOMIC); 121 if (!info) { 122 if (net_ratelimit()) 123 printk(KERN_ERR "OOM queueing packet %p\n", 124 skb); 125 rcu_read_unlock(); 126 kfree_skb(skb); 127 return 1; 128 } 129 130 *info = (struct nf_info) { 131 (struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn }; 132 133 /* If it's going away, ignore hook. */ 134 if (!try_module_get(info->elem->owner)) { 135 rcu_read_unlock(); 136 kfree(info); 137 return 0; 138 } 139 140 /* Bump dev refs so they don't vanish while packet is out */ 141 if (indev) dev_hold(indev); 142 if (outdev) dev_hold(outdev); 143 144#ifdef CONFIG_BRIDGE_NETFILTER 145 if (skb->nf_bridge) { 146 physindev = skb->nf_bridge->physindev; 147 if (physindev) dev_hold(physindev); 148 physoutdev = skb->nf_bridge->physoutdev; 149 if (physoutdev) dev_hold(physoutdev); 150 } 151#endif 152 afinfo->saveroute(skb, info); 153 status = qh->outfn(skb, info, queuenum, qh->data); 154 155 rcu_read_unlock(); 156 157 if (status < 0) { 158 /* James M doesn't say fuck enough. */ 159 if (indev) dev_put(indev); 160 if (outdev) dev_put(outdev); 161#ifdef CONFIG_BRIDGE_NETFILTER 162 if (physindev) dev_put(physindev); 163 if (physoutdev) dev_put(physoutdev); 164#endif 165 module_put(info->elem->owner); 166 kfree(info); 167 kfree_skb(skb); 168 169 return 1; 170 } 171 172 return 1; 173} 174 175int nf_queue(struct sk_buff *skb, 176 struct list_head *elem, 177 int pf, unsigned int hook, 178 struct net_device *indev, 179 struct net_device *outdev, 180 int (*okfn)(struct sk_buff *), 181 unsigned int queuenum) 182{ 183 struct sk_buff *segs; 184 185 if (!skb_is_gso(skb)) 186 return __nf_queue(skb, elem, pf, hook, indev, outdev, okfn, 187 queuenum); 188 189 switch (pf) { 190 case AF_INET: 191 skb->protocol = htons(ETH_P_IP); 192 break; 193 case AF_INET6: 194 skb->protocol = htons(ETH_P_IPV6); 195 break; 196 } 197 198 segs = skb_gso_segment(skb, 0); 199 kfree_skb(skb); 200 if (unlikely(IS_ERR(segs))) 201 return 1; 202 203 do { 204 struct sk_buff *nskb = segs->next; 205 206 segs->next = NULL; 207 if (!__nf_queue(segs, elem, pf, hook, indev, outdev, okfn, 208 queuenum)) 209 kfree_skb(segs); 210 segs = nskb; 211 } while (segs); 212 return 1; 213} 214 215void nf_reinject(struct sk_buff *skb, struct nf_info *info, 216 unsigned int verdict) 217{ 218 struct list_head *elem = &info->elem->list; 219 struct list_head *i; 220 struct nf_afinfo *afinfo; 221 222 rcu_read_lock(); 223 224 /* Release those devices we held, or Alexey will kill me. */ 225 if (info->indev) dev_put(info->indev); 226 if (info->outdev) dev_put(info->outdev); 227#ifdef CONFIG_BRIDGE_NETFILTER 228 if (skb->nf_bridge) { 229 if (skb->nf_bridge->physindev) 230 dev_put(skb->nf_bridge->physindev); 231 if (skb->nf_bridge->physoutdev) 232 dev_put(skb->nf_bridge->physoutdev); 233 } 234#endif 235 236 /* Drop reference to owner of hook which queued us. */ 237 module_put(info->elem->owner); 238 239 list_for_each_rcu(i, &nf_hooks[info->pf][info->hook]) { 240 if (i == elem) 241 break; 242 } 243 244 if (i == &nf_hooks[info->pf][info->hook]) { 245 /* The module which sent it to userspace is gone. */ 246 NFDEBUG("%s: module disappeared, dropping packet.\n", 247 __FUNCTION__); 248 verdict = NF_DROP; 249 } 250 251 /* Continue traversal iff userspace said ok... */ 252 if (verdict == NF_REPEAT) { 253 elem = elem->prev; 254 verdict = NF_ACCEPT; 255 } 256 257 if (verdict == NF_ACCEPT) { 258 afinfo = nf_get_afinfo(info->pf); 259 if (!afinfo || afinfo->reroute(skb, info) < 0) 260 verdict = NF_DROP; 261 } 262 263 if (verdict == NF_ACCEPT) { 264 next_hook: 265 verdict = nf_iterate(&nf_hooks[info->pf][info->hook], 266 skb, info->hook, 267 info->indev, info->outdev, &elem, 268 info->okfn, INT_MIN); 269 } 270 271 switch (verdict & NF_VERDICT_MASK) { 272 case NF_ACCEPT: 273 case NF_STOP: 274 info->okfn(skb); 275 case NF_STOLEN: 276 break; 277 case NF_QUEUE: 278 if (!__nf_queue(skb, elem, info->pf, info->hook, 279 info->indev, info->outdev, info->okfn, 280 verdict >> NF_VERDICT_BITS)) 281 goto next_hook; 282 break; 283 default: 284 kfree_skb(skb); 285 } 286 rcu_read_unlock(); 287 kfree(info); 288 return; 289} 290EXPORT_SYMBOL(nf_reinject); 291 292#ifdef CONFIG_PROC_FS 293static void *seq_start(struct seq_file *seq, loff_t *pos) 294{ 295 if (*pos >= NPROTO) 296 return NULL; 297 298 return pos; 299} 300 301static void *seq_next(struct seq_file *s, void *v, loff_t *pos) 302{ 303 (*pos)++; 304 305 if (*pos >= NPROTO) 306 return NULL; 307 308 return pos; 309} 310 311static void seq_stop(struct seq_file *s, void *v) 312{ 313 314} 315 316static int seq_show(struct seq_file *s, void *v) 317{ 318 int ret; 319 loff_t *pos = v; 320 struct nf_queue_handler *qh; 321 322 rcu_read_lock(); 323 qh = rcu_dereference(queue_handler[*pos]); 324 if (!qh) 325 ret = seq_printf(s, "%2lld NONE\n", *pos); 326 else 327 ret = seq_printf(s, "%2lld %s\n", *pos, qh->name); 328 rcu_read_unlock(); 329 330 return ret; 331} 332 333static const struct seq_operations nfqueue_seq_ops = { 334 .start = seq_start, 335 .next = seq_next, 336 .stop = seq_stop, 337 .show = seq_show, 338}; 339 340static int nfqueue_open(struct inode *inode, struct file *file) 341{ 342 return seq_open(file, &nfqueue_seq_ops); 343} 344 345static const struct file_operations nfqueue_file_ops = { 346 .owner = THIS_MODULE, 347 .open = nfqueue_open, 348 .read = seq_read, 349 .llseek = seq_lseek, 350 .release = seq_release, 351}; 352#endif /* PROC_FS */ 353 354 355int __init netfilter_queue_init(void) 356{ 357#ifdef CONFIG_PROC_FS 358 struct proc_dir_entry *pde; 359 360 pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter); 361 if (!pde) 362 return -1; 363 pde->proc_fops = &nfqueue_file_ops; 364#endif 365 return 0; 366} 367