This add support for quota per destination ip to quota match.
Subsystems (2)
PATCH 1/1 This add support for quota per destination ip to quota match.
Please, I wan 't to hear commentaries about this. I 'm newbie...
include/linux/netfilter_ipv4/ipt_quota.h +20 -0
@@ -0,0 +1,20 @@ +#ifndef _IPT_QUOTA_H +#define _IPT_QUOTA_H + +#include <linux/list.h> + +/* print debug info in both kernel/netfilter module & iptable library */ +/* #define DEBUG_IPT_QUOTA */ + +#define IPT_QUOTA 0x0001 +#define IPT_IPDSTQUOTA 0x0002 +#define IPT_QUOTA_FLAG_NEGATE 0x0004 +#define IPT_QUOTA_FLAG_COUNT_FULL 0x0009 + +struct ipt_quota_info { +u_int64_t quota; +u_int16_t flags; +struct list_head *ipquota_hash; +}; + +#endif /*_IPT_QUOTA_H*/
net/ipv4/netfilter/ipt_quota.c +381 -0
381 lines not on this page · raw message
dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT
$CONFIG_IP_NF_IPTABLES
dep_tristate ' quota match support' CONFIG_IP_NF_MATCH_QUOTA
$CONFIG_IP_NF_IPTABLESCONFIG_IP_NF_MATCH_LIMIT
quota match supportCONFIG_IP_NF_MATCH_QUOTA
This match implements network quotas and quotas per destination ip.
If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say `N'.
Author: Sam Johnston <[email protected]>
Status: worksforme
This option adds CONFIG_IP_NF_MATCH_QUOTA, which implements network quotas by decrementing a byte counter with each packet. Also implements quota per destination ip address.
(Diego Woitasen <[email protected]>)
Supported options are:
--quota <bytes>
The quota in bytes.
--ipdstquota <bytes>
The quota per destination ip address in bytes
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
/*
* Shared library add-on to iptables to add quota support
*
* Sam Johnston <[email protected]>
*
* 2003/04/02 Diego Woitasen ([email protected]) add quota per dst ip *
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ipt_quota.h>
#include <linux/netfilter_ipv4/ip_tables.h>
static struct option opts[] = {
{"quota", 1, 0, IPT_QUOTA},
{"ipdstquota", 1, 0, IPT_IPDSTQUOTA}, {"count-headers", 0, 0, IPT_QUOTA_FLAG_COUNT_FULL}, {0}
};
/* print usage */
static void
help (void)
{
printf ("quota options:\n\n"
" --quota [!] quota quota (bytes)\n" " --ipdstquota [!] quota quota per ip (bytes)\n" "\n" " --count-headers count headers as well as data\n"); }
/* initialise match */
static void
init (struct ipt_entry_match *m, unsigned int *nfcache) {
struct ipt_quota_info *info = (struct ipt_quota_info *) m->data; info->flags = 0; info->quota = 0; info->ipquota_hash = NULL; /* no can cache */ *nfcache |= NFC_UNKNOWN;
}
/* print matchinfo */
static void
print (const struct ipt_ip *ip, const struct ipt_entry_match *match,
int numeric)
{
struct ipt_quota_info *q = (struct ipt_quota_info *) match->data;
if (IPT_QUOTA & q->flags)
printf ("quota");
else if (IPT_IPDSTQUOTA & q->flags)
printf ("ipdstquota");
if (IPT_QUOTA_FLAG_NEGATE & q->flags)
printf (" ! ");
printf ("%llu bytes", (unsigned long long) q->quota);
if (IPT_QUOTA_FLAG_COUNT_FULL & q->flags)
printf (" (incl. headers)");}
/* save matchinfo */
static void
save (const struct ipt_ip *ip, const struct ipt_entry_match *match) {
struct ipt_quota_info *q = (struct ipt_quota_info *) match->data;
if (IPT_QUOTA & q->flags)
printf ("--quota");
else if (IPT_IPDSTQUOTA & q->flags)
printf ("--ipdstquota");
if (IPT_QUOTA_FLAG_NEGATE & q->flags)
printf (" ! ");
printf (" %llu", (unsigned long long) q->quota);
if (IPT_QUOTA_FLAG_COUNT_FULL & q->flags)
printf (" --count-headers");}
/* parse quota option */
static intparse_quota (const char *s, struct ipt_quota_info *quota, int c) {
if (s && (*s == '-'))
exit_error (PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
quota->quota = strtoull (s, (char **) NULL, 10);#ifdef DEBUG_IPT_QUOTA
printf ("Quota: %llu\n", quota->quota);
#endif
if (quota->quota == -1)
exit_error (PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
else
return 1;}
/* parse all options, returning true if we found any for us */ static int
parse (int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
unsigned int *nfcache, struct ipt_entry_match **match)
{
struct ipt_quota_info *info = (struct ipt_quota_info *) (*match)->data;
switch (c)
{
case IPT_QUOTA_FLAG_COUNT_FULL:
if (check_inverse (optarg, &invert, NULL, 0))
exit_error (PARAMETER_PROBLEM, "count-headers: unexpected '!'");
info->flags |= IPT_QUOTA_FLAG_COUNT_FULL;
break;
case IPT_QUOTA:
case IPT_IPDSTQUOTA:
if ((info->flags & IPT_QUOTA) && (info->flags & IPT_IPDSTQUOTA))
exit_error (PARAMETER_PROBLEM,
"syntax error: you can't use --quota and --ipdstquota");
check_inverse (optarg, &invert, &optind, 0);
if (invert)
info->flags |= IPT_QUOTA_FLAG_NEGATE;
parse_quota (argv[optind - 1], info, c);
info->flags |= (u_int16_t) c;
*flags = 1;
break;
default:
exit_error (PARAMETER_PROBLEM, "unknown option: try --help");
return 0;
} return 1;
}
/* no final check */
static voidfinal_check (unsigned int flags)
{
if (flags != 1)
exit_error (PARAMETER_PROBLEM, "quota: missing arguments");}
struct iptables_match quota = { NULL,
"quota",
NETFILTER_VERSION,
IPT_ALIGN (sizeof (struct ipt_quota_info)),
IPT_ALIGN (sizeof (struct ipt_quota_info)),
&help,
&init,
&parse,
&final_check,
&print,
&save,
opts
};
void_init (void)
{
register_match ("a);
}
Quoted 1 line · Diego Woitasen
Please, I wan 't to hear commentaries about this. I 'm newbie...
Please submit this to the author of the quota match. Send it as a patch against patch-o-matic. And don't wrap lines.
A change like this has to go through the original author unless he/she/it doesn't want to touch the stuff anymore.
Personally I'd like to see one more feature, the ability to have quota per source ip as well.
Signature · 1 line
/Martin