1/* iptables match extension to limit the number of packets per second 2 * seperately for each hashbucket (sourceip/sourceport/dstip/dstport) 3 * 4 * (C) 2003-2004 by Harald Welte <laforge@netfilter.org> 5 * 6 * $Id: xt_hashlimit.c,v 1.1.1.1 2007/08/03 18:53:54 Exp $ 7 * 8 * Development of this code was funded by Astaro AG, http://www.astaro.com/ 9 */ 10#include <linux/module.h> 11#include <linux/spinlock.h> 12#include <linux/random.h> 13#include <linux/jhash.h> 14#include <linux/slab.h> 15#include <linux/vmalloc.h> 16#include <linux/proc_fs.h> 17#include <linux/seq_file.h> 18#include <linux/list.h> 19#include <linux/skbuff.h> 20#include <linux/mm.h> 21#include <linux/in.h> 22#include <linux/ip.h> 23#include <linux/ipv6.h> 24 25#include <linux/netfilter/x_tables.h> 26#include <linux/netfilter_ipv4/ip_tables.h> 27#include <linux/netfilter_ipv6/ip6_tables.h> 28#include <linux/netfilter/xt_hashlimit.h> 29#include <linux/mutex.h> 30 31MODULE_LICENSE("GPL"); 32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 33MODULE_DESCRIPTION("iptables match for limiting per hash-bucket"); 34MODULE_ALIAS("ipt_hashlimit"); 35MODULE_ALIAS("ip6t_hashlimit"); 36 37/* need to declare this at the top */ 38static struct proc_dir_entry *hashlimit_procdir4; 39static struct proc_dir_entry *hashlimit_procdir6; 40static const struct file_operations dl_file_ops; 41 42/* hash table crap */ 43struct dsthash_dst { 44 union { 45 struct { 46 __be32 src; 47 __be32 dst; 48 } ip; 49 struct { 50 __be32 src[4]; 51 __be32 dst[4]; 52 } ip6; 53 } addr; 54 __be16 src_port; 55 __be16 dst_port; 56}; 57 58struct dsthash_ent { 59 /* static / read-only parts in the beginning */ 60 struct hlist_node node; 61 struct dsthash_dst dst; 62 63 /* modified structure members in the end */ 64 unsigned long expires; /* precalculated expiry time */ 65 struct { 66 unsigned long prev; /* last modification */ 67 u_int32_t credit; 68 u_int32_t credit_cap, cost; 69 } rateinfo; 70}; 71 72struct xt_hashlimit_htable { 73 struct hlist_node node; /* global list of all htables */ 74 atomic_t use; 75 int family; 76 77 struct hashlimit_cfg cfg; /* config */ 78 79 /* used internally */ 80 spinlock_t lock; /* lock for list_head */ 81 u_int32_t rnd; /* random seed for hash */ 82 int rnd_initialized; 83 unsigned int count; /* number entries in table */ 84 struct timer_list timer; /* timer for gc */ 85 86 /* seq_file stuff */ 87 struct proc_dir_entry *pde; 88 89 struct hlist_head hash[0]; /* hashtable itself */ 90}; 91 92static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */ 93static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */ 94static HLIST_HEAD(hashlimit_htables); 95static struct kmem_cache *hashlimit_cachep __read_mostly; 96 97static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b) 98{ 99 return !memcmp(&ent->dst, b, sizeof(ent->dst)); 100} 101 102static u_int32_t 103hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst) 104{ 105 return jhash(dst, sizeof(*dst), ht->rnd) % ht->cfg.size; 106} 107 108static struct dsthash_ent * 109dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst) 110{ 111 struct dsthash_ent *ent; 112 struct hlist_node *pos; 113 u_int32_t hash = hash_dst(ht, dst); 114 115 if (!hlist_empty(&ht->hash[hash])) { 116 hlist_for_each_entry(ent, pos, &ht->hash[hash], node) 117 if (dst_cmp(ent, dst)) 118 return ent; 119 } 120 return NULL; 121} 122 123/* allocate dsthash_ent, initialize dst, put in htable and lock it */ 124static struct dsthash_ent * 125dsthash_alloc_init(struct xt_hashlimit_htable *ht, struct dsthash_dst *dst) 126{ 127 struct dsthash_ent *ent; 128 129 /* initialize hash with random val at the time we allocate 130 * the first hashtable entry */ 131 if (!ht->rnd_initialized) { 132 get_random_bytes(&ht->rnd, 4); 133 ht->rnd_initialized = 1; 134 } 135 136 if (ht->cfg.max && ht->count >= ht->cfg.max) { 137 if (net_ratelimit()) 138 printk(KERN_WARNING 139 "xt_hashlimit: max count of %u reached\n", 140 ht->cfg.max); 141 return NULL; 142 } 143 144 ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC); 145 if (!ent) { 146 if (net_ratelimit()) 147 printk(KERN_ERR 148 "xt_hashlimit: can't allocate dsthash_ent\n"); 149 return NULL; 150 } 151 memcpy(&ent->dst, dst, sizeof(ent->dst)); 152 153 hlist_add_head(&ent->node, &ht->hash[hash_dst(ht, dst)]); 154 ht->count++; 155 return ent; 156} 157 158static inline void 159dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent) 160{ 161 hlist_del(&ent->node); 162 kmem_cache_free(hashlimit_cachep, ent); 163 ht->count--; 164} 165static void htable_gc(unsigned long htlong); 166 167static int htable_create(struct xt_hashlimit_info *minfo, int family) 168{ 169 struct xt_hashlimit_htable *hinfo; 170 unsigned int size; 171 unsigned int i; 172 173 if (minfo->cfg.size) 174 size = minfo->cfg.size; 175 else { 176 size = ((num_physpages << PAGE_SHIFT) / 16384) / 177 sizeof(struct list_head); 178 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE)) 179 size = 8192; 180 if (size < 16) 181 size = 16; 182 } 183 hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + 184 sizeof(struct list_head) * size); 185 if (!hinfo) { 186 printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n"); 187 return -1; 188 } 189 minfo->hinfo = hinfo; 190 191 /* copy match config into hashtable config */ 192 memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg)); 193 hinfo->cfg.size = size; 194 if (!hinfo->cfg.max) 195 hinfo->cfg.max = 8 * hinfo->cfg.size; 196 else if (hinfo->cfg.max < hinfo->cfg.size) 197 hinfo->cfg.max = hinfo->cfg.size; 198 199 for (i = 0; i < hinfo->cfg.size; i++) 200 INIT_HLIST_HEAD(&hinfo->hash[i]); 201 202 atomic_set(&hinfo->use, 1); 203 hinfo->count = 0; 204 hinfo->family = family; 205 hinfo->rnd_initialized = 0; 206 spin_lock_init(&hinfo->lock); 207 hinfo->pde = create_proc_entry(minfo->name, 0, 208 family == AF_INET ? hashlimit_procdir4 : 209 hashlimit_procdir6); 210 if (!hinfo->pde) { 211 vfree(hinfo); 212 return -1; 213 } 214 hinfo->pde->proc_fops = &dl_file_ops; 215 hinfo->pde->data = hinfo; 216 217 setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo); 218 hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval); 219 add_timer(&hinfo->timer); 220 221 spin_lock_bh(&hashlimit_lock); 222 hlist_add_head(&hinfo->node, &hashlimit_htables); 223 spin_unlock_bh(&hashlimit_lock); 224 225 return 0; 226} 227 228static int select_all(struct xt_hashlimit_htable *ht, struct dsthash_ent *he) 229{ 230 return 1; 231} 232 233static int select_gc(struct xt_hashlimit_htable *ht, struct dsthash_ent *he) 234{ 235 return (jiffies >= he->expires); 236} 237 238static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, 239 int (*select)(struct xt_hashlimit_htable *ht, 240 struct dsthash_ent *he)) 241{ 242 unsigned int i; 243 244 /* lock hash table and iterate over it */ 245 spin_lock_bh(&ht->lock); 246 for (i = 0; i < ht->cfg.size; i++) { 247 struct dsthash_ent *dh; 248 struct hlist_node *pos, *n; 249 hlist_for_each_entry_safe(dh, pos, n, &ht->hash[i], node) { 250 if ((*select)(ht, dh)) 251 dsthash_free(ht, dh); 252 } 253 } 254 spin_unlock_bh(&ht->lock); 255} 256 257/* hash table garbage collector, run by timer */ 258static void htable_gc(unsigned long htlong) 259{ 260 struct xt_hashlimit_htable *ht = (struct xt_hashlimit_htable *)htlong; 261 262 htable_selective_cleanup(ht, select_gc); 263 264 /* re-add the timer accordingly */ 265 ht->timer.expires = jiffies + msecs_to_jiffies(ht->cfg.gc_interval); 266 add_timer(&ht->timer); 267} 268 269static void htable_destroy(struct xt_hashlimit_htable *hinfo) 270{ 271 /* remove timer, if it is pending */ 272 if (timer_pending(&hinfo->timer)) 273 del_timer(&hinfo->timer); 274 275 /* remove proc entry */ 276 remove_proc_entry(hinfo->pde->name, 277 hinfo->family == AF_INET ? hashlimit_procdir4 : 278 hashlimit_procdir6); 279 htable_selective_cleanup(hinfo, select_all); 280 vfree(hinfo); 281} 282 283static struct xt_hashlimit_htable *htable_find_get(char *name, int family) 284{ 285 struct xt_hashlimit_htable *hinfo; 286 struct hlist_node *pos; 287 288 spin_lock_bh(&hashlimit_lock); 289 hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) { 290 if (!strcmp(name, hinfo->pde->name) && 291 hinfo->family == family) { 292 atomic_inc(&hinfo->use); 293 spin_unlock_bh(&hashlimit_lock); 294 return hinfo; 295 } 296 } 297 spin_unlock_bh(&hashlimit_lock); 298 return NULL; 299} 300 301static void htable_put(struct xt_hashlimit_htable *hinfo) 302{ 303 if (atomic_dec_and_test(&hinfo->use)) { 304 spin_lock_bh(&hashlimit_lock); 305 hlist_del(&hinfo->node); 306 spin_unlock_bh(&hashlimit_lock); 307 htable_destroy(hinfo); 308 } 309} 310 311/* The algorithm used is the Simple Token Bucket Filter (TBF) 312 * see net/sched/sch_tbf.c in the linux source tree 313 */ 314 315/* Rusty: This is my (non-mathematically-inclined) understanding of 316 this algorithm. The `average rate' in jiffies becomes your initial 317 amount of credit `credit' and the most credit you can ever have 318 `credit_cap'. The `peak rate' becomes the cost of passing the 319 test, `cost'. 320 321 `prev' tracks the last packet hit: you gain one credit per jiffy. 322 If you get credit balance more than this, the extra credit is 323 discarded. Every time the match passes, you lose `cost' credits; 324 if you don't have that many, the test fails. 325 326 See Alexey's formal explanation in net/sched/sch_tbf.c. 327 328 To get the maximum range, we multiply by this factor (ie. you get N 329 credits per jiffy). We want to allow a rate as low as 1 per day 330 (slowest userspace tool allows), which means 331 CREDITS_PER_JIFFY*HZ*60*60*24 < 2^32 ie. 332*/ 333#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24)) 334 335/* Repeated shift and or gives us all 1s, final shift and add 1 gives 336 * us the power of 2 below the theoretical max, so GCC simply does a 337 * shift. */ 338#define _POW2_BELOW2(x) ((x)|((x)>>1)) 339#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2)) 340#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4)) 341#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8)) 342#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16)) 343#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1) 344 345#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 346 347/* Precision saver. */ 348static inline u_int32_t 349user2credits(u_int32_t user) 350{ 351 /* If multiplying would overflow... */ 352 if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 353 /* Divide first. */ 354 return (user / XT_HASHLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 355 356 return (user * HZ * CREDITS_PER_JIFFY) / XT_HASHLIMIT_SCALE; 357} 358 359static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) 360{ 361 dh->rateinfo.credit += (now - dh->rateinfo.prev) * CREDITS_PER_JIFFY; 362 if (dh->rateinfo.credit > dh->rateinfo.credit_cap) 363 dh->rateinfo.credit = dh->rateinfo.credit_cap; 364 dh->rateinfo.prev = now; 365} 366 367static int 368hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst, 369 const struct sk_buff *skb, unsigned int protoff) 370{ 371 __be16 _ports[2], *ports; 372 int nexthdr; 373 374 memset(dst, 0, sizeof(*dst)); 375 376 switch (hinfo->family) { 377 case AF_INET: 378 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) 379 dst->addr.ip.dst = ip_hdr(skb)->daddr; 380 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP) 381 dst->addr.ip.src = ip_hdr(skb)->saddr; 382 383 if (!(hinfo->cfg.mode & 384 (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT))) 385 return 0; 386 nexthdr = ip_hdr(skb)->protocol; 387 break; 388#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 389 case AF_INET6: 390 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) 391 memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr, 392 sizeof(dst->addr.ip6.dst)); 393 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP) 394 memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr, 395 sizeof(dst->addr.ip6.src)); 396 397 if (!(hinfo->cfg.mode & 398 (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT))) 399 return 0; 400 nexthdr = ipv6_find_hdr(skb, &protoff, -1, NULL); 401 if (nexthdr < 0) 402 return -1; 403 break; 404#endif 405 default: 406 BUG(); 407 return 0; 408 } 409 410 switch (nexthdr) { 411 case IPPROTO_TCP: 412 case IPPROTO_UDP: 413 case IPPROTO_UDPLITE: 414 case IPPROTO_SCTP: 415 case IPPROTO_DCCP: 416 ports = skb_header_pointer(skb, protoff, sizeof(_ports), 417 &_ports); 418 break; 419 default: 420 _ports[0] = _ports[1] = 0; 421 ports = _ports; 422 break; 423 } 424 if (!ports) 425 return -1; 426 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SPT) 427 dst->src_port = ports[0]; 428 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DPT) 429 dst->dst_port = ports[1]; 430 return 0; 431} 432 433static int 434hashlimit_match(const struct sk_buff *skb, 435 const struct net_device *in, 436 const struct net_device *out, 437 const struct xt_match *match, 438 const void *matchinfo, 439 int offset, 440 unsigned int protoff, 441 int *hotdrop) 442{ 443 struct xt_hashlimit_info *r = 444 ((struct xt_hashlimit_info *)matchinfo)->u.master; 445 struct xt_hashlimit_htable *hinfo = r->hinfo; 446 unsigned long now = jiffies; 447 struct dsthash_ent *dh; 448 struct dsthash_dst dst; 449 450 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0) 451 goto hotdrop; 452 453 spin_lock_bh(&hinfo->lock); 454 dh = dsthash_find(hinfo, &dst); 455 if (!dh) { 456 dh = dsthash_alloc_init(hinfo, &dst); 457 if (!dh) { 458 spin_unlock_bh(&hinfo->lock); 459 goto hotdrop; 460 } 461 462 dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire); 463 dh->rateinfo.prev = jiffies; 464 dh->rateinfo.credit = user2credits(hinfo->cfg.avg * 465 hinfo->cfg.burst); 466 dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * 467 hinfo->cfg.burst); 468 dh->rateinfo.cost = user2credits(hinfo->cfg.avg); 469 } else { 470 /* update expiration timeout */ 471 dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); 472 rateinfo_recalc(dh, now); 473 } 474 475 if (dh->rateinfo.credit >= dh->rateinfo.cost) { 476 /* We're underlimit. */ 477 dh->rateinfo.credit -= dh->rateinfo.cost; 478 spin_unlock_bh(&hinfo->lock); 479 return 1; 480 } 481 482 spin_unlock_bh(&hinfo->lock); 483 484 /* default case: we're overlimit, thus don't match */ 485 return 0; 486 487hotdrop: 488 *hotdrop = 1; 489 return 0; 490} 491 492static int 493hashlimit_checkentry(const char *tablename, 494 const void *inf, 495 const struct xt_match *match, 496 void *matchinfo, 497 unsigned int hook_mask) 498{ 499 struct xt_hashlimit_info *r = matchinfo; 500 501 /* Check for overflow. */ 502 if (r->cfg.burst == 0 || 503 user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) { 504 printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n", 505 r->cfg.avg, r->cfg.burst); 506 return 0; 507 } 508 if (r->cfg.mode == 0 || 509 r->cfg.mode > (XT_HASHLIMIT_HASH_DPT | 510 XT_HASHLIMIT_HASH_DIP | 511 XT_HASHLIMIT_HASH_SIP | 512 XT_HASHLIMIT_HASH_SPT)) 513 return 0; 514 if (!r->cfg.gc_interval) 515 return 0; 516 if (!r->cfg.expire) 517 return 0; 518 if (r->name[sizeof(r->name) - 1] != '\0') 519 return 0; 520 521 /* This is the best we've got: We cannot release and re-grab lock, 522 * since checkentry() is called before x_tables.c grabs xt_mutex. 523 * We also cannot grab the hashtable spinlock, since htable_create will 524 * call vmalloc, and that can sleep. And we cannot just re-search 525 * the list of htable's in htable_create(), since then we would 526 * create duplicate proc files. -HW */ 527 mutex_lock(&hlimit_mutex); 528 r->hinfo = htable_find_get(r->name, match->family); 529 if (!r->hinfo && htable_create(r, match->family) != 0) { 530 mutex_unlock(&hlimit_mutex); 531 return 0; 532 } 533 mutex_unlock(&hlimit_mutex); 534 535 /* Ugly hack: For SMP, we only want to use one set */ 536 r->u.master = r; 537 return 1; 538} 539 540static void 541hashlimit_destroy(const struct xt_match *match, void *matchinfo) 542{ 543 struct xt_hashlimit_info *r = matchinfo; 544 545 htable_put(r->hinfo); 546} 547 548#ifdef CONFIG_COMPAT 549struct compat_xt_hashlimit_info { 550 char name[IFNAMSIZ]; 551 struct hashlimit_cfg cfg; 552 compat_uptr_t hinfo; 553 compat_uptr_t master; 554}; 555 556static void compat_from_user(void *dst, void *src) 557{ 558 int off = offsetof(struct compat_xt_hashlimit_info, hinfo); 559 560 memcpy(dst, src, off); 561 memset(dst + off, 0, sizeof(struct compat_xt_hashlimit_info) - off); 562} 563 564static int compat_to_user(void __user *dst, void *src) 565{ 566 int off = offsetof(struct compat_xt_hashlimit_info, hinfo); 567 568 return copy_to_user(dst, src, off) ? -EFAULT : 0; 569} 570#endif 571 572static struct xt_match xt_hashlimit[] = { 573 { 574 .name = "hashlimit", 575 .family = AF_INET, 576 .match = hashlimit_match, 577 .matchsize = sizeof(struct xt_hashlimit_info), 578#ifdef CONFIG_COMPAT 579 .compatsize = sizeof(struct compat_xt_hashlimit_info), 580 .compat_from_user = compat_from_user, 581 .compat_to_user = compat_to_user, 582#endif 583 .checkentry = hashlimit_checkentry, 584 .destroy = hashlimit_destroy, 585 .me = THIS_MODULE 586 }, 587 { 588 .name = "hashlimit", 589 .family = AF_INET6, 590 .match = hashlimit_match, 591 .matchsize = sizeof(struct xt_hashlimit_info), 592#ifdef CONFIG_COMPAT 593 .compatsize = sizeof(struct compat_xt_hashlimit_info), 594 .compat_from_user = compat_from_user, 595 .compat_to_user = compat_to_user, 596#endif 597 .checkentry = hashlimit_checkentry, 598 .destroy = hashlimit_destroy, 599 .me = THIS_MODULE 600 }, 601}; 602 603/* PROC stuff */ 604static void *dl_seq_start(struct seq_file *s, loff_t *pos) 605{ 606 struct proc_dir_entry *pde = s->private; 607 struct xt_hashlimit_htable *htable = pde->data; 608 unsigned int *bucket; 609 610 spin_lock_bh(&htable->lock); 611 if (*pos >= htable->cfg.size) 612 return NULL; 613 614 bucket = kmalloc(sizeof(unsigned int), GFP_ATOMIC); 615 if (!bucket) 616 return ERR_PTR(-ENOMEM); 617 618 *bucket = *pos; 619 return bucket; 620} 621 622static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos) 623{ 624 struct proc_dir_entry *pde = s->private; 625 struct xt_hashlimit_htable *htable = pde->data; 626 unsigned int *bucket = (unsigned int *)v; 627 628 *pos = ++(*bucket); 629 if (*pos >= htable->cfg.size) { 630 kfree(v); 631 return NULL; 632 } 633 return bucket; 634} 635 636static void dl_seq_stop(struct seq_file *s, void *v) 637{ 638 struct proc_dir_entry *pde = s->private; 639 struct xt_hashlimit_htable *htable = pde->data; 640 unsigned int *bucket = (unsigned int *)v; 641 642 kfree(bucket); 643 spin_unlock_bh(&htable->lock); 644} 645 646static int dl_seq_real_show(struct dsthash_ent *ent, int family, 647 struct seq_file *s) 648{ 649 /* recalculate to show accurate numbers */ 650 rateinfo_recalc(ent, jiffies); 651 652 switch (family) { 653 case AF_INET: 654 return seq_printf(s, "%ld %u.%u.%u.%u:%u->" 655 "%u.%u.%u.%u:%u %u %u %u\n", 656 (long)(ent->expires - jiffies)/HZ, 657 NIPQUAD(ent->dst.addr.ip.src), 658 ntohs(ent->dst.src_port), 659 NIPQUAD(ent->dst.addr.ip.dst), 660 ntohs(ent->dst.dst_port), 661 ent->rateinfo.credit, ent->rateinfo.credit_cap, 662 ent->rateinfo.cost); 663 case AF_INET6: 664 return seq_printf(s, "%ld " NIP6_FMT ":%u->" 665 NIP6_FMT ":%u %u %u %u\n", 666 (long)(ent->expires - jiffies)/HZ, 667 NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.src), 668 ntohs(ent->dst.src_port), 669 NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.dst), 670 ntohs(ent->dst.dst_port), 671 ent->rateinfo.credit, ent->rateinfo.credit_cap, 672 ent->rateinfo.cost); 673 default: 674 BUG(); 675 return 0; 676 } 677} 678 679static int dl_seq_show(struct seq_file *s, void *v) 680{ 681 struct proc_dir_entry *pde = s->private; 682 struct xt_hashlimit_htable *htable = pde->data; 683 unsigned int *bucket = (unsigned int *)v; 684 struct dsthash_ent *ent; 685 struct hlist_node *pos; 686 687 if (!hlist_empty(&htable->hash[*bucket])) { 688 hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node) 689 if (dl_seq_real_show(ent, htable->family, s)) 690 return 1; 691 } 692 return 0; 693} 694 695static struct seq_operations dl_seq_ops = { 696 .start = dl_seq_start, 697 .next = dl_seq_next, 698 .stop = dl_seq_stop, 699 .show = dl_seq_show 700}; 701 702static int dl_proc_open(struct inode *inode, struct file *file) 703{ 704 int ret = seq_open(file, &dl_seq_ops); 705 706 if (!ret) { 707 struct seq_file *sf = file->private_data; 708 sf->private = PDE(inode); 709 } 710 return ret; 711} 712 713static const struct file_operations dl_file_ops = { 714 .owner = THIS_MODULE, 715 .open = dl_proc_open, 716 .read = seq_read, 717 .llseek = seq_lseek, 718 .release = seq_release 719}; 720 721static int __init xt_hashlimit_init(void) 722{ 723 int err; 724 725 err = xt_register_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit)); 726 if (err < 0) 727 goto err1; 728 729 err = -ENOMEM; 730 hashlimit_cachep = kmem_cache_create("xt_hashlimit", 731 sizeof(struct dsthash_ent), 0, 0, 732 NULL, NULL); 733 if (!hashlimit_cachep) { 734 printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n"); 735 goto err2; 736 } 737 hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", proc_net); 738 if (!hashlimit_procdir4) { 739 printk(KERN_ERR "xt_hashlimit: unable to create proc dir " 740 "entry\n"); 741 goto err3; 742 } 743 hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net); 744 if (!hashlimit_procdir6) { 745 printk(KERN_ERR "xt_hashlimit: unable to create proc dir " 746 "entry\n"); 747 goto err4; 748 } 749 return 0; 750err4: 751 remove_proc_entry("ipt_hashlimit", proc_net); 752err3: 753 kmem_cache_destroy(hashlimit_cachep); 754err2: 755 xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit)); 756err1: 757 return err; 758 759} 760 761static void __exit xt_hashlimit_fini(void) 762{ 763 remove_proc_entry("ipt_hashlimit", proc_net); 764 remove_proc_entry("ip6t_hashlimit", proc_net); 765 kmem_cache_destroy(hashlimit_cachep); 766 xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit)); 767} 768 769module_init(xt_hashlimit_init); 770module_exit(xt_hashlimit_fini); 771