Skip to content

Commit

Permalink
netfilter: xtables: replace XT_MATCH_ITERATE macro
Browse files Browse the repository at this point in the history
The macro is replaced by a list.h-like foreach loop. This makes
the code more inspectable.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
  • Loading branch information
Jan Engelhardt authored and Patrick McHardy committed Feb 24, 2010
1 parent 0559518 commit dcea992
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 49 deletions.
10 changes: 9 additions & 1 deletion include/linux/netfilter/x_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ struct xt_counters_info {

#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define XT_MATCH_ITERATE(type, e, fn, args...) \
({ \
Expand All @@ -139,7 +140,6 @@ struct xt_counters_info {
__ret; \
})

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
({ \
Expand Down Expand Up @@ -172,6 +172,14 @@ struct xt_counters_info {
(pos) < (typeof(pos))((char *)(ehead) + (esize)); \
(pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))

/* can only be xt_entry_match, so no use of typeof here */
#define xt_ematch_foreach(pos, entry) \
for ((pos) = (struct xt_entry_match *)entry->elems; \
(pos) < (struct xt_entry_match *)((char *)(entry) + \
(entry)->target_offset); \
(pos) = (struct xt_entry_match *)((char *)(pos) + \
(pos)->u.match_size))

#ifdef __KERNEL__

#include <linux/netdevice.h>
Expand Down
6 changes: 1 addition & 5 deletions include/linux/netfilter_ipv4/ip_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ ipt_get_target(struct ipt_entry *e)
return (void *)e + e->target_offset;
}

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define IPT_MATCH_ITERATE(e, fn, args...) \
XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
Expand Down Expand Up @@ -315,10 +315,6 @@ compat_ipt_get_target(struct compat_ipt_entry *e)

#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s)

/* fn returns 0 to continue iteration */
#define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \
XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args)

#endif /* CONFIG_COMPAT */
#endif /*__KERNEL__*/
#endif /* _IPTABLES_H */
6 changes: 1 addition & 5 deletions include/linux/netfilter_ipv6/ip6_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,11 @@ ip6t_get_target(struct ip6t_entry *e)
return (void *)e + e->target_offset;
}

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define IP6T_MATCH_ITERATE(e, fn, args...) \
XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)

#ifndef __KERNEL__
/* fn returns 0 to continue iteration */
#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
Expand Down Expand Up @@ -343,10 +343,6 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e)

#define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s)

/* fn returns 0 to continue iteration */
#define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \
XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args)

#endif /* CONFIG_COMPAT */
#endif /*__KERNEL__*/
#endif /* _IP6_TABLES_H */
78 changes: 61 additions & 17 deletions net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,16 +366,21 @@ ipt_do_table(struct sk_buff *skb,

do {
const struct ipt_entry_target *t;
const struct xt_entry_match *ematch;

IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (!ip_packet_match(ip, indev, outdev,
&e->ip, mtpar.fragoff) ||
IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) {
&e->ip, mtpar.fragoff)) {
no_match:
e = ipt_next_entry(e);
continue;
}

xt_ematch_foreach(ematch, e)
if (do_match(ematch, skb, &mtpar) != 0)
goto no_match;

ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);

t = ipt_get_target(e);
Expand Down Expand Up @@ -686,6 +691,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
int ret;
unsigned int j;
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;

ret = check_entry(e, name);
if (ret)
Expand All @@ -697,7 +703,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
xt_ematch_foreach(ematch, e) {
ret = find_check_match(ematch, &mtpar, &j);
if (ret != 0)
break;
}
if (ret != 0)
goto cleanup_matches;

Expand All @@ -720,7 +730,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
err:
module_put(t->u.kernel.target->me);
cleanup_matches:
IPT_MATCH_ITERATE(e, cleanup_match, net, &j);
xt_ematch_foreach(ematch, e)
if (cleanup_match(ematch, net, &j) != 0)
break;
return ret;
}

Expand Down Expand Up @@ -791,9 +803,12 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
{
struct xt_tgdtor_param par;
struct ipt_entry_target *t;
struct xt_entry_match *ematch;

/* Cleanup all matches */
IPT_MATCH_ITERATE(e, cleanup_match, net, NULL);
xt_ematch_foreach(ematch, e)
if (cleanup_match(ematch, net, NULL) != 0)
break;
t = ipt_get_target(e);

par.net = net;
Expand Down Expand Up @@ -1060,13 +1075,16 @@ static int compat_calc_entry(const struct ipt_entry *e,
const struct xt_table_info *info,
const void *base, struct xt_table_info *newinfo)
{
const struct xt_entry_match *ematch;
const struct ipt_entry_target *t;
unsigned int entry_offset;
int off, i, ret;

off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
entry_offset = (void *)e - base;
IPT_MATCH_ITERATE(e, compat_calc_match, &off);
xt_ematch_foreach(ematch, e)
if (compat_calc_match(ematch, &off) != 0)
break;
t = ipt_get_target_c(e);
off += xt_compat_target_offset(t->u.kernel.target);
newinfo->size -= off;
Expand Down Expand Up @@ -1441,7 +1459,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
struct compat_ipt_entry __user *ce;
u_int16_t target_offset, next_offset;
compat_uint_t origsize;
int ret;
const struct xt_entry_match *ematch;
int ret = 0;

origsize = *size;
ce = (struct compat_ipt_entry __user *)*dstptr;
Expand All @@ -1453,7 +1472,11 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
*dstptr += sizeof(struct compat_ipt_entry);
*size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);

ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size);
xt_ematch_foreach(ematch, e) {
ret = xt_compat_match_to_user(ematch, dstptr, size);
if (ret != 0)
break;
}
target_offset = e->target_offset - (origsize - *size);
if (ret)
return ret;
Expand Down Expand Up @@ -1505,9 +1528,12 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i)
static void compat_release_entry(struct compat_ipt_entry *e)
{
struct ipt_entry_target *t;
struct xt_entry_match *ematch;

/* Cleanup all matches */
COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL);
xt_ematch_foreach(ematch, e)
if (compat_release_match(ematch, NULL) != 0)
break;
t = compat_ipt_get_target(e);
module_put(t->u.kernel.target->me);
}
Expand All @@ -1522,6 +1548,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
const unsigned int *underflows,
const char *name)
{
struct xt_entry_match *ematch;
struct ipt_entry_target *t;
struct xt_target *target;
unsigned int entry_offset;
Expand Down Expand Up @@ -1550,8 +1577,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
entry_offset = (void *)e - (void *)base;
j = 0;
ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name,
&e->ip, e->comefrom, &off, &j);
xt_ematch_foreach(ematch, e) {
ret = compat_find_calc_match(ematch, name,
&e->ip, e->comefrom, &off, &j);
if (ret != 0)
break;
}
if (ret != 0)
goto release_matches;

Expand Down Expand Up @@ -1590,7 +1621,9 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
out:
module_put(t->u.kernel.target->me);
release_matches:
IPT_MATCH_ITERATE(e, compat_release_match, &j);
xt_ematch_foreach(ematch, e)
if (compat_release_match(ematch, &j) != 0)
break;
return ret;
}

Expand All @@ -1604,6 +1637,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
struct ipt_entry *de;
unsigned int origsize;
int ret, h;
struct xt_entry_match *ematch;

ret = 0;
origsize = *size;
Expand All @@ -1614,8 +1648,11 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
*dstptr += sizeof(struct ipt_entry);
*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);

ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user,
dstptr, size);
xt_ematch_foreach(ematch, e) {
ret = xt_compat_match_from_user(ematch, dstptr, size);
if (ret != 0)
break;
}
if (ret)
return ret;
de->target_offset = e->target_offset - (origsize - *size);
Expand All @@ -1636,17 +1673,22 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
static int
compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
{
struct xt_entry_match *ematch;
struct xt_mtchk_param mtpar;
unsigned int j;
int ret;
int ret = 0;

j = 0;
mtpar.net = net;
mtpar.table = name;
mtpar.entryinfo = &e->ip;
mtpar.hook_mask = e->comefrom;
mtpar.family = NFPROTO_IPV4;
ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
xt_ematch_foreach(ematch, e) {
ret = check_match(ematch, &mtpar, &j);
if (ret != 0)
break;
}
if (ret)
goto cleanup_matches;

Expand All @@ -1656,7 +1698,9 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
return 0;

cleanup_matches:
IPT_MATCH_ITERATE(e, cleanup_match, net, &j);
xt_ematch_foreach(ematch, e)
if (cleanup_match(ematch, net, &j) != 0)
break;
return ret;
}

Expand Down
Loading

0 comments on commit dcea992

Please sign in to comment.