diff options
48 files changed, 240 insertions, 386 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index bcd40ec83257..763a704ce83f 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -193,6 +193,25 @@ struct xt_match_param { | |||
193 | bool *hotdrop; | 193 | bool *hotdrop; |
194 | }; | 194 | }; |
195 | 195 | ||
196 | /** | ||
197 | * struct xt_mtchk_param - parameters for match extensions' | ||
198 | * checkentry functions | ||
199 | * | ||
200 | * @table: table the rule is tried to be inserted into | ||
201 | * @entryinfo: the family-specific rule data | ||
202 | * (struct ipt_ip, ip6t_ip, ebt_entry) | ||
203 | * @match: struct xt_match through which this function was invoked | ||
204 | * @matchinfo: per-match data | ||
205 | * @hook_mask: via which hooks the new rule is reachable | ||
206 | */ | ||
207 | struct xt_mtchk_param { | ||
208 | const char *table; | ||
209 | const void *entryinfo; | ||
210 | const struct xt_match *match; | ||
211 | void *matchinfo; | ||
212 | unsigned int hook_mask; | ||
213 | }; | ||
214 | |||
196 | struct xt_match | 215 | struct xt_match |
197 | { | 216 | { |
198 | struct list_head list; | 217 | struct list_head list; |
@@ -208,12 +227,7 @@ struct xt_match | |||
208 | const struct xt_match_param *); | 227 | const struct xt_match_param *); |
209 | 228 | ||
210 | /* Called when user tries to insert an entry of this type. */ | 229 | /* Called when user tries to insert an entry of this type. */ |
211 | /* Should return true or false. */ | 230 | bool (*checkentry)(const struct xt_mtchk_param *); |
212 | bool (*checkentry)(const char *tablename, | ||
213 | const void *ip, | ||
214 | const struct xt_match *match, | ||
215 | void *matchinfo, | ||
216 | unsigned int hook_mask); | ||
217 | 231 | ||
218 | /* Called when entry of this type deleted. */ | 232 | /* Called when entry of this type deleted. */ |
219 | void (*destroy)(const struct xt_match *match, void *matchinfo); | 233 | void (*destroy)(const struct xt_match *match, void *matchinfo); |
@@ -342,10 +356,8 @@ extern void xt_unregister_match(struct xt_match *target); | |||
342 | extern int xt_register_matches(struct xt_match *match, unsigned int n); | 356 | extern int xt_register_matches(struct xt_match *match, unsigned int n); |
343 | extern void xt_unregister_matches(struct xt_match *match, unsigned int n); | 357 | extern void xt_unregister_matches(struct xt_match *match, unsigned int n); |
344 | 358 | ||
345 | extern int xt_check_match(const struct xt_match *match, unsigned short family, | 359 | extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, |
346 | unsigned int size, const char *table, unsigned int hook, | 360 | unsigned int size, u_int8_t proto, bool inv_proto); |
347 | unsigned short proto, int inv_proto, | ||
348 | const void *entry, void *matchinfo); | ||
349 | extern int xt_check_target(const struct xt_target *target, unsigned short family, | 361 | extern int xt_check_target(const struct xt_target *target, unsigned short family, |
350 | unsigned int size, const char *table, unsigned int hook, | 362 | unsigned int size, const char *table, unsigned int hook, |
351 | unsigned short proto, int inv_proto, | 363 | unsigned short proto, int inv_proto, |
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c index c9e1bc149513..bd91dc58d49b 100644 --- a/net/bridge/netfilter/ebt_802_3.c +++ b/net/bridge/netfilter/ebt_802_3.c | |||
@@ -36,12 +36,9 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
36 | return true; | 36 | return true; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par) |
40 | ebt_802_3_mt_check(const char *table, const void *entry, | ||
41 | const struct xt_match *match, void *data, | ||
42 | unsigned int hook_mask) | ||
43 | { | 40 | { |
44 | const struct ebt_802_3_info *info = data; | 41 | const struct ebt_802_3_info *info = par->matchinfo; |
45 | 42 | ||
46 | if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) | 43 | if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) |
47 | return false; | 44 | return false; |
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c index 0ad0db3e815d..b595f091f35b 100644 --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c | |||
@@ -171,14 +171,11 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
171 | return true; | 171 | return true; |
172 | } | 172 | } |
173 | 173 | ||
174 | static bool | 174 | static bool ebt_among_mt_check(const struct xt_mtchk_param *par) |
175 | ebt_among_mt_check(const char *table, const void *entry, | ||
176 | const struct xt_match *match, void *data, | ||
177 | unsigned int hook_mask) | ||
178 | { | 175 | { |
176 | const struct ebt_among_info *info = par->matchinfo; | ||
179 | const struct ebt_entry_match *em = | 177 | const struct ebt_entry_match *em = |
180 | container_of(data, const struct ebt_entry_match, data); | 178 | container_of(par->matchinfo, const struct ebt_entry_match, data); |
181 | const struct ebt_among_info *info = data; | ||
182 | int expected_length = sizeof(struct ebt_among_info); | 179 | int expected_length = sizeof(struct ebt_among_info); |
183 | const struct ebt_mac_wormhash *wh_dst, *wh_src; | 180 | const struct ebt_mac_wormhash *wh_dst, *wh_src; |
184 | int err; | 181 | int err; |
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c index 1ff8fa3a9e7b..b7ad60419f9a 100644 --- a/net/bridge/netfilter/ebt_arp.c +++ b/net/bridge/netfilter/ebt_arp.c | |||
@@ -100,13 +100,10 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
100 | return true; | 100 | return true; |
101 | } | 101 | } |
102 | 102 | ||
103 | static bool | 103 | static bool ebt_arp_mt_check(const struct xt_mtchk_param *par) |
104 | ebt_arp_mt_check(const char *table, const void *entry, | ||
105 | const struct xt_match *match, void *data, | ||
106 | unsigned int hook_mask) | ||
107 | { | 104 | { |
108 | const struct ebt_arp_info *info = data; | 105 | const struct ebt_arp_info *info = par->matchinfo; |
109 | const struct ebt_entry *e = entry; | 106 | const struct ebt_entry *e = par->entryinfo; |
110 | 107 | ||
111 | if ((e->ethproto != htons(ETH_P_ARP) && | 108 | if ((e->ethproto != htons(ETH_P_ARP) && |
112 | e->ethproto != htons(ETH_P_RARP)) || | 109 | e->ethproto != htons(ETH_P_RARP)) || |
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c index c70ea39840b7..d771bbfbcbe6 100644 --- a/net/bridge/netfilter/ebt_ip.c +++ b/net/bridge/netfilter/ebt_ip.c | |||
@@ -77,13 +77,10 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
77 | return true; | 77 | return true; |
78 | } | 78 | } |
79 | 79 | ||
80 | static bool | 80 | static bool ebt_ip_mt_check(const struct xt_mtchk_param *par) |
81 | ebt_ip_mt_check(const char *table, const void *entry, | ||
82 | const struct xt_match *match, void *data, | ||
83 | unsigned int hook_mask) | ||
84 | { | 81 | { |
85 | const struct ebt_ip_info *info = data; | 82 | const struct ebt_ip_info *info = par->matchinfo; |
86 | const struct ebt_entry *e = entry; | 83 | const struct ebt_entry *e = par->entryinfo; |
87 | 84 | ||
88 | if (e->ethproto != htons(ETH_P_IP) || | 85 | if (e->ethproto != htons(ETH_P_IP) || |
89 | e->invflags & EBT_IPROTO) | 86 | e->invflags & EBT_IPROTO) |
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 5acee02de723..784a6573876c 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c | |||
@@ -90,13 +90,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
90 | return true; | 90 | return true; |
91 | } | 91 | } |
92 | 92 | ||
93 | static bool | 93 | static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par) |
94 | ebt_ip6_mt_check(const char *table, const void *entry, | ||
95 | const struct xt_match *match, void *data, | ||
96 | unsigned int hook_mask) | ||
97 | { | 94 | { |
98 | const struct ebt_entry *e = entry; | 95 | const struct ebt_entry *e = par->entryinfo; |
99 | struct ebt_ip6_info *info = data; | 96 | struct ebt_ip6_info *info = par->matchinfo; |
100 | 97 | ||
101 | if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) | 98 | if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) |
102 | return false; | 99 | return false; |
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c index 9a3ec8cadaa4..f7bd9192ff0c 100644 --- a/net/bridge/netfilter/ebt_limit.c +++ b/net/bridge/netfilter/ebt_limit.c | |||
@@ -64,12 +64,9 @@ user2credits(u_int32_t user) | |||
64 | return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; | 64 | return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; |
65 | } | 65 | } |
66 | 66 | ||
67 | static bool | 67 | static bool ebt_limit_mt_check(const struct xt_mtchk_param *par) |
68 | ebt_limit_mt_check(const char *table, const void *e, | ||
69 | const struct xt_match *match, void *data, | ||
70 | unsigned int hook_mask) | ||
71 | { | 68 | { |
72 | struct ebt_limit_info *info = data; | 69 | struct ebt_limit_info *info = par->matchinfo; |
73 | 70 | ||
74 | /* Check for overflow. */ | 71 | /* Check for overflow. */ |
75 | if (info->burst == 0 || | 72 | if (info->burst == 0 || |
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c index 5b22ef96127c..ea570f214b1d 100644 --- a/net/bridge/netfilter/ebt_mark_m.c +++ b/net/bridge/netfilter/ebt_mark_m.c | |||
@@ -22,12 +22,9 @@ ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
22 | return ((skb->mark & info->mask) == info->mark) ^ info->invert; | 22 | return ((skb->mark & info->mask) == info->mark) ^ info->invert; |
23 | } | 23 | } |
24 | 24 | ||
25 | static bool | 25 | static bool ebt_mark_mt_check(const struct xt_mtchk_param *par) |
26 | ebt_mark_mt_check(const char *table, const void *e, | ||
27 | const struct xt_match *match, void *data, | ||
28 | unsigned int hook_mask) | ||
29 | { | 26 | { |
30 | const struct ebt_mark_m_info *info = data; | 27 | const struct ebt_mark_m_info *info = par->matchinfo; |
31 | 28 | ||
32 | if (info->bitmask & ~EBT_MARK_MASK) | 29 | if (info->bitmask & ~EBT_MARK_MASK) |
33 | return false; | 30 | return false; |
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c index b756f88fb10f..883e96e2a542 100644 --- a/net/bridge/netfilter/ebt_pkttype.c +++ b/net/bridge/netfilter/ebt_pkttype.c | |||
@@ -20,12 +20,9 @@ ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
20 | return (skb->pkt_type == info->pkt_type) ^ info->invert; | 20 | return (skb->pkt_type == info->pkt_type) ^ info->invert; |
21 | } | 21 | } |
22 | 22 | ||
23 | static bool | 23 | static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par) |
24 | ebt_pkttype_mt_check(const char *table, const void *e, | ||
25 | const struct xt_match *match, void *data, | ||
26 | unsigned int hook_mask) | ||
27 | { | 24 | { |
28 | const struct ebt_pkttype_info *info = data; | 25 | const struct ebt_pkttype_info *info = par->matchinfo; |
29 | 26 | ||
30 | if (info->invert != 0 && info->invert != 1) | 27 | if (info->invert != 0 && info->invert != 1) |
31 | return false; | 28 | return false; |
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c index 06d777c62c32..48527e621626 100644 --- a/net/bridge/netfilter/ebt_stp.c +++ b/net/bridge/netfilter/ebt_stp.c | |||
@@ -153,15 +153,12 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
153 | return true; | 153 | return true; |
154 | } | 154 | } |
155 | 155 | ||
156 | static bool | 156 | static bool ebt_stp_mt_check(const struct xt_mtchk_param *par) |
157 | ebt_stp_mt_check(const char *table, const void *entry, | ||
158 | const struct xt_match *match, void *data, | ||
159 | unsigned int hook_mask) | ||
160 | { | 157 | { |
161 | const struct ebt_stp_info *info = data; | 158 | const struct ebt_stp_info *info = par->matchinfo; |
162 | const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; | 159 | const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; |
163 | const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 160 | const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
164 | const struct ebt_entry *e = entry; | 161 | const struct ebt_entry *e = par->entryinfo; |
165 | 162 | ||
166 | if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || | 163 | if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || |
167 | !(info->bitmask & EBT_STP_MASK)) | 164 | !(info->bitmask & EBT_STP_MASK)) |
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index b05b4a818341..3dddd489328e 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c | |||
@@ -84,13 +84,10 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
84 | return true; | 84 | return true; |
85 | } | 85 | } |
86 | 86 | ||
87 | static bool | 87 | static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par) |
88 | ebt_vlan_mt_check(const char *table, const void *entry, | ||
89 | const struct xt_match *match, void *data, | ||
90 | unsigned int hook_mask) | ||
91 | { | 88 | { |
92 | struct ebt_vlan_info *info = data; | 89 | struct ebt_vlan_info *info = par->matchinfo; |
93 | const struct ebt_entry *e = entry; | 90 | const struct ebt_entry *e = par->entryinfo; |
94 | 91 | ||
95 | /* Is it 802.1Q frame checked? */ | 92 | /* Is it 802.1Q frame checked? */ |
96 | if (e->ethproto != htons(ETH_P_8021Q)) { | 93 | if (e->ethproto != htons(ETH_P_8021Q)) { |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index f8e1822f38d4..5ce37b2f5b84 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -324,9 +324,10 @@ find_table_lock(const char *name, int *error, struct mutex *mutex) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | static inline int | 326 | static inline int |
327 | ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, | 327 | ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, |
328 | const char *name, unsigned int hookmask, unsigned int *cnt) | 328 | unsigned int *cnt) |
329 | { | 329 | { |
330 | const struct ebt_entry *e = par->entryinfo; | ||
330 | struct xt_match *match; | 331 | struct xt_match *match; |
331 | size_t left = ((char *)e + e->watchers_offset) - (char *)m; | 332 | size_t left = ((char *)e + e->watchers_offset) - (char *)m; |
332 | int ret; | 333 | int ret; |
@@ -343,9 +344,10 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, | |||
343 | return -ENOENT; | 344 | return -ENOENT; |
344 | m->u.match = match; | 345 | m->u.match = match; |
345 | 346 | ||
346 | ret = xt_check_match(match, NFPROTO_BRIDGE, m->match_size, | 347 | par->match = match; |
347 | name, hookmask, e->ethproto, e->invflags & EBT_IPROTO, | 348 | par->matchinfo = m->data; |
348 | e, m->data); | 349 | ret = xt_check_match(par, NFPROTO_BRIDGE, m->match_size, |
350 | e->ethproto, e->invflags & EBT_IPROTO); | ||
349 | if (ret < 0) { | 351 | if (ret < 0) { |
350 | module_put(match->me); | 352 | module_put(match->me); |
351 | return ret; | 353 | return ret; |
@@ -607,6 +609,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
607 | unsigned int i, j, hook = 0, hookmask = 0; | 609 | unsigned int i, j, hook = 0, hookmask = 0; |
608 | size_t gap; | 610 | size_t gap; |
609 | int ret; | 611 | int ret; |
612 | struct xt_mtchk_param par; | ||
610 | 613 | ||
611 | /* don't mess with the struct ebt_entries */ | 614 | /* don't mess with the struct ebt_entries */ |
612 | if (e->bitmask == 0) | 615 | if (e->bitmask == 0) |
@@ -647,7 +650,11 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
647 | hookmask = cl_s[i - 1].hookmask; | 650 | hookmask = cl_s[i - 1].hookmask; |
648 | } | 651 | } |
649 | i = 0; | 652 | i = 0; |
650 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); | 653 | |
654 | par.table = name; | ||
655 | par.entryinfo = e; | ||
656 | par.hook_mask = hookmask; | ||
657 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, &par, &i); | ||
651 | if (ret != 0) | 658 | if (ret != 0) |
652 | goto cleanup_matches; | 659 | goto cleanup_matches; |
653 | j = 0; | 660 | j = 0; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 99fdb59454fd..4147298a6a81 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -607,20 +607,20 @@ check_entry(struct ipt_entry *e, const char *name) | |||
607 | } | 607 | } |
608 | 608 | ||
609 | static int | 609 | static int |
610 | check_match(struct ipt_entry_match *m, const char *name, | 610 | check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
611 | const struct ipt_ip *ip, | 611 | unsigned int *i) |
612 | unsigned int hookmask, unsigned int *i) | ||
613 | { | 612 | { |
614 | struct xt_match *match; | 613 | const struct ipt_ip *ip = par->entryinfo; |
615 | int ret; | 614 | int ret; |
616 | 615 | ||
617 | match = m->u.kernel.match; | 616 | par->match = m->u.kernel.match; |
618 | ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), | 617 | par->matchinfo = m->data; |
619 | name, hookmask, ip->proto, | 618 | |
620 | ip->invflags & IPT_INV_PROTO, ip, m->data); | 619 | ret = xt_check_match(par, NFPROTO_IPV4, m->u.match_size - sizeof(*m), |
620 | ip->proto, ip->invflags & IPT_INV_PROTO); | ||
621 | if (ret < 0) { | 621 | if (ret < 0) { |
622 | duprintf("ip_tables: check failed for `%s'.\n", | 622 | duprintf("ip_tables: check failed for `%s'.\n", |
623 | m->u.kernel.match->name); | 623 | par.match->name); |
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | ++*i; | 626 | ++*i; |
@@ -628,10 +628,7 @@ check_match(struct ipt_entry_match *m, const char *name, | |||
628 | } | 628 | } |
629 | 629 | ||
630 | static int | 630 | static int |
631 | find_check_match(struct ipt_entry_match *m, | 631 | find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, |
632 | const char *name, | ||
633 | const struct ipt_ip *ip, | ||
634 | unsigned int hookmask, | ||
635 | unsigned int *i) | 632 | unsigned int *i) |
636 | { | 633 | { |
637 | struct xt_match *match; | 634 | struct xt_match *match; |
@@ -646,7 +643,7 @@ find_check_match(struct ipt_entry_match *m, | |||
646 | } | 643 | } |
647 | m->u.kernel.match = match; | 644 | m->u.kernel.match = match; |
648 | 645 | ||
649 | ret = check_match(m, name, ip, hookmask, i); | 646 | ret = check_match(m, par, i); |
650 | if (ret) | 647 | if (ret) |
651 | goto err; | 648 | goto err; |
652 | 649 | ||
@@ -683,14 +680,17 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
683 | struct xt_target *target; | 680 | struct xt_target *target; |
684 | int ret; | 681 | int ret; |
685 | unsigned int j; | 682 | unsigned int j; |
683 | struct xt_mtchk_param mtpar; | ||
686 | 684 | ||
687 | ret = check_entry(e, name); | 685 | ret = check_entry(e, name); |
688 | if (ret) | 686 | if (ret) |
689 | return ret; | 687 | return ret; |
690 | 688 | ||
691 | j = 0; | 689 | j = 0; |
692 | ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, | 690 | mtpar.table = name; |
693 | e->comefrom, &j); | 691 | mtpar.entryinfo = &e->ip; |
692 | mtpar.hook_mask = e->comefrom; | ||
693 | ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | ||
694 | if (ret != 0) | 694 | if (ret != 0) |
695 | goto cleanup_matches; | 695 | goto cleanup_matches; |
696 | 696 | ||
@@ -1644,12 +1644,15 @@ static int | |||
1644 | compat_check_entry(struct ipt_entry *e, const char *name, | 1644 | compat_check_entry(struct ipt_entry *e, const char *name, |
1645 | unsigned int *i) | 1645 | unsigned int *i) |
1646 | { | 1646 | { |
1647 | struct xt_mtchk_param mtpar; | ||
1647 | unsigned int j; | 1648 | unsigned int j; |
1648 | int ret; | 1649 | int ret; |
1649 | 1650 | ||
1650 | j = 0; | 1651 | j = 0; |
1651 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, | 1652 | mtpar.table = name; |
1652 | e->comefrom, &j); | 1653 | mtpar.entryinfo = &e->ip; |
1654 | mtpar.hook_mask = e->comefrom; | ||
1655 | ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); | ||
1653 | if (ret) | 1656 | if (ret) |
1654 | goto cleanup_matches; | 1657 | goto cleanup_matches; |
1655 | 1658 | ||
@@ -2144,15 +2147,9 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par) | |||
2144 | !!(icmpinfo->invflags&IPT_ICMP_INV)); | 2147 | !!(icmpinfo->invflags&IPT_ICMP_INV)); |
2145 | } | 2148 | } |
2146 | 2149 | ||
2147 | /* Called when user tries to insert an entry of this type. */ | 2150 | static bool icmp_checkentry(const struct xt_mtchk_param *par) |
2148 | static bool | ||
2149 | icmp_checkentry(const char *tablename, | ||
2150 | const void *entry, | ||
2151 | const struct xt_match *match, | ||
2152 | void *matchinfo, | ||
2153 | unsigned int hook_mask) | ||
2154 | { | 2151 | { |
2155 | const struct ipt_icmp *icmpinfo = matchinfo; | 2152 | const struct ipt_icmp *icmpinfo = par->matchinfo; |
2156 | 2153 | ||
2157 | /* Must specify no unknown invflags */ | 2154 | /* Must specify no unknown invflags */ |
2158 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); | 2155 | return !(icmpinfo->invflags & ~IPT_ICMP_INV); |
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index e60995e4c20c..88762f02779d 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c | |||
@@ -68,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | |||
68 | return ret; | 68 | return ret; |
69 | } | 69 | } |
70 | 70 | ||
71 | static bool | 71 | static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par) |
72 | addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | ||
73 | const struct xt_match *match, void *matchinfo, | ||
74 | unsigned int hook_mask) | ||
75 | { | 72 | { |
76 | struct ipt_addrtype_info_v1 *info = matchinfo; | 73 | struct ipt_addrtype_info_v1 *info = par->matchinfo; |
77 | 74 | ||
78 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && | 75 | if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && |
79 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 76 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
@@ -82,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, | |||
82 | return false; | 79 | return false; |
83 | } | 80 | } |
84 | 81 | ||
85 | if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && | 82 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | |
83 | (1 << NF_INET_LOCAL_IN)) && | ||
86 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { | 84 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { |
87 | printk(KERN_ERR "ipt_addrtype: output interface limitation " | 85 | printk(KERN_ERR "ipt_addrtype: output interface limitation " |
88 | "not valid in PRE_ROUTING and INPUT\n"); | 86 | "not valid in PRE_ROUTING and INPUT\n"); |
89 | return false; | 87 | return false; |
90 | } | 88 | } |
91 | 89 | ||
92 | if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && | 90 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | |
91 | (1 << NF_INET_LOCAL_OUT)) && | ||
93 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { | 92 | info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { |
94 | printk(KERN_ERR "ipt_addrtype: input interface limitation " | 93 | printk(KERN_ERR "ipt_addrtype: input interface limitation " |
95 | "not valid in POST_ROUTING and OUTPUT\n"); | 94 | "not valid in POST_ROUTING and OUTPUT\n"); |
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index 2fce19ef4f3f..0104c0b399de 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c | |||
@@ -61,13 +61,9 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
61 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); | 61 | !!(ahinfo->invflags & IPT_AH_INV_SPI)); |
62 | } | 62 | } |
63 | 63 | ||
64 | /* Called when user tries to insert an entry of this type. */ | 64 | static bool ah_mt_check(const struct xt_mtchk_param *par) |
65 | static bool | ||
66 | ah_mt_check(const char *tablename, const void *ip_void, | ||
67 | const struct xt_match *match, void *matchinfo, | ||
68 | unsigned int hook_mask) | ||
69 | { | 65 | { |
70 | const struct ipt_ah *ahinfo = matchinfo; | 66 | const struct ipt_ah *ahinfo = par->matchinfo; |
71 | 67 | ||
72 | /* Must specify no unknown invflags */ | 68 | /* Must specify no unknown invflags */ |
73 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { | 69 | if (ahinfo->invflags & ~IPT_AH_INV_MASK) { |
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index 069154631508..6289b64144c6 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c | |||
@@ -85,13 +85,10 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
85 | return true; | 85 | return true; |
86 | } | 86 | } |
87 | 87 | ||
88 | static bool | 88 | static bool ecn_mt_check(const struct xt_mtchk_param *par) |
89 | ecn_mt_check(const char *tablename, const void *ip_void, | ||
90 | const struct xt_match *match, void *matchinfo, | ||
91 | unsigned int hook_mask) | ||
92 | { | 89 | { |
93 | const struct ipt_ecn_info *info = matchinfo; | 90 | const struct ipt_ecn_info *info = par->matchinfo; |
94 | const struct ipt_ip *ip = ip_void; | 91 | const struct ipt_ip *ip = par->entryinfo; |
95 | 92 | ||
96 | if (info->operation & IPT_ECN_OP_MATCH_MASK) | 93 | if (info->operation & IPT_ECN_OP_MATCH_MASK) |
97 | return false; | 94 | return false; |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index cf2c5370a4e8..9c843e3777bc 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -629,20 +629,20 @@ check_entry(struct ip6t_entry *e, const char *name) | |||
629 | return 0; | 629 | return 0; |
630 | } | 630 | } |
631 | 631 | ||
632 | static int check_match(struct ip6t_entry_match *m, const char *name, | 632 | static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, |
633 | const struct ip6t_ip6 *ipv6, | 633 | unsigned int *i) |
634 | unsigned int hookmask, unsigned int *i) | ||
635 | { | 634 | { |
636 | struct xt_match *match; | 635 | const struct ip6t_ip6 *ipv6 = par->entryinfo; |
637 | int ret; | 636 | int ret; |
638 | 637 | ||
639 | match = m->u.kernel.match; | 638 | par->match = m->u.kernel.match; |
640 | ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), | 639 | par->matchinfo = m->data; |
641 | name, hookmask, ipv6->proto, | 640 | |
642 | ipv6->invflags & IP6T_INV_PROTO, ipv6, m->data); | 641 | ret = xt_check_match(par, NFPROTO_IPV6, m->u.match_size - sizeof(*m), |
642 | ipv6->proto, ipv6->invflags & IP6T_INV_PROTO); | ||
643 | if (ret < 0) { | 643 | if (ret < 0) { |
644 | duprintf("ip_tables: check failed for `%s'.\n", | 644 | duprintf("ip_tables: check failed for `%s'.\n", |
645 | m->u.kernel.match->name); | 645 | par.match->name); |
646 | return ret; | 646 | return ret; |
647 | } | 647 | } |
648 | ++*i; | 648 | ++*i; |
@@ -650,10 +650,7 @@ static int check_match(struct ip6t_entry_match *m, const char *name, | |||
650 | } | 650 | } |
651 | 651 | ||
652 | static int | 652 | static int |
653 | find_check_match(struct ip6t_entry_match *m, | 653 | find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, |
654 | const char *name, | ||
655 | const struct ip6t_ip6 *ipv6, | ||
656 | unsigned int hookmask, | ||
657 | unsigned int *i) | 654 | unsigned int *i) |
658 | { | 655 | { |
659 | struct xt_match *match; | 656 | struct xt_match *match; |
@@ -668,7 +665,7 @@ find_check_match(struct ip6t_entry_match *m, | |||
668 | } | 665 | } |
669 | m->u.kernel.match = match; | 666 | m->u.kernel.match = match; |
670 | 667 | ||
671 | ret = check_match(m, name, ipv6, hookmask, i); | 668 | ret = check_match(m, par, i); |
672 | if (ret) | 669 | if (ret) |
673 | goto err; | 670 | goto err; |
674 | 671 | ||
@@ -705,14 +702,17 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
705 | struct xt_target *target; | 702 | struct xt_target *target; |
706 | int ret; | 703 | int ret; |
707 | unsigned int j; | 704 | unsigned int j; |
705 | struct xt_mtchk_param mtpar; | ||
708 | 706 | ||
709 | ret = check_entry(e, name); | 707 | ret = check_entry(e, name); |
710 | if (ret) | 708 | if (ret) |
711 | return ret; | 709 | return ret; |
712 | 710 | ||
713 | j = 0; | 711 | j = 0; |
714 | ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, | 712 | mtpar.table = name; |
715 | e->comefrom, &j); | 713 | mtpar.entryinfo = &e->ipv6; |
714 | mtpar.hook_mask = e->comefrom; | ||
715 | ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); | ||
716 | if (ret != 0) | 716 | if (ret != 0) |
717 | goto cleanup_matches; | 717 | goto cleanup_matches; |
718 | 718 | ||
@@ -1669,10 +1669,13 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name, | |||
1669 | { | 1669 | { |
1670 | unsigned int j; | 1670 | unsigned int j; |
1671 | int ret; | 1671 | int ret; |
1672 | struct xt_mtchk_param mtpar; | ||
1672 | 1673 | ||
1673 | j = 0; | 1674 | j = 0; |
1674 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, | 1675 | mtpar.table = name; |
1675 | e->comefrom, &j); | 1676 | mtpar.entryinfo = &e->ipv6; |
1677 | mtpar.hook_mask = e->comefrom; | ||
1678 | ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); | ||
1676 | if (ret) | 1679 | if (ret) |
1677 | goto cleanup_matches; | 1680 | goto cleanup_matches; |
1678 | 1681 | ||
@@ -2166,14 +2169,9 @@ icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par) | |||
2166 | } | 2169 | } |
2167 | 2170 | ||
2168 | /* Called when user tries to insert an entry of this type. */ | 2171 | /* Called when user tries to insert an entry of this type. */ |
2169 | static bool | 2172 | static bool icmp6_checkentry(const struct xt_mtchk_param *par) |
2170 | icmp6_checkentry(const char *tablename, | ||
2171 | const void *entry, | ||
2172 | const struct xt_match *match, | ||
2173 | void *matchinfo, | ||
2174 | unsigned int hook_mask) | ||
2175 | { | 2173 | { |
2176 | const struct ip6t_icmp *icmpinfo = matchinfo; | 2174 | const struct ip6t_icmp *icmpinfo = par->matchinfo; |
2177 | 2175 | ||
2178 | /* Must specify no unknown invflags */ | 2176 | /* Must specify no unknown invflags */ |
2179 | return !(icmpinfo->invflags & ~IP6T_ICMP_INV); | 2177 | return !(icmpinfo->invflags & ~IP6T_ICMP_INV); |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index a04f2b8396e9..3a82f24746b9 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
@@ -90,13 +90,9 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
90 | !(ahinfo->hdrres && ah->reserved); | 90 | !(ahinfo->hdrres && ah->reserved); |
91 | } | 91 | } |
92 | 92 | ||
93 | /* Called when user tries to insert an entry of this type. */ | 93 | static bool ah_mt6_check(const struct xt_mtchk_param *par) |
94 | static bool | ||
95 | ah_mt6_check(const char *tablename, const void *entry, | ||
96 | const struct xt_match *match, void *matchinfo, | ||
97 | unsigned int hook_mask) | ||
98 | { | 94 | { |
99 | const struct ip6t_ah *ahinfo = matchinfo; | 95 | const struct ip6t_ah *ahinfo = par->matchinfo; |
100 | 96 | ||
101 | if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { | 97 | if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { |
102 | pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); | 98 | pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 6951d0dacf45..673aa0a5084e 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
@@ -107,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
107 | && (ntohs(fh->frag_off) & IP6_MF)); | 107 | && (ntohs(fh->frag_off) & IP6_MF)); |
108 | } | 108 | } |
109 | 109 | ||
110 | /* Called when user tries to insert an entry of this type. */ | 110 | static bool frag_mt6_check(const struct xt_mtchk_param *par) |
111 | static bool | ||
112 | frag_mt6_check(const char *tablename, const void *ip, | ||
113 | const struct xt_match *match, void *matchinfo, | ||
114 | unsigned int hook_mask) | ||
115 | { | 111 | { |
116 | const struct ip6t_frag *fraginfo = matchinfo; | 112 | const struct ip6t_frag *fraginfo = par->matchinfo; |
117 | 113 | ||
118 | if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { | 114 | if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { |
119 | pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); | 115 | pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d3351978819a..cbe8dec9744b 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -160,13 +160,9 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
160 | return false; | 160 | return false; |
161 | } | 161 | } |
162 | 162 | ||
163 | /* Called when user tries to insert an entry of this type. */ | 163 | static bool hbh_mt6_check(const struct xt_mtchk_param *par) |
164 | static bool | ||
165 | hbh_mt6_check(const char *tablename, const void *entry, | ||
166 | const struct xt_match *match, void *matchinfo, | ||
167 | unsigned int hook_mask) | ||
168 | { | 164 | { |
169 | const struct ip6t_opts *optsinfo = matchinfo; | 165 | const struct ip6t_opts *optsinfo = par->matchinfo; |
170 | 166 | ||
171 | if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { | 167 | if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { |
172 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); | 168 | pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); |
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c index 6aaca511d473..14e6724d5672 100644 --- a/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/net/ipv6/netfilter/ip6t_ipv6header.c | |||
@@ -118,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | static bool | 121 | static bool ipv6header_mt6_check(const struct xt_mtchk_param *par) |
122 | ipv6header_mt6_check(const char *tablename, const void *ip, | ||
123 | const struct xt_match *match, void *matchinfo, | ||
124 | unsigned int hook_mask) | ||
125 | { | 122 | { |
126 | const struct ip6t_ipv6header_info *info = matchinfo; | 123 | const struct ip6t_ipv6header_info *info = par->matchinfo; |
127 | 124 | ||
128 | /* invflags is 0 or 0xff in hard mode */ | 125 | /* invflags is 0 or 0xff in hard mode */ |
129 | if ((!info->modeflag) && info->invflags != 0x00 && | 126 | if ((!info->modeflag) && info->invflags != 0x00 && |
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c index 2803258b6d07..aafe4e66577b 100644 --- a/net/ipv6/netfilter/ip6t_mh.c +++ b/net/ipv6/netfilter/ip6t_mh.c | |||
@@ -67,13 +67,9 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
67 | !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); | 67 | !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); |
68 | } | 68 | } |
69 | 69 | ||
70 | /* Called when user tries to insert an entry of this type. */ | 70 | static bool mh_mt6_check(const struct xt_mtchk_param *par) |
71 | static bool | ||
72 | mh_mt6_check(const char *tablename, const void *entry, | ||
73 | const struct xt_match *match, void *matchinfo, | ||
74 | unsigned int hook_mask) | ||
75 | { | 71 | { |
76 | const struct ip6t_mh *mhinfo = matchinfo; | 72 | const struct ip6t_mh *mhinfo = par->matchinfo; |
77 | 73 | ||
78 | /* Must specify no unknown invflags */ | 74 | /* Must specify no unknown invflags */ |
79 | return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); | 75 | return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 9cf4b8a37af7..356b8d6f6baa 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
@@ -186,13 +186,9 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
186 | return false; | 186 | return false; |
187 | } | 187 | } |
188 | 188 | ||
189 | /* Called when user tries to insert an entry of this type. */ | 189 | static bool rt_mt6_check(const struct xt_mtchk_param *par) |
190 | static bool | ||
191 | rt_mt6_check(const char *tablename, const void *entry, | ||
192 | const struct xt_match *match, void *matchinfo, | ||
193 | unsigned int hook_mask) | ||
194 | { | 190 | { |
195 | const struct ip6t_rt *rtinfo = matchinfo; | 191 | const struct ip6t_rt *rtinfo = par->matchinfo; |
196 | 192 | ||
197 | if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { | 193 | if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { |
198 | pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); | 194 | pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index d1f2fb3e8f2d..817ab14f7cd6 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -321,39 +321,39 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, | |||
321 | } | 321 | } |
322 | EXPORT_SYMBOL_GPL(xt_find_revision); | 322 | EXPORT_SYMBOL_GPL(xt_find_revision); |
323 | 323 | ||
324 | int xt_check_match(const struct xt_match *match, unsigned short family, | 324 | int xt_check_match(struct xt_mtchk_param *par, u_int8_t family, |
325 | unsigned int size, const char *table, unsigned int hook_mask, | 325 | unsigned int size, u_int8_t proto, bool inv_proto) |
326 | unsigned short proto, int inv_proto, const void *entry, | ||
327 | void *matchinfo) | ||
328 | { | 326 | { |
329 | if (XT_ALIGN(match->matchsize) != size && | 327 | if (XT_ALIGN(par->match->matchsize) != size && |
330 | match->matchsize != -1) { | 328 | par->match->matchsize != -1) { |
331 | /* | 329 | /* |
332 | * ebt_among is exempt from centralized matchsize checking | 330 | * ebt_among is exempt from centralized matchsize checking |
333 | * because it uses a dynamic-size data set. | 331 | * because it uses a dynamic-size data set. |
334 | */ | 332 | */ |
335 | printk("%s_tables: %s match: invalid size %Zu != %u\n", | 333 | printk("%s_tables: %s match: invalid size %Zu != %u\n", |
336 | xt_prefix[family], match->name, | 334 | xt_prefix[family], par->match->name, |
337 | XT_ALIGN(match->matchsize), size); | 335 | XT_ALIGN(par->match->matchsize), size); |
338 | return -EINVAL; | 336 | return -EINVAL; |
339 | } | 337 | } |
340 | if (match->table && strcmp(match->table, table)) { | 338 | if (par->match->table != NULL && |
339 | strcmp(par->match->table, par->table) != 0) { | ||
341 | printk("%s_tables: %s match: only valid in %s table, not %s\n", | 340 | printk("%s_tables: %s match: only valid in %s table, not %s\n", |
342 | xt_prefix[family], match->name, match->table, table); | 341 | xt_prefix[family], par->match->name, |
342 | par->match->table, par->table); | ||
343 | return -EINVAL; | 343 | return -EINVAL; |
344 | } | 344 | } |
345 | if (match->hooks && (hook_mask & ~match->hooks) != 0) { | 345 | if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { |
346 | printk("%s_tables: %s match: bad hook_mask %#x/%#x\n", | 346 | printk("%s_tables: %s match: bad hook_mask %#x/%#x\n", |
347 | xt_prefix[family], match->name, hook_mask, match->hooks); | 347 | xt_prefix[family], par->match->name, |
348 | par->hook_mask, par->match->hooks); | ||
348 | return -EINVAL; | 349 | return -EINVAL; |
349 | } | 350 | } |
350 | if (match->proto && (match->proto != proto || inv_proto)) { | 351 | if (par->match->proto && (par->match->proto != proto || inv_proto)) { |
351 | printk("%s_tables: %s match: only valid for protocol %u\n", | 352 | printk("%s_tables: %s match: only valid for protocol %u\n", |
352 | xt_prefix[family], match->name, match->proto); | 353 | xt_prefix[family], par->match->name, par->match->proto); |
353 | return -EINVAL; | 354 | return -EINVAL; |
354 | } | 355 | } |
355 | if (match->checkentry != NULL && | 356 | if (par->match->checkentry != NULL && !par->match->checkentry(par)) |
356 | !match->checkentry(table, entry, match, matchinfo, hook_mask)) | ||
357 | return -EINVAL; | 357 | return -EINVAL; |
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index 30c19b5fe908..43a36c728e56 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c | |||
@@ -92,12 +92,9 @@ connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
92 | return what >= sinfo->count.from; | 92 | return what >= sinfo->count.from; |
93 | } | 93 | } |
94 | 94 | ||
95 | static bool | 95 | static bool connbytes_mt_check(const struct xt_mtchk_param *par) |
96 | connbytes_mt_check(const char *tablename, const void *ip, | ||
97 | const struct xt_match *match, void *matchinfo, | ||
98 | unsigned int hook_mask) | ||
99 | { | 96 | { |
100 | const struct xt_connbytes_info *sinfo = matchinfo; | 97 | const struct xt_connbytes_info *sinfo = par->matchinfo; |
101 | 98 | ||
102 | if (sinfo->what != XT_CONNBYTES_PKTS && | 99 | if (sinfo->what != XT_CONNBYTES_PKTS && |
103 | sinfo->what != XT_CONNBYTES_BYTES && | 100 | sinfo->what != XT_CONNBYTES_BYTES && |
@@ -109,17 +106,16 @@ connbytes_mt_check(const char *tablename, const void *ip, | |||
109 | sinfo->direction != XT_CONNBYTES_DIR_BOTH) | 106 | sinfo->direction != XT_CONNBYTES_DIR_BOTH) |
110 | return false; | 107 | return false; |
111 | 108 | ||
112 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 109 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
113 | printk(KERN_WARNING "can't load conntrack support for " | 110 | printk(KERN_WARNING "can't load conntrack support for " |
114 | "proto=%u\n", match->family); | 111 | "proto=%u\n", par->match->family); |
115 | return false; | 112 | return false; |
116 | } | 113 | } |
117 | 114 | ||
118 | return true; | 115 | return true; |
119 | } | 116 | } |
120 | 117 | ||
121 | static void | 118 | static void connbytes_mt_destroy(const struct xt_match *match, void *matchinfo) |
122 | connbytes_mt_destroy(const struct xt_match *match, void *matchinfo) | ||
123 | { | 119 | { |
124 | nf_ct_l3proto_module_put(match->family); | 120 | nf_ct_l3proto_module_put(match->family); |
125 | } | 121 | } |
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 8b8f70e76646..1361e9919cf2 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c | |||
@@ -221,24 +221,21 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
221 | return false; | 221 | return false; |
222 | } | 222 | } |
223 | 223 | ||
224 | static bool | 224 | static bool connlimit_mt_check(const struct xt_mtchk_param *par) |
225 | connlimit_mt_check(const char *tablename, const void *ip, | ||
226 | const struct xt_match *match, void *matchinfo, | ||
227 | unsigned int hook_mask) | ||
228 | { | 225 | { |
229 | struct xt_connlimit_info *info = matchinfo; | 226 | struct xt_connlimit_info *info = par->matchinfo; |
230 | unsigned int i; | 227 | unsigned int i; |
231 | 228 | ||
232 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 229 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
233 | printk(KERN_WARNING "cannot load conntrack support for " | 230 | printk(KERN_WARNING "cannot load conntrack support for " |
234 | "address family %u\n", match->family); | 231 | "address family %u\n", par->match->family); |
235 | return false; | 232 | return false; |
236 | } | 233 | } |
237 | 234 | ||
238 | /* init private data */ | 235 | /* init private data */ |
239 | info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); | 236 | info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); |
240 | if (info->data == NULL) { | 237 | if (info->data == NULL) { |
241 | nf_ct_l3proto_module_put(match->family); | 238 | nf_ct_l3proto_module_put(par->match->family); |
242 | return false; | 239 | return false; |
243 | } | 240 | } |
244 | 241 | ||
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index df4f4a865a5e..b935b7888a90 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c | |||
@@ -61,33 +61,27 @@ connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par) | |||
61 | return ((ct->mark & info->mask) == info->mark) ^ info->invert; | 61 | return ((ct->mark & info->mask) == info->mark) ^ info->invert; |
62 | } | 62 | } |
63 | 63 | ||
64 | static bool | 64 | static bool connmark_mt_check_v0(const struct xt_mtchk_param *par) |
65 | connmark_mt_check_v0(const char *tablename, const void *ip, | ||
66 | const struct xt_match *match, void *matchinfo, | ||
67 | unsigned int hook_mask) | ||
68 | { | 65 | { |
69 | const struct xt_connmark_info *cm = matchinfo; | 66 | const struct xt_connmark_info *cm = par->matchinfo; |
70 | 67 | ||
71 | if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { | 68 | if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { |
72 | printk(KERN_WARNING "connmark: only support 32bit mark\n"); | 69 | printk(KERN_WARNING "connmark: only support 32bit mark\n"); |
73 | return false; | 70 | return false; |
74 | } | 71 | } |
75 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 72 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
76 | printk(KERN_WARNING "can't load conntrack support for " | 73 | printk(KERN_WARNING "can't load conntrack support for " |
77 | "proto=%u\n", match->family); | 74 | "proto=%u\n", par->match->family); |
78 | return false; | 75 | return false; |
79 | } | 76 | } |
80 | return true; | 77 | return true; |
81 | } | 78 | } |
82 | 79 | ||
83 | static bool | 80 | static bool connmark_mt_check(const struct xt_mtchk_param *par) |
84 | connmark_mt_check(const char *tablename, const void *ip, | ||
85 | const struct xt_match *match, void *matchinfo, | ||
86 | unsigned int hook_mask) | ||
87 | { | 81 | { |
88 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 82 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
89 | printk(KERN_WARNING "cannot load conntrack support for " | 83 | printk(KERN_WARNING "cannot load conntrack support for " |
90 | "proto=%u\n", match->family); | 84 | "proto=%u\n", par->match->family); |
91 | return false; | 85 | return false; |
92 | } | 86 | } |
93 | return true; | 87 | return true; |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 13a7e4eacdfd..f04c46a02ce0 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -278,14 +278,11 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
278 | return true; | 278 | return true; |
279 | } | 279 | } |
280 | 280 | ||
281 | static bool | 281 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) |
282 | conntrack_mt_check(const char *tablename, const void *ip, | ||
283 | const struct xt_match *match, void *matchinfo, | ||
284 | unsigned int hook_mask) | ||
285 | { | 282 | { |
286 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 283 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
287 | printk(KERN_WARNING "can't load conntrack support for " | 284 | printk(KERN_WARNING "can't load conntrack support for " |
288 | "proto=%u\n", match->family); | 285 | "proto=%u\n", par->match->family); |
289 | return false; | 286 | return false; |
290 | } | 287 | } |
291 | return true; | 288 | return true; |
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c index 7aa30bb91050..e5d3e8673287 100644 --- a/net/netfilter/xt_dccp.c +++ b/net/netfilter/xt_dccp.c | |||
@@ -121,12 +121,9 @@ dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
121 | XT_DCCP_OPTION, info->flags, info->invflags); | 121 | XT_DCCP_OPTION, info->flags, info->invflags); |
122 | } | 122 | } |
123 | 123 | ||
124 | static bool | 124 | static bool dccp_mt_check(const struct xt_mtchk_param *par) |
125 | dccp_mt_check(const char *tablename, const void *inf, | ||
126 | const struct xt_match *match, void *matchinfo, | ||
127 | unsigned int hook_mask) | ||
128 | { | 125 | { |
129 | const struct xt_dccp_info *info = matchinfo; | 126 | const struct xt_dccp_info *info = par->matchinfo; |
130 | 127 | ||
131 | return !(info->flags & ~XT_DCCP_VALID_FLAGS) | 128 | return !(info->flags & ~XT_DCCP_VALID_FLAGS) |
132 | && !(info->invflags & ~XT_DCCP_VALID_FLAGS) | 129 | && !(info->invflags & ~XT_DCCP_VALID_FLAGS) |
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c index 57d612061358..c3f8085460d7 100644 --- a/net/netfilter/xt_dscp.c +++ b/net/netfilter/xt_dscp.c | |||
@@ -43,15 +43,12 @@ dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
43 | return (dscp == info->dscp) ^ !!info->invert; | 43 | return (dscp == info->dscp) ^ !!info->invert; |
44 | } | 44 | } |
45 | 45 | ||
46 | static bool | 46 | static bool dscp_mt_check(const struct xt_mtchk_param *par) |
47 | dscp_mt_check(const char *tablename, const void *info, | ||
48 | const struct xt_match *match, void *matchinfo, | ||
49 | unsigned int hook_mask) | ||
50 | { | 47 | { |
51 | const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; | 48 | const struct xt_dscp_info *info = par->matchinfo; |
52 | 49 | ||
53 | if (dscp > XT_DSCP_MAX) { | 50 | if (info->dscp > XT_DSCP_MAX) { |
54 | printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); | 51 | printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp); |
55 | return false; | 52 | return false; |
56 | } | 53 | } |
57 | 54 | ||
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c index 6d59f2e7c1c1..609439967c2c 100644 --- a/net/netfilter/xt_esp.c +++ b/net/netfilter/xt_esp.c | |||
@@ -66,13 +66,9 @@ static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
66 | !!(espinfo->invflags & XT_ESP_INV_SPI)); | 66 | !!(espinfo->invflags & XT_ESP_INV_SPI)); |
67 | } | 67 | } |
68 | 68 | ||
69 | /* Called when user tries to insert an entry of this type. */ | 69 | static bool esp_mt_check(const struct xt_mtchk_param *par) |
70 | static bool | ||
71 | esp_mt_check(const char *tablename, const void *ip_void, | ||
72 | const struct xt_match *match, void *matchinfo, | ||
73 | unsigned int hook_mask) | ||
74 | { | 70 | { |
75 | const struct xt_esp *espinfo = matchinfo; | 71 | const struct xt_esp *espinfo = par->matchinfo; |
76 | 72 | ||
77 | if (espinfo->invflags & ~XT_ESP_INV_MASK) { | 73 | if (espinfo->invflags & ~XT_ESP_INV_MASK) { |
78 | duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); | 74 | duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 22a60a728cf1..2f73820e46d7 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -664,12 +664,9 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
664 | return false; | 664 | return false; |
665 | } | 665 | } |
666 | 666 | ||
667 | static bool | 667 | static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par) |
668 | hashlimit_mt_check_v0(const char *tablename, const void *inf, | ||
669 | const struct xt_match *match, void *matchinfo, | ||
670 | unsigned int hook_mask) | ||
671 | { | 668 | { |
672 | struct xt_hashlimit_info *r = matchinfo; | 669 | struct xt_hashlimit_info *r = par->matchinfo; |
673 | 670 | ||
674 | /* Check for overflow. */ | 671 | /* Check for overflow. */ |
675 | if (r->cfg.burst == 0 || | 672 | if (r->cfg.burst == 0 || |
@@ -698,8 +695,8 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf, | |||
698 | * the list of htable's in htable_create(), since then we would | 695 | * the list of htable's in htable_create(), since then we would |
699 | * create duplicate proc files. -HW */ | 696 | * create duplicate proc files. -HW */ |
700 | mutex_lock(&hlimit_mutex); | 697 | mutex_lock(&hlimit_mutex); |
701 | r->hinfo = htable_find_get(r->name, match->family); | 698 | r->hinfo = htable_find_get(r->name, par->match->family); |
702 | if (!r->hinfo && htable_create_v0(r, match->family) != 0) { | 699 | if (!r->hinfo && htable_create_v0(r, par->match->family) != 0) { |
703 | mutex_unlock(&hlimit_mutex); | 700 | mutex_unlock(&hlimit_mutex); |
704 | return false; | 701 | return false; |
705 | } | 702 | } |
@@ -710,12 +707,9 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf, | |||
710 | return true; | 707 | return true; |
711 | } | 708 | } |
712 | 709 | ||
713 | static bool | 710 | static bool hashlimit_mt_check(const struct xt_mtchk_param *par) |
714 | hashlimit_mt_check(const char *tablename, const void *inf, | ||
715 | const struct xt_match *match, void *matchinfo, | ||
716 | unsigned int hook_mask) | ||
717 | { | 711 | { |
718 | struct xt_hashlimit_mtinfo1 *info = matchinfo; | 712 | struct xt_hashlimit_mtinfo1 *info = par->matchinfo; |
719 | 713 | ||
720 | /* Check for overflow. */ | 714 | /* Check for overflow. */ |
721 | if (info->cfg.burst == 0 || | 715 | if (info->cfg.burst == 0 || |
@@ -729,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf, | |||
729 | return false; | 723 | return false; |
730 | if (info->name[sizeof(info->name)-1] != '\0') | 724 | if (info->name[sizeof(info->name)-1] != '\0') |
731 | return false; | 725 | return false; |
732 | if (match->family == NFPROTO_IPV4) { | 726 | if (par->match->family == NFPROTO_IPV4) { |
733 | if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) | 727 | if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) |
734 | return false; | 728 | return false; |
735 | } else { | 729 | } else { |
@@ -744,8 +738,8 @@ hashlimit_mt_check(const char *tablename, const void *inf, | |||
744 | * the list of htable's in htable_create(), since then we would | 738 | * the list of htable's in htable_create(), since then we would |
745 | * create duplicate proc files. -HW */ | 739 | * create duplicate proc files. -HW */ |
746 | mutex_lock(&hlimit_mutex); | 740 | mutex_lock(&hlimit_mutex); |
747 | info->hinfo = htable_find_get(info->name, match->family); | 741 | info->hinfo = htable_find_get(info->name, par->match->family); |
748 | if (!info->hinfo && htable_create(info, match->family) != 0) { | 742 | if (!info->hinfo && htable_create(info, par->match->family) != 0) { |
749 | mutex_unlock(&hlimit_mutex); | 743 | mutex_unlock(&hlimit_mutex); |
750 | return false; | 744 | return false; |
751 | } | 745 | } |
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index 73bdc3ba13fc..86d3c332fcb8 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c | |||
@@ -54,16 +54,13 @@ helper_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
54 | return ret; | 54 | return ret; |
55 | } | 55 | } |
56 | 56 | ||
57 | static bool | 57 | static bool helper_mt_check(const struct xt_mtchk_param *par) |
58 | helper_mt_check(const char *tablename, const void *inf, | ||
59 | const struct xt_match *match, void *matchinfo, | ||
60 | unsigned int hook_mask) | ||
61 | { | 58 | { |
62 | struct xt_helper_info *info = matchinfo; | 59 | struct xt_helper_info *info = par->matchinfo; |
63 | 60 | ||
64 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 61 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
65 | printk(KERN_WARNING "can't load conntrack support for " | 62 | printk(KERN_WARNING "can't load conntrack support for " |
66 | "proto=%u\n", match->family); | 63 | "proto=%u\n", par->match->family); |
67 | return false; | 64 | return false; |
68 | } | 65 | } |
69 | info->name[29] = '\0'; | 66 | info->name[29] = '\0'; |
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index c475eac5dbec..c908d69a5595 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c | |||
@@ -92,12 +92,9 @@ user2credits(u_int32_t user) | |||
92 | return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; | 92 | return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; |
93 | } | 93 | } |
94 | 94 | ||
95 | static bool | 95 | static bool limit_mt_check(const struct xt_mtchk_param *par) |
96 | limit_mt_check(const char *tablename, const void *inf, | ||
97 | const struct xt_match *match, void *matchinfo, | ||
98 | unsigned int hook_mask) | ||
99 | { | 96 | { |
100 | struct xt_rateinfo *r = matchinfo; | 97 | struct xt_rateinfo *r = par->matchinfo; |
101 | 98 | ||
102 | /* Check for overflow. */ | 99 | /* Check for overflow. */ |
103 | if (r->burst == 0 | 100 | if (r->burst == 0 |
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c index 885476146531..10b9e34bbc5b 100644 --- a/net/netfilter/xt_mark.c +++ b/net/netfilter/xt_mark.c | |||
@@ -38,12 +38,9 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
38 | return ((skb->mark & info->mask) == info->mark) ^ info->invert; | 38 | return ((skb->mark & info->mask) == info->mark) ^ info->invert; |
39 | } | 39 | } |
40 | 40 | ||
41 | static bool | 41 | static bool mark_mt_check_v0(const struct xt_mtchk_param *par) |
42 | mark_mt_check_v0(const char *tablename, const void *entry, | ||
43 | const struct xt_match *match, void *matchinfo, | ||
44 | unsigned int hook_mask) | ||
45 | { | 42 | { |
46 | const struct xt_mark_info *minfo = matchinfo; | 43 | const struct xt_mark_info *minfo = par->matchinfo; |
47 | 44 | ||
48 | if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { | 45 | if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { |
49 | printk(KERN_WARNING "mark: only supports 32bit mark\n"); | 46 | printk(KERN_WARNING "mark: only supports 32bit mark\n"); |
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c index 7087e291528d..d06bb2dd3900 100644 --- a/net/netfilter/xt_multiport.c +++ b/net/netfilter/xt_multiport.c | |||
@@ -158,50 +158,37 @@ check(u_int16_t proto, | |||
158 | && count <= XT_MULTI_PORTS; | 158 | && count <= XT_MULTI_PORTS; |
159 | } | 159 | } |
160 | 160 | ||
161 | /* Called when user tries to insert an entry of this type. */ | 161 | static bool multiport_mt_check_v0(const struct xt_mtchk_param *par) |
162 | static bool | ||
163 | multiport_mt_check_v0(const char *tablename, const void *info, | ||
164 | const struct xt_match *match, void *matchinfo, | ||
165 | unsigned int hook_mask) | ||
166 | { | 162 | { |
167 | const struct ipt_ip *ip = info; | 163 | const struct ipt_ip *ip = par->entryinfo; |
168 | const struct xt_multiport *multiinfo = matchinfo; | 164 | const struct xt_multiport *multiinfo = par->matchinfo; |
169 | 165 | ||
170 | return check(ip->proto, ip->invflags, multiinfo->flags, | 166 | return check(ip->proto, ip->invflags, multiinfo->flags, |
171 | multiinfo->count); | 167 | multiinfo->count); |
172 | } | 168 | } |
173 | 169 | ||
174 | static bool | 170 | static bool multiport_mt_check(const struct xt_mtchk_param *par) |
175 | multiport_mt_check(const char *tablename, const void *info, | ||
176 | const struct xt_match *match, void *matchinfo, | ||
177 | unsigned int hook_mask) | ||
178 | { | 171 | { |
179 | const struct ipt_ip *ip = info; | 172 | const struct ipt_ip *ip = par->entryinfo; |
180 | const struct xt_multiport_v1 *multiinfo = matchinfo; | 173 | const struct xt_multiport_v1 *multiinfo = par->matchinfo; |
181 | 174 | ||
182 | return check(ip->proto, ip->invflags, multiinfo->flags, | 175 | return check(ip->proto, ip->invflags, multiinfo->flags, |
183 | multiinfo->count); | 176 | multiinfo->count); |
184 | } | 177 | } |
185 | 178 | ||
186 | static bool | 179 | static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par) |
187 | multiport_mt6_check_v0(const char *tablename, const void *info, | ||
188 | const struct xt_match *match, void *matchinfo, | ||
189 | unsigned int hook_mask) | ||
190 | { | 180 | { |
191 | const struct ip6t_ip6 *ip = info; | 181 | const struct ip6t_ip6 *ip = par->entryinfo; |
192 | const struct xt_multiport *multiinfo = matchinfo; | 182 | const struct xt_multiport *multiinfo = par->matchinfo; |
193 | 183 | ||
194 | return check(ip->proto, ip->invflags, multiinfo->flags, | 184 | return check(ip->proto, ip->invflags, multiinfo->flags, |
195 | multiinfo->count); | 185 | multiinfo->count); |
196 | } | 186 | } |
197 | 187 | ||
198 | static bool | 188 | static bool multiport_mt6_check(const struct xt_mtchk_param *par) |
199 | multiport_mt6_check(const char *tablename, const void *info, | ||
200 | const struct xt_match *match, void *matchinfo, | ||
201 | unsigned int hook_mask) | ||
202 | { | 189 | { |
203 | const struct ip6t_ip6 *ip = info; | 190 | const struct ip6t_ip6 *ip = par->entryinfo; |
204 | const struct xt_multiport_v1 *multiinfo = matchinfo; | 191 | const struct xt_multiport_v1 *multiinfo = par->matchinfo; |
205 | 192 | ||
206 | return check(ip->proto, ip->invflags, multiinfo->flags, | 193 | return check(ip->proto, ip->invflags, multiinfo->flags, |
207 | multiinfo->count); | 194 | multiinfo->count); |
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c index 493b5eb8d148..32f84e84d9e6 100644 --- a/net/netfilter/xt_owner.c +++ b/net/netfilter/xt_owner.c | |||
@@ -107,12 +107,9 @@ owner_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
107 | return true; | 107 | return true; |
108 | } | 108 | } |
109 | 109 | ||
110 | static bool | 110 | static bool owner_mt_check_v0(const struct xt_mtchk_param *par) |
111 | owner_mt_check_v0(const char *tablename, const void *ip, | ||
112 | const struct xt_match *match, void *matchinfo, | ||
113 | unsigned int hook_mask) | ||
114 | { | 111 | { |
115 | const struct ipt_owner_info *info = matchinfo; | 112 | const struct ipt_owner_info *info = par->matchinfo; |
116 | 113 | ||
117 | if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { | 114 | if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { |
118 | printk(KERN_WARNING KBUILD_MODNAME | 115 | printk(KERN_WARNING KBUILD_MODNAME |
@@ -124,12 +121,9 @@ owner_mt_check_v0(const char *tablename, const void *ip, | |||
124 | return true; | 121 | return true; |
125 | } | 122 | } |
126 | 123 | ||
127 | static bool | 124 | static bool owner_mt6_check_v0(const struct xt_mtchk_param *par) |
128 | owner_mt6_check_v0(const char *tablename, const void *ip, | ||
129 | const struct xt_match *match, void *matchinfo, | ||
130 | unsigned int hook_mask) | ||
131 | { | 125 | { |
132 | const struct ip6t_owner_info *info = matchinfo; | 126 | const struct ip6t_owner_info *info = par->matchinfo; |
133 | 127 | ||
134 | if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { | 128 | if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { |
135 | printk(KERN_WARNING KBUILD_MODNAME | 129 | printk(KERN_WARNING KBUILD_MODNAME |
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index e980e179d4f1..b01786d2dd91 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c | |||
@@ -91,12 +91,9 @@ match_outdev: | |||
91 | return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); | 91 | return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); |
92 | } | 92 | } |
93 | 93 | ||
94 | static bool | 94 | static bool physdev_mt_check(const struct xt_mtchk_param *par) |
95 | physdev_mt_check(const char *tablename, const void *ip, | ||
96 | const struct xt_match *match, void *matchinfo, | ||
97 | unsigned int hook_mask) | ||
98 | { | 95 | { |
99 | const struct xt_physdev_info *info = matchinfo; | 96 | const struct xt_physdev_info *info = par->matchinfo; |
100 | 97 | ||
101 | if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || | 98 | if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || |
102 | info->bitmask & ~XT_PHYSDEV_OP_MASK) | 99 | info->bitmask & ~XT_PHYSDEV_OP_MASK) |
@@ -104,12 +101,12 @@ physdev_mt_check(const char *tablename, const void *ip, | |||
104 | if (info->bitmask & XT_PHYSDEV_OP_OUT && | 101 | if (info->bitmask & XT_PHYSDEV_OP_OUT && |
105 | (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || | 102 | (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || |
106 | info->invert & XT_PHYSDEV_OP_BRIDGED) && | 103 | info->invert & XT_PHYSDEV_OP_BRIDGED) && |
107 | hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | | 104 | par->hook_mask & ((1 << NF_INET_LOCAL_OUT) | |
108 | (1 << NF_INET_POST_ROUTING))) { | 105 | (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) { |
109 | printk(KERN_WARNING "physdev match: using --physdev-out in the " | 106 | printk(KERN_WARNING "physdev match: using --physdev-out in the " |
110 | "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " | 107 | "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " |
111 | "traffic is not supported anymore.\n"); | 108 | "traffic is not supported anymore.\n"); |
112 | if (hook_mask & (1 << NF_INET_LOCAL_OUT)) | 109 | if (par->hook_mask & (1 << NF_INET_LOCAL_OUT)) |
113 | return false; | 110 | return false; |
114 | } | 111 | } |
115 | return true; | 112 | return true; |
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c index b0a00fb0511b..328bd20ddd25 100644 --- a/net/netfilter/xt_policy.c +++ b/net/netfilter/xt_policy.c | |||
@@ -128,26 +128,23 @@ policy_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
128 | return ret; | 128 | return ret; |
129 | } | 129 | } |
130 | 130 | ||
131 | static bool | 131 | static bool policy_mt_check(const struct xt_mtchk_param *par) |
132 | policy_mt_check(const char *tablename, const void *ip_void, | ||
133 | const struct xt_match *match, void *matchinfo, | ||
134 | unsigned int hook_mask) | ||
135 | { | 132 | { |
136 | const struct xt_policy_info *info = matchinfo; | 133 | const struct xt_policy_info *info = par->matchinfo; |
137 | 134 | ||
138 | if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { | 135 | if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { |
139 | printk(KERN_ERR "xt_policy: neither incoming nor " | 136 | printk(KERN_ERR "xt_policy: neither incoming nor " |
140 | "outgoing policy selected\n"); | 137 | "outgoing policy selected\n"); |
141 | return false; | 138 | return false; |
142 | } | 139 | } |
143 | if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) | 140 | if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) | |
144 | && info->flags & XT_POLICY_MATCH_OUT) { | 141 | (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) { |
145 | printk(KERN_ERR "xt_policy: output policy not valid in " | 142 | printk(KERN_ERR "xt_policy: output policy not valid in " |
146 | "PRE_ROUTING and INPUT\n"); | 143 | "PRE_ROUTING and INPUT\n"); |
147 | return false; | 144 | return false; |
148 | } | 145 | } |
149 | if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) | 146 | if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) | |
150 | && info->flags & XT_POLICY_MATCH_IN) { | 147 | (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) { |
151 | printk(KERN_ERR "xt_policy: input policy not valid in " | 148 | printk(KERN_ERR "xt_policy: input policy not valid in " |
152 | "POST_ROUTING and OUTPUT\n"); | 149 | "POST_ROUTING and OUTPUT\n"); |
153 | return false; | 150 | return false; |
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c index 3ab92666c149..c84fce5e0f3e 100644 --- a/net/netfilter/xt_quota.c +++ b/net/netfilter/xt_quota.c | |||
@@ -37,12 +37,9 @@ quota_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
37 | return ret; | 37 | return ret; |
38 | } | 38 | } |
39 | 39 | ||
40 | static bool | 40 | static bool quota_mt_check(const struct xt_mtchk_param *par) |
41 | quota_mt_check(const char *tablename, const void *entry, | ||
42 | const struct xt_match *match, void *matchinfo, | ||
43 | unsigned int hook_mask) | ||
44 | { | 41 | { |
45 | struct xt_quota_info *q = matchinfo; | 42 | struct xt_quota_info *q = par->matchinfo; |
46 | 43 | ||
47 | if (q->flags & ~XT_QUOTA_MASK) | 44 | if (q->flags & ~XT_QUOTA_MASK) |
48 | return false; | 45 | return false; |
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c index e9f64ef45655..4b05ce168a78 100644 --- a/net/netfilter/xt_rateest.c +++ b/net/netfilter/xt_rateest.c | |||
@@ -74,13 +74,9 @@ xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
74 | return ret; | 74 | return ret; |
75 | } | 75 | } |
76 | 76 | ||
77 | static bool xt_rateest_mt_checkentry(const char *tablename, | 77 | static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par) |
78 | const void *ip, | ||
79 | const struct xt_match *match, | ||
80 | void *matchinfo, | ||
81 | unsigned int hook_mask) | ||
82 | { | 78 | { |
83 | struct xt_rateest_match_info *info = matchinfo; | 79 | struct xt_rateest_match_info *info = par->matchinfo; |
84 | struct xt_rateest *est1, *est2; | 80 | struct xt_rateest *est1, *est2; |
85 | 81 | ||
86 | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | | 82 | if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index baeb90a56231..a512b49f3fe4 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -280,12 +280,9 @@ out: | |||
280 | return ret; | 280 | return ret; |
281 | } | 281 | } |
282 | 282 | ||
283 | static bool | 283 | static bool recent_mt_check(const struct xt_mtchk_param *par) |
284 | recent_mt_check(const char *tablename, const void *ip, | ||
285 | const struct xt_match *match, void *matchinfo, | ||
286 | unsigned int hook_mask) | ||
287 | { | 284 | { |
288 | const struct xt_recent_mtinfo *info = matchinfo; | 285 | const struct xt_recent_mtinfo *info = par->matchinfo; |
289 | struct recent_table *t; | 286 | struct recent_table *t; |
290 | unsigned i; | 287 | unsigned i; |
291 | bool ret = false; | 288 | bool ret = false; |
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c index b0014ab65da7..e223cb43ae8e 100644 --- a/net/netfilter/xt_sctp.c +++ b/net/netfilter/xt_sctp.c | |||
@@ -147,12 +147,9 @@ sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
147 | XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); | 147 | XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); |
148 | } | 148 | } |
149 | 149 | ||
150 | static bool | 150 | static bool sctp_mt_check(const struct xt_mtchk_param *par) |
151 | sctp_mt_check(const char *tablename, const void *inf, | ||
152 | const struct xt_match *match, void *matchinfo, | ||
153 | unsigned int hook_mask) | ||
154 | { | 151 | { |
155 | const struct xt_sctp_info *info = matchinfo; | 152 | const struct xt_sctp_info *info = par->matchinfo; |
156 | 153 | ||
157 | return !(info->flags & ~XT_SCTP_VALID_FLAGS) | 154 | return !(info->flags & ~XT_SCTP_VALID_FLAGS) |
158 | && !(info->invflags & ~XT_SCTP_VALID_FLAGS) | 155 | && !(info->invflags & ~XT_SCTP_VALID_FLAGS) |
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index 29f5a8a1b024..88b1235519d7 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c | |||
@@ -37,14 +37,11 @@ state_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
37 | return (sinfo->statemask & statebit); | 37 | return (sinfo->statemask & statebit); |
38 | } | 38 | } |
39 | 39 | ||
40 | static bool | 40 | static bool state_mt_check(const struct xt_mtchk_param *par) |
41 | state_mt_check(const char *tablename, const void *inf, | ||
42 | const struct xt_match *match, void *matchinfo, | ||
43 | unsigned int hook_mask) | ||
44 | { | 41 | { |
45 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | 42 | if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { |
46 | printk(KERN_WARNING "can't load conntrack support for " | 43 | printk(KERN_WARNING "can't load conntrack support for " |
47 | "proto=%u\n", match->family); | 44 | "proto=%u\n", par->match->family); |
48 | return false; | 45 | return false; |
49 | } | 46 | } |
50 | return true; | 47 | return true; |
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index dcadc491db21..0d75141139d5 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c | |||
@@ -49,12 +49,9 @@ statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
49 | return ret; | 49 | return ret; |
50 | } | 50 | } |
51 | 51 | ||
52 | static bool | 52 | static bool statistic_mt_check(const struct xt_mtchk_param *par) |
53 | statistic_mt_check(const char *tablename, const void *entry, | ||
54 | const struct xt_match *match, void *matchinfo, | ||
55 | unsigned int hook_mask) | ||
56 | { | 53 | { |
57 | struct xt_statistic_info *info = matchinfo; | 54 | struct xt_statistic_info *info = par->matchinfo; |
58 | 55 | ||
59 | if (info->mode > XT_STATISTIC_MODE_MAX || | 56 | if (info->mode > XT_STATISTIC_MODE_MAX || |
60 | info->flags & ~XT_STATISTIC_MASK) | 57 | info->flags & ~XT_STATISTIC_MASK) |
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index 33f2d29ca4f7..c9407aa78f73 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c | |||
@@ -40,12 +40,9 @@ string_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
40 | 40 | ||
41 | #define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m)) | 41 | #define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m)) |
42 | 42 | ||
43 | static bool | 43 | static bool string_mt_check(const struct xt_mtchk_param *par) |
44 | string_mt_check(const char *tablename, const void *ip, | ||
45 | const struct xt_match *match, void *matchinfo, | ||
46 | unsigned int hook_mask) | ||
47 | { | 44 | { |
48 | struct xt_string_info *conf = matchinfo; | 45 | struct xt_string_info *conf = par->matchinfo; |
49 | struct ts_config *ts_conf; | 46 | struct ts_config *ts_conf; |
50 | int flags = TS_AUTOLOAD; | 47 | int flags = TS_AUTOLOAD; |
51 | 48 | ||
@@ -56,7 +53,7 @@ string_mt_check(const char *tablename, const void *ip, | |||
56 | return false; | 53 | return false; |
57 | if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) | 54 | if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) |
58 | return false; | 55 | return false; |
59 | if (match->revision == 1) { | 56 | if (par->match->revision == 1) { |
60 | if (conf->u.v1.flags & | 57 | if (conf->u.v1.flags & |
61 | ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) | 58 | ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) |
62 | return false; | 59 | return false; |
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c index 66cf71b1d59c..1ebdc4934eed 100644 --- a/net/netfilter/xt_tcpudp.c +++ b/net/netfilter/xt_tcpudp.c | |||
@@ -126,13 +126,9 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
126 | return true; | 126 | return true; |
127 | } | 127 | } |
128 | 128 | ||
129 | /* Called when user tries to insert an entry of this type. */ | 129 | static bool tcp_mt_check(const struct xt_mtchk_param *par) |
130 | static bool | ||
131 | tcp_mt_check(const char *tablename, const void *info, | ||
132 | const struct xt_match *match, void *matchinfo, | ||
133 | unsigned int hook_mask) | ||
134 | { | 130 | { |
135 | const struct xt_tcp *tcpinfo = matchinfo; | 131 | const struct xt_tcp *tcpinfo = par->matchinfo; |
136 | 132 | ||
137 | /* Must specify no unknown invflags */ | 133 | /* Must specify no unknown invflags */ |
138 | return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); | 134 | return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); |
@@ -165,13 +161,9 @@ static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
165 | !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); | 161 | !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); |
166 | } | 162 | } |
167 | 163 | ||
168 | /* Called when user tries to insert an entry of this type. */ | 164 | static bool udp_mt_check(const struct xt_mtchk_param *par) |
169 | static bool | ||
170 | udp_mt_check(const char *tablename, const void *info, | ||
171 | const struct xt_match *match, void *matchinfo, | ||
172 | unsigned int hook_mask) | ||
173 | { | 165 | { |
174 | const struct xt_udp *udpinfo = matchinfo; | 166 | const struct xt_udp *udpinfo = par->matchinfo; |
175 | 167 | ||
176 | /* Must specify no unknown invflags */ | 168 | /* Must specify no unknown invflags */ |
177 | return !(udpinfo->invflags & ~XT_UDP_INV_MASK); | 169 | return !(udpinfo->invflags & ~XT_UDP_INV_MASK); |
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index 28599d3979c4..29375ba8db73 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c | |||
@@ -218,12 +218,9 @@ time_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
218 | return true; | 218 | return true; |
219 | } | 219 | } |
220 | 220 | ||
221 | static bool | 221 | static bool time_mt_check(const struct xt_mtchk_param *par) |
222 | time_mt_check(const char *tablename, const void *ip, | ||
223 | const struct xt_match *match, void *matchinfo, | ||
224 | unsigned int hook_mask) | ||
225 | { | 222 | { |
226 | const struct xt_time_info *info = matchinfo; | 223 | const struct xt_time_info *info = par->matchinfo; |
227 | 224 | ||
228 | if (info->daytime_start > XT_TIME_MAX_DAYTIME || | 225 | if (info->daytime_start > XT_TIME_MAX_DAYTIME || |
229 | info->daytime_stop > XT_TIME_MAX_DAYTIME) { | 226 | info->daytime_stop > XT_TIME_MAX_DAYTIME) { |