* [PATCHv2 0/2] Find address type on the packet's interface [not found] <20071024-160736-1193234856.pather@balabit.hu> @ 2007-10-24 14:21 ` Laszlo Attila Toth [not found] ` <20071024-160736-1193234856.panther@balabit.hu> 0 siblings, 1 reply; 5+ messages in thread From: Laszlo Attila Toth @ 2007-10-24 14:21 UTC (permalink / raw) To: kaber; +Cc: netfilter-devel, Laszlo Attila Toth Hi Patrick, This extension of ipt_addrtype match lets the address type checking be limited to the incoming or outgoing interface of the packets except in the FORWARD hook because either incoming or outgouing interface could be used. Because of this extension the match has a new revision. Rev 0 can be used by older tools and rev 1 is for the modified iptables match. The latter one is for revision 1 only. Usage: iptables .... -m addrtype --...-type ... --limit-iface ... Regards, Attila ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <20071024-160736-1193234856.panther@balabit.hu>]
[parent not found: <69d5a58b11473e65f29837c537a6d29b4e02e19b.1193232178.git.panther@balabit.hu>]
* [PATCHv2 1/2] Find address type on a specific or on any interface [not found] ` <69d5a58b11473e65f29837c537a6d29b4e02e19b.1193232178.git.panther@balabit.hu> @ 2007-10-24 14:21 ` Laszlo Attila Toth 0 siblings, 0 replies; 5+ messages in thread From: Laszlo Attila Toth @ 2007-10-24 14:21 UTC (permalink / raw) To: kaber; +Cc: netfilter-devel, Laszlo Attila Toth Address type search can be limited to any interface by inet_dev_addr_type function. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> --- include/net/route.h | 1 + net/ipv4/fib_frontend.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/net/route.h b/include/net/route.h index f7ce625..4c82218 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -119,6 +119,7 @@ extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mt extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned inet_addr_type(__be32 addr); +extern unsigned inet_dev_addr_type(__be32 addr, const struct net_device *on_dev); extern void ip_rt_multicast_event(struct in_device *); extern int ip_rt_ioctl(unsigned int cmd, void __user *arg); extern void ip_rt_get_source(u8 *src, struct rtable *rt); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 78b514b..06ef507 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -147,7 +147,11 @@ out: return dev; } -unsigned inet_addr_type(__be32 addr) +/* + * Find address type as if only "dev" was present in the system. If + * on_dev is NULL then all interfaces are taken into consideration. + */ +static inline unsigned __inet_dev_addr_type(__be32 addr, const struct net_device *dev) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; @@ -166,13 +170,24 @@ unsigned inet_addr_type(__be32 addr) ret = RTN_UNICAST; if (!ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res)) { - ret = res.type; + if ((!dev || dev == res.fi->fib_dev)) + ret = res.type; fib_res_put(&res); } } return ret; } +unsigned inet_addr_type(__be32 addr) +{ + return __inet_dev_addr_type(addr, NULL); +} + +unsigned inet_dev_addr_type(__be32 addr, const struct net_device *dev) +{ + return __inet_dev_addr_type(addr, dev); +} + /* Given (packet source, input interface) and optional (dst, oif, tos): - (main) check, that source is valid i.e. not broadcast or our local address. @@ -922,4 +937,5 @@ void __init ip_fib_init(void) } EXPORT_SYMBOL(inet_addr_type); +EXPORT_SYMBOL(inet_dev_addr_type); EXPORT_SYMBOL(ip_dev_find); -- 1.5.2.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
[parent not found: <364a3c83187b863e5a7fd28803383b05fb29b6e6.1193232178.git.panther@balabit.hu>]
* [PATCHv2 2/2] Addrtype match extension: limit addrtype check on the packet's interface [not found] ` <364a3c83187b863e5a7fd28803383b05fb29b6e6.1193232178.git.panther@balabit.hu> @ 2007-10-24 14:21 ` Laszlo Attila Toth 2007-11-14 10:25 ` Patrick McHardy 0 siblings, 1 reply; 5+ messages in thread From: Laszlo Attila Toth @ 2007-10-24 14:21 UTC (permalink / raw) To: kaber; +Cc: netfilter-devel, Laszlo Attila Toth Addrtype match has a new revision (1), which lets address type checking limit to the interface the current packet belongs to. The limitation cannot be applied in the FORWARD hook. Revision 0 lets older userspace programs use the match as earlier. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> --- include/linux/netfilter_ipv4/ipt_addrtype.h | 15 ++++- net/ipv4/netfilter/ipt_addrtype.c | 90 +++++++++++++++++++++----- 2 files changed, 86 insertions(+), 19 deletions(-) diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h index 166ed01..856c79d 100644 --- a/include/linux/netfilter_ipv4/ipt_addrtype.h +++ b/include/linux/netfilter_ipv4/ipt_addrtype.h @@ -1,7 +1,20 @@ #ifndef _IPT_ADDRTYPE_H #define _IPT_ADDRTYPE_H -struct ipt_addrtype_info { +enum +{ + IPT_ADDRTYPE_INVERT_SOURCE = 0x0001, + IPT_ADDRTYPE_INVERT_DEST = 0x0002, + IPT_ADDRTYPE_LIMIT_IFACE = 0x0004, +}; + +struct ipt_addrtype_info_v1 { + u_int16_t source; /* source-type mask */ + u_int16_t dest; /* dest-type mask */ + u_int32_t flags; +}; + +struct ipt_addrtype_info_v0 { u_int16_t source; /* source-type mask */ u_int16_t dest; /* dest-type mask */ u_int32_t invert_source; diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 59f01f7..7abe2f7 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -22,44 +22,98 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); MODULE_DESCRIPTION("iptables addrtype match"); -static inline bool match_type(__be32 addr, u_int16_t mask) +static inline bool match_type(__be32 addr, const struct net_device *in, u_int16_t mask) { - return !!(mask & (1 << inet_addr_type(addr))); + return !!(mask & (1 << inet_dev_addr_type(addr, in))); } -static bool match(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) +static bool addrtype_match_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 ipt_addrtype_info_v0 *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; - if (info->dest) - ret &= match_type(iph->daddr, info->dest)^info->invert_dest; + ret &= match_type(iph->saddr, NULL, info->source)^info->invert_source; + if (ret && (info->dest)) + ret &= match_type(iph->daddr, NULL, info->dest)^info->invert_dest; return ret; } -static struct xt_match addrtype_match __read_mostly = { - .name = "addrtype", - .family = AF_INET, - .match = match, - .matchsize = sizeof(struct ipt_addrtype_info), - .me = THIS_MODULE +static bool addrtype_match_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 *limit_dev = NULL; + bool ret = true; + + /* not valid in the FORWARD hook */ + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) + limit_dev = (in ? in : out); + + if (info->source) + ret &= match_type(iph->saddr, limit_dev, info->source) ^ + (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); + if (ret && (info->dest)) + ret &= match_type(iph->daddr, limit_dev, info->dest) ^ + (info->flags & IPT_ADDRTYPE_INVERT_DEST); + + return ret; +} + +static bool addrtype_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 (hook_mask & (1 << NF_IP_FORWARD) + && info->flags & IPT_ADDRTYPE_LIMIT_IFACE) { + printk(KERN_ERR "ipt_addrtype: limit-interface not valid in " + "FORWARD\n"); + return false; + } + return true; +} + + +static struct xt_match addrtype_match[] __read_mostly = { + { + .name = "addrtype", + .family = AF_INET, + .revision = 0, + .match = addrtype_match_v0, + .matchsize = sizeof(struct ipt_addrtype_info_v0), + .me = THIS_MODULE + }, + { + .name = "addrtype", + .family = AF_INET, + .revision = 1, + .match = addrtype_match_v1, + .checkentry = addrtype_checkentry_v1, + .matchsize = sizeof(struct ipt_addrtype_info_v1), + .me = THIS_MODULE + } }; static int __init ipt_addrtype_init(void) { - return xt_register_match(&addrtype_match); + return xt_register_matches(addrtype_match, + ARRAY_SIZE(addrtype_match)); } static void __exit ipt_addrtype_fini(void) { - xt_unregister_match(&addrtype_match); + xt_unregister_matches(addrtype_match, + ARRAY_SIZE(addrtype_match)); } module_init(ipt_addrtype_init); -- 1.5.2.5 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCHv2 2/2] Addrtype match extension: limit addrtype check on the packet's interface 2007-10-24 14:21 ` [PATCHv2 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth @ 2007-11-14 10:25 ` Patrick McHardy 0 siblings, 0 replies; 5+ messages in thread From: Patrick McHardy @ 2007-11-14 10:25 UTC (permalink / raw) To: Laszlo Attila Toth; +Cc: netfilter-devel Laszlo Attila Toth wrote: > Addrtype match has a new revision (1), which lets address type checking > limit to the interface the current packet belongs to. The limitation > cannot be applied in the FORWARD hook. > > Revision 0 lets older userspace programs use the match as earlier. Dave has opened his net-2.6.25 tree, so time to look at this again. > +static bool addrtype_match_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 *limit_dev = NULL; > + bool ret = true; > + > + /* not valid in the FORWARD hook */ > + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) > + limit_dev = (in ? in : out); I would prefer if the user specifies the device to use (in/out) and have proper checks that its not used on hooks where its invalid. That would also allow to use it in the FORWARD hook. Using a single device also doesn't seem to make much sense in case the match is on both source and dest. > + > + if (info->source) > + ret &= match_type(iph->saddr, limit_dev, info->source) ^ > + (info->flags & IPT_ADDRTYPE_INVERT_SOURCE); > + if (ret && (info->dest)) Unnecessary parens. > + ret &= match_type(iph->daddr, limit_dev, info->dest) ^ > + (info->flags & IPT_ADDRTYPE_INVERT_DEST); > + > + return ret; > +} > + > +static bool addrtype_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 (hook_mask & (1 << NF_IP_FORWARD) > + && info->flags & IPT_ADDRTYPE_LIMIT_IFACE) { Please don't reintroduce the weird && on continuation line style, I try to get rid of it whenever I touch some code. ^ permalink raw reply [flat|nested] 5+ messages in thread
[parent not found: <20071024-154635-1193233595.panther@balabit.hu>]
* [PATCHv2 iptables] Address type match: limited to incoming or outgoing interface [not found] ` <20071024-154635-1193233595.panther@balabit.hu> @ 2007-10-24 14:21 ` Laszlo Attila Toth 0 siblings, 0 replies; 5+ messages in thread From: Laszlo Attila Toth @ 2007-10-24 14:21 UTC (permalink / raw) To: kaber; +Cc: netfilter-devel, Laszlo Attila Toth Address type checking can be limited to the incoming or outgoing interface depending on the current chain if it is not the FORWARD chain. Older version (revision 0) of address type match is not supported. Signed-off-by: Laszlo Attila Toth <panther@balabit.hu> --- extensions/libipt_addrtype.c | 74 +++++++++++++++++----------- extensions/libipt_addrtype.man | 11 ++++ include/linux/netfilter_ipv4/ipt_addrtype.h | 15 +++++ 3 files changed, 70 insertions(+), 30 deletions(-) Index: include/linux/netfilter_ipv4/ipt_addrtype.h =================================================================== --- include/linux/netfilter_ipv4/ipt_addrtype.h (revision 7083) +++ include/linux/netfilter_ipv4/ipt_addrtype.h (working copy) @@ -1,9 +1,22 @@ #ifndef _IPT_ADDRTYPE_H #define _IPT_ADDRTYPE_H -struct ipt_addrtype_info { +enum +{ + IPT_ADDRTYPE_INVERT_SOURCE = 0x0001, + IPT_ADDRTYPE_INVERT_DEST = 0x0002, + IPT_ADDRTYPE_LIMIT_IFACE = 0x0004, +}; + +struct ipt_addrtype_info_v1 { u_int16_t source; /* source-type mask */ u_int16_t dest; /* dest-type mask */ + u_int32_t flags; +}; + +struct ipt_addrtype_info_v0 { + u_int16_t source; /* source-type mask */ + u_int16_t dest; /* dest-type mask */ u_int32_t invert_source; u_int32_t invert_dest; }; Index: extensions/libipt_addrtype.c =================================================================== --- extensions/libipt_addrtype.c (revision 7083) +++ extensions/libipt_addrtype.c (working copy) @@ -42,6 +42,7 @@ "Address type match v%s options:\n" " [!] --src-type type[,...] Match source address type\n" " [!] --dst-type type[,...] Match destination address type\n" +" --limit-iface Match on the packet's interface only\n" "\n" "Valid types: \n" , IPTABLES_VERSION); @@ -49,7 +50,7 @@ } static int -parse_type(const char *name, size_t strlen, u_int16_t *mask) +addrtype_parse_type(const char *name, size_t strlen, u_int16_t *mask) { int i; @@ -63,52 +64,60 @@ return 0; } -static void parse_types(const char *arg, u_int16_t *mask) +static void addrtype_parse_types(const char *arg, u_int16_t *mask) { const char *comma; while ((comma = strchr(arg, ',')) != NULL) { - if (comma == arg || !parse_type(arg, comma-arg, mask)) + if (comma == arg || !addrtype_parse_type(arg, comma-arg, mask)) exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg); arg = comma + 1; } - if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask)) + if (strlen(arg) == 0 || !addrtype_parse_type(arg, strlen(arg), mask)) exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg); } #define IPT_ADDRTYPE_OPT_SRCTYPE 0x1 #define IPT_ADDRTYPE_OPT_DSTTYPE 0x2 +#define IPT_ADDRTYPE_OPT_LIMIT_IFACE 0x4 static int addrtype_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { - struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) (*match)->data; + struct ipt_addrtype_info_v1 *info = + (struct ipt_addrtype_info_v1 *) (*match)->data; switch (c) { case '1': - if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE) + if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE) exit_error(PARAMETER_PROBLEM, "addrtype: can't specify src-type twice"); check_inverse(optarg, &invert, &optind, 0); - parse_types(argv[optind-1], &info->source); + addrtype_parse_types(argv[optind-1], &info->source); if (invert) - info->invert_source = 1; + info->flags |= IPT_ADDRTYPE_INVERT_SOURCE; *flags |= IPT_ADDRTYPE_OPT_SRCTYPE; break; case '2': - if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE) + if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE) exit_error(PARAMETER_PROBLEM, "addrtype: can't specify dst-type twice"); check_inverse(optarg, &invert, &optind, 0); - parse_types(argv[optind-1], &info->dest); + addrtype_parse_types(argv[optind-1], &info->dest); if (invert) - info->invert_dest = 1; + info->flags |= IPT_ADDRTYPE_INVERT_DEST; *flags |= IPT_ADDRTYPE_OPT_DSTTYPE; break; + case '3': + if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE) + exit_error(PARAMETER_PROBLEM, + "addrtype: can't specify limit-iface twice"); + info->flags |= IPT_ADDRTYPE_LIMIT_IFACE; + *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE; + break; default: return 0; } @@ -122,8 +131,8 @@ exit_error(PARAMETER_PROBLEM, "addrtype: you must specify --src-type or --dst-type"); } - -static void print_types(u_int16_t mask) + +static void addrtype_print_types(u_int16_t mask) { const char *sep = ""; int i; @@ -140,54 +149,62 @@ static void addrtype_print(const void *ip, const struct xt_entry_match *match, int numeric) { - const struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) match->data; + const struct ipt_addrtype_info_v1 *info = + (struct ipt_addrtype_info_v1 *) match->data; printf("ADDRTYPE match "); if (info->source) { printf("src-type "); - if (info->invert_source) + if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) printf("!"); - print_types(info->source); + addrtype_print_types(info->source); } if (info->dest) { printf("dst-type "); - if (info->invert_dest) + if (info->flags & IPT_ADDRTYPE_INVERT_DEST) printf("!"); - print_types(info->dest); + addrtype_print_types(info->dest); } + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) { + printf("limit-iface "); + } } static void addrtype_save(const void *ip, const struct xt_entry_match *match) { - const struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) match->data; + const struct ipt_addrtype_info_v1 *info = + (struct ipt_addrtype_info_v1 *) match->data; if (info->source) { printf("--src-type "); - if (info->invert_source) + if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) printf("! "); - print_types(info->source); + addrtype_print_types(info->source); } if (info->dest) { printf("--dst-type "); - if (info->invert_dest) + if (info->flags & IPT_ADDRTYPE_INVERT_DEST) printf("! "); - print_types(info->dest); + addrtype_print_types(info->dest); } + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE) { + printf("--limit-iface "); + } } static const struct option addrtype_opts[] = { { "src-type", 1, NULL, '1' }, { "dst-type", 1, NULL, '2' }, + { "limit-iface", 0, NULL, '3' }, { } }; static struct iptables_match addrtype_match = { .name = "addrtype", .version = IPTABLES_VERSION, - .size = IPT_ALIGN(sizeof(struct ipt_addrtype_info)), - .userspacesize = IPT_ALIGN(sizeof(struct ipt_addrtype_info)), + .revision = 1, + .size = IPT_ALIGN(sizeof(struct ipt_addrtype_info_v1)), + .userspacesize = IPT_ALIGN(sizeof(struct ipt_addrtype_info_v1)), .help = addrtype_help, .parse = addrtype_parse, .final_check = addrtype_check, @@ -196,7 +213,6 @@ .extra_opts = addrtype_opts, }; - void _init(void) { register_match(&addrtype_match); Index: extensions/libipt_addrtype.man =================================================================== --- extensions/libipt_addrtype.man (revision 7083) +++ extensions/libipt_addrtype.man (working copy) @@ -35,3 +35,14 @@ .TP .BI "--dst-type " "type" Matches if the destination address is of given type +.TP +.BI "--limit-iface" +The address type checing can be limited to the interface the packet is coming in in the +.B PREROUTING +and +.B INPUT +or going out in the +.B OUTPUT +and +.B POSTROUTING +chains and user-defined chains which are only called from those chains. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-11-14 10:25 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20071024-160736-1193234856.pather@balabit.hu>
2007-10-24 14:21 ` [PATCHv2 0/2] Find address type on the packet's interface Laszlo Attila Toth
[not found] ` <20071024-160736-1193234856.panther@balabit.hu>
[not found] ` <69d5a58b11473e65f29837c537a6d29b4e02e19b.1193232178.git.panther@balabit.hu>
2007-10-24 14:21 ` [PATCHv2 1/2] Find address type on a specific or on any interface Laszlo Attila Toth
[not found] ` <364a3c83187b863e5a7fd28803383b05fb29b6e6.1193232178.git.panther@balabit.hu>
2007-10-24 14:21 ` [PATCHv2 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
2007-11-14 10:25 ` Patrick McHardy
[not found] ` <20071024-154635-1193233595.panther@balabit.hu>
2007-10-24 14:21 ` [PATCHv2 iptables] Address type match: limited to incoming or outgoing interface Laszlo Attila Toth
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).