~ubuntu-branches/ubuntu/precise/xtables-addons/precise-updates

« back to all changes in this revision

Viewing changes to extensions/ipset-6/xt_set.c

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2011-08-07 20:48:13 UTC
  • mfrom: (1.3.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20110807204813-lqf8ovq06adveq3j
Tags: 1.37-1
Imported Upstream version 1.37
This will trigger a rebuild and fix version on iptables libs
(Closes: #636905)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
static inline int
31
31
match_set(ip_set_id_t index, const struct sk_buff *skb,
32
 
          u8 pf, u8 dim, u8 flags, int inv)
 
32
          const struct xt_action_param *par,
 
33
          const struct ip_set_adt_opt *opt, int inv)
33
34
{
34
 
        if (ip_set_test(index, skb, pf, dim, flags))
 
35
        if (ip_set_test(index, skb, par, opt))
35
36
                inv = !inv;
36
37
        return inv;
37
38
}
38
39
 
 
40
#define ADT_OPT(n, f, d, fs, cfs, t)    \
 
41
const struct ip_set_adt_opt n = {       \
 
42
        .family = f,                    \
 
43
        .dim = d,                       \
 
44
        .flags = fs,                    \
 
45
        .cmdflags = cfs,                \
 
46
        .timeout = t,                   \
 
47
}
 
48
 
39
49
/* Revision 0 interface: backward compatible with netfilter/iptables */
40
50
 
41
 
/* Backward compatibility constrains (incomplete):
42
 
 *  2.6.24: [NETLINK]: Introduce nested and byteorder flag to netlink attribute
43
 
 *  2.6.25: is_vmalloc_addr(): Check if an address is within the vmalloc
44
 
 *          boundaries
45
 
 *  2.6.27: rcu: split list.h and move rcu-protected lists into rculist.h
46
 
 *  2.6.28: netfilter: ctnetlink: remove bogus module dependency between
47
 
 *          ctnetlink and nf_nat (nfnl_lock/nfnl_unlock)
48
 
 *  2.6.29: generic swap(): introduce global macro swap(a, b)
49
 
 *  2.6.31: netfilter: passive OS fingerprint xtables match
50
 
 *  2.6.34: rcu: Add lockdep-enabled variants of rcu_dereference()
51
 
 */
52
 
 
53
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
54
 
#error "Linux kernel version too old: must be >= 2.6.34"
55
 
#endif
56
 
 
57
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
58
 
#define CHECK_OK        1
59
 
#define CHECK_FAIL(err) 0
60
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
61
 
#define CHECK_OK        0
62
 
#define CHECK_FAIL(err) (err)
63
 
#endif
64
 
 
65
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
66
 
static bool
67
 
set_match_v0(const struct sk_buff *skb, const struct xt_match_param *par)
68
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
69
51
static bool
70
52
set_match_v0(const struct sk_buff *skb, struct xt_action_param *par)
71
 
#endif
72
53
{
73
54
        const struct xt_set_info_match_v0 *info = par->matchinfo;
 
55
        ADT_OPT(opt, par->family, info->match_set.u.compat.dim,
 
56
                info->match_set.u.compat.flags, 0, UINT_MAX);
74
57
 
75
 
        return match_set(info->match_set.index, skb, par->family,
76
 
                         info->match_set.u.compat.dim,
77
 
                         info->match_set.u.compat.flags,
 
58
        return match_set(info->match_set.index, skb, par, &opt,
78
59
                         info->match_set.u.compat.flags & IPSET_INV_MATCH);
79
60
}
80
61
 
94
75
        }
95
76
}
96
77
 
97
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
98
 
static bool
99
 
set_match_v0_checkentry(const struct xt_mtchk_param *par)
100
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
101
78
static int
102
79
set_match_v0_checkentry(const struct xt_mtchk_param *par)
103
 
#endif
104
80
{
105
81
        struct xt_set_info_match_v0 *info = par->matchinfo;
106
82
        ip_set_id_t index;
110
86
        if (index == IPSET_INVALID_ID) {
111
87
                pr_warning("Cannot find set indentified by id %u to match\n",
112
88
                           info->match_set.index);
113
 
                return CHECK_FAIL(-ENOENT);     /* error */
 
89
                return -ENOENT;
114
90
        }
115
91
        if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
116
92
                pr_warning("Protocol error: set match dimension "
117
93
                           "is over the limit!\n");
118
94
                ip_set_nfnl_put(info->match_set.index);
119
 
                return CHECK_FAIL(-ERANGE);     /* error */
 
95
                return -ERANGE;
120
96
        }
121
97
 
122
98
        /* Fill out compatibility data */
123
99
        compat_flags(&info->match_set);
124
100
 
125
 
        return CHECK_OK;
 
101
        return 0;
126
102
}
127
103
 
128
104
static void
133
109
        ip_set_nfnl_put(info->match_set.index);
134
110
}
135
111
 
136
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
137
 
static unsigned int
138
 
set_target_v0(struct sk_buff *skb, const struct xt_target_param *par)
139
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
140
112
static unsigned int
141
113
set_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
142
 
#endif
143
114
{
144
115
        const struct xt_set_info_target_v0 *info = par->targinfo;
 
116
        ADT_OPT(add_opt, par->family, info->add_set.u.compat.dim,
 
117
                info->add_set.u.compat.flags, 0, UINT_MAX);
 
118
        ADT_OPT(del_opt, par->family, info->del_set.u.compat.dim,
 
119
                info->del_set.u.compat.flags, 0, UINT_MAX);
145
120
 
146
121
        if (info->add_set.index != IPSET_INVALID_ID)
147
 
                ip_set_add(info->add_set.index, skb, par->family,
148
 
                           info->add_set.u.compat.dim,
149
 
                           info->add_set.u.compat.flags);
 
122
                ip_set_add(info->add_set.index, skb, par, &add_opt);
150
123
        if (info->del_set.index != IPSET_INVALID_ID)
151
 
                ip_set_del(info->del_set.index, skb, par->family,
152
 
                           info->del_set.u.compat.dim,
153
 
                           info->del_set.u.compat.flags);
 
124
                ip_set_del(info->del_set.index, skb, par, &del_opt);
154
125
 
155
126
        return XT_CONTINUE;
156
127
}
157
128
 
158
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
159
 
static bool
160
 
set_target_v0_checkentry(const struct xt_tgchk_param *par)
161
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
162
129
static int
163
130
set_target_v0_checkentry(const struct xt_tgchk_param *par)
164
 
#endif
165
131
{
166
132
        struct xt_set_info_target_v0 *info = par->targinfo;
167
133
        ip_set_id_t index;
171
137
                if (index == IPSET_INVALID_ID) {
172
138
                        pr_warning("Cannot find add_set index %u as target\n",
173
139
                                   info->add_set.index);
174
 
                        return CHECK_FAIL(-ENOENT);     /* error */
 
140
                        return -ENOENT;
175
141
                }
176
142
        }
177
143
 
182
148
                                   info->del_set.index);
183
149
                        if (info->add_set.index != IPSET_INVALID_ID)
184
150
                                ip_set_nfnl_put(info->add_set.index);
185
 
                        return CHECK_FAIL(-ENOENT);     /* error */
 
151
                        return -ENOENT;
186
152
                }
187
153
        }
188
154
        if (info->add_set.u.flags[IPSET_DIM_MAX-1] != 0 ||
193
159
                        ip_set_nfnl_put(info->add_set.index);
194
160
                if (info->del_set.index != IPSET_INVALID_ID)
195
161
                        ip_set_nfnl_put(info->del_set.index);
196
 
                return CHECK_FAIL(-ERANGE);     /* error */
 
162
                return -ERANGE;
197
163
        }
198
164
 
199
165
        /* Fill out compatibility data */
200
166
        compat_flags(&info->add_set);
201
167
        compat_flags(&info->del_set);
202
168
 
203
 
        return CHECK_OK;
 
169
        return 0;
204
170
}
205
171
 
206
172
static void
214
180
                ip_set_nfnl_put(info->del_set.index);
215
181
}
216
182
 
217
 
/* Revision 1: current interface to netfilter/iptables */
 
183
/* Revision 1 match and target */
218
184
 
219
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
220
 
static bool
221
 
set_match(const struct sk_buff *skb, const struct xt_match_param *par)
222
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
223
 
static bool
224
 
set_match(const struct sk_buff *skb, struct xt_action_param *par)
225
 
#endif
 
185
static bool
 
186
set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
226
187
{
227
 
        const struct xt_set_info_match *info = par->matchinfo;
 
188
        const struct xt_set_info_match_v1 *info = par->matchinfo;
 
189
        ADT_OPT(opt, par->family, info->match_set.dim,
 
190
                info->match_set.flags, 0, UINT_MAX);
228
191
 
229
 
        return match_set(info->match_set.index, skb, par->family,
230
 
                         info->match_set.dim,
231
 
                         info->match_set.flags,
 
192
        return match_set(info->match_set.index, skb, par, &opt,
232
193
                         info->match_set.flags & IPSET_INV_MATCH);
233
194
}
234
195
 
235
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
236
 
static bool
237
 
set_match_checkentry(const struct xt_mtchk_param *par)
238
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
239
196
static int
240
 
set_match_checkentry(const struct xt_mtchk_param *par)
241
 
#endif
 
197
set_match_v1_checkentry(const struct xt_mtchk_param *par)
242
198
{
243
 
        struct xt_set_info_match *info = par->matchinfo;
 
199
        struct xt_set_info_match_v1 *info = par->matchinfo;
244
200
        ip_set_id_t index;
245
201
 
246
202
        index = ip_set_nfnl_get_byindex(info->match_set.index);
248
204
        if (index == IPSET_INVALID_ID) {
249
205
                pr_warning("Cannot find set indentified by id %u to match\n",
250
206
                           info->match_set.index);
251
 
                return CHECK_FAIL(-ENOENT);     /* error */
 
207
                return -ENOENT;
252
208
        }
253
209
        if (info->match_set.dim > IPSET_DIM_MAX) {
254
210
                pr_warning("Protocol error: set match dimension "
255
211
                           "is over the limit!\n");
256
212
                ip_set_nfnl_put(info->match_set.index);
257
 
                return CHECK_FAIL(-ERANGE);     /* error */
 
213
                return -ERANGE;
258
214
        }
259
215
 
260
 
        return CHECK_OK;
 
216
        return 0;
261
217
}
262
218
 
263
219
static void
264
 
set_match_destroy(const struct xt_mtdtor_param *par)
 
220
set_match_v1_destroy(const struct xt_mtdtor_param *par)
265
221
{
266
 
        struct xt_set_info_match *info = par->matchinfo;
 
222
        struct xt_set_info_match_v1 *info = par->matchinfo;
267
223
 
268
224
        ip_set_nfnl_put(info->match_set.index);
269
225
}
270
226
 
271
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
272
 
static unsigned int
273
 
set_target(struct sk_buff *skb, const struct xt_target_param *par)
274
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
275
 
static unsigned int
276
 
set_target(struct sk_buff *skb, const struct xt_action_param *par)
277
 
#endif
 
227
static unsigned int
 
228
set_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
278
229
{
279
 
        const struct xt_set_info_target *info = par->targinfo;
 
230
        const struct xt_set_info_target_v1 *info = par->targinfo;
 
231
        ADT_OPT(add_opt, par->family, info->add_set.dim,
 
232
                info->add_set.flags, 0, UINT_MAX);
 
233
        ADT_OPT(del_opt, par->family, info->del_set.dim,
 
234
                info->del_set.flags, 0, UINT_MAX);
280
235
 
281
236
        if (info->add_set.index != IPSET_INVALID_ID)
282
 
                ip_set_add(info->add_set.index,
283
 
                           skb, par->family,
284
 
                           info->add_set.dim,
285
 
                           info->add_set.flags);
 
237
                ip_set_add(info->add_set.index, skb, par, &add_opt);
286
238
        if (info->del_set.index != IPSET_INVALID_ID)
287
 
                ip_set_del(info->del_set.index,
288
 
                           skb, par->family,
289
 
                           info->del_set.dim,
290
 
                           info->del_set.flags);
 
239
                ip_set_del(info->del_set.index, skb, par, &del_opt);
291
240
 
292
241
        return XT_CONTINUE;
293
242
}
294
243
 
295
 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
296
 
static bool
297
 
set_target_checkentry(const struct xt_tgchk_param *par)
298
 
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) */
299
244
static int
300
 
set_target_checkentry(const struct xt_tgchk_param *par)
301
 
#endif
 
245
set_target_v1_checkentry(const struct xt_tgchk_param *par)
302
246
{
303
 
        const struct xt_set_info_target *info = par->targinfo;
 
247
        const struct xt_set_info_target_v1 *info = par->targinfo;
304
248
        ip_set_id_t index;
305
249
 
306
250
        if (info->add_set.index != IPSET_INVALID_ID) {
308
252
                if (index == IPSET_INVALID_ID) {
309
253
                        pr_warning("Cannot find add_set index %u as target\n",
310
254
                                   info->add_set.index);
311
 
                        return CHECK_FAIL(-ENOENT);     /* error */
 
255
                        return -ENOENT;
312
256
                }
313
257
        }
314
258
 
319
263
                                   info->del_set.index);
320
264
                        if (info->add_set.index != IPSET_INVALID_ID)
321
265
                                ip_set_nfnl_put(info->add_set.index);
322
 
                        return CHECK_FAIL(-ENOENT);     /* error */
 
266
                        return -ENOENT;
323
267
                }
324
268
        }
325
269
        if (info->add_set.dim > IPSET_DIM_MAX ||
330
274
                        ip_set_nfnl_put(info->add_set.index);
331
275
                if (info->del_set.index != IPSET_INVALID_ID)
332
276
                        ip_set_nfnl_put(info->del_set.index);
333
 
                return CHECK_FAIL(-ERANGE);     /* error */
 
277
                return -ERANGE;
334
278
        }
335
279
 
336
 
        return CHECK_OK;
 
280
        return 0;
337
281
}
338
282
 
339
283
static void
340
 
set_target_destroy(const struct xt_tgdtor_param *par)
 
284
set_target_v1_destroy(const struct xt_tgdtor_param *par)
341
285
{
342
 
        const struct xt_set_info_target *info = par->targinfo;
 
286
        const struct xt_set_info_target_v1 *info = par->targinfo;
343
287
 
344
288
        if (info->add_set.index != IPSET_INVALID_ID)
345
289
                ip_set_nfnl_put(info->add_set.index);
347
291
                ip_set_nfnl_put(info->del_set.index);
348
292
}
349
293
 
 
294
/* Revision 2 target */
 
295
 
 
296
static unsigned int
 
297
set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
 
298
{
 
299
        const struct xt_set_info_target_v2 *info = par->targinfo;
 
300
        ADT_OPT(add_opt, par->family, info->add_set.dim,
 
301
                info->add_set.flags, info->flags, info->timeout);
 
302
        ADT_OPT(del_opt, par->family, info->del_set.dim,
 
303
                info->del_set.flags, 0, UINT_MAX);
 
304
 
 
305
        if (info->add_set.index != IPSET_INVALID_ID)
 
306
                ip_set_add(info->add_set.index, skb, par, &add_opt);
 
307
        if (info->del_set.index != IPSET_INVALID_ID)
 
308
                ip_set_del(info->del_set.index, skb, par, &del_opt);
 
309
 
 
310
        return XT_CONTINUE;
 
311
}
 
312
 
 
313
#define set_target_v2_checkentry        set_target_v1_checkentry
 
314
#define set_target_v2_destroy           set_target_v1_destroy
 
315
 
350
316
static struct xt_match set_matches[] __read_mostly = {
351
317
        {
352
318
                .name           = "set",
362
328
                .name           = "set",
363
329
                .family         = NFPROTO_IPV4,
364
330
                .revision       = 1,
365
 
                .match          = set_match,
366
 
                .matchsize      = sizeof(struct xt_set_info_match),
367
 
                .checkentry     = set_match_checkentry,
368
 
                .destroy        = set_match_destroy,
 
331
                .match          = set_match_v1,
 
332
                .matchsize      = sizeof(struct xt_set_info_match_v1),
 
333
                .checkentry     = set_match_v1_checkentry,
 
334
                .destroy        = set_match_v1_destroy,
369
335
                .me             = THIS_MODULE
370
336
        },
371
337
        {
372
338
                .name           = "set",
373
339
                .family         = NFPROTO_IPV6,
374
340
                .revision       = 1,
375
 
                .match          = set_match,
376
 
                .matchsize      = sizeof(struct xt_set_info_match),
377
 
                .checkentry     = set_match_checkentry,
378
 
                .destroy        = set_match_destroy,
 
341
                .match          = set_match_v1,
 
342
                .matchsize      = sizeof(struct xt_set_info_match_v1),
 
343
                .checkentry     = set_match_v1_checkentry,
 
344
                .destroy        = set_match_v1_destroy,
379
345
                .me             = THIS_MODULE
380
346
        },
381
347
};
395
361
                .name           = "SET",
396
362
                .revision       = 1,
397
363
                .family         = NFPROTO_IPV4,
398
 
                .target         = set_target,
399
 
                .targetsize     = sizeof(struct xt_set_info_target),
400
 
                .checkentry     = set_target_checkentry,
401
 
                .destroy        = set_target_destroy,
 
364
                .target         = set_target_v1,
 
365
                .targetsize     = sizeof(struct xt_set_info_target_v1),
 
366
                .checkentry     = set_target_v1_checkentry,
 
367
                .destroy        = set_target_v1_destroy,
402
368
                .me             = THIS_MODULE
403
369
        },
404
370
        {
405
371
                .name           = "SET",
406
372
                .revision       = 1,
407
373
                .family         = NFPROTO_IPV6,
408
 
                .target         = set_target,
409
 
                .targetsize     = sizeof(struct xt_set_info_target),
410
 
                .checkentry     = set_target_checkentry,
411
 
                .destroy        = set_target_destroy,
 
374
                .target         = set_target_v1,
 
375
                .targetsize     = sizeof(struct xt_set_info_target_v1),
 
376
                .checkentry     = set_target_v1_checkentry,
 
377
                .destroy        = set_target_v1_destroy,
 
378
                .me             = THIS_MODULE
 
379
        },
 
380
        {
 
381
                .name           = "SET",
 
382
                .revision       = 2,
 
383
                .family         = NFPROTO_IPV4,
 
384
                .target         = set_target_v2,
 
385
                .targetsize     = sizeof(struct xt_set_info_target_v2),
 
386
                .checkentry     = set_target_v2_checkentry,
 
387
                .destroy        = set_target_v2_destroy,
 
388
                .me             = THIS_MODULE
 
389
        },
 
390
        {
 
391
                .name           = "SET",
 
392
                .revision       = 2,
 
393
                .family         = NFPROTO_IPV6,
 
394
                .target         = set_target_v2,
 
395
                .targetsize     = sizeof(struct xt_set_info_target_v2),
 
396
                .checkentry     = set_target_v2_checkentry,
 
397
                .destroy        = set_target_v2_destroy,
412
398
                .me             = THIS_MODULE
413
399
        },
414
400
};