From 6e23ae2a48750bda407a4a58f52a4865d7308bf5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 19 Nov 2007 18:53:30 -0800 Subject: [NETFILTER]: Introduce NF_INET_ hook values The IPv4 and IPv6 hook values are identical, yet some code tries to figure out the "correct" value by looking at the address family. Introduce NF_INET_* values for both IPv4 and IPv6. The old values are kept in a #ifndef __KERNEL__ section for userspace compatibility. Signed-off-by: Patrick McHardy Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_tables.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index d79ed69cbc1f..54da61603eff 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -156,10 +156,10 @@ struct ipt_getinfo unsigned int valid_hooks; /* Hook entry points: one per netfilter hook. */ - unsigned int hook_entry[NF_IP_NUMHOOKS]; + unsigned int hook_entry[NF_INET_NUMHOOKS]; /* Underflow points. */ - unsigned int underflow[NF_IP_NUMHOOKS]; + unsigned int underflow[NF_INET_NUMHOOKS]; /* Number of entries */ unsigned int num_entries; @@ -185,10 +185,10 @@ struct ipt_replace unsigned int size; /* Hook entry points. */ - unsigned int hook_entry[NF_IP_NUMHOOKS]; + unsigned int hook_entry[NF_INET_NUMHOOKS]; /* Underflow points. */ - unsigned int underflow[NF_IP_NUMHOOKS]; + unsigned int underflow[NF_INET_NUMHOOKS]; /* Information about old entries: */ /* Number of counters (must be equal to current number of entries). */ -- cgit v1.2.3-59-g8ed1b From e2cf5ecbea861ff05105bbd40f4f0d7823d9e213 Mon Sep 17 00:00:00 2001 From: Laszlo Attila Toth Date: Tue, 4 Dec 2007 23:30:18 -0800 Subject: [NETFILTER]: ipt_addrtype: limit address type checking to an interface Addrtype match has a new revision (1), which lets address type checking limited to the interface the current packet belongs to. Either incoming or outgoing interface can be used depending on the current hook. In the FORWARD hook two maches should be used if both interfaces have to be checked. The new structure is ipt_addrtype_info_v1. Revision 0 lets older userspace programs use the match as earlier. ipt_addrtype_info is used. Signed-off-by: Laszlo Attila Toth Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ipt_addrtype.h | 14 ++++ net/ipv4/netfilter/ipt_addrtype.c | 104 +++++++++++++++++++++++----- 2 files changed, 102 insertions(+), 16 deletions(-) (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h index 166ed01a8122..446de6aef983 100644 --- a/include/linux/netfilter_ipv4/ipt_addrtype.h +++ b/include/linux/netfilter_ipv4/ipt_addrtype.h @@ -1,6 +1,20 @@ #ifndef _IPT_ADDRTYPE_H #define _IPT_ADDRTYPE_H +enum { + IPT_ADDRTYPE_INVERT_SOURCE = 0x0001, + IPT_ADDRTYPE_INVERT_DEST = 0x0002, + IPT_ADDRTYPE_LIMIT_IFACE_IN = 0x0004, + IPT_ADDRTYPE_LIMIT_IFACE_OUT = 0x0008, +}; + +struct ipt_addrtype_info_v1 { + u_int16_t source; /* source-type mask */ + u_int16_t dest; /* dest-type mask */ + u_int32_t flags; +}; + +/* revision 0 */ struct ipt_addrtype_info { u_int16_t source; /* source-type mask */ u_int16_t dest; /* dest-type mask */ diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index b75421c5e087..14394c6a3c29 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -2,6 +2,7 @@ * iptables module to match inet_addr_type() of an ip. * * Copyright (c) 2004 Patrick McHardy + * (C) 2007 Laszlo Attila Toth * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,45 +23,116 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy "); MODULE_DESCRIPTION("iptables addrtype match"); -static inline bool match_type(__be32 addr, u_int16_t mask) +static inline bool match_type(const struct net_device *dev, __be32 addr, + u_int16_t mask) { - return !!(mask & (1 << inet_addr_type(addr))); + return !!(mask & (1 << inet_dev_addr_type(dev, addr))); } static bool -addrtype_mt(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const struct xt_match *match, - const void *matchinfo, int offset, unsigned int protoff, - bool *hotdrop) +addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) { const struct ipt_addrtype_info *info = matchinfo; const struct iphdr *iph = ip_hdr(skb); bool ret = true; if (info->source) - ret &= match_type(iph->saddr, info->source)^info->invert_source; + ret &= match_type(NULL, iph->saddr, info->source) ^ + info->invert_source; if (info->dest) - ret &= match_type(iph->daddr, info->dest)^info->invert_dest; + ret &= match_type(NULL, iph->daddr, info->dest) ^ + info->invert_dest; return ret; } -static struct xt_match addrtype_mt_reg __read_mostly = { - .name = "addrtype", - .family = AF_INET, - .match = addrtype_mt, - .matchsize = sizeof(struct ipt_addrtype_info), - .me = THIS_MODULE +static bool +addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) +{ + const struct ipt_addrtype_info_v1 *info = matchinfo; + const struct iphdr *iph = ip_hdr(skb); + const struct net_device *dev = NULL; + bool ret = true; + + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) + dev = in; + else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) + dev = out; + + if (info->source) + ret &= match_type(dev, iph->saddr, info->source) ^ + (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); + if (ret && info->dest) + ret &= match_type(dev, iph->daddr, info->dest) ^ + (info->flags & IPT_ADDRTYPE_INVERT_DEST); + return ret; +} + +static bool +addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask) +{ + struct ipt_addrtype_info_v1 *info = matchinfo; + + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && + info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { + printk(KERN_ERR "ipt_addrtype: both incoming and outgoing " + "interface limitation cannot be selected\n"); + return false; + } + + if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && + info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { + printk(KERN_ERR "ipt_addrtype: output interface limitation " + "not valid in PRE_ROUTING and INPUT\n"); + return false; + } + + if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && + info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { + printk(KERN_ERR "ipt_addrtype: input interface limitation " + "not valid in POST_ROUTING and OUTPUT\n"); + return false; + } + + return true; +} + +static struct xt_match addrtype_mt_reg[] __read_mostly = { + { + .name = "addrtype", + .family = AF_INET, + .match = addrtype_mt_v0, + .matchsize = sizeof(struct ipt_addrtype_info), + .me = THIS_MODULE + }, + { + .name = "addrtype", + .family = AF_INET, + .revision = 1, + .match = addrtype_mt_v1, + .checkentry = addrtype_mt_checkentry_v1, + .matchsize = sizeof(struct ipt_addrtype_info_v1), + .me = THIS_MODULE + } }; static int __init addrtype_mt_init(void) { - return xt_register_match(&addrtype_mt_reg); + return xt_register_matches(addrtype_mt_reg, + ARRAY_SIZE(addrtype_mt_reg)); } static void __exit addrtype_mt_exit(void) { - xt_unregister_match(&addrtype_mt_reg); + xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); } module_init(addrtype_mt_init); -- cgit v1.2.3-59-g8ed1b From 89c002d66aafab93814b38d8dae43fa50aec390a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 17 Dec 2007 21:46:59 -0800 Subject: [NETFILTER]: {ip,ip6,arp}_tables: consolidate iterator macros Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/x_tables.h | 43 ++++++++++++++++++++++++ include/linux/netfilter_arp/arp_tables.h | 17 ++-------- include/linux/netfilter_ipv4/ip_tables.h | 55 ++++--------------------------- include/linux/netfilter_ipv6/ip6_tables.h | 36 +++----------------- 4 files changed, 55 insertions(+), 96 deletions(-) (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 616e6f4ede59..8ab754e14ec0 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -126,6 +126,49 @@ struct xt_counters_info #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ +/* fn returns 0 to continue iteration */ +#define XT_MATCH_ITERATE(type, e, fn, args...) \ +({ \ + unsigned int __i; \ + int __ret = 0; \ + struct xt_entry_match *__m; \ + \ + for (__i = sizeof(type); \ + __i < (e)->target_offset; \ + __i += __m->u.match_size) { \ + __m = (void *)e + __i; \ + \ + __ret = fn(__m , ## args); \ + if (__ret != 0) \ + break; \ + } \ + __ret; \ +}) + +/* fn returns 0 to continue iteration */ +#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \ +({ \ + unsigned int __i, __n; \ + int __ret = 0; \ + type *__entry; \ + \ + for (__i = 0, __n = 0; __i < (size); \ + __i += __entry->next_offset, __n++) { \ + __entry = (void *)(entries) + __i; \ + if (__n < n) \ + continue; \ + \ + __ret = fn(__entry , ## args); \ + if (__ret != 0) \ + break; \ + } \ + __ret; \ +}) + +/* fn returns 0 to continue iteration */ +#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \ + XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) + #ifdef __KERNEL__ #include diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index 2fc73fa8e37f..e44811b9be6c 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -217,21 +217,8 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e } /* fn returns 0 to continue iteration */ -#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct arpt_entry *__entry; \ - \ - for (__i = 0; __i < (size); __i += __entry->next_offset) { \ - __entry = (void *)(entries) + __i; \ - \ - __ret = fn(__entry , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) +#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) /* * Main firewall chains definitions and global var's definitions. diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 54da61603eff..1e0cfca7f354 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -229,60 +229,17 @@ ipt_get_target(struct ipt_entry *e) } /* fn returns 0 to continue iteration */ -#define IPT_MATCH_ITERATE(e, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ipt_entry_match *__match; \ - \ - for (__i = sizeof(struct ipt_entry); \ - __i < (e)->target_offset; \ - __i += __match->u.match_size) { \ - __match = (void *)(e) + __i; \ - \ - __ret = fn(__match , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) +#define IPT_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ -#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ipt_entry *__entry; \ - \ - for (__i = 0; __i < (size); __i += __entry->next_offset) { \ - __entry = (void *)(entries) + __i; \ - \ - __ret = fn(__entry , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) +#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) /* fn returns 0 to continue iteration */ #define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ -({ \ - unsigned int __i, __n; \ - int __ret = 0; \ - struct ipt_entry *__entry; \ - \ - for (__i = 0, __n = 0; __i < (size); \ - __i += __entry->next_offset, __n++) { \ - __entry = (void *)(entries) + __i; \ - if (__n < n) \ - continue; \ - \ - __ret = fn(__entry , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) + XT_ENTRY_ITERATE_CONTINUE(struct ipt_entry, entries, size, n, fn, \ + ## args) /* * Main firewall chains definitions and global var's definitions. diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 2e98654188b3..8257b52015f3 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -289,40 +289,12 @@ ip6t_get_target(struct ip6t_entry *e) } /* fn returns 0 to continue iteration */ -#define IP6T_MATCH_ITERATE(e, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ip6t_entry_match *__m; \ - \ - for (__i = sizeof(struct ip6t_entry); \ - __i < (e)->target_offset; \ - __i += __m->u.match_size) { \ - __m = (void *)(e) + __i; \ - \ - __ret = fn(__m , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) +#define IP6T_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ -#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ -({ \ - unsigned int __i; \ - int __ret = 0; \ - struct ip6t_entry *__e; \ - \ - for (__i = 0; __i < (size); __i += __e->next_offset) { \ - __e = (void *)(entries) + __i; \ - \ - __ret = fn(__e , ## args); \ - if (__ret != 0) \ - break; \ - } \ - __ret; \ -}) +#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) /* * Main firewall chains definitions and global var's definitions. -- cgit v1.2.3-59-g8ed1b From 73cd598df46a73d6f02063f2520df115a9b88aa5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 17 Dec 2007 21:47:32 -0800 Subject: [NETFILTER]: ip_tables: fix compat types Use compat types and compat iterators when dealing with compat entries for clarity. This doesn't actually make a difference for ip_tables, but is needed for ip6_tables and arp_tables. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_ipv4/ip_tables.h | 25 ++++++++++++---- net/ipv4/netfilter/ip_tables.c | 51 +++++++++++++++++--------------- 2 files changed, 47 insertions(+), 29 deletions(-) (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 1e0cfca7f354..45fcad91e67b 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -236,11 +236,6 @@ ipt_get_target(struct ipt_entry *e) #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) -/* fn returns 0 to continue iteration */ -#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ - XT_ENTRY_ITERATE_CONTINUE(struct ipt_entry, entries, size, n, fn, \ - ## args) - /* * Main firewall chains definitions and global var's definitions. */ @@ -316,8 +311,28 @@ struct compat_ipt_entry unsigned char elems[0]; }; +/* Helper functions */ +static inline struct ipt_entry_target * +compat_ipt_get_target(struct compat_ipt_entry *e) +{ + return (void *)e + e->target_offset; +} + #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) +/* fn returns 0 to continue iteration */ +#define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args) + +/* fn returns 0 to continue iteration */ +#define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args) + +/* fn returns 0 to continue iteration */ +#define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ + XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \ + fn, ## args) + #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */ diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index cc896fe2fd92..d8caa1ed4879 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1559,7 +1559,7 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i) } static inline int -compat_release_entry(struct ipt_entry *e, unsigned int *i) +compat_release_entry(struct compat_ipt_entry *e, unsigned int *i) { struct ipt_entry_target *t; @@ -1567,14 +1567,14 @@ compat_release_entry(struct ipt_entry *e, unsigned int *i) return 1; /* Cleanup all matches */ - IPT_MATCH_ITERATE(e, compat_release_match, NULL); - t = ipt_get_target(e); + COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL); + t = compat_ipt_get_target(e); module_put(t->u.kernel.target->me); return 0; } static inline int -check_compat_entry_size_and_hooks(struct ipt_entry *e, +check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, struct xt_table_info *newinfo, unsigned int *size, unsigned char *base, @@ -1603,19 +1603,20 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } - ret = check_entry(e, name); + /* For purposes of check_entry casting the compat entry is fine */ + ret = check_entry((struct ipt_entry *)e, name); if (ret) return ret; off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); entry_offset = (void *)e - (void *)base; j = 0; - ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip, - e->comefrom, &off, &j); + ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name, + &e->ip, e->comefrom, &off, &j); if (ret != 0) goto release_matches; - t = ipt_get_target(e); + t = compat_ipt_get_target(e); target = try_then_request_module(xt_find_target(AF_INET, t->u.user.name, t->u.user.revision), @@ -1643,7 +1644,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, } /* Clear counters and comefrom */ - e->counters = ((struct ipt_counters) { 0, 0 }); + memset(&e->counters, 0, sizeof(e->counters)); e->comefrom = 0; (*i)++; @@ -1657,7 +1658,7 @@ release_matches: } static int -compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, +compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { @@ -1671,15 +1672,17 @@ compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, origsize = *size; de = (struct ipt_entry *)*dstptr; memcpy(de, e, sizeof(struct ipt_entry)); + memcpy(&de->counters, &e->counters, sizeof(e->counters)); - *dstptr += sizeof(struct compat_ipt_entry); + *dstptr += sizeof(struct ipt_entry); *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); - ret = IPT_MATCH_ITERATE(e, xt_compat_match_from_user, dstptr, size); + ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user, + dstptr, size); if (ret) return ret; de->target_offset = e->target_offset - (origsize - *size); - t = ipt_get_target(e); + t = compat_ipt_get_target(e); target = t->u.kernel.target; xt_compat_target_from_user(t, dstptr, size); @@ -1746,11 +1749,11 @@ translate_compat_table(const char *name, j = 0; xt_compat_lock(AF_INET); /* Walk through entries, checking offsets. */ - ret = IPT_ENTRY_ITERATE(entry0, total_size, - check_compat_entry_size_and_hooks, - info, &size, entry0, - entry0 + total_size, - hook_entries, underflows, &j, name); + ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, + check_compat_entry_size_and_hooks, + info, &size, entry0, + entry0 + total_size, + hook_entries, underflows, &j, name); if (ret != 0) goto out_unlock; @@ -1791,9 +1794,9 @@ translate_compat_table(const char *name, entry1 = newinfo->entries[raw_smp_processor_id()]; pos = entry1; size = total_size; - ret = IPT_ENTRY_ITERATE(entry0, total_size, - compat_copy_entry_from_user, &pos, &size, - name, newinfo, entry1); + ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, + compat_copy_entry_from_user, &pos, &size, + name, newinfo, entry1); compat_flush_offsets(); xt_compat_unlock(AF_INET); if (ret) @@ -1808,8 +1811,8 @@ translate_compat_table(const char *name, name, &i); if (ret) { j -= i; - IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i, - compat_release_entry, &j); + COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, + compat_release_entry, &j); IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); xt_free_table_info(newinfo); return ret; @@ -1828,7 +1831,7 @@ translate_compat_table(const char *name, free_newinfo: xt_free_table_info(newinfo); out: - IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); + COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); return ret; out_unlock: compat_flush_offsets(); -- cgit v1.2.3-59-g8ed1b From 8b6f3f62fea7b85fce8f7d12aabba7b191bf60d2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 14 Jan 2008 23:33:14 -0800 Subject: [NETFILTER]: Annotate start of kernel fields in NF headers Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/xt_RATEEST.h | 2 ++ include/linux/netfilter/xt_connlimit.h | 2 +- include/linux/netfilter/xt_hashlimit.h | 2 +- include/linux/netfilter/xt_quota.h | 2 ++ include/linux/netfilter/xt_rateest.h | 2 ++ include/linux/netfilter/xt_statistic.h | 1 + include/linux/netfilter/xt_string.h | 2 ++ include/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 1 + 8 files changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter/xt_RATEEST.h b/include/linux/netfilter/xt_RATEEST.h index 670f2e49d4fb..f79e3133cbea 100644 --- a/include/linux/netfilter/xt_RATEEST.h +++ b/include/linux/netfilter/xt_RATEEST.h @@ -5,6 +5,8 @@ struct xt_rateest_target_info { char name[IFNAMSIZ]; int8_t interval; u_int8_t ewma_log; + + /* Used internally by the kernel */ struct xt_rateest *est __attribute__((aligned(8))); }; diff --git a/include/linux/netfilter/xt_connlimit.h b/include/linux/netfilter/xt_connlimit.h index 315d2dce9da6..7e3284bcbd2b 100644 --- a/include/linux/netfilter/xt_connlimit.h +++ b/include/linux/netfilter/xt_connlimit.h @@ -15,7 +15,7 @@ struct xt_connlimit_info { }; unsigned int limit, inverse; - /* this needs to be at the end */ + /* Used internally by the kernel */ struct xt_connlimit_data *data __attribute__((aligned(8))); }; diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h index b4556b8edbfd..c19972e4564d 100644 --- a/include/linux/netfilter/xt_hashlimit.h +++ b/include/linux/netfilter/xt_hashlimit.h @@ -29,9 +29,9 @@ struct hashlimit_cfg { struct xt_hashlimit_info { char name [IFNAMSIZ]; /* name */ struct hashlimit_cfg cfg; - struct xt_hashlimit_htable *hinfo; /* Used internally by the kernel */ + struct xt_hashlimit_htable *hinfo; union { void *ptr; struct xt_hashlimit_info *master; diff --git a/include/linux/netfilter/xt_quota.h b/include/linux/netfilter/xt_quota.h index acd7fd77bbee..4c8368d781e5 100644 --- a/include/linux/netfilter/xt_quota.h +++ b/include/linux/netfilter/xt_quota.h @@ -9,6 +9,8 @@ enum xt_quota_flags { struct xt_quota_info { u_int32_t flags; u_int32_t pad; + + /* Used internally by the kernel */ aligned_u64 quota; struct xt_quota_info *master; }; diff --git a/include/linux/netfilter/xt_rateest.h b/include/linux/netfilter/xt_rateest.h index 51948e15aea2..2010cb74250f 100644 --- a/include/linux/netfilter/xt_rateest.h +++ b/include/linux/netfilter/xt_rateest.h @@ -26,6 +26,8 @@ struct xt_rateest_match_info { u_int32_t pps1; u_int32_t bps2; u_int32_t pps2; + + /* Used internally by the kernel */ struct xt_rateest *est1 __attribute__((aligned(8))); struct xt_rateest *est2 __attribute__((aligned(8))); }; diff --git a/include/linux/netfilter/xt_statistic.h b/include/linux/netfilter/xt_statistic.h index c344e9916e23..3d38bc975048 100644 --- a/include/linux/netfilter/xt_statistic.h +++ b/include/linux/netfilter/xt_statistic.h @@ -23,6 +23,7 @@ struct xt_statistic_info { struct { u_int32_t every; u_int32_t packet; + /* Used internally by the kernel */ u_int32_t count; } nth; } u; diff --git a/include/linux/netfilter/xt_string.h b/include/linux/netfilter/xt_string.h index 3b3419f2637d..bb21dd1aee2d 100644 --- a/include/linux/netfilter/xt_string.h +++ b/include/linux/netfilter/xt_string.h @@ -12,6 +12,8 @@ struct xt_string_info char pattern[XT_STRING_MAX_PATTERN_SIZE]; u_int8_t patlen; u_int8_t invert; + + /* Used internally by the kernel */ struct ts_config __attribute__((aligned(8))) *config; }; diff --git a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h index daf50be22c9d..e5a3687c8a72 100644 --- a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h +++ b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h @@ -27,6 +27,7 @@ struct ipt_clusterip_tgt_info { u_int32_t hash_mode; u_int32_t hash_initval; + /* Used internally by the kernel */ struct clusterip_config *config; }; -- cgit v1.2.3-59-g8ed1b From f72e25a897c7edda03a0e1f767925d98772684da Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 14 Jan 2008 23:42:47 -0800 Subject: [NETFILTER]: Rename ipt_iprange to xt_iprange This patch moves ipt_iprange to xt_iprange, in preparation for adding IPv6 support to xt_iprange. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/Kbuild | 1 + include/linux/netfilter/xt_iprange.h | 17 +++++++ include/linux/netfilter_ipv4/ipt_iprange.h | 6 +-- net/ipv4/netfilter/Kconfig | 10 ---- net/ipv4/netfilter/Makefile | 1 - net/ipv4/netfilter/ipt_iprange.c | 77 ------------------------------ net/netfilter/Kconfig | 11 +++++ net/netfilter/Makefile | 1 + net/netfilter/xt_iprange.c | 76 +++++++++++++++++++++++++++++ 9 files changed, 107 insertions(+), 93 deletions(-) create mode 100644 include/linux/netfilter/xt_iprange.h delete mode 100644 net/ipv4/netfilter/ipt_iprange.c create mode 100644 net/netfilter/xt_iprange.c (limited to 'include/linux/netfilter_ipv4') diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild index ac9e6429f747..91fef0cae42f 100644 --- a/include/linux/netfilter/Kbuild +++ b/include/linux/netfilter/Kbuild @@ -21,6 +21,7 @@ header-y += xt_dccp.h header-y += xt_dscp.h header-y += xt_esp.h header-y += xt_hashlimit.h +header-y += xt_iprange.h header-y += xt_helper.h header-y += xt_length.h header-y += xt_limit.h diff --git a/include/linux/netfilter/xt_iprange.h b/include/linux/netfilter/xt_iprange.h new file mode 100644 index 000000000000..a4299c7d3680 --- /dev/null +++ b/include/linux/netfilter/xt_iprange.h @@ -0,0 +1,17 @@ +#ifndef _LINUX_NETFILTER_XT_IPRANGE_H +#define _LINUX_NETFILTER_XT_IPRANGE_H 1 + +enum { + IPRANGE_SRC = 1 << 0, /* match source IP address */ + IPRANGE_DST = 1 << 1, /* match destination IP address */ + IPRANGE_SRC_INV = 1 << 4, /* negate the condition */ + IPRANGE_DST_INV = 1 << 5, /* -"- */ +}; + +struct xt_iprange_mtinfo { + union nf_inet_addr src_min, src_max; + union nf_inet_addr dst_min, dst_max; + u_int8_t flags; +}; + +#endif /* _LINUX_NETFILTER_XT_IPRANGE_H */ diff --git a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h index a92fefc3c7ec..5f1aebde4d2f 100644 --- a/include/linux/netfilter_ipv4/ipt_iprange.h +++ b/include/linux/netfilter_ipv4/ipt_iprange.h @@ -2,11 +2,7 @@ #define _IPT_IPRANGE_H #include - -#define IPRANGE_SRC 0x01 /* Match source IP address */ -#define IPRANGE_DST 0x02 /* Match destination IP address */ -#define IPRANGE_SRC_INV 0x10 /* Negate the condition */ -#define IPRANGE_DST_INV 0x20 /* Negate the condition */ +#include struct ipt_iprange { /* Inclusive: network order. */ diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 10ca307b8499..9a077cb24798 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -57,16 +57,6 @@ config IP_NF_IPTABLES To compile it as a module, choose M here. If unsure, say N. # The matches. -config IP_NF_MATCH_IPRANGE - tristate '"iprange" match support' - depends on IP_NF_IPTABLES - depends on NETFILTER_ADVANCED - help - This option makes possible to match IP addresses against IP address - ranges. - - To compile it as a module, choose M here. If unsure, say N. - config IP_NF_MATCH_RECENT tristate '"recent" match support' depends on IP_NF_IPTABLES diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index fd7d4a5b436c..0c7dc78a62e9 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -44,7 +44,6 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o -obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c deleted file mode 100644 index 9a2aba816c9b..000000000000 --- a/net/ipv4/netfilter/ipt_iprange.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * iptables module to match IP address ranges - * - * (C) 2003 Jozsef Kadlecsik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jozsef Kadlecsik "); -MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); - -static bool -iprange_mt(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const struct xt_match *match, - const void *matchinfo, int offset, unsigned int protoff, - bool *hotdrop) -{ - const struct ipt_iprange_info *info = matchinfo; - const struct iphdr *iph = ip_hdr(skb); - - if (info->flags & IPRANGE_SRC) { - if ((ntohl(iph->saddr) < ntohl(info->src.min_ip) - || ntohl(iph->saddr) > ntohl(info->src.max_ip)) - ^ !!(info->flags & IPRANGE_SRC_INV)) { - pr_debug("src IP %u.%u.%u.%u NOT in range %s" - "%u.%u.%u.%u-%u.%u.%u.%u\n", - NIPQUAD(iph->saddr), - info->flags & IPRANGE_SRC_INV ? "(INV) " : "", - NIPQUAD(info->src.min_ip), - NIPQUAD(info->src.max_ip)); - return false; - } - } - if (info->flags & IPRANGE_DST) { - if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip) - || ntohl(iph->daddr) > ntohl(info->dst.max_ip)) - ^ !!(info->flags & IPRANGE_DST_INV)) { - pr_debug("dst IP %u.%u.%u.%u NOT in range %s" - "%u.%u.%u.%u-%u.%u.%u.%u\n", - NIPQUAD(iph->daddr), - info->flags & IPRANGE_DST_INV ? "(INV) " : "", - NIPQUAD(info->dst.min_ip), - NIPQUAD(info->dst.max_ip)); - return false; - } - } - return true; -} - -static struct xt_match iprange_mt_reg __read_mostly = { - .name = "iprange", - .family = AF_INET, - .match = iprange_mt, - .matchsize = sizeof(struct ipt_iprange_info), - .me = THIS_MODULE -}; - -static int __init iprange_mt_init(void) -{ - return xt_register_match(&iprange_mt_reg); -} - -static void __exit iprange_mt_exit(void) -{ - xt_unregister_match(&iprange_mt_reg); -} - -module_init(iprange_mt_init); -module_exit(iprange_mt_exit); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 79d71437e310..daf5b881064d 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -567,6 +567,17 @@ config NETFILTER_XT_MATCH_HELPER To compile it as a module, choose M here. If unsure, say Y. +config NETFILTER_XT_MATCH_IPRANGE + tristate '"iprange" address range match support' + depends on NETFILTER_XTABLES + depends on NETFILTER_ADVANCED + ---help--- + This option adds a "iprange" match, which allows you to match based on + an IP address range. (Normal iptables only matches on single addresses + with an optional mask.) + + If unsure, say M. + config NETFILTER_XT_MATCH_LENGTH tristate '"length" match support' depends on NETFILTER_XTABLES diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 3b9ea8fb3a07..c910caee0d4f 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o +obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c new file mode 100644 index 000000000000..c57a6cf8a081 --- /dev/null +++ b/net/netfilter/xt_iprange.c @@ -0,0 +1,76 @@ +/* + * xt_iprange - Netfilter module to match IP address ranges + * + * (C) 2003 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +static bool +iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) +{ + const struct ipt_iprange_info *info = matchinfo; + const struct iphdr *iph = ip_hdr(skb); + + if (info->flags & IPRANGE_SRC) { + if ((ntohl(iph->saddr) < ntohl(info->src.min_ip) + || ntohl(iph->saddr) > ntohl(info->src.max_ip)) + ^ !!(info->flags & IPRANGE_SRC_INV)) { + pr_debug("src IP %u.%u.%u.%u NOT in range %s" + "%u.%u.%u.%u-%u.%u.%u.%u\n", + NIPQUAD(iph->saddr), + info->flags & IPRANGE_SRC_INV ? "(INV) " : "", + NIPQUAD(info->src.min_ip), + NIPQUAD(info->src.max_ip)); + return false; + } + } + if (info->flags & IPRANGE_DST) { + if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip) + || ntohl(iph->daddr) > ntohl(info->dst.max_ip)) + ^ !!(info->flags & IPRANGE_DST_INV)) { + pr_debug("dst IP %u.%u.%u.%u NOT in range %s" + "%u.%u.%u.%u-%u.%u.%u.%u\n", + NIPQUAD(iph->daddr), + info->flags & IPRANGE_DST_INV ? "(INV) " : "", + NIPQUAD(info->dst.min_ip), + NIPQUAD(info->dst.max_ip)); + return false; + } + } + return true; +} + +static struct xt_match iprange_mt_reg __read_mostly = { + .name = "iprange", + .family = AF_INET, + .match = iprange_mt_v0, + .matchsize = sizeof(struct ipt_iprange_info), + .me = THIS_MODULE +}; + +static int __init iprange_mt_init(void) +{ + return xt_register_match(&iprange_mt_reg); +} + +static void __exit iprange_mt_exit(void) +{ + xt_unregister_match(&iprange_mt_reg); +} + +module_init(iprange_mt_init); +module_exit(iprange_mt_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); -- cgit v1.2.3-59-g8ed1b