-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 78295 b: refs/heads/master c: 50c164a h: refs/heads/master i: 78293: f4bffe0 78291: 67f0779 78287: 6151adb v: v3
- Loading branch information
Patrick McHardy
authored and
David S. Miller
committed
Jan 28, 2008
1 parent
27f8945
commit 4f5e6cf
Showing
6 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 5859034d7eb8793d3d78d3af515c4175e7b9d03a | ||
refs/heads/master: 50c164a81f1c0dfad056f99e5685537fdd0f07dd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#ifndef _XT_RATEEST_MATCH_H | ||
#define _XT_RATEEST_MATCH_H | ||
|
||
enum xt_rateest_match_flags { | ||
XT_RATEEST_MATCH_INVERT = 1<<0, | ||
XT_RATEEST_MATCH_ABS = 1<<1, | ||
XT_RATEEST_MATCH_REL = 1<<2, | ||
XT_RATEEST_MATCH_DELTA = 1<<3, | ||
XT_RATEEST_MATCH_BPS = 1<<4, | ||
XT_RATEEST_MATCH_PPS = 1<<5, | ||
}; | ||
|
||
enum xt_rateest_match_mode { | ||
XT_RATEEST_MATCH_NONE, | ||
XT_RATEEST_MATCH_EQ, | ||
XT_RATEEST_MATCH_LT, | ||
XT_RATEEST_MATCH_GT, | ||
}; | ||
|
||
struct xt_rateest_match_info { | ||
char name1[IFNAMSIZ]; | ||
char name2[IFNAMSIZ]; | ||
u_int16_t flags; | ||
u_int16_t mode; | ||
u_int32_t bps1; | ||
u_int32_t pps1; | ||
u_int32_t bps2; | ||
u_int32_t pps2; | ||
struct xt_rateest *est1 __attribute__((aligned(8))); | ||
struct xt_rateest *est2 __attribute__((aligned(8))); | ||
}; | ||
|
||
#endif /* _XT_RATEEST_MATCH_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
/* | ||
* (C) 2007 Patrick McHardy <kaber@trash.net> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
#include <linux/module.h> | ||
#include <linux/skbuff.h> | ||
#include <linux/gen_stats.h> | ||
|
||
#include <linux/netfilter/x_tables.h> | ||
#include <linux/netfilter/xt_rateest.h> | ||
#include <net/netfilter/xt_rateest.h> | ||
|
||
|
||
static bool xt_rateest_mt(const struct sk_buff *skb, | ||
const struct net_device *in, | ||
const struct net_device *out, | ||
const struct xt_match *match, | ||
const void *matchinfo, | ||
int offset, | ||
unsigned int protoff, | ||
bool *hotdrop) | ||
{ | ||
const struct xt_rateest_match_info *info = matchinfo; | ||
struct gnet_stats_rate_est *r; | ||
u_int32_t bps1, bps2, pps1, pps2; | ||
bool ret = true; | ||
|
||
spin_lock_bh(&info->est1->lock); | ||
r = &info->est1->rstats; | ||
if (info->flags & XT_RATEEST_MATCH_DELTA) { | ||
bps1 = info->bps1 >= r->bps ? info->bps1 - r->bps : 0; | ||
pps1 = info->pps1 >= r->pps ? info->pps1 - r->pps : 0; | ||
} else { | ||
bps1 = r->bps; | ||
pps1 = r->pps; | ||
} | ||
spin_unlock_bh(&info->est1->lock); | ||
|
||
if (info->flags & XT_RATEEST_MATCH_ABS) { | ||
bps2 = info->bps2; | ||
pps2 = info->pps2; | ||
} else { | ||
spin_lock_bh(&info->est2->lock); | ||
r = &info->est2->rstats; | ||
if (info->flags & XT_RATEEST_MATCH_DELTA) { | ||
bps2 = info->bps2 >= r->bps ? info->bps2 - r->bps : 0; | ||
pps2 = info->pps2 >= r->pps ? info->pps2 - r->pps : 0; | ||
} else { | ||
bps2 = r->bps; | ||
pps2 = r->pps; | ||
} | ||
spin_unlock_bh(&info->est2->lock); | ||
} | ||
|
||
switch (info->mode) { | ||
case XT_RATEEST_MATCH_LT: | ||
if (info->flags & XT_RATEEST_MATCH_BPS) | ||
ret &= bps1 < bps2; | ||
if (info->flags & XT_RATEEST_MATCH_PPS) | ||
ret &= pps1 < pps2; | ||
break; | ||
case XT_RATEEST_MATCH_GT: | ||
if (info->flags & XT_RATEEST_MATCH_BPS) | ||
ret &= bps1 > bps2; | ||
if (info->flags & XT_RATEEST_MATCH_PPS) | ||
ret &= pps1 > pps2; | ||
break; | ||
case XT_RATEEST_MATCH_EQ: | ||
if (info->flags & XT_RATEEST_MATCH_BPS) | ||
ret &= bps1 == bps2; | ||
if (info->flags & XT_RATEEST_MATCH_PPS) | ||
ret &= pps2 == pps2; | ||
break; | ||
} | ||
|
||
ret ^= info->flags & XT_RATEEST_MATCH_INVERT ? true : false; | ||
return ret; | ||
} | ||
|
||
static bool xt_rateest_mt_checkentry(const char *tablename, | ||
const void *ip, | ||
const struct xt_match *match, | ||
void *matchinfo, | ||
unsigned int hook_mask) | ||
{ | ||
struct xt_rateest_match_info *info = (void *)matchinfo; | ||
struct xt_rateest *est1, *est2; | ||
|
||
if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | | ||
XT_RATEEST_MATCH_REL)) != 1) | ||
goto err1; | ||
|
||
if (!(info->flags & (XT_RATEEST_MATCH_BPS | XT_RATEEST_MATCH_PPS))) | ||
goto err1; | ||
|
||
switch (info->mode) { | ||
case XT_RATEEST_MATCH_EQ: | ||
case XT_RATEEST_MATCH_LT: | ||
case XT_RATEEST_MATCH_GT: | ||
break; | ||
default: | ||
goto err1; | ||
} | ||
|
||
est1 = xt_rateest_lookup(info->name1); | ||
if (!est1) | ||
goto err1; | ||
|
||
if (info->flags & XT_RATEEST_MATCH_REL) { | ||
est2 = xt_rateest_lookup(info->name2); | ||
if (!est2) | ||
goto err2; | ||
} else | ||
est2 = NULL; | ||
|
||
|
||
info->est1 = est1; | ||
info->est2 = est2; | ||
return true; | ||
|
||
err2: | ||
xt_rateest_put(est1); | ||
err1: | ||
return false; | ||
} | ||
|
||
static void xt_rateest_mt_destroy(const struct xt_match *match, | ||
void *matchinfo) | ||
{ | ||
struct xt_rateest_match_info *info = (void *)matchinfo; | ||
|
||
xt_rateest_put(info->est1); | ||
if (info->est2) | ||
xt_rateest_put(info->est2); | ||
} | ||
|
||
static struct xt_match xt_rateest_match[] __read_mostly = { | ||
{ | ||
.family = AF_INET, | ||
.name = "rateest", | ||
.match = xt_rateest_mt, | ||
.checkentry = xt_rateest_mt_checkentry, | ||
.destroy = xt_rateest_mt_destroy, | ||
.matchsize = sizeof(struct xt_rateest_match_info), | ||
.me = THIS_MODULE, | ||
}, | ||
{ | ||
.family = AF_INET6, | ||
.name = "rateest", | ||
.match = xt_rateest_mt, | ||
.checkentry = xt_rateest_mt_checkentry, | ||
.destroy = xt_rateest_mt_destroy, | ||
.matchsize = sizeof(struct xt_rateest_match_info), | ||
.me = THIS_MODULE, | ||
}, | ||
}; | ||
|
||
static int __init xt_rateest_mt_init(void) | ||
{ | ||
return xt_register_matches(xt_rateest_match, | ||
ARRAY_SIZE(xt_rateest_match)); | ||
} | ||
|
||
static void __exit xt_rateest_mt_fini(void) | ||
{ | ||
xt_unregister_matches(xt_rateest_match, ARRAY_SIZE(xt_rateest_match)); | ||
} | ||
|
||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_DESCRIPTION("xtables rate estimator match"); | ||
MODULE_ALIAS("ipt_rateest"); | ||
MODULE_ALIAS("ip6t_rateest"); | ||
module_init(xt_rateest_mt_init); | ||
module_exit(xt_rateest_mt_fini); |