Re: [PATCH v2 3/3] ipset: change 'iface' part in hash:net,iface set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 9 Jul 2012, Mr Dash Four wrote:

> Kernel changes to ipset, allowing 'in' and 'out' values to be
> specified for the 'iface' part of hash:net,iface type sets only.
> 
> Signed-off-by: Mr Dash Four <mr.dash.four@xxxxxxxxxxxxxx>
> ---
>  include/linux/netfilter/ipset/ip_set.h      |   13 +++++++++++
>  net/netfilter/ipset/ip_set_bitmap_ipmac.c   |    4 ++++
>  net/netfilter/ipset/ip_set_core.c           |   33 +++++++++++++++++++++++++++
>  net/netfilter/ipset/ip_set_hash_ipport.c    |    6 +++--
>  net/netfilter/ipset/ip_set_hash_ipportip.c  |    6 +++--
>  net/netfilter/ipset/ip_set_hash_ipportnet.c |    6 +++--
>  net/netfilter/ipset/ip_set_hash_netport.c   |    6 +++--
>  7 files changed, 66 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
> index 2edc64c..47b72f8 100644
> --- a/include/linux/netfilter/ipset/ip_set.h
> +++ b/include/linux/netfilter/ipset/ip_set.h
> @@ -190,6 +190,10 @@ enum ip_set_dim {
>  	 * If changed, new revision of iptables match/target is required.
>  	 */
>  	IPSET_DIM_MAX = 6,
> +	/* 
> +	 * Indicates whether the new 'iface' format (in/out) has been used.
> +	 */
> +	IPSET_DIM_IFACE = 7, 
>  };

It's not a dimension, please give it some other name,
like IPSET_IFACE_INOUT_FLAG.
  
>  /* Option flags for kernel operations */
> @@ -198,6 +202,7 @@ enum ip_set_kopt {
>  	IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
>  	IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
>  	IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
> +	IPSET_DIM_IFACE_INOUT = (1 << IPSET_DIM_IFACE),
>  };

Similarly, rename IPSET_DIM_IFACE_INOUT too.
  
>  #ifdef __KERNEL__
> @@ -486,6 +491,14 @@ struct ip_set_req_get_set {
>  #define IP_SET_OP_GET_BYINDEX	0x00000007	/* Get set name by index */
>  /* Uses ip_set_req_get_set */
>  
> +#define IP_SET_OP_GET_FEATURES	0x00000008	/* Get set features by name */
> +struct ip_set_req_get_features {
> +	unsigned int op;
> +	unsigned int version;
> +	__u8 features;
> +	union ip_set_name_index set;
> +};
> +

In spite of stuffing a u8 sized value into features, please make it an
unsigned int. We don't spare anything with __u8 here.

>  #define IP_SET_OP_VERSION	0x00000100	/* Ask kernel version */
>  struct ip_set_req_version {
>  	unsigned int op;
> diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> index d7eaf10..1d8d754 100644
> --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
> @@ -348,6 +348,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	ipset_adtfn adtfn = set->variant->adt[adt];
>  	struct ipmac data;
>  
> +	/* in|out not allowed in this set type, only src|dst */
> +	if (opt->flags & IPSET_DIM_IFACE_INOUT)
> +		return -EINVAL;
> +

Drop this unnecessary checking: ipset doesn't care about iptables syntax.

>  	/* MAC can be src only */
>  	if (!(opt->flags & IPSET_DIM_TWO_SRC))
>  		return 0;
>
> diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
> index 9730882..55d52c4 100644
> --- a/net/netfilter/ipset/ip_set_core.c
> +++ b/net/netfilter/ipset/ip_set_core.c
> @@ -609,6 +609,26 @@ find_set_id(const char *name)
>  	return index;
>  }
>  
> +static ip_set_id_t
> +find_set_features(const char *name, __u8 *features)
> +{
> +	ip_set_id_t i, index = IPSET_INVALID_ID;
> +	const struct ip_set *set;
> +
> +	for (i = 0; index == IPSET_INVALID_ID && i < ip_set_max; i++) {
> +		set = ip_set_list[i];
> +		if (set != NULL && STREQ(set->name, name)) {
> +			index = i;
> +			/* In theory, we could return the entire set of features
> +			 * for a given set, though, for now, we only return 
> +			 * the IPSET_TYPE_IFACE bit
> +			 */
> +			*features = set->type->features & IPSET_TYPE_IFACE;

I believe it's better to return the entire feature, not just 
IPSET_TYPE_IFACE.

> +		}
> +	}
> +	return index;
> +}
> +
>  static inline struct ip_set *
>  find_set(const char *name)
>  {
> @@ -1702,6 +1722,19 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
>  		nfnl_unlock();
>  		goto copy;
>  	}
> +	case IP_SET_OP_GET_FEATURES: {
> +		struct ip_set_req_get_features *req_get = data;
> +
> +		if (*len != sizeof(struct ip_set_req_get_features)) {
> +			ret = -EINVAL;
> +			goto done;
> +		}
> +		req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
> +		nfnl_lock();
> +		req_get->set.index = find_set_features(req_get->set.name,&req_get->features);
> +		nfnl_unlock();
> +		goto copy;
> +	}
>  	default:
>  		ret = -EBADMSG;
>  		goto done;
> diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
> index 92722bb..615a6e3 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipport.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipport.c
> @@ -143,7 +143,8 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	ipset_adtfn adtfn = set->variant->adt[adt];
>  	struct hash_ipport4_elem data = { };
>  
> -	if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;

Drop this and all other checkings below:
  
> @@ -361,7 +362,8 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	ipset_adtfn adtfn = set->variant->adt[adt];
>  	struct hash_ipport6_elem data = { };
>  
> -	if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
> index 0637ce0..732fe63 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipportip.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
> @@ -146,7 +146,8 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	ipset_adtfn adtfn = set->variant->adt[adt];
>  	struct hash_ipportip4_elem data = { };
>  
> -	if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> @@ -374,7 +375,8 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	ipset_adtfn adtfn = set->variant->adt[adt];
>  	struct hash_ipportip6_elem data = { };
>  
> -	if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
> index 1ce21ca..4a01705 100644
> --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
> +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
> @@ -192,7 +192,8 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	if (adt == IPSET_TEST)
>  		data.cidr = HOST_MASK - 1;
>  
> -	if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> @@ -503,7 +504,8 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	if (adt == IPSET_TEST)
>  		data.cidr = HOST_MASK - 1;
>  
> -	if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
> index fc3143a..554a468 100644
> --- a/net/netfilter/ipset/ip_set_hash_netport.c
> +++ b/net/netfilter/ipset/ip_set_hash_netport.c
> @@ -189,7 +189,8 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	if (adt == IPSET_TEST)
>  		data.cidr = HOST_MASK - 1;
>  
> -	if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> @@ -467,7 +468,8 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
>  	if (adt == IPSET_TEST)
>  		data.cidr = HOST_MASK - 1;
>  
> -	if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
> +	if ((opt->flags & IPSET_DIM_IFACE_INOUT) || /* in|out not allowed in this set type, only src|dst */
> +		!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
>  				 &data.port, &data.proto))
>  		return -EINVAL;
>  
> -- 
> 1.7.10.4

Best regards,
Jozsef
-
E-mail  : kadlec@xxxxxxxxxxxxxxxxx, kadlecsik.jozsef@xxxxxxxxxxxxx
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux