Re: [PATCH libnftnl v4 1/3] src: add ct timeout support

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

 



Hi Harsha,

On Sun, Aug 05, 2018 at 02:49:22PM +0530, Harsha Sharma wrote:
[...]
> diff --git a/include/libnftnl/cttimeout.h b/include/libnftnl/cttimeout.h
> new file mode 100644
> index 0000000..6f0ef75
> --- /dev/null
> +++ b/include/libnftnl/cttimeout.h
> @@ -0,0 +1,39 @@
> +#ifndef _LIBNETFILTER_CTTIMEOUT_H_
> +#define _LIBNETFILTER_CTTIMEOUT_H_
> +
> +#include <stdint.h>
> +#include <sys/types.h>
> +#include <linux/netfilter/nfnetlink_conntrack.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +struct nftnl_obj_ct_timeout;
> +
> +enum nftnl_obj_ct_timeout_tcp_attr {
> +	NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT = 0,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_SYN_RECV,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_ESTABLISHED,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_FIN_WAIT,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE_WAIT,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_LAST_ACK,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_TIME_WAIT,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT2,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_RETRANS,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_UNACK,
> +	NFTA_CT_TIMEOUT_ATTR_TCP_MAX

You can use enum tcp_conntrack instead, this is already part of the
uapi, so it is exposed to userspace. So we can get rid of this.

> +};
> +
> +enum nftnl_obj_ct_timeout_udp_attr {
> +	NFTA_CT_TIMEOUT_ATTR_UDP_UNREPLIED = 0,
> +	NFTA_CT_TIMEOUT_ATTR_UDP_REPLIED,
> +	NFTA_CT_TIMEOUT_ATTR_UDP_MAX
> +};

I would like you kill this libnftnl/cttimeout.h file and the
nftnl_timeout_policy_attr_set_u32() interface.

My proposal is: Pass an array of int to NFTNL_OBJ_CT_TIMEOUT_POLICY
via nftnl_obj_set_data(), where -1 means unset, ie. timeout for this
state is not set and default existing value should be used instead.

More comments below.

[...]
> diff --git a/include/libnftnl/object.h b/include/libnftnl/object.h
> index 93a40d0..14f6e83 100644
> --- a/include/libnftnl/object.h
> +++ b/include/libnftnl/object.h
> @@ -7,6 +7,7 @@
>  #include <sys/types.h>
>  
>  #include <libnftnl/common.h>
> +#include <libnftnl/cttimeout.h>
>  
>  #ifdef __cplusplus
>  extern "C" {
> @@ -41,6 +42,13 @@ enum {
>  	NFTNL_OBJ_CT_HELPER_L4PROTO,
>  };
>  
> +enum {
> +	NFTNL_OBJ_CT_TIMEOUT_L3PROTO = NFTNL_OBJ_BASE,
> +	NFTNL_OBJ_CT_TIMEOUT_L4PROTO,
> +	NFTNL_OBJ_CT_TIMEOUT_DATA,
> +	NFTNL_OBJ_CT_TIMEOUT_POLICY,

NFTNL_OBJ_CT_TIMEOUT_POLICY and NFTNL_OBJ_CT_TIMEOUT_DATA look
redundant, actually one of the is unused.

[...]
> diff --git a/src/libnftnl.map b/src/libnftnl.map
> index 0d6b20c..8e2e544 100644
> --- a/src/libnftnl.map
> +++ b/src/libnftnl.map
> @@ -340,6 +340,8 @@ LIBNFTNL_7 {
>    nftnl_flowtable_list_add_tail;
>    nftnl_flowtable_list_del;
>    nftnl_flowtable_list_foreach;
> +  nftnl_timeout_policy_attr_set_u32;
> +  nftnl_obj_get_void;

I would prefer you use the existing nftnl_obj_get_data() to fetch the
array of int that represents the timeout policy. So we don't need
nftnl_obj_get_void().

> diff --git a/src/obj/ct_timeout.c b/src/obj/ct_timeout.c
> new file mode 100644
> index 0000000..cd6cbc7
> --- /dev/null
> +++ b/src/obj/ct_timeout.c
> @@ -0,0 +1,371 @@
> +/*
> + * (C) 2017 Red Hat GmbH
> + * Author: Florian Westphal <fw@xxxxxxxxx>

If this is based on Florian's work, you can refer to that.

But I think you've written this code, right?

> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published
> + * by the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <arpa/inet.h>
> +#include <errno.h>
> +#include <inttypes.h>
> +
> +#include <linux/netfilter/nf_tables.h>
> +
> +#include "internal.h"
> +#include <libmnl/libmnl.h>
> +#include <libnftnl/object.h>
> +#include <libnftnl/cttimeout.h>
> +
> +#include "obj.h"
> +
> +static const char *const tcp_state_to_name[] = {
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT]	= "SYN_SENT",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_SYN_RECV]	= "SYN_RECV",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_ESTABLISHED]	= "ESTABLISHED",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_FIN_WAIT]	= "FIN_WAIT",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE_WAIT]	= "CLOSE_WAIT",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_LAST_ACK]	= "LAST_ACK",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_TIME_WAIT]	= "TIME_WAIT",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_CLOSE]	= "CLOSE",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_SYN_SENT2]	= "SYN_SENT2",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_RETRANS]	= "RETRANS",
> +	[NFTA_CT_TIMEOUT_ATTR_TCP_UNACK]	= "UNACKNOWLEDGED",

As said, use enum tcp_conntrack instead of these NFTA_CT_* that will
be now gone.

[...]
> +static struct {
> +	uint32_t attr_max;
> +	const char *const *state_to_name;
> +	uint32_t *dflt_timeout;
> +} timeout_protocol[IPPROTO_MAX] = {
> +	[IPPROTO_TCP]	= {
> +		.attr_max	= NFTA_CT_TIMEOUT_ATTR_TCP_MAX,
> +		.state_to_name	= tcp_state_to_name,
> +		.dflt_timeout	= tcp_dflt_timeout,
> +	},
> +	[IPPROTO_UDP]	= {
> +		.attr_max	= NFTA_CT_TIMEOUT_ATTR_UDP_MAX,
> +		.state_to_name	= udp_state_to_name,
> +		.dflt_timeout	= udp_dflt_timeout,
> +	},
> +};
> +
> +

Double line break, one single it just fine.

> +struct _container_policy_cb {
> +	unsigned int nlattr_max;
> +	void *tb;
> +};
> +
> +int
> +nftnl_timeout_policy_attr_set_u32(struct nftnl_obj *e,
> +				 uint32_t type, uint32_t data)
> +{
> +	struct nftnl_obj_ct_timeout *t = nftnl_obj_data(e);
> +	size_t timeout_array_size;

Missing line break between variable definition and function body.

> +	/* Layer 4 protocol needs to be already set. */
> +	if (!(e->flags & (1 << NFTNL_OBJ_CT_TIMEOUT_L4PROTO)))
> +		return -1;
> +	if (t->timeout == NULL) {
> +		/* if not supported, default to generic protocol tracker. */
> +		if (timeout_protocol[t->l4proto].attr_max != 0) {
> +			timeout_array_size = sizeof(uint32_t) *
> +					timeout_protocol[t->l4proto].attr_max;
> +		} else {
> +			timeout_array_size = sizeof(uint32_t) *
> +					timeout_protocol[IPPROTO_RAW].attr_max;
> +		}
> +		t->timeout = calloc(1, timeout_array_size);
> +		if (t->timeout == NULL)
> +			return -1;
> +	}
> +
> +	/* this state does not exists in this protocol tracker.*/
> +	if (type > timeout_protocol[t->l4proto].attr_max)
> +		return -1;
> +
> +	t->timeout[type] = data;
> +	t->polset |= (1 << type);
> +
> +	if (!(e->flags & (1 << NFTNL_OBJ_CT_TIMEOUT_POLICY)))
> +		e->flags |= (1 << NFTNL_OBJ_CT_TIMEOUT_POLICY);
> +	if (!(e->flags & (1 << NFTNL_OBJ_CT_TIMEOUT_DATA)))
> +		e->flags |= (1 << NFTNL_OBJ_CT_TIMEOUT_DATA);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(nftnl_timeout_policy_attr_set_u32);

Place EXPORT_SYMBOL() before the function, otherwise clang breaks. See
other spots in this library.

[...]
> +static int nftnl_obj_ct_timeout_snprintf_default(char *buf, size_t len,
> +					       const struct nftnl_obj *e)
> +{
> +	int ret = 0;
> +	int offset = 0, remain = len;
> +
> +	struct nftnl_obj_ct_timeout *timeout = nftnl_obj_data(e);
> +
> +	if (e->flags & (1 << NFTNL_OBJ_CT_TIMEOUT_L3PROTO)) {
> +		ret = snprintf(buf+offset, len, "family %d ",

                ret = snprintf(buf + offset, ...)

is preferred for new code, I mean, "buf + offset" with space between
variables.

I know other code doesn't follow this, but better if we fix coding
style in new code.

[...]
> diff --git a/src/object.c b/src/object.c
> index d8278f3..988c17d 100644
> --- a/src/object.c
> +++ b/src/object.c
[...]
> @@ -206,6 +207,12 @@ uint32_t nftnl_obj_get_u32(struct nftnl_obj *obj, uint16_t attr)
>  	return ret == NULL ? 0 : *((uint32_t *)ret);
>  }
>  
> +EXPORT_SYMBOL(nftnl_obj_get_void);
> +void *nftnl_obj_get_void(struct nftnl_obj *obj, uint16_t attr)
> +{
> +	return (void *)nftnl_obj_get(obj, attr);
> +}
> +
>  EXPORT_SYMBOL(nftnl_obj_get_u64);
>  uint64_t nftnl_obj_get_u64(struct nftnl_obj *obj, uint16_t attr)
>  {
> @@ -454,7 +461,8 @@ static int nftnl_obj_snprintf_dflt(char *buf, size_t size,
>  					 obj);
>  		SNPRINTF_BUFFER_SIZE(ret, remain, offset);
>  	}
> -	ret = snprintf(buf + offset, offset, "]");
> +
> +	ret = snprintf(buf + strlen(buf), offset, "]");

Hm, there must be a reason for this change. Otherwise, remove it.

Thanks.
--
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