userspace support for IPv6 TProxy
PATCH 1/1 userspace support for IPv6 TProxy
[ Sorry if this reaches you twice, I sent to the wrong address the first time ]
This patchset implements support for the IPv6 TProxy functionality. It also includes the still missing option to the socket match (--transparent) which is already present in the kernel but not in the userspace sources.
Balazs Scheidler (2):
TProxy: added IPv6 support for socket match
TProxy: added IPv6 support to the TPROXY target
extensions/libxt_TPROXY.c | 213 +++++++++++++++++++++++++++++------ extensions/libxt_socket.c | 103 ++++++++++++++++-- extensions/libxt_socket.man | 6 +- include/linux/netfilter/xt_TPROXY.h | 15 ++- include/linux/netfilter/xt_socket.h | 8 ++ 5 files changed, 295 insertions(+), 50 deletions(-) create mode 100644 include/linux/netfilter/xt_socket.h
PATCH 1/1 TProxy: added IPv6 support for socket match
This patch also adds userspace support for the --transparent mode of matching, which the kernel already supports, but the iptables userspace doesn't.
--- extensions/libxt_socket.c | 103 ++++++++++++++++++++++++++++++++--- extensions/libxt_socket.man | 6 ++- include/linux/netfilter/xt_socket.h | 8 +++ 3 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 include/linux/netfilter/xt_socket.h
extensions/libxt_socket.c +95 -8
@@ -1,19 +1,106 @@/* * Shared library add-on to iptables to add early socket matching support. * -* Copyright (C) 2007 BalaBit IT Ltd. +* Copyright (C) 2007, 2009 BalaBit IT Ltd. */ +#include <stdio.h> +#include <getopt.h> #include <xtables.h> +#include <linux/netfilter/xt_socket.h> -static struct xtables_match socket_mt_reg = { - .name ="socket" , - .version =XTABLES_VERSION , - .family =NFPROTO_IPV4 , - .size =XT_ALIGN (0 ), - .userspacesize =XT_ALIGN (0 ), +static void socket_mt_help_v0 (void ) +{ +printf ("socket match has no options.\n\n" ); +} + +static void socket_mt_help_v1 (void ) +{ +printf ("socket match options:\n" +"--transparent Matches only if the socket's transparent option is set\n" ); +} + +static const struct option socket_opts_v1[] = { + {"transparent" ,0 ,NULL ,'1' }, + { } +}; + +static int socket_mt_parse_v0 (int c,char **argv,int invert, +unsigned int *flags,const void *entry, +struct xt_entry_match **match) +{ +return 0 ; +} + +static int socket_mt_parse_v1 (int c,char **argv,int invert, +unsigned int *flags,const void *entry, +struct xt_entry_match **match) +{ +struct xt_socket_match_info1 *info = (void *) (*match)->data; + +switch (c) { +case '1' : +if (*flags) +xtables_error (PARAMETER_PROBLEM , +"Can't specify multiple --transparent" ); + info->transparent =1 ; + *flags =1 ; +break ; +default : +return 0 ; + } +return 1 ; +} + +static void socket_mt_check (unsigned int flags) +{ +} + +static void socket_mt_print_v1 (const void *ip, +const struct xt_entry_match *match, +int numeric) +{ +const struct xt_socket_match_info1 *info = (const void *)match->data; +printf ("socket " ); +if (info->transparent) +printf ("transparent " ); +} + +static void socket_mt_save_v1 (const void *ip, +const struct xt_entry_match *match) +{ +const struct xt_socket_match_info1 *info = (const void *)match->data; + +if (info->transparent) +printf ("--transparent " ); +} + +static struct xtables_match socket_matches[] = { + { + .name ="socket" , + .revision =0 , + .version =XTABLES_VERSION , + .family =NFPROTO_IPV4 , + .parse = socket_mt_parse_v0, + .final_check = socket_mt_check, + .help = socket_mt_help_v0, + }, + { + .name ="socket" , + .version =XTABLES_VERSION , + .revision =1 , + .family =NFPROTO_UNSPEC , + .size =XT_ALIGN (sizeof (struct xt_socket_match_info1 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_socket_match_info1 )), + .parse = socket_mt_parse_v1, + .print = socket_mt_print_v1, + .save = socket_mt_save_v1, + .final_check = socket_mt_check, + .help = socket_mt_help_v1, + .extra_opts = socket_opts_v1, + } };void _init (void ) { -xtables_register_match (&socket_mt_reg); +xtables_register_matches (socket_matches,ARRAY_SIZE (socket_matches)); }
extensions/libxt_socket.man +5 -1
@@ -1,2 +1,6 @@ This matches if an open socket can be found by doing a socket lookup on the -packet. +packet which doesn\'t listen on the \'any\' IP address (0.0.0.0). +.TP +.BI "\-\-transparent" +Enables additional check, that the actual socket's transparent socket option +has to be set.
include/linux/netfilter/xt_socket.h new file +8 -0
@@ -0,0 +1,8 @@ +#ifndef _XT_SOCKET_H_match +#define _XT_SOCKET_H_match + +struct xt_socket_match_info1 { +__u8 transparent:1 ; +}; + +#endif /* _XT_SOCKET_H_match */
Signature · 1 line
1.6.0.4
Re: [PATCH] TProxy: added IPv6 support for socket match
include/linux/netfilter/xt_socket.h line 8
Quoted 10 lines · Balazs Scheidler
+++
b/include/linux/netfilter/xt_socket.hinclude/linux/netfilter/xt_socket.h new file +8
-0@@ -0,0 +1,8 @@ +#ifndef _XT_SOCKET_H_match +#define _XT_SOCKET_H_match + +struct xt_socket_match_info1 { +__u8 transparent:1 ; +}; + +#endif /* _XT_SOCKET_H_match */
Bitfields are a no-no in the ABI.
Re: [PATCH] TProxy: added IPv6 support for socket match
Quoted 14 lines · Jan Engelhardt
include/linux/netfilter/xt_socket.h line 8
Quoted 10 lines · Balazs Scheidler
+++
b/include/linux/netfilter/xt_socket.hinclude/linux/netfilter/xt_socket.h new file +8
-0@@ -0,0 +1,8 @@ +#ifndef _XT_SOCKET_H_match +#define _XT_SOCKET_H_match + +struct xt_socket_match_info1 { +__u8 transparent:1 ; +}; + +#endif /* _XT_SOCKET_H_match */ Bitfields are a no-no in the ABI.
Ops, I took that patch from an ancient userspace patch created earlier by Panther.
It did work for me, as the kernel uses:
enum {
XT_SOCKET_TRANSPARENT = 1 << 0,
};struct xt_socket_mtinfo1 {
__u8 flags;
};Thanks for noticing.
Signature · 1 line
Bazsi
PATCH 1/1 TProxy: added IPv6 support to the TPROXY target
In reply to Balazs Scheidler--- extensions/libxt_TPROXY.c | 213 +++++++++++++++++++++++++++++------ include/linux/netfilter/xt_TPROXY.h | 15 ++- 2 files changed, 187 insertions(+), 41 deletions(-)
extensions/libxt_TPROXY.c +176 -37
@@ -1,7 +1,7 @@/* * Shared library add-on to iptables to add TPROXY target support. * -* Copyright (C) 2002-2008 BalaBit IT Ltd. +* Copyright (C) 2002-2009 BalaBit IT Ltd. */ #include <getopt.h> #include <stdbool.h>
@@ -36,65 +36,114 @@ static void tproxy_tg_help(void) " --tproxy-mark value[/mask] Mark packets with the given value/mask\n\n"); } -static void parse_tproxy_lport (const char *s,struct xt_tproxy_target_info *info) +static void parse_tproxy_lport (const char *s,unsigned short *lport) { -unsigned int lport; +unsigned int value; -if (xtables_strtoui (s,NULL , &lport,0 ,UINT16_MAX )) - info->lport =htons (lport); +if (xtables_strtoui (s,NULL , &value,0 ,UINT16_MAX )) + *lport =htons (value);else xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--on-port" , s); } -static void parse_tproxy_laddr (const char *s,struct xt_tproxy_target_info *info) +static void parse_tproxy_laddr_v0 (const char *s,__be32 *laddr) { -struct in_addr *laddr; +struct in_addr *ina; -if ((laddr =xtables_numeric_to_ipaddr (s)) ==NULL ) +if ((ina =xtables_numeric_to_ipaddr (s)) ==NULL )xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--on-ip" , s); - info->laddr = laddr->s_addr; + *laddr = ina->s_addr; } -static void parse_tproxy_mark (char *s,struct xt_tproxy_target_info *info) +static void parse_tproxy_laddr (const char *s,int family,union nf_inet_addr *laddr) +{ + +if (family ==NFPROTO_IPV6 ) { +struct in6_addr *addr6; + +if ((addr6 =xtables_numeric_to_ip6addr (s))) { + laddr->in6 = *addr6; + }else { +xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--on-ip" , s); + } + }else { +struct in_addr *addr; + +if ((addr =xtables_numeric_to_ipaddr (s))) { + laddr->in = *addr; + }else { +xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--on-ip" , s); + } + + } +} + +static void parse_tproxy_mark (char *s,unsigned int *value,unsigned int *mask) { -unsigned int value, mask =UINT32_MAX ;char *end; -if (!xtables_strtoui (s, &end, &value,0 ,UINT32_MAX )) + *mask =UINT32_MAX ; +if (!xtables_strtoui (s, &end, value,0 ,UINT32_MAX ))xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--tproxy-mark" , s);if (*end =='/' ) -if (!xtables_strtoui (end +1 , &end, &mask,0 ,UINT32_MAX )) +if (!xtables_strtoui (end +1 , &end, mask,0 ,UINT32_MAX ))xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--tproxy-mark" , s);if (*end !='\0' )xtables_param_act (XTF_BAD_VALUE ,"TPROXY" ,"--tproxy-mark" , s); +} + +static int tproxy_tg_parse_v0 (int c,char **argv,int invert,unsigned int *flags, +const void *entry,struct xt_entry_target **target) +{ +struct xt_tproxy_target_info_v0 *tproxyinfo = (void *)(*target)->data; + +switch (c) { +case '1' : +xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--on-port" , *flags &PARAM_ONPORT ); +xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--on-port" , invert); +parse_tproxy_lport (optarg, &tproxyinfo->lport); + *flags |=PARAM_ONPORT ; +return 1 ; +case '2' : +xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--on-ip" , *flags &PARAM_ONIP ); +xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--on-ip" , invert); +parse_tproxy_laddr_v0 (optarg, &tproxyinfo->laddr); + *flags |=PARAM_ONIP ; +return 1 ; +case '3' : +xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--tproxy-mark" , *flags &PARAM_MARK ); +xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--tproxy-mark" , invert); +parse_tproxy_mark (optarg, &tproxyinfo->mark_value, &tproxyinfo->mark_mask); + *flags |=PARAM_MARK ; +return 1 ; + } - info->mark_mask = mask; - info->mark_value = value; +return 0 ; } -static int tproxy_tg_parse (int c,char **argv,int invert,unsigned int *flags, +static int tproxy_tg_parse_v1 (int family,int c,char **argv,int invert,unsigned int *flags,const void *entry,struct xt_entry_target **target) { -struct xt_tproxy_target_info *tproxyinfo = (void *)(*target)->data; +struct xt_tproxy_target_info_v1 *tproxyinfo = (void *)(*target)->data;switch (c) {case '1' :xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--on-port" , *flags &PARAM_ONPORT );xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--on-port" , invert); -parse_tproxy_lport (optarg, tproxyinfo); +parse_tproxy_lport (optarg, &tproxyinfo->lport); *flags |=PARAM_ONPORT ;return 1 ;case '2' :xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--on-ip" , *flags &PARAM_ONIP );xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--on-ip" , invert); -parse_tproxy_laddr (optarg, tproxyinfo); +parse_tproxy_laddr (optarg, family, &tproxyinfo->laddr); *flags |=PARAM_ONIP ;return 1 ;case '3' :xtables_param_act (XTF_ONLY_ONCE ,"TPROXY" ,"--tproxy-mark" , *flags &PARAM_MARK );xtables_param_act (XTF_NO_INVERT ,"TPROXY" ,"--tproxy-mark" , invert); -parse_tproxy_mark (optarg, tproxyinfo); +parse_tproxy_mark (optarg, &tproxyinfo->mark_value, &tproxyinfo->mark_mask); *flags |=PARAM_MARK ;return 1 ; }
@@ -102,6 +151,18 @@ static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags,return 0 ; } +static int tproxy_tg_parse4_v1 (int c,char **argv,int invert,unsigned int *flags, +const void *entry,struct xt_entry_target **target) +{ +return tproxy_tg_parse_v1 (NFPROTO_IPV4 , c, argv, invert, flags, entry, target); +} + +static int tproxy_tg_parse6_v1 (int c,char **argv,int invert,unsigned int *flags, +const void *entry,struct xt_entry_target **target) +{ +return tproxy_tg_parse_v1 (NFPROTO_IPV6 , c, argv, invert, flags, entry, target); +} +static void tproxy_tg_check (unsigned int flags) {if (!(flags &PARAM_ONPORT ))
@@ -109,19 +170,43 @@ static void tproxy_tg_check(unsigned int flags) "TPROXY target: Parameter --on-port is required"); } -static void tproxy_tg_print (const void *ip,const struct xt_entry_target *target, +static void tproxy_tg_print_v0 (const void *ip,const struct xt_entry_target *target,int numeric) { -const struct xt_tproxy_target_info *info = (const void *)target->data; +const struct xt_tproxy_target_info_v0 *info = (const void *)target->data;printf ("TPROXY redirect %s:%u mark 0x%x/0x%x" ,xtables_ipaddr_to_numeric ((const struct in_addr *)&info->laddr),ntohs (info->lport), (unsigned int )info->mark_value, (unsigned int )info->mark_mask); } -static void tproxy_tg_save (const void *ip,const struct xt_entry_target *target) +static void tproxy_tg_print_v1 (int family,const void *ip,const struct xt_entry_target *target, +int numeric) { -const struct xt_tproxy_target_info *info = (const void *)target->data; +const struct xt_tproxy_target_info_v1 *info = (const void *)target->data; +printf ("TPROXY redirect %s:%u mark 0x%x/0x%x" , + family ==AF_INET + ?xtables_ipaddr_to_numeric (&info->laddr.in) + :xtables_ip6addr_to_numeric (&info->laddr.in6), +ntohs (info->lport), (unsigned int )info->mark_value, + (unsigned int )info->mark_mask); +} + +static void tproxy_tg_print4_v1 (const void *ip,const struct xt_entry_target *target, +int numeric) +{ +return tproxy_tg_print_v1 (NFPROTO_IPV4 , ip, target, numeric); +} + +static void tproxy_tg_print6_v1 (const void *ip,const struct xt_entry_target *target, +int numeric) +{ +return tproxy_tg_print_v1 (NFPROTO_IPV6 , ip, target, numeric); +} + +static void tproxy_tg_save_v0 (const void *ip,const struct xt_entry_target *target) +{ +const struct xt_tproxy_target_info_v0 *info = (const void *)target->data;printf ("--on-port %u " ,ntohs (info->lport)); printf("--on-ip %s ",
@@ -130,21 +215,75 @@ static void tproxy_tg_save(const void *ip, const struct xt_entry_target *target) (unsigned int)info->mark_value, (unsigned int)info->mark_mask); } -static struct xtables_target tproxy_tg_reg = { - .name ="TPROXY" , - .family =NFPROTO_IPV4 , - .version =XTABLES_VERSION , - .size =XT_ALIGN (sizeof (struct xt_tproxy_target_info )), - .userspacesize =XT_ALIGN (sizeof (struct xt_tproxy_target_info )), - .help = tproxy_tg_help, - .parse = tproxy_tg_parse, - .final_check = tproxy_tg_check, - .print = tproxy_tg_print, - .save = tproxy_tg_save, - .extra_opts = tproxy_tg_opts, +static void tproxy_tg_save_v1 (int family,const void *ip,const struct xt_entry_target *target) +{ +const struct xt_tproxy_target_info_v1 *info = (const void *)target->data; + +printf ("--on-port %u " ,ntohs (info->lport)); +printf ("--on-ip %s " , + family ==AF_INET + ?xtables_ipaddr_to_numeric (&info->laddr.in) + :xtables_ip6addr_to_numeric (&info->laddr.in6)); +printf ("--tproxy-mark 0x%x/0x%x " , + (unsigned int )info->mark_value, (unsigned int )info->mark_mask); +} + +static void tproxy_tg_save4_v1 (const void *ip,const struct xt_entry_target *target) +{ +return tproxy_tg_save_v1 (NFPROTO_IPV4 , ip, target); +} + +static void tproxy_tg_save6_v1 (const void *ip,const struct xt_entry_target *target) +{ +return tproxy_tg_save_v1 (NFPROTO_IPV6 , ip, target); +} + + +static struct xtables_target tproxy_tg_reg[] = { + { + .name ="TPROXY" , + .family =NFPROTO_IPV4 , + .version =XTABLES_VERSION , + .size =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v0 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v0 )), + .help = tproxy_tg_help, + .parse = tproxy_tg_parse_v0, + .final_check = tproxy_tg_check, + .print = tproxy_tg_print_v0, + .save = tproxy_tg_save_v0, + .extra_opts = tproxy_tg_opts, + }, + { + .name ="TPROXY" , + .family =NFPROTO_IPV4 , + .version =XTABLES_VERSION , + .revision =1 , + .size =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v1 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v1 )), + .help = tproxy_tg_help, + .parse = tproxy_tg_parse4_v1, + .final_check = tproxy_tg_check, + .print = tproxy_tg_print4_v1, + .save = tproxy_tg_save4_v1, + .extra_opts = tproxy_tg_opts, + }, + { + .name ="TPROXY" , + .family =NFPROTO_IPV6 , + .version =XTABLES_VERSION , + .revision =1 , + .size =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v1 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_tproxy_target_info_v1 )), + .help = tproxy_tg_help, + .parse = tproxy_tg_parse6_v1, + .final_check = tproxy_tg_check, + .print = tproxy_tg_print6_v1, + .save = tproxy_tg_save6_v1, + .extra_opts = tproxy_tg_opts, + }, };void _init (void ) { -xtables_register_target (&tproxy_tg_reg); +xtables_register_targets (tproxy_tg_reg,ARRAY_SIZE (tproxy_tg_reg)); }
include/linux/netfilter/xt_TPROXY.h +11 -4
@@ -1,14 +1,21 @@ -#ifndef _XT_TPROXY_H_target -#define _XT_TPROXY_H_target +#ifndef _XT_TPROXY_H +#define _XT_TPROXY_H/* TPROXY target is capable of marking the packet to perform * redirection. We can get rid of that whenever we get support for * mutliple targets in the same rule. */ -struct xt_tproxy_target_info { +struct xt_tproxy_target_info_v0 {u_int32_t mark_mask;u_int32_t mark_value;__be32 laddr;__be16 lport; }; -#endif /* _XT_TPROXY_H_target */ +struct xt_tproxy_target_info_v1 { +u_int32_t mark_mask; +u_int32_t mark_value; +union nf_inet_addr laddr; +__be16 lport; +}; + +#endif /* _XT_TPROXY_H */
Signature · 1 line
1.6.0.4