diff options
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 16 | ||||
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 109 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 170 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 168 | ||||
-rw-r--r-- | net/netfilter/nf_queue.c | 4 | ||||
-rw-r--r-- | net/netfilter/x_tables.c | 42 |
8 files changed, 278 insertions, 235 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 820252aee81f..24555834d431 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -142,6 +142,12 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h, | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | static inline __pure | ||
146 | struct ebt_entry *ebt_next_entry(const struct ebt_entry *entry) | ||
147 | { | ||
148 | return (void *)entry + entry->next_offset; | ||
149 | } | ||
150 | |||
145 | /* Do some firewalling */ | 151 | /* Do some firewalling */ |
146 | unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, | 152 | unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, |
147 | const struct net_device *in, const struct net_device *out, | 153 | const struct net_device *in, const struct net_device *out, |
@@ -249,8 +255,7 @@ letsreturn: | |||
249 | /* jump to a udc */ | 255 | /* jump to a udc */ |
250 | cs[sp].n = i + 1; | 256 | cs[sp].n = i + 1; |
251 | cs[sp].chaininfo = chaininfo; | 257 | cs[sp].chaininfo = chaininfo; |
252 | cs[sp].e = (struct ebt_entry *) | 258 | cs[sp].e = ebt_next_entry(point); |
253 | (((char *)point) + point->next_offset); | ||
254 | i = 0; | 259 | i = 0; |
255 | chaininfo = (struct ebt_entries *) (base + verdict); | 260 | chaininfo = (struct ebt_entries *) (base + verdict); |
256 | #ifdef CONFIG_NETFILTER_DEBUG | 261 | #ifdef CONFIG_NETFILTER_DEBUG |
@@ -266,8 +271,7 @@ letsreturn: | |||
266 | sp++; | 271 | sp++; |
267 | continue; | 272 | continue; |
268 | letscontinue: | 273 | letscontinue: |
269 | point = (struct ebt_entry *) | 274 | point = ebt_next_entry(point); |
270 | (((char *)point) + point->next_offset); | ||
271 | i++; | 275 | i++; |
272 | } | 276 | } |
273 | 277 | ||
@@ -787,7 +791,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s | |||
787 | /* this can't be 0, so the loop test is correct */ | 791 | /* this can't be 0, so the loop test is correct */ |
788 | cl_s[i].cs.n = pos + 1; | 792 | cl_s[i].cs.n = pos + 1; |
789 | pos = 0; | 793 | pos = 0; |
790 | cl_s[i].cs.e = ((void *)e + e->next_offset); | 794 | cl_s[i].cs.e = ebt_next_entry(e); |
791 | e = (struct ebt_entry *)(hlp2->data); | 795 | e = (struct ebt_entry *)(hlp2->data); |
792 | nentries = hlp2->nentries; | 796 | nentries = hlp2->nentries; |
793 | cl_s[i].from = chain_nr; | 797 | cl_s[i].from = chain_nr; |
@@ -797,7 +801,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s | |||
797 | continue; | 801 | continue; |
798 | } | 802 | } |
799 | letscontinue: | 803 | letscontinue: |
800 | e = (void *)e + e->next_offset; | 804 | e = ebt_next_entry(e); |
801 | pos++; | 805 | pos++; |
802 | } | 806 | } |
803 | return 0; | 807 | return 0; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 831fe1879dc0..7505dff4ffdf 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -231,6 +231,12 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset) | |||
231 | return (struct arpt_entry *)(base + offset); | 231 | return (struct arpt_entry *)(base + offset); |
232 | } | 232 | } |
233 | 233 | ||
234 | static inline __pure | ||
235 | struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry) | ||
236 | { | ||
237 | return (void *)entry + entry->next_offset; | ||
238 | } | ||
239 | |||
234 | unsigned int arpt_do_table(struct sk_buff *skb, | 240 | unsigned int arpt_do_table(struct sk_buff *skb, |
235 | unsigned int hook, | 241 | unsigned int hook, |
236 | const struct net_device *in, | 242 | const struct net_device *in, |
@@ -267,67 +273,64 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
267 | 273 | ||
268 | arp = arp_hdr(skb); | 274 | arp = arp_hdr(skb); |
269 | do { | 275 | do { |
270 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { | 276 | struct arpt_entry_target *t; |
271 | struct arpt_entry_target *t; | 277 | int hdr_len; |
272 | int hdr_len; | ||
273 | |||
274 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + | ||
275 | (2 * skb->dev->addr_len); | ||
276 | 278 | ||
277 | ADD_COUNTER(e->counters, hdr_len, 1); | 279 | if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { |
280 | e = arpt_next_entry(e); | ||
281 | continue; | ||
282 | } | ||
278 | 283 | ||
279 | t = arpt_get_target(e); | 284 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + |
285 | (2 * skb->dev->addr_len); | ||
286 | ADD_COUNTER(e->counters, hdr_len, 1); | ||
280 | 287 | ||
281 | /* Standard target? */ | 288 | t = arpt_get_target(e); |
282 | if (!t->u.kernel.target->target) { | ||
283 | int v; | ||
284 | 289 | ||
285 | v = ((struct arpt_standard_target *)t)->verdict; | 290 | /* Standard target? */ |
286 | if (v < 0) { | 291 | if (!t->u.kernel.target->target) { |
287 | /* Pop from stack? */ | 292 | int v; |
288 | if (v != ARPT_RETURN) { | ||
289 | verdict = (unsigned)(-v) - 1; | ||
290 | break; | ||
291 | } | ||
292 | e = back; | ||
293 | back = get_entry(table_base, | ||
294 | back->comefrom); | ||
295 | continue; | ||
296 | } | ||
297 | if (table_base + v | ||
298 | != (void *)e + e->next_offset) { | ||
299 | /* Save old back ptr in next entry */ | ||
300 | struct arpt_entry *next | ||
301 | = (void *)e + e->next_offset; | ||
302 | next->comefrom = | ||
303 | (void *)back - table_base; | ||
304 | |||
305 | /* set back pointer to next entry */ | ||
306 | back = next; | ||
307 | } | ||
308 | 293 | ||
309 | e = get_entry(table_base, v); | 294 | v = ((struct arpt_standard_target *)t)->verdict; |
310 | } else { | 295 | if (v < 0) { |
311 | /* Targets which reenter must return | 296 | /* Pop from stack? */ |
312 | * abs. verdicts | 297 | if (v != ARPT_RETURN) { |
313 | */ | 298 | verdict = (unsigned)(-v) - 1; |
314 | tgpar.target = t->u.kernel.target; | ||
315 | tgpar.targinfo = t->data; | ||
316 | verdict = t->u.kernel.target->target(skb, | ||
317 | &tgpar); | ||
318 | |||
319 | /* Target might have changed stuff. */ | ||
320 | arp = arp_hdr(skb); | ||
321 | |||
322 | if (verdict == ARPT_CONTINUE) | ||
323 | e = (void *)e + e->next_offset; | ||
324 | else | ||
325 | /* Verdict */ | ||
326 | break; | 299 | break; |
300 | } | ||
301 | e = back; | ||
302 | back = get_entry(table_base, back->comefrom); | ||
303 | continue; | ||
327 | } | 304 | } |
328 | } else { | 305 | if (table_base + v |
329 | e = (void *)e + e->next_offset; | 306 | != arpt_next_entry(e)) { |
307 | /* Save old back ptr in next entry */ | ||
308 | struct arpt_entry *next = arpt_next_entry(e); | ||
309 | next->comefrom = (void *)back - table_base; | ||
310 | |||
311 | /* set back pointer to next entry */ | ||
312 | back = next; | ||
313 | } | ||
314 | |||
315 | e = get_entry(table_base, v); | ||
316 | continue; | ||
330 | } | 317 | } |
318 | |||
319 | /* Targets which reenter must return | ||
320 | * abs. verdicts | ||
321 | */ | ||
322 | tgpar.target = t->u.kernel.target; | ||
323 | tgpar.targinfo = t->data; | ||
324 | verdict = t->u.kernel.target->target(skb, &tgpar); | ||
325 | |||
326 | /* Target might have changed stuff. */ | ||
327 | arp = arp_hdr(skb); | ||
328 | |||
329 | if (verdict == ARPT_CONTINUE) | ||
330 | e = arpt_next_entry(e); | ||
331 | else | ||
332 | /* Verdict */ | ||
333 | break; | ||
331 | } while (!hotdrop); | 334 | } while (!hotdrop); |
332 | xt_info_rdunlock_bh(); | 335 | xt_info_rdunlock_bh(); |
333 | 336 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 5f22c91c6e15..c156db215987 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -596,7 +596,7 @@ static int __init ip_queue_init(void) | |||
596 | #ifdef CONFIG_SYSCTL | 596 | #ifdef CONFIG_SYSCTL |
597 | ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table); | 597 | ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table); |
598 | #endif | 598 | #endif |
599 | status = nf_register_queue_handler(PF_INET, &nfqh); | 599 | status = nf_register_queue_handler(NFPROTO_IPV4, &nfqh); |
600 | if (status < 0) { | 600 | if (status < 0) { |
601 | printk(KERN_ERR "ip_queue: failed to register queue handler\n"); | 601 | printk(KERN_ERR "ip_queue: failed to register queue handler\n"); |
602 | goto cleanup_sysctl; | 602 | goto cleanup_sysctl; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2ec8d7290c40..7b35c0b3841b 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -238,8 +238,8 @@ static struct nf_loginfo trace_loginfo = { | |||
238 | /* Mildly perf critical (only if packet tracing is on) */ | 238 | /* Mildly perf critical (only if packet tracing is on) */ |
239 | static inline int | 239 | static inline int |
240 | get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, | 240 | get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, |
241 | char *hookname, char **chainname, | 241 | const char *hookname, const char **chainname, |
242 | char **comment, unsigned int *rulenum) | 242 | const char **comment, unsigned int *rulenum) |
243 | { | 243 | { |
244 | struct ipt_standard_target *t = (void *)ipt_get_target(s); | 244 | struct ipt_standard_target *t = (void *)ipt_get_target(s); |
245 | 245 | ||
@@ -257,8 +257,8 @@ get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e, | |||
257 | && unconditional(&s->ip)) { | 257 | && unconditional(&s->ip)) { |
258 | /* Tail of chains: STANDARD target (return/policy) */ | 258 | /* Tail of chains: STANDARD target (return/policy) */ |
259 | *comment = *chainname == hookname | 259 | *comment = *chainname == hookname |
260 | ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY] | 260 | ? comments[NF_IP_TRACE_COMMENT_POLICY] |
261 | : (char *)comments[NF_IP_TRACE_COMMENT_RETURN]; | 261 | : comments[NF_IP_TRACE_COMMENT_RETURN]; |
262 | } | 262 | } |
263 | return 1; | 263 | return 1; |
264 | } else | 264 | } else |
@@ -277,14 +277,14 @@ static void trace_packet(struct sk_buff *skb, | |||
277 | { | 277 | { |
278 | void *table_base; | 278 | void *table_base; |
279 | const struct ipt_entry *root; | 279 | const struct ipt_entry *root; |
280 | char *hookname, *chainname, *comment; | 280 | const char *hookname, *chainname, *comment; |
281 | unsigned int rulenum = 0; | 281 | unsigned int rulenum = 0; |
282 | 282 | ||
283 | table_base = (void *)private->entries[smp_processor_id()]; | 283 | table_base = private->entries[smp_processor_id()]; |
284 | root = get_entry(table_base, private->hook_entry[hook]); | 284 | root = get_entry(table_base, private->hook_entry[hook]); |
285 | 285 | ||
286 | hookname = chainname = (char *)hooknames[hook]; | 286 | hookname = chainname = hooknames[hook]; |
287 | comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE]; | 287 | comment = comments[NF_IP_TRACE_COMMENT_RULE]; |
288 | 288 | ||
289 | IPT_ENTRY_ITERATE(root, | 289 | IPT_ENTRY_ITERATE(root, |
290 | private->size - private->hook_entry[hook], | 290 | private->size - private->hook_entry[hook], |
@@ -297,6 +297,12 @@ static void trace_packet(struct sk_buff *skb, | |||
297 | } | 297 | } |
298 | #endif | 298 | #endif |
299 | 299 | ||
300 | static inline __pure | ||
301 | struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry) | ||
302 | { | ||
303 | return (void *)entry + entry->next_offset; | ||
304 | } | ||
305 | |||
300 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ | 306 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ |
301 | unsigned int | 307 | unsigned int |
302 | ipt_do_table(struct sk_buff *skb, | 308 | ipt_do_table(struct sk_buff *skb, |
@@ -305,6 +311,8 @@ ipt_do_table(struct sk_buff *skb, | |||
305 | const struct net_device *out, | 311 | const struct net_device *out, |
306 | struct xt_table *table) | 312 | struct xt_table *table) |
307 | { | 313 | { |
314 | #define tb_comefrom ((struct ipt_entry *)table_base)->comefrom | ||
315 | |||
308 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 316 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
309 | const struct iphdr *ip; | 317 | const struct iphdr *ip; |
310 | u_int16_t datalen; | 318 | u_int16_t datalen; |
@@ -348,92 +356,84 @@ ipt_do_table(struct sk_buff *skb, | |||
348 | back = get_entry(table_base, private->underflow[hook]); | 356 | back = get_entry(table_base, private->underflow[hook]); |
349 | 357 | ||
350 | do { | 358 | do { |
359 | struct ipt_entry_target *t; | ||
360 | |||
351 | IP_NF_ASSERT(e); | 361 | IP_NF_ASSERT(e); |
352 | IP_NF_ASSERT(back); | 362 | IP_NF_ASSERT(back); |
353 | if (ip_packet_match(ip, indev, outdev, | 363 | if (!ip_packet_match(ip, indev, outdev, |
354 | &e->ip, mtpar.fragoff)) { | 364 | &e->ip, mtpar.fragoff) || |
355 | struct ipt_entry_target *t; | 365 | IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { |
356 | 366 | e = ipt_next_entry(e); | |
357 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) | 367 | continue; |
358 | goto no_match; | 368 | } |
359 | 369 | ||
360 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 370 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
361 | 371 | ||
362 | t = ipt_get_target(e); | 372 | t = ipt_get_target(e); |
363 | IP_NF_ASSERT(t->u.kernel.target); | 373 | IP_NF_ASSERT(t->u.kernel.target); |
364 | 374 | ||
365 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 375 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |
366 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | 376 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) |
367 | /* The packet is traced: log it */ | 377 | /* The packet is traced: log it */ |
368 | if (unlikely(skb->nf_trace)) | 378 | if (unlikely(skb->nf_trace)) |
369 | trace_packet(skb, hook, in, out, | 379 | trace_packet(skb, hook, in, out, |
370 | table->name, private, e); | 380 | table->name, private, e); |
371 | #endif | 381 | #endif |
372 | /* Standard target? */ | 382 | /* Standard target? */ |
373 | if (!t->u.kernel.target->target) { | 383 | if (!t->u.kernel.target->target) { |
374 | int v; | 384 | int v; |
375 | 385 | ||
376 | v = ((struct ipt_standard_target *)t)->verdict; | 386 | v = ((struct ipt_standard_target *)t)->verdict; |
377 | if (v < 0) { | 387 | if (v < 0) { |
378 | /* Pop from stack? */ | 388 | /* Pop from stack? */ |
379 | if (v != IPT_RETURN) { | 389 | if (v != IPT_RETURN) { |
380 | verdict = (unsigned)(-v) - 1; | 390 | verdict = (unsigned)(-v) - 1; |
381 | break; | 391 | break; |
382 | } | ||
383 | e = back; | ||
384 | back = get_entry(table_base, | ||
385 | back->comefrom); | ||
386 | continue; | ||
387 | } | ||
388 | if (table_base + v != (void *)e + e->next_offset | ||
389 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
390 | /* Save old back ptr in next entry */ | ||
391 | struct ipt_entry *next | ||
392 | = (void *)e + e->next_offset; | ||
393 | next->comefrom | ||
394 | = (void *)back - table_base; | ||
395 | /* set back pointer to next entry */ | ||
396 | back = next; | ||
397 | } | 392 | } |
393 | e = back; | ||
394 | back = get_entry(table_base, back->comefrom); | ||
395 | continue; | ||
396 | } | ||
397 | if (table_base + v != ipt_next_entry(e) | ||
398 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
399 | /* Save old back ptr in next entry */ | ||
400 | struct ipt_entry *next = ipt_next_entry(e); | ||
401 | next->comefrom = (void *)back - table_base; | ||
402 | /* set back pointer to next entry */ | ||
403 | back = next; | ||
404 | } | ||
405 | |||
406 | e = get_entry(table_base, v); | ||
407 | continue; | ||
408 | } | ||
409 | |||
410 | /* Targets which reenter must return | ||
411 | abs. verdicts */ | ||
412 | tgpar.target = t->u.kernel.target; | ||
413 | tgpar.targinfo = t->data; | ||
414 | |||
398 | 415 | ||
399 | e = get_entry(table_base, v); | ||
400 | } else { | ||
401 | /* Targets which reenter must return | ||
402 | abs. verdicts */ | ||
403 | tgpar.target = t->u.kernel.target; | ||
404 | tgpar.targinfo = t->data; | ||
405 | #ifdef CONFIG_NETFILTER_DEBUG | 416 | #ifdef CONFIG_NETFILTER_DEBUG |
406 | ((struct ipt_entry *)table_base)->comefrom | 417 | tb_comefrom = 0xeeeeeeec; |
407 | = 0xeeeeeeec; | ||
408 | #endif | 418 | #endif |
409 | verdict = t->u.kernel.target->target(skb, | 419 | verdict = t->u.kernel.target->target(skb, &tgpar); |
410 | &tgpar); | ||
411 | #ifdef CONFIG_NETFILTER_DEBUG | 420 | #ifdef CONFIG_NETFILTER_DEBUG |
412 | if (((struct ipt_entry *)table_base)->comefrom | 421 | if (comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) { |
413 | != 0xeeeeeeec | 422 | printk("Target %s reentered!\n", |
414 | && verdict == IPT_CONTINUE) { | 423 | t->u.kernel.target->name); |
415 | printk("Target %s reentered!\n", | 424 | verdict = NF_DROP; |
416 | t->u.kernel.target->name); | 425 | } |
417 | verdict = NF_DROP; | 426 | tb_comefrom = 0x57acc001; |
418 | } | ||
419 | ((struct ipt_entry *)table_base)->comefrom | ||
420 | = 0x57acc001; | ||
421 | #endif | 427 | #endif |
422 | /* Target might have changed stuff. */ | 428 | /* Target might have changed stuff. */ |
423 | ip = ip_hdr(skb); | 429 | ip = ip_hdr(skb); |
424 | datalen = skb->len - ip->ihl * 4; | 430 | datalen = skb->len - ip->ihl * 4; |
425 | |||
426 | if (verdict == IPT_CONTINUE) | ||
427 | e = (void *)e + e->next_offset; | ||
428 | else | ||
429 | /* Verdict */ | ||
430 | break; | ||
431 | } | ||
432 | } else { | ||
433 | 431 | ||
434 | no_match: | 432 | if (verdict == IPT_CONTINUE) |
435 | e = (void *)e + e->next_offset; | 433 | e = ipt_next_entry(e); |
436 | } | 434 | else |
435 | /* Verdict */ | ||
436 | break; | ||
437 | } while (!hotdrop); | 437 | } while (!hotdrop); |
438 | xt_info_rdunlock_bh(); | 438 | xt_info_rdunlock_bh(); |
439 | 439 | ||
@@ -444,6 +444,8 @@ ipt_do_table(struct sk_buff *skb, | |||
444 | return NF_DROP; | 444 | return NF_DROP; |
445 | else return verdict; | 445 | else return verdict; |
446 | #endif | 446 | #endif |
447 | |||
448 | #undef tb_comefrom | ||
447 | } | 449 | } |
448 | 450 | ||
449 | /* Figures out from what hook each rule can be called: returns 0 if | 451 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -2158,7 +2160,7 @@ static bool icmp_checkentry(const struct xt_mtchk_param *par) | |||
2158 | static struct xt_target ipt_standard_target __read_mostly = { | 2160 | static struct xt_target ipt_standard_target __read_mostly = { |
2159 | .name = IPT_STANDARD_TARGET, | 2161 | .name = IPT_STANDARD_TARGET, |
2160 | .targetsize = sizeof(int), | 2162 | .targetsize = sizeof(int), |
2161 | .family = AF_INET, | 2163 | .family = NFPROTO_IPV4, |
2162 | #ifdef CONFIG_COMPAT | 2164 | #ifdef CONFIG_COMPAT |
2163 | .compatsize = sizeof(compat_int_t), | 2165 | .compatsize = sizeof(compat_int_t), |
2164 | .compat_from_user = compat_standard_from_user, | 2166 | .compat_from_user = compat_standard_from_user, |
@@ -2170,7 +2172,7 @@ static struct xt_target ipt_error_target __read_mostly = { | |||
2170 | .name = IPT_ERROR_TARGET, | 2172 | .name = IPT_ERROR_TARGET, |
2171 | .target = ipt_error, | 2173 | .target = ipt_error, |
2172 | .targetsize = IPT_FUNCTION_MAXNAMELEN, | 2174 | .targetsize = IPT_FUNCTION_MAXNAMELEN, |
2173 | .family = AF_INET, | 2175 | .family = NFPROTO_IPV4, |
2174 | }; | 2176 | }; |
2175 | 2177 | ||
2176 | static struct nf_sockopt_ops ipt_sockopts = { | 2178 | static struct nf_sockopt_ops ipt_sockopts = { |
@@ -2196,17 +2198,17 @@ static struct xt_match icmp_matchstruct __read_mostly = { | |||
2196 | .matchsize = sizeof(struct ipt_icmp), | 2198 | .matchsize = sizeof(struct ipt_icmp), |
2197 | .checkentry = icmp_checkentry, | 2199 | .checkentry = icmp_checkentry, |
2198 | .proto = IPPROTO_ICMP, | 2200 | .proto = IPPROTO_ICMP, |
2199 | .family = AF_INET, | 2201 | .family = NFPROTO_IPV4, |
2200 | }; | 2202 | }; |
2201 | 2203 | ||
2202 | static int __net_init ip_tables_net_init(struct net *net) | 2204 | static int __net_init ip_tables_net_init(struct net *net) |
2203 | { | 2205 | { |
2204 | return xt_proto_init(net, AF_INET); | 2206 | return xt_proto_init(net, NFPROTO_IPV4); |
2205 | } | 2207 | } |
2206 | 2208 | ||
2207 | static void __net_exit ip_tables_net_exit(struct net *net) | 2209 | static void __net_exit ip_tables_net_exit(struct net *net) |
2208 | { | 2210 | { |
2209 | xt_proto_fini(net, AF_INET); | 2211 | xt_proto_fini(net, NFPROTO_IPV4); |
2210 | } | 2212 | } |
2211 | 2213 | ||
2212 | static struct pernet_operations ip_tables_net_ops = { | 2214 | static struct pernet_operations ip_tables_net_ops = { |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index b693f841aeb4..1cf3f0c6a959 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -598,7 +598,7 @@ static int __init ip6_queue_init(void) | |||
598 | #ifdef CONFIG_SYSCTL | 598 | #ifdef CONFIG_SYSCTL |
599 | ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table); | 599 | ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table); |
600 | #endif | 600 | #endif |
601 | status = nf_register_queue_handler(PF_INET6, &nfqh); | 601 | status = nf_register_queue_handler(NFPROTO_IPV6, &nfqh); |
602 | if (status < 0) { | 602 | if (status < 0) { |
603 | printk(KERN_ERR "ip6_queue: failed to register queue handler\n"); | 603 | printk(KERN_ERR "ip6_queue: failed to register queue handler\n"); |
604 | goto cleanup_sysctl; | 604 | goto cleanup_sysctl; |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 219e165aea10..5164e0bf3bcc 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -270,8 +270,8 @@ static struct nf_loginfo trace_loginfo = { | |||
270 | /* Mildly perf critical (only if packet tracing is on) */ | 270 | /* Mildly perf critical (only if packet tracing is on) */ |
271 | static inline int | 271 | static inline int |
272 | get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, | 272 | get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, |
273 | char *hookname, char **chainname, | 273 | const char *hookname, const char **chainname, |
274 | char **comment, unsigned int *rulenum) | 274 | const char **comment, unsigned int *rulenum) |
275 | { | 275 | { |
276 | struct ip6t_standard_target *t = (void *)ip6t_get_target(s); | 276 | struct ip6t_standard_target *t = (void *)ip6t_get_target(s); |
277 | 277 | ||
@@ -289,8 +289,8 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e, | |||
289 | && unconditional(&s->ipv6)) { | 289 | && unconditional(&s->ipv6)) { |
290 | /* Tail of chains: STANDARD target (return/policy) */ | 290 | /* Tail of chains: STANDARD target (return/policy) */ |
291 | *comment = *chainname == hookname | 291 | *comment = *chainname == hookname |
292 | ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY] | 292 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] |
293 | : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN]; | 293 | : comments[NF_IP6_TRACE_COMMENT_RETURN]; |
294 | } | 294 | } |
295 | return 1; | 295 | return 1; |
296 | } else | 296 | } else |
@@ -309,14 +309,14 @@ static void trace_packet(struct sk_buff *skb, | |||
309 | { | 309 | { |
310 | void *table_base; | 310 | void *table_base; |
311 | const struct ip6t_entry *root; | 311 | const struct ip6t_entry *root; |
312 | char *hookname, *chainname, *comment; | 312 | const char *hookname, *chainname, *comment; |
313 | unsigned int rulenum = 0; | 313 | unsigned int rulenum = 0; |
314 | 314 | ||
315 | table_base = (void *)private->entries[smp_processor_id()]; | 315 | table_base = private->entries[smp_processor_id()]; |
316 | root = get_entry(table_base, private->hook_entry[hook]); | 316 | root = get_entry(table_base, private->hook_entry[hook]); |
317 | 317 | ||
318 | hookname = chainname = (char *)hooknames[hook]; | 318 | hookname = chainname = hooknames[hook]; |
319 | comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE]; | 319 | comment = comments[NF_IP6_TRACE_COMMENT_RULE]; |
320 | 320 | ||
321 | IP6T_ENTRY_ITERATE(root, | 321 | IP6T_ENTRY_ITERATE(root, |
322 | private->size - private->hook_entry[hook], | 322 | private->size - private->hook_entry[hook], |
@@ -329,6 +329,12 @@ static void trace_packet(struct sk_buff *skb, | |||
329 | } | 329 | } |
330 | #endif | 330 | #endif |
331 | 331 | ||
332 | static inline __pure struct ip6t_entry * | ||
333 | ip6t_next_entry(const struct ip6t_entry *entry) | ||
334 | { | ||
335 | return (void *)entry + entry->next_offset; | ||
336 | } | ||
337 | |||
332 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ | 338 | /* Returns one of the generic firewall policies, like NF_ACCEPT. */ |
333 | unsigned int | 339 | unsigned int |
334 | ip6t_do_table(struct sk_buff *skb, | 340 | ip6t_do_table(struct sk_buff *skb, |
@@ -337,6 +343,8 @@ ip6t_do_table(struct sk_buff *skb, | |||
337 | const struct net_device *out, | 343 | const struct net_device *out, |
338 | struct xt_table *table) | 344 | struct xt_table *table) |
339 | { | 345 | { |
346 | #define tb_comefrom ((struct ip6t_entry *)table_base)->comefrom | ||
347 | |||
340 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); | 348 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
341 | bool hotdrop = false; | 349 | bool hotdrop = false; |
342 | /* Initializing verdict to NF_DROP keeps gcc happy. */ | 350 | /* Initializing verdict to NF_DROP keeps gcc happy. */ |
@@ -375,96 +383,86 @@ ip6t_do_table(struct sk_buff *skb, | |||
375 | back = get_entry(table_base, private->underflow[hook]); | 383 | back = get_entry(table_base, private->underflow[hook]); |
376 | 384 | ||
377 | do { | 385 | do { |
386 | struct ip6t_entry_target *t; | ||
387 | |||
378 | IP_NF_ASSERT(e); | 388 | IP_NF_ASSERT(e); |
379 | IP_NF_ASSERT(back); | 389 | IP_NF_ASSERT(back); |
380 | if (ip6_packet_match(skb, indev, outdev, &e->ipv6, | 390 | if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, |
381 | &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { | 391 | &mtpar.thoff, &mtpar.fragoff, &hotdrop) || |
382 | struct ip6t_entry_target *t; | 392 | IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { |
383 | 393 | e = ip6t_next_entry(e); | |
384 | if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) | 394 | continue; |
385 | goto no_match; | 395 | } |
386 | 396 | ||
387 | ADD_COUNTER(e->counters, | 397 | ADD_COUNTER(e->counters, |
388 | ntohs(ipv6_hdr(skb)->payload_len) + | 398 | ntohs(ipv6_hdr(skb)->payload_len) + |
389 | sizeof(struct ipv6hdr), 1); | 399 | sizeof(struct ipv6hdr), 1); |
390 | 400 | ||
391 | t = ip6t_get_target(e); | 401 | t = ip6t_get_target(e); |
392 | IP_NF_ASSERT(t->u.kernel.target); | 402 | IP_NF_ASSERT(t->u.kernel.target); |
393 | 403 | ||
394 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 404 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |
395 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | 405 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) |
396 | /* The packet is traced: log it */ | 406 | /* The packet is traced: log it */ |
397 | if (unlikely(skb->nf_trace)) | 407 | if (unlikely(skb->nf_trace)) |
398 | trace_packet(skb, hook, in, out, | 408 | trace_packet(skb, hook, in, out, |
399 | table->name, private, e); | 409 | table->name, private, e); |
400 | #endif | 410 | #endif |
401 | /* Standard target? */ | 411 | /* Standard target? */ |
402 | if (!t->u.kernel.target->target) { | 412 | if (!t->u.kernel.target->target) { |
403 | int v; | 413 | int v; |
404 | 414 | ||
405 | v = ((struct ip6t_standard_target *)t)->verdict; | 415 | v = ((struct ip6t_standard_target *)t)->verdict; |
406 | if (v < 0) { | 416 | if (v < 0) { |
407 | /* Pop from stack? */ | 417 | /* Pop from stack? */ |
408 | if (v != IP6T_RETURN) { | 418 | if (v != IP6T_RETURN) { |
409 | verdict = (unsigned)(-v) - 1; | 419 | verdict = (unsigned)(-v) - 1; |
410 | break; | 420 | break; |
411 | } | ||
412 | e = back; | ||
413 | back = get_entry(table_base, | ||
414 | back->comefrom); | ||
415 | continue; | ||
416 | } | ||
417 | if (table_base + v != (void *)e + e->next_offset | ||
418 | && !(e->ipv6.flags & IP6T_F_GOTO)) { | ||
419 | /* Save old back ptr in next entry */ | ||
420 | struct ip6t_entry *next | ||
421 | = (void *)e + e->next_offset; | ||
422 | next->comefrom | ||
423 | = (void *)back - table_base; | ||
424 | /* set back pointer to next entry */ | ||
425 | back = next; | ||
426 | } | 421 | } |
422 | e = back; | ||
423 | back = get_entry(table_base, back->comefrom); | ||
424 | continue; | ||
425 | } | ||
426 | if (table_base + v != ip6t_next_entry(e) | ||
427 | && !(e->ipv6.flags & IP6T_F_GOTO)) { | ||
428 | /* Save old back ptr in next entry */ | ||
429 | struct ip6t_entry *next = ip6t_next_entry(e); | ||
430 | next->comefrom = (void *)back - table_base; | ||
431 | /* set back pointer to next entry */ | ||
432 | back = next; | ||
433 | } | ||
427 | 434 | ||
428 | e = get_entry(table_base, v); | 435 | e = get_entry(table_base, v); |
429 | } else { | 436 | continue; |
430 | /* Targets which reenter must return | 437 | } |
431 | abs. verdicts */ | ||
432 | tgpar.target = t->u.kernel.target; | ||
433 | tgpar.targinfo = t->data; | ||
434 | 438 | ||
435 | #ifdef CONFIG_NETFILTER_DEBUG | 439 | /* Targets which reenter must return |
436 | ((struct ip6t_entry *)table_base)->comefrom | 440 | abs. verdicts */ |
437 | = 0xeeeeeeec; | 441 | tgpar.target = t->u.kernel.target; |
438 | #endif | 442 | tgpar.targinfo = t->data; |
439 | verdict = t->u.kernel.target->target(skb, | ||
440 | &tgpar); | ||
441 | 443 | ||
442 | #ifdef CONFIG_NETFILTER_DEBUG | 444 | #ifdef CONFIG_NETFILTER_DEBUG |
443 | if (((struct ip6t_entry *)table_base)->comefrom | 445 | tb_comefrom = 0xeeeeeeec; |
444 | != 0xeeeeeeec | ||
445 | && verdict == IP6T_CONTINUE) { | ||
446 | printk("Target %s reentered!\n", | ||
447 | t->u.kernel.target->name); | ||
448 | verdict = NF_DROP; | ||
449 | } | ||
450 | ((struct ip6t_entry *)table_base)->comefrom | ||
451 | = 0x57acc001; | ||
452 | #endif | 446 | #endif |
453 | if (verdict == IP6T_CONTINUE) | 447 | verdict = t->u.kernel.target->target(skb, &tgpar); |
454 | e = (void *)e + e->next_offset; | ||
455 | else | ||
456 | /* Verdict */ | ||
457 | break; | ||
458 | } | ||
459 | } else { | ||
460 | 448 | ||
461 | no_match: | 449 | #ifdef CONFIG_NETFILTER_DEBUG |
462 | e = (void *)e + e->next_offset; | 450 | if (tb_comefrom != 0xeeeeeeec && verdict == IP6T_CONTINUE) { |
451 | printk("Target %s reentered!\n", | ||
452 | t->u.kernel.target->name); | ||
453 | verdict = NF_DROP; | ||
463 | } | 454 | } |
455 | tb_comefrom = 0x57acc001; | ||
456 | #endif | ||
457 | if (verdict == IP6T_CONTINUE) | ||
458 | e = ip6t_next_entry(e); | ||
459 | else | ||
460 | /* Verdict */ | ||
461 | break; | ||
464 | } while (!hotdrop); | 462 | } while (!hotdrop); |
465 | 463 | ||
466 | #ifdef CONFIG_NETFILTER_DEBUG | 464 | #ifdef CONFIG_NETFILTER_DEBUG |
467 | ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON; | 465 | tb_comefrom = NETFILTER_LINK_POISON; |
468 | #endif | 466 | #endif |
469 | xt_info_rdunlock_bh(); | 467 | xt_info_rdunlock_bh(); |
470 | 468 | ||
@@ -475,6 +473,8 @@ ip6t_do_table(struct sk_buff *skb, | |||
475 | return NF_DROP; | 473 | return NF_DROP; |
476 | else return verdict; | 474 | else return verdict; |
477 | #endif | 475 | #endif |
476 | |||
477 | #undef tb_comefrom | ||
478 | } | 478 | } |
479 | 479 | ||
480 | /* Figures out from what hook each rule can be called: returns 0 if | 480 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -2191,7 +2191,7 @@ static bool icmp6_checkentry(const struct xt_mtchk_param *par) | |||
2191 | static struct xt_target ip6t_standard_target __read_mostly = { | 2191 | static struct xt_target ip6t_standard_target __read_mostly = { |
2192 | .name = IP6T_STANDARD_TARGET, | 2192 | .name = IP6T_STANDARD_TARGET, |
2193 | .targetsize = sizeof(int), | 2193 | .targetsize = sizeof(int), |
2194 | .family = AF_INET6, | 2194 | .family = NFPROTO_IPV6, |
2195 | #ifdef CONFIG_COMPAT | 2195 | #ifdef CONFIG_COMPAT |
2196 | .compatsize = sizeof(compat_int_t), | 2196 | .compatsize = sizeof(compat_int_t), |
2197 | .compat_from_user = compat_standard_from_user, | 2197 | .compat_from_user = compat_standard_from_user, |
@@ -2203,7 +2203,7 @@ static struct xt_target ip6t_error_target __read_mostly = { | |||
2203 | .name = IP6T_ERROR_TARGET, | 2203 | .name = IP6T_ERROR_TARGET, |
2204 | .target = ip6t_error, | 2204 | .target = ip6t_error, |
2205 | .targetsize = IP6T_FUNCTION_MAXNAMELEN, | 2205 | .targetsize = IP6T_FUNCTION_MAXNAMELEN, |
2206 | .family = AF_INET6, | 2206 | .family = NFPROTO_IPV6, |
2207 | }; | 2207 | }; |
2208 | 2208 | ||
2209 | static struct nf_sockopt_ops ip6t_sockopts = { | 2209 | static struct nf_sockopt_ops ip6t_sockopts = { |
@@ -2229,17 +2229,17 @@ static struct xt_match icmp6_matchstruct __read_mostly = { | |||
2229 | .matchsize = sizeof(struct ip6t_icmp), | 2229 | .matchsize = sizeof(struct ip6t_icmp), |
2230 | .checkentry = icmp6_checkentry, | 2230 | .checkentry = icmp6_checkentry, |
2231 | .proto = IPPROTO_ICMPV6, | 2231 | .proto = IPPROTO_ICMPV6, |
2232 | .family = AF_INET6, | 2232 | .family = NFPROTO_IPV6, |
2233 | }; | 2233 | }; |
2234 | 2234 | ||
2235 | static int __net_init ip6_tables_net_init(struct net *net) | 2235 | static int __net_init ip6_tables_net_init(struct net *net) |
2236 | { | 2236 | { |
2237 | return xt_proto_init(net, AF_INET6); | 2237 | return xt_proto_init(net, NFPROTO_IPV6); |
2238 | } | 2238 | } |
2239 | 2239 | ||
2240 | static void __net_exit ip6_tables_net_exit(struct net *net) | 2240 | static void __net_exit ip6_tables_net_exit(struct net *net) |
2241 | { | 2241 | { |
2242 | xt_proto_fini(net, AF_INET6); | 2242 | xt_proto_fini(net, NFPROTO_IPV6); |
2243 | } | 2243 | } |
2244 | 2244 | ||
2245 | static struct pernet_operations ip6_tables_net_ops = { | 2245 | static struct pernet_operations ip6_tables_net_ops = { |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 4f2310c93e01..3a6fd77f7761 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -204,10 +204,10 @@ int nf_queue(struct sk_buff *skb, | |||
204 | queuenum); | 204 | queuenum); |
205 | 205 | ||
206 | switch (pf) { | 206 | switch (pf) { |
207 | case AF_INET: | 207 | case NFPROTO_IPV4: |
208 | skb->protocol = htons(ETH_P_IP); | 208 | skb->protocol = htons(ETH_P_IP); |
209 | break; | 209 | break; |
210 | case AF_INET6: | 210 | case NFPROTO_IPV6: |
211 | skb->protocol = htons(ETH_P_IPV6); | 211 | skb->protocol = htons(ETH_P_IPV6); |
212 | break; | 212 | break; |
213 | } | 213 | } |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 150e5cf62f85..46dba5f043d5 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -329,6 +329,32 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target, | |||
329 | } | 329 | } |
330 | EXPORT_SYMBOL_GPL(xt_find_revision); | 330 | EXPORT_SYMBOL_GPL(xt_find_revision); |
331 | 331 | ||
332 | static char *textify_hooks(char *buf, size_t size, unsigned int mask) | ||
333 | { | ||
334 | static const char *const names[] = { | ||
335 | "PREROUTING", "INPUT", "FORWARD", | ||
336 | "OUTPUT", "POSTROUTING", "BROUTING", | ||
337 | }; | ||
338 | unsigned int i; | ||
339 | char *p = buf; | ||
340 | bool np = false; | ||
341 | int res; | ||
342 | |||
343 | *p = '\0'; | ||
344 | for (i = 0; i < ARRAY_SIZE(names); ++i) { | ||
345 | if (!(mask & (1 << i))) | ||
346 | continue; | ||
347 | res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]); | ||
348 | if (res > 0) { | ||
349 | size -= res; | ||
350 | p += res; | ||
351 | } | ||
352 | np = true; | ||
353 | } | ||
354 | |||
355 | return buf; | ||
356 | } | ||
357 | |||
332 | int xt_check_match(struct xt_mtchk_param *par, | 358 | int xt_check_match(struct xt_mtchk_param *par, |
333 | unsigned int size, u_int8_t proto, bool inv_proto) | 359 | unsigned int size, u_int8_t proto, bool inv_proto) |
334 | { | 360 | { |
@@ -351,9 +377,13 @@ int xt_check_match(struct xt_mtchk_param *par, | |||
351 | return -EINVAL; | 377 | return -EINVAL; |
352 | } | 378 | } |
353 | if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { | 379 | if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) { |
354 | printk("%s_tables: %s match: bad hook_mask %#x/%#x\n", | 380 | char used[64], allow[64]; |
381 | |||
382 | printk("%s_tables: %s match: used from hooks %s, but only " | ||
383 | "valid from %s\n", | ||
355 | xt_prefix[par->family], par->match->name, | 384 | xt_prefix[par->family], par->match->name, |
356 | par->hook_mask, par->match->hooks); | 385 | textify_hooks(used, sizeof(used), par->hook_mask), |
386 | textify_hooks(allow, sizeof(allow), par->match->hooks)); | ||
357 | return -EINVAL; | 387 | return -EINVAL; |
358 | } | 388 | } |
359 | if (par->match->proto && (par->match->proto != proto || inv_proto)) { | 389 | if (par->match->proto && (par->match->proto != proto || inv_proto)) { |
@@ -497,9 +527,13 @@ int xt_check_target(struct xt_tgchk_param *par, | |||
497 | return -EINVAL; | 527 | return -EINVAL; |
498 | } | 528 | } |
499 | if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { | 529 | if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { |
500 | printk("%s_tables: %s target: bad hook_mask %#x/%#x\n", | 530 | char used[64], allow[64]; |
531 | |||
532 | printk("%s_tables: %s target: used from hooks %s, but only " | ||
533 | "usable from %s\n", | ||
501 | xt_prefix[par->family], par->target->name, | 534 | xt_prefix[par->family], par->target->name, |
502 | par->hook_mask, par->target->hooks); | 535 | textify_hooks(used, sizeof(used), par->hook_mask), |
536 | textify_hooks(allow, sizeof(allow), par->target->hooks)); | ||
503 | return -EINVAL; | 537 | return -EINVAL; |
504 | } | 538 | } |
505 | if (par->target->proto && (par->target->proto != proto || inv_proto)) { | 539 | if (par->target->proto && (par->target->proto != proto || inv_proto)) { |