diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-02-24 12:34:48 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-02-24 12:34:48 -0500 |
commit | dcea992aca82cb08b4674c4c783e325835408d1e (patch) | |
tree | b3490bbbf49931f1405a7ebeb2f2f9d2b136cd9a | |
parent | 0559518b5b99c591226460c0bbf8e6a570c518a8 (diff) |
netfilter: xtables: replace XT_MATCH_ITERATE macro
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>
-rw-r--r-- | include/linux/netfilter/x_tables.h | 10 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/ip_tables.h | 6 | ||||
-rw-r--r-- | include/linux/netfilter_ipv6/ip6_tables.h | 6 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 78 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 78 | ||||
-rw-r--r-- | net/netfilter/xt_TCPMSS.c | 12 |
6 files changed, 141 insertions, 49 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 9df3f5a8f9f7..84c7c928e9eb 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -120,6 +120,7 @@ struct xt_counters_info { | |||
120 | 120 | ||
121 | #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ | 121 | #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ |
122 | 122 | ||
123 | #ifndef __KERNEL__ | ||
123 | /* fn returns 0 to continue iteration */ | 124 | /* fn returns 0 to continue iteration */ |
124 | #define XT_MATCH_ITERATE(type, e, fn, args...) \ | 125 | #define XT_MATCH_ITERATE(type, e, fn, args...) \ |
125 | ({ \ | 126 | ({ \ |
@@ -139,7 +140,6 @@ struct xt_counters_info { | |||
139 | __ret; \ | 140 | __ret; \ |
140 | }) | 141 | }) |
141 | 142 | ||
142 | #ifndef __KERNEL__ | ||
143 | /* fn returns 0 to continue iteration */ | 143 | /* fn returns 0 to continue iteration */ |
144 | #define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \ | 144 | #define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \ |
145 | ({ \ | 145 | ({ \ |
@@ -172,6 +172,14 @@ struct xt_counters_info { | |||
172 | (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ | 172 | (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ |
173 | (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) | 173 | (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) |
174 | 174 | ||
175 | /* can only be xt_entry_match, so no use of typeof here */ | ||
176 | #define xt_ematch_foreach(pos, entry) \ | ||
177 | for ((pos) = (struct xt_entry_match *)entry->elems; \ | ||
178 | (pos) < (struct xt_entry_match *)((char *)(entry) + \ | ||
179 | (entry)->target_offset); \ | ||
180 | (pos) = (struct xt_entry_match *)((char *)(pos) + \ | ||
181 | (pos)->u.match_size)) | ||
182 | |||
175 | #ifdef __KERNEL__ | 183 | #ifdef __KERNEL__ |
176 | 184 | ||
177 | #include <linux/netdevice.h> | 185 | #include <linux/netdevice.h> |
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 5b20ae724b41..704a7b6e8169 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h | |||
@@ -223,11 +223,11 @@ ipt_get_target(struct ipt_entry *e) | |||
223 | return (void *)e + e->target_offset; | 223 | return (void *)e + e->target_offset; |
224 | } | 224 | } |
225 | 225 | ||
226 | #ifndef __KERNEL__ | ||
226 | /* fn returns 0 to continue iteration */ | 227 | /* fn returns 0 to continue iteration */ |
227 | #define IPT_MATCH_ITERATE(e, fn, args...) \ | 228 | #define IPT_MATCH_ITERATE(e, fn, args...) \ |
228 | XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) | 229 | XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) |
229 | 230 | ||
230 | #ifndef __KERNEL__ | ||
231 | /* fn returns 0 to continue iteration */ | 231 | /* fn returns 0 to continue iteration */ |
232 | #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ | 232 | #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ |
233 | XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) | 233 | XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) |
@@ -315,10 +315,6 @@ compat_ipt_get_target(struct compat_ipt_entry *e) | |||
315 | 315 | ||
316 | #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) | 316 | #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) |
317 | 317 | ||
318 | /* fn returns 0 to continue iteration */ | ||
319 | #define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \ | ||
320 | XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args) | ||
321 | |||
322 | #endif /* CONFIG_COMPAT */ | 318 | #endif /* CONFIG_COMPAT */ |
323 | #endif /*__KERNEL__*/ | 319 | #endif /*__KERNEL__*/ |
324 | #endif /* _IPTABLES_H */ | 320 | #endif /* _IPTABLES_H */ |
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 8bb3f5ba5ff2..e5ba03d783c6 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h | |||
@@ -280,11 +280,11 @@ ip6t_get_target(struct ip6t_entry *e) | |||
280 | return (void *)e + e->target_offset; | 280 | return (void *)e + e->target_offset; |
281 | } | 281 | } |
282 | 282 | ||
283 | #ifndef __KERNEL__ | ||
283 | /* fn returns 0 to continue iteration */ | 284 | /* fn returns 0 to continue iteration */ |
284 | #define IP6T_MATCH_ITERATE(e, fn, args...) \ | 285 | #define IP6T_MATCH_ITERATE(e, fn, args...) \ |
285 | XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) | 286 | XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) |
286 | 287 | ||
287 | #ifndef __KERNEL__ | ||
288 | /* fn returns 0 to continue iteration */ | 288 | /* fn returns 0 to continue iteration */ |
289 | #define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ | 289 | #define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ |
290 | XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) | 290 | XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) |
@@ -343,10 +343,6 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e) | |||
343 | 343 | ||
344 | #define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s) | 344 | #define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s) |
345 | 345 | ||
346 | /* fn returns 0 to continue iteration */ | ||
347 | #define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \ | ||
348 | XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args) | ||
349 | |||
350 | #endif /* CONFIG_COMPAT */ | 346 | #endif /* CONFIG_COMPAT */ |
351 | #endif /*__KERNEL__*/ | 347 | #endif /*__KERNEL__*/ |
352 | #endif /* _IP6_TABLES_H */ | 348 | #endif /* _IP6_TABLES_H */ |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 9c8aa394c51c..3a7fc732b918 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -366,16 +366,21 @@ ipt_do_table(struct sk_buff *skb, | |||
366 | 366 | ||
367 | do { | 367 | do { |
368 | const struct ipt_entry_target *t; | 368 | const struct ipt_entry_target *t; |
369 | const struct xt_entry_match *ematch; | ||
369 | 370 | ||
370 | IP_NF_ASSERT(e); | 371 | IP_NF_ASSERT(e); |
371 | IP_NF_ASSERT(back); | 372 | IP_NF_ASSERT(back); |
372 | if (!ip_packet_match(ip, indev, outdev, | 373 | if (!ip_packet_match(ip, indev, outdev, |
373 | &e->ip, mtpar.fragoff) || | 374 | &e->ip, mtpar.fragoff)) { |
374 | IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { | 375 | no_match: |
375 | e = ipt_next_entry(e); | 376 | e = ipt_next_entry(e); |
376 | continue; | 377 | continue; |
377 | } | 378 | } |
378 | 379 | ||
380 | xt_ematch_foreach(ematch, e) | ||
381 | if (do_match(ematch, skb, &mtpar) != 0) | ||
382 | goto no_match; | ||
383 | |||
379 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 384 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
380 | 385 | ||
381 | t = ipt_get_target(e); | 386 | t = ipt_get_target(e); |
@@ -686,6 +691,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
686 | int ret; | 691 | int ret; |
687 | unsigned int j; | 692 | unsigned int j; |
688 | struct xt_mtchk_param mtpar; | 693 | struct xt_mtchk_param mtpar; |
694 | struct xt_entry_match *ematch; | ||
689 | 695 | ||
690 | ret = check_entry(e, name); | 696 | ret = check_entry(e, name); |
691 | if (ret) | 697 | if (ret) |
@@ -697,7 +703,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
697 | mtpar.entryinfo = &e->ip; | 703 | mtpar.entryinfo = &e->ip; |
698 | mtpar.hook_mask = e->comefrom; | 704 | mtpar.hook_mask = e->comefrom; |
699 | mtpar.family = NFPROTO_IPV4; | 705 | mtpar.family = NFPROTO_IPV4; |
700 | ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | 706 | xt_ematch_foreach(ematch, e) { |
707 | ret = find_check_match(ematch, &mtpar, &j); | ||
708 | if (ret != 0) | ||
709 | break; | ||
710 | } | ||
701 | if (ret != 0) | 711 | if (ret != 0) |
702 | goto cleanup_matches; | 712 | goto cleanup_matches; |
703 | 713 | ||
@@ -720,7 +730,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
720 | err: | 730 | err: |
721 | module_put(t->u.kernel.target->me); | 731 | module_put(t->u.kernel.target->me); |
722 | cleanup_matches: | 732 | cleanup_matches: |
723 | IPT_MATCH_ITERATE(e, cleanup_match, net, &j); | 733 | xt_ematch_foreach(ematch, e) |
734 | if (cleanup_match(ematch, net, &j) != 0) | ||
735 | break; | ||
724 | return ret; | 736 | return ret; |
725 | } | 737 | } |
726 | 738 | ||
@@ -791,9 +803,12 @@ cleanup_entry(struct ipt_entry *e, struct net *net) | |||
791 | { | 803 | { |
792 | struct xt_tgdtor_param par; | 804 | struct xt_tgdtor_param par; |
793 | struct ipt_entry_target *t; | 805 | struct ipt_entry_target *t; |
806 | struct xt_entry_match *ematch; | ||
794 | 807 | ||
795 | /* Cleanup all matches */ | 808 | /* Cleanup all matches */ |
796 | IPT_MATCH_ITERATE(e, cleanup_match, net, NULL); | 809 | xt_ematch_foreach(ematch, e) |
810 | if (cleanup_match(ematch, net, NULL) != 0) | ||
811 | break; | ||
797 | t = ipt_get_target(e); | 812 | t = ipt_get_target(e); |
798 | 813 | ||
799 | par.net = net; | 814 | par.net = net; |
@@ -1060,13 +1075,16 @@ static int compat_calc_entry(const struct ipt_entry *e, | |||
1060 | const struct xt_table_info *info, | 1075 | const struct xt_table_info *info, |
1061 | const void *base, struct xt_table_info *newinfo) | 1076 | const void *base, struct xt_table_info *newinfo) |
1062 | { | 1077 | { |
1078 | const struct xt_entry_match *ematch; | ||
1063 | const struct ipt_entry_target *t; | 1079 | const struct ipt_entry_target *t; |
1064 | unsigned int entry_offset; | 1080 | unsigned int entry_offset; |
1065 | int off, i, ret; | 1081 | int off, i, ret; |
1066 | 1082 | ||
1067 | off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); | 1083 | off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); |
1068 | entry_offset = (void *)e - base; | 1084 | entry_offset = (void *)e - base; |
1069 | IPT_MATCH_ITERATE(e, compat_calc_match, &off); | 1085 | xt_ematch_foreach(ematch, e) |
1086 | if (compat_calc_match(ematch, &off) != 0) | ||
1087 | break; | ||
1070 | t = ipt_get_target_c(e); | 1088 | t = ipt_get_target_c(e); |
1071 | off += xt_compat_target_offset(t->u.kernel.target); | 1089 | off += xt_compat_target_offset(t->u.kernel.target); |
1072 | newinfo->size -= off; | 1090 | newinfo->size -= off; |
@@ -1441,7 +1459,8 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, | |||
1441 | struct compat_ipt_entry __user *ce; | 1459 | struct compat_ipt_entry __user *ce; |
1442 | u_int16_t target_offset, next_offset; | 1460 | u_int16_t target_offset, next_offset; |
1443 | compat_uint_t origsize; | 1461 | compat_uint_t origsize; |
1444 | int ret; | 1462 | const struct xt_entry_match *ematch; |
1463 | int ret = 0; | ||
1445 | 1464 | ||
1446 | origsize = *size; | 1465 | origsize = *size; |
1447 | ce = (struct compat_ipt_entry __user *)*dstptr; | 1466 | ce = (struct compat_ipt_entry __user *)*dstptr; |
@@ -1453,7 +1472,11 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, | |||
1453 | *dstptr += sizeof(struct compat_ipt_entry); | 1472 | *dstptr += sizeof(struct compat_ipt_entry); |
1454 | *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); | 1473 | *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); |
1455 | 1474 | ||
1456 | ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); | 1475 | xt_ematch_foreach(ematch, e) { |
1476 | ret = xt_compat_match_to_user(ematch, dstptr, size); | ||
1477 | if (ret != 0) | ||
1478 | break; | ||
1479 | } | ||
1457 | target_offset = e->target_offset - (origsize - *size); | 1480 | target_offset = e->target_offset - (origsize - *size); |
1458 | if (ret) | 1481 | if (ret) |
1459 | return ret; | 1482 | return ret; |
@@ -1505,9 +1528,12 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i) | |||
1505 | static void compat_release_entry(struct compat_ipt_entry *e) | 1528 | static void compat_release_entry(struct compat_ipt_entry *e) |
1506 | { | 1529 | { |
1507 | struct ipt_entry_target *t; | 1530 | struct ipt_entry_target *t; |
1531 | struct xt_entry_match *ematch; | ||
1508 | 1532 | ||
1509 | /* Cleanup all matches */ | 1533 | /* Cleanup all matches */ |
1510 | COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL); | 1534 | xt_ematch_foreach(ematch, e) |
1535 | if (compat_release_match(ematch, NULL) != 0) | ||
1536 | break; | ||
1511 | t = compat_ipt_get_target(e); | 1537 | t = compat_ipt_get_target(e); |
1512 | module_put(t->u.kernel.target->me); | 1538 | module_put(t->u.kernel.target->me); |
1513 | } | 1539 | } |
@@ -1522,6 +1548,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1522 | const unsigned int *underflows, | 1548 | const unsigned int *underflows, |
1523 | const char *name) | 1549 | const char *name) |
1524 | { | 1550 | { |
1551 | struct xt_entry_match *ematch; | ||
1525 | struct ipt_entry_target *t; | 1552 | struct ipt_entry_target *t; |
1526 | struct xt_target *target; | 1553 | struct xt_target *target; |
1527 | unsigned int entry_offset; | 1554 | unsigned int entry_offset; |
@@ -1550,8 +1577,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1550 | off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); | 1577 | off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); |
1551 | entry_offset = (void *)e - (void *)base; | 1578 | entry_offset = (void *)e - (void *)base; |
1552 | j = 0; | 1579 | j = 0; |
1553 | ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name, | 1580 | xt_ematch_foreach(ematch, e) { |
1554 | &e->ip, e->comefrom, &off, &j); | 1581 | ret = compat_find_calc_match(ematch, name, |
1582 | &e->ip, e->comefrom, &off, &j); | ||
1583 | if (ret != 0) | ||
1584 | break; | ||
1585 | } | ||
1555 | if (ret != 0) | 1586 | if (ret != 0) |
1556 | goto release_matches; | 1587 | goto release_matches; |
1557 | 1588 | ||
@@ -1590,7 +1621,9 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1590 | out: | 1621 | out: |
1591 | module_put(t->u.kernel.target->me); | 1622 | module_put(t->u.kernel.target->me); |
1592 | release_matches: | 1623 | release_matches: |
1593 | IPT_MATCH_ITERATE(e, compat_release_match, &j); | 1624 | xt_ematch_foreach(ematch, e) |
1625 | if (compat_release_match(ematch, &j) != 0) | ||
1626 | break; | ||
1594 | return ret; | 1627 | return ret; |
1595 | } | 1628 | } |
1596 | 1629 | ||
@@ -1604,6 +1637,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, | |||
1604 | struct ipt_entry *de; | 1637 | struct ipt_entry *de; |
1605 | unsigned int origsize; | 1638 | unsigned int origsize; |
1606 | int ret, h; | 1639 | int ret, h; |
1640 | struct xt_entry_match *ematch; | ||
1607 | 1641 | ||
1608 | ret = 0; | 1642 | ret = 0; |
1609 | origsize = *size; | 1643 | origsize = *size; |
@@ -1614,8 +1648,11 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, | |||
1614 | *dstptr += sizeof(struct ipt_entry); | 1648 | *dstptr += sizeof(struct ipt_entry); |
1615 | *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); | 1649 | *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); |
1616 | 1650 | ||
1617 | ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user, | 1651 | xt_ematch_foreach(ematch, e) { |
1618 | dstptr, size); | 1652 | ret = xt_compat_match_from_user(ematch, dstptr, size); |
1653 | if (ret != 0) | ||
1654 | break; | ||
1655 | } | ||
1619 | if (ret) | 1656 | if (ret) |
1620 | return ret; | 1657 | return ret; |
1621 | de->target_offset = e->target_offset - (origsize - *size); | 1658 | de->target_offset = e->target_offset - (origsize - *size); |
@@ -1636,9 +1673,10 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, | |||
1636 | static int | 1673 | static int |
1637 | compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) | 1674 | compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) |
1638 | { | 1675 | { |
1676 | struct xt_entry_match *ematch; | ||
1639 | struct xt_mtchk_param mtpar; | 1677 | struct xt_mtchk_param mtpar; |
1640 | unsigned int j; | 1678 | unsigned int j; |
1641 | int ret; | 1679 | int ret = 0; |
1642 | 1680 | ||
1643 | j = 0; | 1681 | j = 0; |
1644 | mtpar.net = net; | 1682 | mtpar.net = net; |
@@ -1646,7 +1684,11 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) | |||
1646 | mtpar.entryinfo = &e->ip; | 1684 | mtpar.entryinfo = &e->ip; |
1647 | mtpar.hook_mask = e->comefrom; | 1685 | mtpar.hook_mask = e->comefrom; |
1648 | mtpar.family = NFPROTO_IPV4; | 1686 | mtpar.family = NFPROTO_IPV4; |
1649 | ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); | 1687 | xt_ematch_foreach(ematch, e) { |
1688 | ret = check_match(ematch, &mtpar, &j); | ||
1689 | if (ret != 0) | ||
1690 | break; | ||
1691 | } | ||
1650 | if (ret) | 1692 | if (ret) |
1651 | goto cleanup_matches; | 1693 | goto cleanup_matches; |
1652 | 1694 | ||
@@ -1656,7 +1698,9 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) | |||
1656 | return 0; | 1698 | return 0; |
1657 | 1699 | ||
1658 | cleanup_matches: | 1700 | cleanup_matches: |
1659 | IPT_MATCH_ITERATE(e, cleanup_match, net, &j); | 1701 | xt_ematch_foreach(ematch, e) |
1702 | if (cleanup_match(ematch, net, &j) != 0) | ||
1703 | break; | ||
1660 | return ret; | 1704 | return ret; |
1661 | } | 1705 | } |
1662 | 1706 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index b7e27c19c7ab..1537e6bad5d9 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -393,16 +393,21 @@ ip6t_do_table(struct sk_buff *skb, | |||
393 | 393 | ||
394 | do { | 394 | do { |
395 | const struct ip6t_entry_target *t; | 395 | const struct ip6t_entry_target *t; |
396 | const struct xt_entry_match *ematch; | ||
396 | 397 | ||
397 | IP_NF_ASSERT(e); | 398 | IP_NF_ASSERT(e); |
398 | IP_NF_ASSERT(back); | 399 | IP_NF_ASSERT(back); |
399 | if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, | 400 | if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, |
400 | &mtpar.thoff, &mtpar.fragoff, &hotdrop) || | 401 | &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { |
401 | IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { | 402 | no_match: |
402 | e = ip6t_next_entry(e); | 403 | e = ip6t_next_entry(e); |
403 | continue; | 404 | continue; |
404 | } | 405 | } |
405 | 406 | ||
407 | xt_ematch_foreach(ematch, e) | ||
408 | if (do_match(ematch, skb, &mtpar) != 0) | ||
409 | goto no_match; | ||
410 | |||
406 | ADD_COUNTER(e->counters, | 411 | ADD_COUNTER(e->counters, |
407 | ntohs(ipv6_hdr(skb)->payload_len) + | 412 | ntohs(ipv6_hdr(skb)->payload_len) + |
408 | sizeof(struct ipv6hdr), 1); | 413 | sizeof(struct ipv6hdr), 1); |
@@ -717,6 +722,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, | |||
717 | int ret; | 722 | int ret; |
718 | unsigned int j; | 723 | unsigned int j; |
719 | struct xt_mtchk_param mtpar; | 724 | struct xt_mtchk_param mtpar; |
725 | struct xt_entry_match *ematch; | ||
720 | 726 | ||
721 | ret = check_entry(e, name); | 727 | ret = check_entry(e, name); |
722 | if (ret) | 728 | if (ret) |
@@ -728,7 +734,11 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, | |||
728 | mtpar.entryinfo = &e->ipv6; | 734 | mtpar.entryinfo = &e->ipv6; |
729 | mtpar.hook_mask = e->comefrom; | 735 | mtpar.hook_mask = e->comefrom; |
730 | mtpar.family = NFPROTO_IPV6; | 736 | mtpar.family = NFPROTO_IPV6; |
731 | ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | 737 | xt_ematch_foreach(ematch, e) { |
738 | ret = find_check_match(ematch, &mtpar, &j); | ||
739 | if (ret != 0) | ||
740 | break; | ||
741 | } | ||
732 | if (ret != 0) | 742 | if (ret != 0) |
733 | goto cleanup_matches; | 743 | goto cleanup_matches; |
734 | 744 | ||
@@ -751,7 +761,9 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, | |||
751 | err: | 761 | err: |
752 | module_put(t->u.kernel.target->me); | 762 | module_put(t->u.kernel.target->me); |
753 | cleanup_matches: | 763 | cleanup_matches: |
754 | IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); | 764 | xt_ematch_foreach(ematch, e) |
765 | if (cleanup_match(ematch, net, &j) != 0) | ||
766 | break; | ||
755 | return ret; | 767 | return ret; |
756 | } | 768 | } |
757 | 769 | ||
@@ -821,9 +833,12 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net) | |||
821 | { | 833 | { |
822 | struct xt_tgdtor_param par; | 834 | struct xt_tgdtor_param par; |
823 | struct ip6t_entry_target *t; | 835 | struct ip6t_entry_target *t; |
836 | struct xt_entry_match *ematch; | ||
824 | 837 | ||
825 | /* Cleanup all matches */ | 838 | /* Cleanup all matches */ |
826 | IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL); | 839 | xt_ematch_foreach(ematch, e) |
840 | if (cleanup_match(ematch, net, NULL) != 0) | ||
841 | break; | ||
827 | t = ip6t_get_target(e); | 842 | t = ip6t_get_target(e); |
828 | 843 | ||
829 | par.net = net; | 844 | par.net = net; |
@@ -1090,13 +1105,16 @@ static int compat_calc_entry(const struct ip6t_entry *e, | |||
1090 | const struct xt_table_info *info, | 1105 | const struct xt_table_info *info, |
1091 | const void *base, struct xt_table_info *newinfo) | 1106 | const void *base, struct xt_table_info *newinfo) |
1092 | { | 1107 | { |
1108 | const struct xt_entry_match *ematch; | ||
1093 | const struct ip6t_entry_target *t; | 1109 | const struct ip6t_entry_target *t; |
1094 | unsigned int entry_offset; | 1110 | unsigned int entry_offset; |
1095 | int off, i, ret; | 1111 | int off, i, ret; |
1096 | 1112 | ||
1097 | off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); | 1113 | off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); |
1098 | entry_offset = (void *)e - base; | 1114 | entry_offset = (void *)e - base; |
1099 | IP6T_MATCH_ITERATE(e, compat_calc_match, &off); | 1115 | xt_ematch_foreach(ematch, e) |
1116 | if (compat_calc_match(ematch, &off) != 0) | ||
1117 | break; | ||
1100 | t = ip6t_get_target_c(e); | 1118 | t = ip6t_get_target_c(e); |
1101 | off += xt_compat_target_offset(t->u.kernel.target); | 1119 | off += xt_compat_target_offset(t->u.kernel.target); |
1102 | newinfo->size -= off; | 1120 | newinfo->size -= off; |
@@ -1474,7 +1492,8 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, | |||
1474 | struct compat_ip6t_entry __user *ce; | 1492 | struct compat_ip6t_entry __user *ce; |
1475 | u_int16_t target_offset, next_offset; | 1493 | u_int16_t target_offset, next_offset; |
1476 | compat_uint_t origsize; | 1494 | compat_uint_t origsize; |
1477 | int ret; | 1495 | const struct xt_entry_match *ematch; |
1496 | int ret = 0; | ||
1478 | 1497 | ||
1479 | origsize = *size; | 1498 | origsize = *size; |
1480 | ce = (struct compat_ip6t_entry __user *)*dstptr; | 1499 | ce = (struct compat_ip6t_entry __user *)*dstptr; |
@@ -1486,7 +1505,11 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, | |||
1486 | *dstptr += sizeof(struct compat_ip6t_entry); | 1505 | *dstptr += sizeof(struct compat_ip6t_entry); |
1487 | *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); | 1506 | *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); |
1488 | 1507 | ||
1489 | ret = IP6T_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); | 1508 | xt_ematch_foreach(ematch, e) { |
1509 | ret = xt_compat_match_to_user(ematch, dstptr, size); | ||
1510 | if (ret != 0) | ||
1511 | break; | ||
1512 | } | ||
1490 | target_offset = e->target_offset - (origsize - *size); | 1513 | target_offset = e->target_offset - (origsize - *size); |
1491 | if (ret) | 1514 | if (ret) |
1492 | return ret; | 1515 | return ret; |
@@ -1538,9 +1561,12 @@ compat_release_match(struct ip6t_entry_match *m, unsigned int *i) | |||
1538 | static void compat_release_entry(struct compat_ip6t_entry *e) | 1561 | static void compat_release_entry(struct compat_ip6t_entry *e) |
1539 | { | 1562 | { |
1540 | struct ip6t_entry_target *t; | 1563 | struct ip6t_entry_target *t; |
1564 | struct xt_entry_match *ematch; | ||
1541 | 1565 | ||
1542 | /* Cleanup all matches */ | 1566 | /* Cleanup all matches */ |
1543 | COMPAT_IP6T_MATCH_ITERATE(e, compat_release_match, NULL); | 1567 | xt_ematch_foreach(ematch, e) |
1568 | if (compat_release_match(ematch, NULL) != 0) | ||
1569 | break; | ||
1544 | t = compat_ip6t_get_target(e); | 1570 | t = compat_ip6t_get_target(e); |
1545 | module_put(t->u.kernel.target->me); | 1571 | module_put(t->u.kernel.target->me); |
1546 | } | 1572 | } |
@@ -1555,6 +1581,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1555 | const unsigned int *underflows, | 1581 | const unsigned int *underflows, |
1556 | const char *name) | 1582 | const char *name) |
1557 | { | 1583 | { |
1584 | struct xt_entry_match *ematch; | ||
1558 | struct ip6t_entry_target *t; | 1585 | struct ip6t_entry_target *t; |
1559 | struct xt_target *target; | 1586 | struct xt_target *target; |
1560 | unsigned int entry_offset; | 1587 | unsigned int entry_offset; |
@@ -1583,8 +1610,12 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1583 | off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); | 1610 | off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); |
1584 | entry_offset = (void *)e - (void *)base; | 1611 | entry_offset = (void *)e - (void *)base; |
1585 | j = 0; | 1612 | j = 0; |
1586 | ret = COMPAT_IP6T_MATCH_ITERATE(e, compat_find_calc_match, name, | 1613 | xt_ematch_foreach(ematch, e) { |
1587 | &e->ipv6, e->comefrom, &off, &j); | 1614 | ret = compat_find_calc_match(ematch, name, |
1615 | &e->ipv6, e->comefrom, &off, &j); | ||
1616 | if (ret != 0) | ||
1617 | break; | ||
1618 | } | ||
1588 | if (ret != 0) | 1619 | if (ret != 0) |
1589 | goto release_matches; | 1620 | goto release_matches; |
1590 | 1621 | ||
@@ -1623,7 +1654,9 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1623 | out: | 1654 | out: |
1624 | module_put(t->u.kernel.target->me); | 1655 | module_put(t->u.kernel.target->me); |
1625 | release_matches: | 1656 | release_matches: |
1626 | IP6T_MATCH_ITERATE(e, compat_release_match, &j); | 1657 | xt_ematch_foreach(ematch, e) |
1658 | if (compat_release_match(ematch, &j) != 0) | ||
1659 | break; | ||
1627 | return ret; | 1660 | return ret; |
1628 | } | 1661 | } |
1629 | 1662 | ||
@@ -1637,6 +1670,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, | |||
1637 | struct ip6t_entry *de; | 1670 | struct ip6t_entry *de; |
1638 | unsigned int origsize; | 1671 | unsigned int origsize; |
1639 | int ret, h; | 1672 | int ret, h; |
1673 | struct xt_entry_match *ematch; | ||
1640 | 1674 | ||
1641 | ret = 0; | 1675 | ret = 0; |
1642 | origsize = *size; | 1676 | origsize = *size; |
@@ -1647,8 +1681,11 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, | |||
1647 | *dstptr += sizeof(struct ip6t_entry); | 1681 | *dstptr += sizeof(struct ip6t_entry); |
1648 | *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); | 1682 | *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); |
1649 | 1683 | ||
1650 | ret = COMPAT_IP6T_MATCH_ITERATE(e, xt_compat_match_from_user, | 1684 | xt_ematch_foreach(ematch, e) { |
1651 | dstptr, size); | 1685 | ret = xt_compat_match_from_user(ematch, dstptr, size); |
1686 | if (ret != 0) | ||
1687 | break; | ||
1688 | } | ||
1652 | if (ret) | 1689 | if (ret) |
1653 | return ret; | 1690 | return ret; |
1654 | de->target_offset = e->target_offset - (origsize - *size); | 1691 | de->target_offset = e->target_offset - (origsize - *size); |
@@ -1670,8 +1707,9 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net, | |||
1670 | const char *name) | 1707 | const char *name) |
1671 | { | 1708 | { |
1672 | unsigned int j; | 1709 | unsigned int j; |
1673 | int ret; | 1710 | int ret = 0; |
1674 | struct xt_mtchk_param mtpar; | 1711 | struct xt_mtchk_param mtpar; |
1712 | struct xt_entry_match *ematch; | ||
1675 | 1713 | ||
1676 | j = 0; | 1714 | j = 0; |
1677 | mtpar.net = net; | 1715 | mtpar.net = net; |
@@ -1679,7 +1717,11 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net, | |||
1679 | mtpar.entryinfo = &e->ipv6; | 1717 | mtpar.entryinfo = &e->ipv6; |
1680 | mtpar.hook_mask = e->comefrom; | 1718 | mtpar.hook_mask = e->comefrom; |
1681 | mtpar.family = NFPROTO_IPV6; | 1719 | mtpar.family = NFPROTO_IPV6; |
1682 | ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); | 1720 | xt_ematch_foreach(ematch, e) { |
1721 | ret = check_match(ematch, &mtpar, &j); | ||
1722 | if (ret != 0) | ||
1723 | break; | ||
1724 | } | ||
1683 | if (ret) | 1725 | if (ret) |
1684 | goto cleanup_matches; | 1726 | goto cleanup_matches; |
1685 | 1727 | ||
@@ -1689,7 +1731,9 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net, | |||
1689 | return 0; | 1731 | return 0; |
1690 | 1732 | ||
1691 | cleanup_matches: | 1733 | cleanup_matches: |
1692 | IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); | 1734 | xt_ematch_foreach(ematch, e) |
1735 | if (cleanup_match(ematch, net, &j) != 0) | ||
1736 | break; | ||
1693 | return ret; | 1737 | return ret; |
1694 | } | 1738 | } |
1695 | 1739 | ||
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 6f21b4377dbb..0e357ac9a2a8 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
@@ -239,6 +239,7 @@ static bool tcpmss_tg4_check(const struct xt_tgchk_param *par) | |||
239 | { | 239 | { |
240 | const struct xt_tcpmss_info *info = par->targinfo; | 240 | const struct xt_tcpmss_info *info = par->targinfo; |
241 | const struct ipt_entry *e = par->entryinfo; | 241 | const struct ipt_entry *e = par->entryinfo; |
242 | const struct xt_entry_match *ematch; | ||
242 | 243 | ||
243 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && | 244 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && |
244 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | | 245 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | |
@@ -248,8 +249,9 @@ static bool tcpmss_tg4_check(const struct xt_tgchk_param *par) | |||
248 | "FORWARD, OUTPUT and POSTROUTING hooks\n"); | 249 | "FORWARD, OUTPUT and POSTROUTING hooks\n"); |
249 | return false; | 250 | return false; |
250 | } | 251 | } |
251 | if (IPT_MATCH_ITERATE(e, find_syn_match)) | 252 | xt_ematch_foreach(ematch, e) |
252 | return true; | 253 | if (find_syn_match(ematch)) |
254 | return true; | ||
253 | printk("xt_TCPMSS: Only works on TCP SYN packets\n"); | 255 | printk("xt_TCPMSS: Only works on TCP SYN packets\n"); |
254 | return false; | 256 | return false; |
255 | } | 257 | } |
@@ -259,6 +261,7 @@ static bool tcpmss_tg6_check(const struct xt_tgchk_param *par) | |||
259 | { | 261 | { |
260 | const struct xt_tcpmss_info *info = par->targinfo; | 262 | const struct xt_tcpmss_info *info = par->targinfo; |
261 | const struct ip6t_entry *e = par->entryinfo; | 263 | const struct ip6t_entry *e = par->entryinfo; |
264 | const struct xt_entry_match *ematch; | ||
262 | 265 | ||
263 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && | 266 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && |
264 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | | 267 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | |
@@ -268,8 +271,9 @@ static bool tcpmss_tg6_check(const struct xt_tgchk_param *par) | |||
268 | "FORWARD, OUTPUT and POSTROUTING hooks\n"); | 271 | "FORWARD, OUTPUT and POSTROUTING hooks\n"); |
269 | return false; | 272 | return false; |
270 | } | 273 | } |
271 | if (IP6T_MATCH_ITERATE(e, find_syn_match)) | 274 | xt_ematch_foreach(ematch, e) |
272 | return true; | 275 | if (find_syn_match(ematch)) |
276 | return true; | ||
273 | printk("xt_TCPMSS: Only works on TCP SYN packets\n"); | 277 | printk("xt_TCPMSS: Only works on TCP SYN packets\n"); |
274 | return false; | 278 | return false; |
275 | } | 279 | } |