21
21
#include "xt_quota2.h"
22
22
#include "compat_xtables.h"
24
struct quota_counter {
25
* @lock: lock to protect quota writers from each other
27
struct xt_quota_counter {
27
30
struct list_head list;
29
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
32
char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)];
30
33
struct proc_dir_entry *procfs_entry;
44
47
static int quota_proc_read(char *page, char **start, off_t offset,
45
48
int count, int *eof, void *data)
47
struct quota_counter *e = data;
50
struct xt_quota_counter *e = data;
50
53
spin_lock_bh(&e->lock);
56
59
static int quota_proc_write(struct file *file, const char __user *input,
57
60
unsigned long size, void *data)
59
struct quota_counter *e = data;
62
struct xt_quota_counter *e = data;
60
63
char buf[sizeof("18446744073709551616")];
62
65
if (size > sizeof(buf))
66
69
buf[sizeof(buf)-1] = '\0';
68
71
spin_lock_bh(&e->lock);
69
e->quota = simple_strtoul(buf, NULL, 0);
72
e->quota = simple_strtoull(buf, NULL, 0);
70
73
spin_unlock_bh(&e->lock);
77
static struct xt_quota_counter *
78
q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
80
struct xt_quota_counter *e;
83
/* Do not need all the procfs things for anonymous counters. */
84
size = anon ? offsetof(typeof(*e), list) : sizeof(*e);
85
e = kmalloc(size, GFP_KERNEL);
90
spin_lock_init(&e->lock);
92
INIT_LIST_HEAD(&e->list);
93
atomic_set(&e->ref, 1);
94
strncpy(e->name, q->name, sizeof(e->name));
75
100
* q2_get_counter - get ref to counter or create new
76
101
* @name: name of counter
78
static struct quota_counter *q2_get_counter(const struct xt_quota_mtinfo2 *q)
103
static struct xt_quota_counter *
104
q2_get_counter(const struct xt_quota_mtinfo2 *q)
80
106
struct proc_dir_entry *p;
81
struct quota_counter *e;
107
struct xt_quota_counter *e;
109
if (*q->name == '\0')
110
return q2_new_counter(q, true);
83
112
spin_lock_bh(&counter_list_lock);
84
list_for_each_entry(e, &counter_list, list) {
113
list_for_each_entry(e, &counter_list, list)
85
114
if (strcmp(e->name, q->name) == 0) {
86
115
atomic_inc(&e->ref);
87
116
spin_unlock_bh(&counter_list_lock);
92
e = kmalloc(sizeof(struct quota_counter), GFP_KERNEL);
120
e = q2_new_counter(q, false);
97
spin_lock_init(&e->lock);
98
INIT_LIST_HEAD(&e->list);
99
atomic_set(&e->ref, 1);
100
strncpy(e->name, q->name, sizeof(e->name));
102
124
p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
104
126
if (p == NULL || IS_ERR(p))
132
154
q->name[sizeof(q->name)-1] = '\0';
133
if (*q->name == '\0' || *q->name == '.' ||
134
strchr(q->name, '/') != NULL) {
135
printk(KERN_ERR "xt_quota.2: illegal name\n");
155
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
156
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
157
par->match->revision);
139
161
q->master = q2_get_counter(q);
140
162
if (q->master == NULL) {
141
printk(KERN_ERR "xt_quota.2: memory alloc failure\n");
163
printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
164
par->match->revision);
148
171
static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
150
173
struct xt_quota_mtinfo2 *q = par->matchinfo;
151
struct quota_counter *e = q->master;
174
struct xt_quota_counter *e = q->master;
176
if (*q->name == '\0') {
153
181
spin_lock_bh(&counter_list_lock);
154
182
if (!atomic_dec_and_test(&e->ref)) {
166
194
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
168
196
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
169
struct quota_counter *e = q->master;
197
struct xt_quota_counter *e = q->master;
170
198
bool ret = q->flags & XT_QUOTA_INVERT;
200
spin_lock_bh(&e->lock);
172
201
if (q->flags & XT_QUOTA_GROW) {
173
spin_lock_bh(&e->lock);
174
202
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
175
203
q->quota = e->quota;
176
spin_unlock_bh(&e->lock);
179
spin_lock_bh(&e->lock);
180
206
if (e->quota >= skb->len) {
181
207
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;