[ANNOUNCE] nftlb 0.3 release

2018-11-15 Thread Laura Garcia
Hi!

I'm honored to present

nftlb 0.3

nftlb stands for nftables load balancer, a user space tool
that builds a complete load balancer and traffic distributor
using the nft infrastructure.

nftlb is a nftables rules manager that creates virtual services
for load balancing at layer 2, layer 3 and layer 4, minimizing
the number of rules and using structures to match efficiently the
packets. It comes with an easy JSON API service to control,
to monitor and to automate the configuration.

Most important changes in this version are:
* Stateless NAT support from ingress
* Automated DSR configuration from layer 3
* Flow mark per service and per backend
* Logging support per virtual service
* L7 helpers support
* Support of custom source IP instead of masquerading
* Kubernetes integration as kube-nftlb

For further details, please refer to the official repository:

https://github.com/zevenet/nftlb

You can download this tool from:

https://github.com/zevenet/nftlb/releases/tag/v0.3

Or deploy the kubernetes integration from:

https://github.com/zevenet/kube-nftlb

Happy load balancing!


PD. Special huge thanks to: Víctor Manuel Oliver Acosta and Pablo Neira Ayuso

--
Detailed changelog:

New features
- network: generalize netlink request to ask for routing data
- farms: new mode stateless dnat
- farms: add l7 helpers support
- farms: add input logging support
- farms: support of farm renaming with the 'newname' attribute
- farms: add mark flow support per virtual service
- nft: add flow mark per backend and farm using masks
- src: add custom source ip address configuration instead of masquerading

Improvements
- events: generalize event loop
- farms: include new attributes for interface and mac address management
- network: add support to interoperate with some network discovery functions
- src: refactorization and api simplification
- events: generalize netlink event for dsr
- farms: make dsr counter global
- backends: include a new backend state config_error
- src: silent fallthrough warning
- backends: ensure the backends list is empty when configuring the
output interface
- farms: validate and rulerize per farm
- config: avoid to print auto-generated information of a farm
- farms: validate and check the farm status before rulerize
- server: expand the server buffer data
- readme: add new examples
- tests: improve diff output format
- nft: improve modularization of nft rules generation
- server: set SO_REUSEADDR socket flag
- main: initial signal handler skeleton
- server: add struct nftlb_client
- server: add struct nftlb_http_state
- server: add nftlb_http_send_response()
- server: add body response field to struct nftlb_http_state
- src: do no use EXIT_{SUCCESS,FAILURE}
- server: statify objects that are only used from server.c
- server: remove unnecessary definitions

Bugfixes
- config: dump configuration with indented JSON
- nft: fix dsr rules to set the mac address instead of matching
- backend: fix update backend status when switching from down to up
- nft: avoid add rules if no backends are available
- objects: set right initial state for farms and backends
- farms: fix start-stop actions
- backends: input validation for net_get_neigh_ether()
- nft: fix stateless nat backend to client rule
- nft: fix udp ipv6 services name
- server: fix some web server memory leaks
- tests: fix some tests cases


[PATCH nft] json: fix json_events_cb() declaration when libjansson is not present

2018-10-31 Thread Laura Garcia Liebana
When nftables is configured without libjansson support, the following
compilation error is shown:

monitor.c: In function ‘netlink_echo_callback’:
monitor.c:910:10: error: too many arguments to function ‘json_events_cb’
   return json_events_cb(nlh, _monh);
  ^~

This patch makes a declaration of the json_events_cb() function
consistent.

Fixes: bb32d8db9a12 ("JSON: Add support for echo option")

Signed-off-by: Laura Garcia Liebana 
---
 include/json.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/json.h b/include/json.h
index 8d45c3c..c724c29 100644
--- a/include/json.h
+++ b/include/json.h
@@ -239,7 +239,8 @@ static inline void monitor_print_rule_json(struct 
netlink_mon_handler *monh,
/* empty */
 }
 
-static inline int json_events_cb(const struct nlmsghdr *nlh)
+static inline int json_events_cb(const struct nlmsghdr *nlh,
+ struct netlink_mon_handler *monh)
 {
return -1;
 }
-- 
2.11.0



Re: url filtering with netfiler

2018-08-07 Thread Laura Garcia
On Tue, Aug 7, 2018 at 3:26 PM, Saber Rezvani  wrote:
> Do you know who exactly working on this feature in nft? could you possibly
> introduce me to him/her?
> You know we have decided to work on this issue. So It is a best practice to
> get in touch with running development team who works on this feature. Even
> we can join them, too.
>

I'm not the right person to decide, but I can contribute with the
implementation for such feature as well.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: url filtering with netfiler

2018-08-07 Thread Laura Garcia
On Fri, Aug 3, 2018 at 11:03 AM, Oleg  wrote:
> On Fri, Aug 03, 2018 at 01:21:05AM +0430, Saber Rezvani wrote:
>> On 08/03/2018 12:14 AM, Oleg wrote:
>> > On Thu, Aug 02, 2018 at 06:44:26PM +0430, Saber Rezvani wrote:
>> >> Dear all,
>> >>
>> >>
>> >> Some of my friends and I have decided to work on Linux community, and
>> >> add a new feature to the networking subsystem. We have concluded that
>> >> URL filtering with IP/NF tables may be a good feature if we can
>> >> implement it in Linux networking subsystem. Because through our research
>> >> we found out with the current IP/NF tables since that payload is spread
>> >> through several packets, it is not possible.

Hi!

I believe that this is a very feasible feature, at least for header
filtering. In fact, iptables has already a string match that could be
used for this purpose.
Hopefully, this ability will be available for nft soon.

>> > Do you think this feature will be useful now? For example, filtering uri in
>> > https isn't possible and http using is decreasing now.

There are some components in the kernel to decrypt HTTPS, so
software-based ssl offload in the kernel is coming.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netfilter: nft_numgen: fix ptr_ret.cocci warnings

2018-05-24 Thread Laura Garcia
On Wed, May 23, 2018 at 12:58 PM, kbuild test robot
<fengguang...@intel.com> wrote:
> From: kbuild test robot <fengguang...@intel.com>
>
> net/netfilter/nft_numgen.c:117:1-3: WARNING: PTR_ERR_OR_ZERO can be used
>
>
>  Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
>
> Generated by: scripts/coccinelle/api/ptr_ret.cocci
>
> Fixes: d734a2888922 ("netfilter: nft_numgen: add map lookups for numgen 
> statements")
> CC: Laura Garcia Liebana <nev...@gmail.com>
> Signed-off-by: kbuild test robot <fengguang...@intel.com>

Acked-by: Laura Garcia Liebana <nev...@gmail.com>
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netfilter: nft_hash: fix ptr_ret.cocci warnings

2018-05-24 Thread Laura Garcia
On Wed, May 23, 2018 at 12:53 PM, kbuild test robot
<fengguang...@intel.com> wrote:
> From: kbuild test robot <fengguang...@intel.com>
>
> net/netfilter/nft_hash.c:180:1-3: WARNING: PTR_ERR_OR_ZERO can be used
> net/netfilter/nft_hash.c:223:1-3: WARNING: PTR_ERR_OR_ZERO can be used
>
>
>  Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
>
> Generated by: scripts/coccinelle/api/ptr_ret.cocci
>
> Fixes: b9ccc07e3f31 ("netfilter: nft_hash: add map lookups for hashing 
> operations")
> CC: Laura Garcia Liebana <nev...@gmail.com>
> Signed-off-by: kbuild test robot <fengguang...@intel.com>

Acked-by: Laura Garcia Liebana <nev...@gmail.com>
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libmnl 3/3] examples: reduce LOCs during neigh attributes validation

2018-05-21 Thread Laura Garcia Liebana
This patch avoids some LOCs duplication.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 examples/rtnl/rtnl-neigh-dump.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/examples/rtnl/rtnl-neigh-dump.c b/examples/rtnl/rtnl-neigh-dump.c
index 54d87e5..f4d5000 100644
--- a/examples/rtnl/rtnl-neigh-dump.c
+++ b/examples/rtnl/rtnl-neigh-dump.c
@@ -22,11 +22,6 @@ static int data_attr_cb(const struct nlattr *attr, void 
*data)
 
switch(type) {
case NDA_DST:
-   if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
-   perror("mnl_attr_validate");
-   return MNL_CB_ERROR;
-   }
-   break;
case NDA_LLADDR:
if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
perror("mnl_attr_validate");
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libmnl 2/3] examples: fix print line format

2018-05-21 Thread Laura Garcia Liebana
Use 80 characters per line limit.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 examples/rtnl/rtnl-neigh-dump.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/examples/rtnl/rtnl-neigh-dump.c b/examples/rtnl/rtnl-neigh-dump.c
index 52fa1c7..54d87e5 100644
--- a/examples/rtnl/rtnl-neigh-dump.c
+++ b/examples/rtnl/rtnl-neigh-dump.c
@@ -62,7 +62,9 @@ static int data_cb(const struct nlmsghdr *nlh, void *data)
unsigned char lladdr[6] = {0};
 
if (memcpy(, addr, 6))
-   printf("%02x:%02x:%02x:%02x:%02x:%02x ", lladdr[0], 
lladdr[1], lladdr[2], lladdr[3], lladdr[4], lladdr[5]);
+   printf("%02x:%02x:%02x:%02x:%02x:%02x ",
+  lladdr[0], lladdr[1], lladdr[2],
+  lladdr[3], lladdr[4], lladdr[5]);
}
 
printf("state=");
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libmnl 1/3] examples: fix neigh max attributes

2018-05-21 Thread Laura Garcia Liebana
Use NDA_MAX for neigh maximum attributes instead of IFA_MAX,
which is only for interfaces.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 examples/rtnl/rtnl-neigh-dump.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/examples/rtnl/rtnl-neigh-dump.c b/examples/rtnl/rtnl-neigh-dump.c
index fc0f205..52fa1c7 100644
--- a/examples/rtnl/rtnl-neigh-dump.c
+++ b/examples/rtnl/rtnl-neigh-dump.c
@@ -17,7 +17,7 @@ static int data_attr_cb(const struct nlattr *attr, void *data)
int type = mnl_attr_get_type(attr);
 
/* skip unsupported attribute in user-space */
-   if (mnl_attr_type_valid(attr, IFA_MAX) < 0)
+   if (mnl_attr_type_valid(attr, NDA_MAX) < 0)
return MNL_CB_OK;
 
switch(type) {
@@ -40,7 +40,7 @@ static int data_attr_cb(const struct nlattr *attr, void *data)
 
 static int data_cb(const struct nlmsghdr *nlh, void *data)
 {
-   struct nlattr *tb[IFA_MAX + 1] = {};
+   struct nlattr *tb[NDA_MAX + 1] = {};
struct ndmsg *ndm = mnl_nlmsg_get_payload(nlh);
 
printf("index=%d family=%d ", ndm->ndm_ifindex, ndm->ndm_family);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libmnl 0/3] examples: rtnl neigh dump cleanups

2018-05-21 Thread Laura Garcia Liebana
These series apply some small code cleanups.

Laura Garcia Liebana (3):
  examples: fix neigh max attributes
  examples: fix print line format
  examples: reduce LOCs during neigh attributes validation

 examples/rtnl/rtnl-neigh-dump.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libmnl] examples: add arp cache dump example

2018-05-17 Thread Laura Garcia Liebana
Adding ARP example in order to dump the info in the form:

index= family= dst= lladdr= 
state=

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 examples/rtnl/Makefile.am |   6 +-
 examples/rtnl/rtnl-arp-dump.c | 161 ++
 2 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 examples/rtnl/rtnl-arp-dump.c

diff --git a/examples/rtnl/Makefile.am b/examples/rtnl/Makefile.am
index 24769b6..e56365c 100644
--- a/examples/rtnl/Makefile.am
+++ b/examples/rtnl/Makefile.am
@@ -6,7 +6,8 @@ check_PROGRAMS = rtnl-addr-dump \
 rtnl-link-set \
 rtnl-route-add \
 rtnl-route-dump \
-rtnl-route-event
+rtnl-route-event \
+rtnl-arp-dump
 
 rtnl_addr_dump_SOURCES = rtnl-addr-dump.c
 rtnl_addr_dump_LDADD = ../../src/libmnl.la
@@ -34,3 +35,6 @@ rtnl_route_dump_LDADD = ../../src/libmnl.la
 
 rtnl_route_event_SOURCES = rtnl-route-event.c
 rtnl_route_event_LDADD = ../../src/libmnl.la
+
+rtnl_arp_dump_SOURCES = rtnl-arp-dump.c
+rtnl_arp_dump_LDADD = ../../src/libmnl.la
diff --git a/examples/rtnl/rtnl-arp-dump.c b/examples/rtnl/rtnl-arp-dump.c
new file mode 100644
index 000..fc0f205
--- /dev/null
+++ b/examples/rtnl/rtnl-arp-dump.c
@@ -0,0 +1,161 @@
+/* This example is placed in the public domain. */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   /* skip unsupported attribute in user-space */
+   if (mnl_attr_type_valid(attr, IFA_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch(type) {
+   case NDA_DST:
+   if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
+   perror("mnl_attr_validate");
+   return MNL_CB_ERROR;
+   }
+   break;
+   case NDA_LLADDR:
+   if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
+   perror("mnl_attr_validate");
+   return MNL_CB_ERROR;
+   }
+   break;
+   }
+   tb[type] = attr;
+   return MNL_CB_OK;
+}
+
+static int data_cb(const struct nlmsghdr *nlh, void *data)
+{
+   struct nlattr *tb[IFA_MAX + 1] = {};
+   struct ndmsg *ndm = mnl_nlmsg_get_payload(nlh);
+
+   printf("index=%d family=%d ", ndm->ndm_ifindex, ndm->ndm_family);
+
+   mnl_attr_parse(nlh, sizeof(*ndm), data_attr_cb, tb);
+   printf("dst=");
+   if (tb[NDA_DST]) {
+   void *addr = mnl_attr_get_payload(tb[NDA_DST]);
+   char out[INET6_ADDRSTRLEN];
+
+   if (inet_ntop(ndm->ndm_family, addr, out, sizeof(out)))
+   printf("%s ", out);
+   }
+
+   mnl_attr_parse(nlh, sizeof(*ndm), data_attr_cb, tb);
+   printf("lladdr=");
+   if (tb[NDA_LLADDR]) {
+   void *addr = mnl_attr_get_payload(tb[NDA_LLADDR]);
+   unsigned char lladdr[6] = {0};
+
+   if (memcpy(, addr, 6))
+   printf("%02x:%02x:%02x:%02x:%02x:%02x ", lladdr[0], 
lladdr[1], lladdr[2], lladdr[3], lladdr[4], lladdr[5]);
+   }
+
+   printf("state=");
+   switch(ndm->ndm_state) {
+   case NUD_INCOMPLETE:
+   printf("incomplete ");
+   break;
+   case NUD_REACHABLE:
+   printf("reachable ");
+   break;
+   case NUD_STALE:
+   printf("stale ");
+   break;
+   case NUD_DELAY:
+   printf("delay ");
+   break;
+   case NUD_PROBE:
+   printf("probe ");
+   break;
+   case NUD_FAILED:
+   printf("failed ");
+   break;
+   case NUD_NOARP:
+   printf("noarp ");
+   break;
+   case NUD_PERMANENT:
+   printf("permanent ");
+   break;
+   default:
+   printf("%d ", ndm->ndm_state);
+   break;
+   }
+
+   printf("\n");
+   return MNL_CB_OK;
+}
+
+int main(int argc, char *argv[])
+{
+   struct mnl_socket *nl;
+   char buf[MNL_SOCKET_BUFFER_SIZE];
+   struct nlmsghdr *nlh;
+   struct rtgenmsg *rt;
+   int ret;
+   unsigned int seq, portid;
+
+   if (argc != 2) {
+   fprintf(stderr, "Usage: %s <inet|inet6>\n", argv[0]);
+   exit(EXIT_FAILURE);
+   }
+
+   nlh = mnl_nlmsg_put_header(buf);
+   nlh->nlmsg_type = RTM_GETNEIGH;
+   nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+   nlh->nlmsg_seq = seq = ti

[ANNOUNCE] nftlb 0.2 release

2018-05-14 Thread Laura Garcia Liebana
Hi!

I'm honored to present

nftlb 0.2

nftlb stands for nftables load balancer, a user space tool
that builds a complete load balancer and traffic distributor
using the nft infrastructure.

nftlb is a nftables rules manager that creates virtual services
for load balancing at layer 2, layer 3 and layer 4, minimizing
the number of rules and using structures to match efficiently the 
packets. It comes with an easy JSON API service to control,
to monitor and to automate the configuration.

Current features are:

* 3 topologies supported: Destination NAT, Source NAT and Direct
Server Return. This enables the load balancer to be setup in
one-armed and two-armed network architectures.
* support for both IPv4 and IPv6 families.
* multilayer capabilities: MAC based LB in layer 2, IP based LB
with protocol agnostic at layer 3, and support of UDP, TCP and
SCTP LB at layer 4.
* multiport support for ranges and lists of ports.
* support of multiple virtual services setup.
* schedulers available: weight, round robin, hash and symmetric
hash.
* priority support per backend.
* JSON API service for monitoring, automation and managemnet.
* web service authentication with a security key.
* automated testbed.

For further details, please refer to the official repository:

https://github.com/zevenet/nftlb

You can download this tool from:

https://github.com/zevenet/nftlb/releases/tag/v0.2


Happy load balancing!
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nftlb] src: add -W and compilation warnings that result from it

2018-05-12 Thread Laura Garcia Liebana
On Fri, May 11, 2018 at 02:50:46PM +0200, Pablo Neira Ayuso wrote:
> config.c: In function ‘config_file’:
> config.c:60:30: warning: ordered comparison of pointer with integer zero 
> [-Wextra]
>   if ((fd = fopen(file, "r")) <= 0) {
>   ^~
> 
> nft.c: In function ‘get_ndv_base’:
> nft.c:173:16: warning: comparison between signed and unsigned integer 
> expressions [-Wsign-compare]
>   for (i = 0; i < n_ndv_base_rules; i++) {
> ^
> 
> Add -Wno-unused-parameter to silence the following warning:
> 
> onfig.c: In function ‘config_json_string’:
> config.c:142:46: warning: unused parameter ‘level’ [-Wunused-parame
>  void config_json_string(json_t *element, int level)
>   ^
> 
> since this may be intentional as all these functions take the level parameter.
> 

Applied, thank you Pablo!

https://github.com/zevenet/nftlb/commit/7921471fc99f59a333bfb97dbf90a02cf2522c16
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nftlb,v4] build: use autotools

2018-05-11 Thread Laura Garcia Liebana
On Fri, May 11, 2018 at 02:24:29PM +0200, Pablo Neira Ayuso wrote:
> - Add configure.ac and Makefile.am files.
> - Update .gitignore file to ignore autogenerated scripts by autotools.
> 

Applied, thanks Pablo!

https://github.com/zevenet/nftlb/commit/52ae2784dd624a1a411addd58e796cb73cc5a1b2
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libnftnl] expr: add map lookups for hash statements

2018-05-10 Thread Laura Garcia Liebana
This patch introduces two new attributes for hash expression
to allow map lookups where the hash is the key.

The new attributes are NFTNL_EXPR_HASH_SET_NAME and
NFTNL_EXPR_HASH_SET_ID in order to identify the given map.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/libnftnl/expr.h |  2 ++
 include/linux/netfilter/nf_tables.h |  4 +++
 src/expr/hash.c | 49 +
 3 files changed, 55 insertions(+)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 25d4103..45ff533 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -238,6 +238,8 @@ enum {
NFTNL_EXPR_HASH_SEED,
NFTNL_EXPR_HASH_OFFSET,
NFTNL_EXPR_HASH_TYPE,
+   NFTNL_EXPR_HASH_SET_NAME,
+   NFTNL_EXPR_HASH_SET_ID,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 54e35c1..48b095e 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -851,6 +851,8 @@ enum nft_hash_types {
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
  * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
+ * @NFTA_HASH_SET_NAME: name of the map to lookup (NLA_STRING)
+ * @NFTA_HASH_SET_ID: id of the map (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -861,6 +863,8 @@ enum nft_hash_attributes {
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
NFTA_HASH_TYPE,
+   NFTA_HASH_SET_NAME,
+   NFTA_HASH_SET_ID,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/expr/hash.c b/src/expr/hash.c
index fcc4fa5..415537e 100644
--- a/src/expr/hash.c
+++ b/src/expr/hash.c
@@ -28,6 +28,10 @@ struct nftnl_expr_hash {
unsigned intmodulus;
unsigned intseed;
unsigned intoffset;
+   struct {
+   const char  *name;
+   uint32_tid;
+   } map;
 };
 
 static int
@@ -57,6 +61,14 @@ nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_HASH_TYPE:
hash->type = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_HASH_SET_NAME:
+   hash->map.name = strdup(data);
+   if (!hash->map.name)
+   return -1;
+   break;
+   case NFTNL_EXPR_HASH_SET_ID:
+   hash->map.id = *((uint32_t *)data);
+   break;
default:
return -1;
}
@@ -91,6 +103,12 @@ nftnl_expr_hash_get(const struct nftnl_expr *e, uint16_t 
type,
case NFTNL_EXPR_HASH_TYPE:
*data_len = sizeof(hash->type);
return >type;
+   case NFTNL_EXPR_HASH_SET_NAME:
+   *data_len = strlen(hash->map.name) + 1;
+   return hash->map.name;
+   case NFTNL_EXPR_HASH_SET_ID:
+   *data_len = sizeof(hash->map.id);
+   return >map.id;
}
return NULL;
 }
@@ -111,9 +129,14 @@ static int nftnl_expr_hash_cb(const struct nlattr *attr, 
void *data)
case NFTA_HASH_SEED:
case NFTA_HASH_OFFSET:
case NFTA_HASH_TYPE:
+   case NFTA_HASH_SET_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+   case NFTA_HASH_SET_NAME:
+   if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+   abi_breakage();
+   break;
}
 
tb[type] = attr;
@@ -139,6 +162,10 @@ nftnl_expr_hash_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_HASH_OFFSET, htonl(hash->offset));
if (e->flags & (1 << NFTNL_EXPR_HASH_TYPE))
mnl_attr_put_u32(nlh, NFTA_HASH_TYPE, htonl(hash->type));
+   if (e->flags & (1 << NFTNL_EXPR_HASH_SET_NAME))
+   mnl_attr_put_str(nlh, NFTA_HASH_SET_NAME, hash->map.name);
+   if (e->flags & (1 << NFTNL_EXPR_HASH_SET_ID))
+   mnl_attr_put_u32(nlh, NFTA_HASH_SET_ID, htonl(hash->map.id));
 }
 
 static int
@@ -179,6 +206,16 @@ nftnl_expr_hash_parse(struct nftnl_expr *e, struct nlattr 
*attr)
hash->type = ntohl(mnl_attr_get_u32(tb[NFTA_HASH_TYPE]));
e->flags |= (1 << NFTNL_EXPR_HASH_TYPE);
}
+   if (tb[NFTA_HASH_SET_NAME]) {
+   hash->map.name =
+ strdup(mnl_attr_get_str(tb[NFTA_HASH_SET_NAME]));
+   e->flags |= (1 << NFTNL_EXPR_HASH_SET_NAME);
+   }
+   if (tb[NFTA_HASH_SET_ID]) {
+   hash->map.id =
+ ntohl(mnl_attr_get_u32(tb[NFTA_HASH_SET_ID]));
+   e->flags |= (1 << NFTNL_E

[PATCH nf-next 2/2] netfilter: nft_hash: add map lookups for hashing operations

2018-05-10 Thread Laura Garcia Liebana
This patch creates new attributes to accept a map as argument and
then perform the lookup with the generated hash accordingly.

Both current hash functions are supported: Jenkins and Symmetric Hash.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |   4 +
 net/netfilter/nft_hash.c | 137 ++-
 2 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index ce031cf72288..9c71f024f9cc 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -856,6 +856,8 @@ enum nft_hash_types {
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
  * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
+ * @NFTA_HASH_SET_NAME: name of the map to lookup (NLA_STRING)
+ * @NFTA_HASH_SET_ID: id of the map (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -866,6 +868,8 @@ enum nft_hash_attributes {
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
NFTA_HASH_TYPE,
+   NFTA_HASH_SET_NAME,
+   NFTA_HASH_SET_ID,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index e235c17f1b8b..f0feed99f560 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -25,6 +25,7 @@ struct nft_jhash {
u32 modulus;
u32 seed;
u32 offset;
+   struct nft_set  *map;
 };
 
 static void nft_jhash_eval(const struct nft_expr *expr,
@@ -35,14 +36,40 @@ static void nft_jhash_eval(const struct nft_expr *expr,
const void *data = >data[priv->sreg];
u32 h;
 
-   h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
+   h = reciprocal_scale(jhash(data, priv->len, priv->seed),
+priv->modulus);
+
regs->data[priv->dreg] = h + priv->offset;
 }
 
+static void nft_jhash_map_eval(const struct nft_expr *expr,
+  struct nft_regs *regs,
+  const struct nft_pktinfo *pkt)
+{
+   struct nft_jhash *priv = nft_expr_priv(expr);
+   const void *data = >data[priv->sreg];
+   const struct nft_set *map = priv->map;
+   const struct nft_set_ext *ext;
+   u32 result;
+   bool found;
+
+   result = reciprocal_scale(jhash(data, priv->len, priv->seed),
+   priv->modulus) + priv->offset;
+
+   found = map->ops->lookup(nft_net(pkt), map, , );
+
+   if (!found)
+   return;
+
+   nft_data_copy(>data[priv->dreg],
+ nft_set_ext_data(ext), map->dlen);
+}
+
 struct nft_symhash {
enum nft_registers  dreg:8;
u32 modulus;
u32 offset;
+   struct nft_set  *map;
 };
 
 static void nft_symhash_eval(const struct nft_expr *expr,
@@ -58,6 +85,29 @@ static void nft_symhash_eval(const struct nft_expr *expr,
regs->data[priv->dreg] = h + priv->offset;
 }
 
+static void nft_symhash_map_eval(const struct nft_expr *expr,
+struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+   const struct nft_set *map = priv->map;
+   const struct nft_set_ext *ext;
+   u32 result;
+   bool found;
+
+   result = reciprocal_scale(__skb_get_hash_symmetric(skb),
+ priv->modulus) + priv->offset;
+
+   found = map->ops->lookup(nft_net(pkt), map, , );
+
+   if (!found)
+   return;
+
+   nft_data_copy(>data[priv->dreg],
+ nft_set_ext_data(ext), map->dlen);
+}
+
 static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_SREG]= { .type = NLA_U32 },
[NFTA_HASH_DREG]= { .type = NLA_U32 },
@@ -66,6 +116,9 @@ static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX 
+ 1] = {
[NFTA_HASH_SEED]= { .type = NLA_U32 },
[NFTA_HASH_OFFSET]  = { .type = NLA_U32 },
[NFTA_HASH_TYPE]= { .type = NLA_U32 },
+   [NFTA_HASH_SET_NAME]= { .type = NLA_STRING,
+   .len = NFT_SET_MAXNAMELEN - 1 },
+   [NFTA_HASH_SET_ID]  = { .type = NLA_U32 },
 };
 
 static int nft_jhash_init(const struct nft_ctx *ctx,
@@ -115,6 +168,25 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_jhash_map_init(const struct nft_

[PATCH nf-next 1/2] netfilter: nft_numgen: add map lookups for numgen random operations

2018-05-10 Thread Laura Garcia Liebana
This patch uses the map lookup already included to be applied
for random number generation.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_numgen.c | 79 +++---
 1 file changed, 75 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index 8a64db8f2e69..7a29cf1ff84e 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -166,18 +166,44 @@ struct nft_ng_random {
enum nft_registers  dreg:8;
u32 modulus;
u32 offset;
+   struct nft_set  *map;
 };
 
+static u32 nft_ng_random_gen(struct nft_ng_random *priv)
+{
+   struct rnd_state *state = this_cpu_ptr(_numgen_prandom_state);
+
+   return reciprocal_scale(prandom_u32_state(state), priv->modulus) +
+  priv->offset;
+}
+
 static void nft_ng_random_eval(const struct nft_expr *expr,
   struct nft_regs *regs,
   const struct nft_pktinfo *pkt)
 {
struct nft_ng_random *priv = nft_expr_priv(expr);
-   struct rnd_state *state = this_cpu_ptr(_numgen_prandom_state);
-   u32 val;
 
-   val = reciprocal_scale(prandom_u32_state(state), priv->modulus);
-   regs->data[priv->dreg] = val + priv->offset;
+   regs->data[priv->dreg] = nft_ng_random_gen(priv);
+}
+
+static void nft_ng_random_map_eval(const struct nft_expr *expr,
+  struct nft_regs *regs,
+  const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_random *priv = nft_expr_priv(expr);
+   const struct nft_set *map = priv->map;
+   const struct nft_set_ext *ext;
+   u32 result;
+   bool found;
+
+   result = nft_ng_random_gen(priv);
+   found = map->ops->lookup(nft_net(pkt), map, , );
+
+   if (!found)
+   return;
+
+   nft_data_copy(>data[priv->dreg],
+ nft_set_ext_data(ext), map->dlen);
 }
 
 static int nft_ng_random_init(const struct nft_ctx *ctx,
@@ -204,6 +230,25 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_ng_random_map_init(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nlattr * const tb[])
+{
+   struct nft_ng_random *priv = nft_expr_priv(expr);
+   u8 genmask = nft_genmask_next(ctx->net);
+
+   nft_ng_random_init(ctx, expr, tb);
+
+   priv->map = nft_set_lookup_global(ctx->net, ctx->table,
+ tb[NFTA_NG_SET_NAME],
+ tb[NFTA_NG_SET_ID], genmask);
+
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+   return 0;
+}
+
 static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
 {
const struct nft_ng_random *priv = nft_expr_priv(expr);
@@ -212,6 +257,22 @@ static int nft_ng_random_dump(struct sk_buff *skb, const 
struct nft_expr *expr)
   priv->offset);
 }
 
+static int nft_ng_random_map_dump(struct sk_buff *skb,
+ const struct nft_expr *expr)
+{
+   const struct nft_ng_random *priv = nft_expr_priv(expr);
+
+   if (nft_ng_dump(skb, priv->dreg, priv->modulus,
+   NFT_NG_RANDOM, priv->offset) ||
+   nla_put_string(skb, NFTA_NG_SET_NAME, priv->map->name))
+   goto nla_put_failure;
+
+   return 0;
+
+nla_put_failure:
+   return -1;
+}
+
 static struct nft_expr_type nft_ng_type;
 static const struct nft_expr_ops nft_ng_inc_ops = {
.type   = _ng_type,
@@ -237,6 +298,14 @@ static const struct nft_expr_ops nft_ng_random_ops = {
.dump   = nft_ng_random_dump,
 };
 
+static const struct nft_expr_ops nft_ng_random_map_ops = {
+   .type   = _ng_type,
+   .size   = NFT_EXPR_SIZE(sizeof(struct nft_ng_random)),
+   .eval   = nft_ng_random_map_eval,
+   .init   = nft_ng_random_map_init,
+   .dump   = nft_ng_random_map_dump,
+};
+
 static const struct nft_expr_ops *
 nft_ng_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
 {
@@ -255,6 +324,8 @@ nft_ng_select_ops(const struct nft_ctx *ctx, const struct 
nlattr * const tb[])
return _ng_inc_map_ops;
return _ng_inc_ops;
case NFT_NG_RANDOM:
+   if (tb[NFTA_NG_SET_NAME])
+   return _ng_random_map_ops;
return _ng_random_ops;
}
 
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nf-next 0/2] netfilter: nft map lookups support for number generator expressions

2018-05-10 Thread Laura Garcia Liebana
The following patches complete the implementation of map lookups
using as a key the given number generator like incremental, random or
the different hash algorithms supported. This is useful for load
balancing use cases but also for dynamic map lookups using these
expressions.

Laura Garcia Liebana (2):
  netfilter: nft_numgen: add map lookups for numgen random operations
  netfilter: nft_hash: add map lookups for hashing operations

 include/uapi/linux/netfilter/nf_tables.h |   4 +
 net/netfilter/nft_hash.c | 137 ++-
 net/netfilter/nft_numgen.c   |  79 +-
 3 files changed, 215 insertions(+), 5 deletions(-)

-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nf-next] netfilter: nf_tables: enable hashing of one element

2018-04-23 Thread Laura Garcia Liebana
The modulus in the hash function was limited to > 1 as initially
there was no sense to create a hashing of just one element.

Nevertheless, there are certain cases specially for load balancing
where this case needs to be addressed.

This patch fixes the following error.

Error: Could not process rule: Numerical result out of range
add rule ip nftlb lb01 dnat to jhash ip saddr mod 1 map { 0: 192.168.0.10 }
^^^

The solution comes to force the hash to 0 when the modulus is 1.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_hash.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 24f2f7567ddb..1c4f791552d0 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -53,7 +53,11 @@ static void nft_symhash_eval(const struct nft_expr *expr,
struct sk_buff *skb = pkt->skb;
u32 h;
 
-   h = reciprocal_scale(__skb_get_hash_symmetric(skb), priv->modulus);
+   if (priv->modulus)
+   h = reciprocal_scale(__skb_get_hash_symmetric(skb),
+priv->modulus);
+   else
+   h = 0;
 
regs->data[priv->dreg] = h + priv->offset;
 }
@@ -97,7 +101,7 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
priv->len = len;
 
priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
-   if (priv->modulus <= 1)
+   if (priv->modulus < 1)
return -ERANGE;
 
if (priv->offset + priv->modulus - 1 < priv->offset)
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] expr: add map lookups for numgen statements

2018-04-22 Thread Laura Garcia Liebana
This patch introduces a map as a numgen attribute, which permits
to lookup a value based on the numgen result as the key.

This approach only supports named maps.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/expression.h|  1 +
 include/linux/netfilter/nf_tables.h |  4 
 include/numgen.h|  2 +-
 src/expression.c|  3 ++-
 src/netlink_delinearize.c   | 18 --
 src/netlink_linearize.c |  8 
 src/numgen.c| 13 +++--
 src/parser_bison.y  | 16 
 8 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index f0ba6fc..8158579 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -309,6 +309,7 @@ struct expr {
enum nft_ng_types   type;
uint32_tmod;
uint32_toffset;
+   struct expr *ng_map;
} numgen;
struct {
/* EXPR_HASH */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 517a39a..8612fe1 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1382,6 +1382,8 @@ enum nft_trace_types {
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
  * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
+ * @NFTA_NG_SET_NAME: name of the map to lookup (NLA_STRING)
+ * @NFTA_NG_SET_ID: if of the map (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
@@ -1389,6 +1391,8 @@ enum nft_ng_attributes {
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
NFTA_NG_OFFSET,
+   NFTA_NG_SET_NAME,
+   NFTA_NG_SET_ID,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/include/numgen.h b/include/numgen.h
index b230620..60eaa37 100644
--- a/include/numgen.h
+++ b/include/numgen.h
@@ -3,6 +3,6 @@
 
 extern struct expr *numgen_expr_alloc(const struct location *loc,
  enum nft_ng_types type, uint32_t until,
- uint32_t offset);
+ uint32_t offset, struct expr *mappings);
 
 #endif /* NFTABLES_NUMGEN_H */
diff --git a/src/expression.c b/src/expression.c
index e698b14..53393ec 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -945,7 +945,8 @@ static void map_expr_print(const struct expr *expr, struct 
output_ctx *octx)
 
 static void map_expr_clone(struct expr *new, const struct expr *expr)
 {
-   new->map  = expr_clone(expr->map);
+   if (expr->map)
+   new->map = expr_clone(expr->map);
new->mappings = expr_clone(expr->mappings);
 }
 
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 2126cf2..a270a92 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -668,13 +668,27 @@ static void netlink_parse_numgen(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers dreg;
uint32_t type, until, offset;
-   struct expr *expr;
+   const char *name;
+   struct expr *expr, *right, *map_expr = NULL;
+   struct set *map;
 
type  = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE);
until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS);
offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_OFFSET);
 
-   expr = numgen_expr_alloc(loc, type, until, offset);
+   name = nftnl_expr_get_str(nle, NFTNL_EXPR_NG_SET_NAME);
+   if (name != NULL) {
+   map  = set_lookup(ctx->table, name);
+   if (map == NULL) {
+   return netlink_error(ctx, loc,
+   "Unknown map '%s' in numgen expression",
+   name);
+   }
+   right = set_ref_expr_alloc(loc, map);
+   map_expr = map_expr_alloc(loc, NULL, right);
+   }
+
+   expr = numgen_expr_alloc(loc, type, until, offset, map_expr);
dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 6c49969..6f8fdc7 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -218,6 +218,14 @@ static void netlink_gen_numgen(struct 
netlink_linearize_ctx *ctx,
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod);
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset);
+
+   if (expr->numgen.ng_map) {
+   nftnl_expr_set_str(nle, NFTNL_EXPR_NG_SET_NAME,
+  expr->numgen.ng_map->map

[PATCH libnftnl] expr: add map lookups for numgen statements

2018-04-22 Thread Laura Garcia Liebana
This patch introduces two new attributes for numgen to allow map
lookups where the number generator will be the key.

Two new attributes needs to be included: NFTNL_EXPR_NG_SET_NAME and
NFTNL_EXPR_NG_SET_ID in order to identify the given map.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/libnftnl/expr.h |  2 ++
 include/linux/netfilter/nf_tables.h |  4 +++
 src/expr/numgen.c   | 49 +
 3 files changed, 55 insertions(+)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 76df942..25d4103 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -57,6 +57,8 @@ enum {
NFTNL_EXPR_NG_MODULUS,
NFTNL_EXPR_NG_TYPE,
NFTNL_EXPR_NG_OFFSET,
+   NFTNL_EXPR_NG_SET_NAME,
+   NFTNL_EXPR_NG_SET_ID,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index b904e33..54e35c1 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1448,6 +1448,8 @@ enum nft_trace_types {
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
  * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
+ * @NFTA_NG_SET_NAME: name of the map to lookup (NLA_STRING)
+ * @NFTA_NG_SET_ID: if of the map (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
@@ -1455,6 +1457,8 @@ enum nft_ng_attributes {
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
NFTA_NG_OFFSET,
+   NFTA_NG_SET_NAME,
+   NFTA_NG_SET_ID,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index 1369b01..5336fde 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -25,6 +25,10 @@ struct nftnl_expr_ng {
unsigned intmodulus;
enum nft_ng_types   type;
unsigned intoffset;
+   struct {
+   const char  *name;
+   uint32_tid;
+   } map;
 };
 
 static int
@@ -46,6 +50,14 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_OFFSET:
ng->offset = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_NG_SET_NAME:
+   ng->map.name = strdup(data);
+   if (!ng->map.name)
+   return -1;
+   break;
+   case NFTNL_EXPR_NG_SET_ID:
+   ng->map.id = *((uint32_t *)data);
+   break;
default:
return -1;
}
@@ -71,6 +83,12 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_OFFSET:
*data_len = sizeof(ng->offset);
return >offset;
+   case NFTNL_EXPR_NG_SET_NAME:
+   *data_len = strlen(ng->map.name) + 1;
+   return ng->map.name;
+   case NFTNL_EXPR_NG_SET_ID:
+   *data_len = sizeof(ng->map.id);
+   return >map.id;
}
return NULL;
 }
@@ -88,9 +106,14 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void 
*data)
case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
case NFTA_NG_OFFSET:
+   case NFTA_NG_SET_ID:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+   case NFTA_NG_SET_NAME:
+   if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+   abi_breakage();
+   break;
}
 
tb[type] = attr;
@@ -110,6 +133,10 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
if (e->flags & (1 << NFTNL_EXPR_NG_OFFSET))
mnl_attr_put_u32(nlh, NFTA_NG_OFFSET, htonl(ng->offset));
+   if (e->flags & (1 << NFTNL_EXPR_NG_SET_NAME))
+   mnl_attr_put_str(nlh, NFTA_NG_SET_NAME, ng->map.name);
+   if (e->flags & (1 << NFTNL_EXPR_NG_SET_ID))
+   mnl_attr_put_u32(nlh, NFTA_NG_SET_ID, htonl(ng->map.id));
 }
 
 static int
@@ -138,6 +165,16 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr 
*attr)
ng->offset = ntohl(mnl_attr_get_u32(tb[NFTA_NG_OFFSET]));
e->flags |= (1 << NFTNL_EXPR_NG_OFFSET);
}
+   if (tb[NFTA_NG_SET_NAME]) {
+   ng->map.name =
+   strdup(mnl_attr_get_str(tb[NFTA_NG_SET_NAME]));
+   e->flags |= (1 << NFTNL_EXPR_NG_SET_NAME);
+   }
+   if (tb[NFTA_NG_SET_ID]) {
+   ng->map.id =
+   ntohl(mnl_attr_get_u32(tb[NFTA_NG_SET_ID]));
+   e->flags |= (1 << NFTNL_EXPR_NG_SET_ID);
+   }
 
return ret;
 }
@@ -198,6 +235,12 @@ nftnl_expr_ng_snpri

[PATCH nf-next] netfilter: nf_tables: add map lookups for numgen statements

2018-04-22 Thread Laura Garcia Liebana
This patch includes a new attribute in the numgen structure to allow
the lookup of an element based on the number generator as a key.

For this purpose, different ops have been included to extend the
current numgen inc functions.

Currently, only supported for numgen incremental operations, but
it will be supported for random in a follow-up patch.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  4 ++
 net/netfilter/nft_numgen.c   | 85 ++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 09f4eb1928f0..f59d84652e58 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1453,6 +1453,8 @@ enum nft_trace_types {
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
  * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
+ * @NFTA_NG_SET_NAME: name of the map to lookup (NLA_STRING)
+ * @NFTA_NG_SET_ID: id of the map (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
@@ -1460,6 +1462,8 @@ enum nft_ng_attributes {
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
NFTA_NG_OFFSET,
+   NFTA_NG_SET_NAME,
+   NFTA_NG_SET_ID,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index 5a3a52c71545..8a64db8f2e69 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -24,13 +24,11 @@ struct nft_ng_inc {
u32 modulus;
atomic_tcounter;
u32 offset;
+   struct nft_set  *map;
 };
 
-static void nft_ng_inc_eval(const struct nft_expr *expr,
-   struct nft_regs *regs,
-   const struct nft_pktinfo *pkt)
+static u32 nft_ng_inc_gen(struct nft_ng_inc *priv)
 {
-   struct nft_ng_inc *priv = nft_expr_priv(expr);
u32 nval, oval;
 
do {
@@ -38,7 +36,36 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
nval = (oval + 1 < priv->modulus) ? oval + 1 : 0;
} while (atomic_cmpxchg(>counter, oval, nval) != oval);
 
-   regs->data[priv->dreg] = nval + priv->offset;
+   return nval + priv->offset;
+}
+
+static void nft_ng_inc_eval(const struct nft_expr *expr,
+   struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+
+   regs->data[priv->dreg] = nft_ng_inc_gen(priv);
+}
+
+static void nft_ng_inc_map_eval(const struct nft_expr *expr,
+   struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+   const struct nft_set *map = priv->map;
+   const struct nft_set_ext *ext;
+   u32 result;
+   bool found;
+
+   result = nft_ng_inc_gen(priv);
+   found = map->ops->lookup(nft_net(pkt), map, , );
+
+   if (!found)
+   return;
+
+   nft_data_copy(>data[priv->dreg],
+ nft_set_ext_data(ext), map->dlen);
 }
 
 static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
@@ -46,6 +73,9 @@ static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] 
= {
[NFTA_NG_MODULUS]   = { .type = NLA_U32 },
[NFTA_NG_TYPE]  = { .type = NLA_U32 },
[NFTA_NG_OFFSET]= { .type = NLA_U32 },
+   [NFTA_NG_SET_NAME]  = { .type = NLA_STRING,
+   .len = NFT_SET_MAXNAMELEN - 1 },
+   [NFTA_NG_SET_ID]= { .type = NLA_U32 },
 };
 
 static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -71,6 +101,25 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_ng_inc_map_init(const struct nft_ctx *ctx,
+  const struct nft_expr *expr,
+  const struct nlattr * const tb[])
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+   u8 genmask = nft_genmask_next(ctx->net);
+
+   nft_ng_inc_init(ctx, expr, tb);
+
+   priv->map = nft_set_lookup_global(ctx->net, ctx->table,
+ tb[NFTA_NG_SET_NAME],
+ tb[NFTA_NG_SET_ID], genmask);
+
+   if (IS_ERR(priv->map))
+   return PTR_ERR(priv->map);
+
+   return 0;
+}
+
 static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
   u32 modulus, enum nft_ng_types type, u32 offset)
 {
@@ -97,6 +146,22 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const 
struct nft_e

Re: [PATCH nft] create u32_integer type to be used as a key for sets and maps

2018-03-26 Thread Laura Garcia
On Sat, Mar 24, 2018 at 12:47 AM, Duncan Roe <duncan_...@optusnet.com.au> wrote:
> On Wed, Mar 14, 2018 at 10:00:35PM +0100, Laura Garcia Liebana wrote:
>> Create the new type u32_integer with a fixed size in order to
>> be used as a key in maps and sets. The type integer cannot be
>> used as a key cause is a dynamic size type and is used as a
>> base type of some subtypes.
>>
>> Without this patch we obtain the following error:
>>
>> Error: unqualified key type integer specified in map definition
>> add map nftlb mapa { type integer : ipv4_addr; }
>>^^^
>>
>> After this patch, we can use an u32 integer as a key for sets
>> and maps:
>>
>> table ip nftlb {
>> map mapa {
>> type u32_integer : ipv4_addr
>>     }
>>
>> set conjunto {
>> type u32_integer
>> }
>> }
>>
>> Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
>> ---
>> This is the v2 of ("fix integer type size to be used as a key
>> for sets and maps"), due to this approach fits better with the
>> current design of nft types than the previous one and avoids
>> possible side effects.
>>
>>  include/datatype.h |  3 +++
>>  src/datatype.c | 10 ++
>>  2 files changed, 13 insertions(+)
>>
>> diff --git a/include/datatype.h b/include/datatype.h
>> index 3f612e5..7f106cd 100644
>> --- a/include/datatype.h
>> +++ b/include/datatype.h
>> @@ -42,6 +42,7 @@
>>   * @TYPE_DEVGROUP:   devgroup code (integer subtype)
>>   * @TYPE_DSCP:   Differentiated Services Code Point (integer 
>> subtype)
>>   * @TYPE_IFNAME: interface name (string subtype)
>> + * @TYPE_U32_INTEGER:unsigned 32 bits integer (integer subtype)
>>   */
>>  enum datatypes {
>>   TYPE_INVALID,
>> @@ -86,6 +87,7 @@ enum datatypes {
>>   TYPE_BOOLEAN,
>>   TYPE_CT_EVENTBIT,
>>   TYPE_IFNAME,
>> + TYPE_U32_INTEGER,
>>   __TYPE_MAX
>>  };
>>  #define TYPE_MAX (__TYPE_MAX - 1)
>> @@ -240,6 +242,7 @@ extern const struct datatype icmpv6_code_type;
>>  extern const struct datatype icmpx_code_type;
>>  extern const struct datatype time_type;
>>  extern const struct datatype boolean_type;
>> +extern const struct datatype u32_integer_type;
>>
>>  extern const struct datatype *concat_type_alloc(uint32_t type);
>>  extern void concat_type_destroy(const struct datatype *dtype);
>> diff --git a/src/datatype.c b/src/datatype.c
>> index 324ac80..f2d1d2b 100644
>> --- a/src/datatype.c
>> +++ b/src/datatype.c
>> @@ -69,6 +69,7 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = {
>>   [TYPE_FIB_ADDR] = _addr_type,
>>   [TYPE_BOOLEAN]  = _type,
>>   [TYPE_IFNAME]   = _type,
>> + [TYPE_U32_INTEGER]  = _integer_type,
>>  };
>>
>>  const struct datatype *datatype_lookup(enum datatypes type)
>> @@ -1144,3 +1145,12 @@ const struct datatype boolean_type = {
>>   .basetype   = _type,
>>   .sym_tbl= _tbl,
>>  };
>> +
>> +const struct datatype u32_integer_type = {
>> + .type   = TYPE_U32_INTEGER,
>> + .name   = "u32_integer",
>> + .desc   = "32 bits integer",
>> + .size   = 4 * BITS_PER_BYTE,
>> + .byteorder  = BYTEORDER_HOST_ENDIAN,
>> + .basetype   = _type,
>> +};
>> --
>> 2.11.0
>>
> Why do we need an invented type when there is already uint32_t in
> /usr/include/stdint.h?

Hi Duncan,

Cause the nft parser doesn't understand uint32_t and the way
that nft sends the types to the kernel requires to specify
the base type, size, byteorder, etc.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] support of dynamic map addition and update of elements

2018-03-15 Thread Laura Garcia Liebana
The support of dynamic adds and updates are only available for sets
and meters. This patch gives such abilities to maps as well.

This patch is useful in cases where dynamic population of maps are
required, for example, to maintain a persistence during some period
of time.

Example:

table ip nftlb {
map persistencia {
type ipv4_addr : mark
timeout 1h
elements = { 192.168.1.132 expires 59m55s : 0x0064,
 192.168.56.101 expires 59m24s : 0x0065 }
}

chain pre {
type nat hook prerouting priority 0; policy accept;
map update \
{ @nh,96,32 : numgen inc mod 2 offset 100 } @persistencia
}
}

An example of the netlink generated sequence:

 nft --debug=netlink add rule ip nftlb pre map add \
{ ip saddr : numgen inc mod 2 offset 100 } @persistencia
ip nftlb pre
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ numgen reg 2 = inc mod 2 offset 100 ]
  [ dynset add reg_key 1 set persistencia sreg_data 2 ]

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/statement.h   | 11 +++
 src/evaluate.c| 10 ++
 src/netlink_delinearize.c | 12 ++--
 src/netlink_linearize.c   | 29 +
 src/parser_bison.y| 12 
 src/statement.c   | 28 
 6 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/include/statement.h b/include/statement.h
index 27c7356..bb4af9d 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -171,6 +171,14 @@ struct set_stmt {
 
 extern struct stmt *set_stmt_alloc(const struct location *loc);
 
+struct map_stmt {
+   struct expr *set;
+   struct expr *map;
+   enum nft_dynset_ops op;
+};
+
+extern struct stmt *map_stmt_alloc(const struct location *loc);
+
 struct meter_stmt {
struct expr *set;
struct expr *key;
@@ -238,6 +246,7 @@ extern struct stmt *xt_stmt_alloc(const struct location 
*loc);
  * @STMT_OBJREF:   stateful object reference statement
  * @STMT_EXTHDR:   extension header statement
  * @STMT_FLOW_OFFLOAD: flow offload statement
+ * @STMT_MAP:  map statement
  */
 enum stmt_types {
STMT_INVALID,
@@ -264,6 +273,7 @@ enum stmt_types {
STMT_OBJREF,
STMT_EXTHDR,
STMT_FLOW_OFFLOAD,
+   STMT_MAP,
 };
 
 /**
@@ -325,6 +335,7 @@ struct stmt {
struct xt_stmt  xt;
struct objref_stmt  objref;
struct flow_stmtflow;
+   struct map_stmt map;
};
 };
 
diff --git a/src/evaluate.c b/src/evaluate.c
index a2c1c72..b71b67b 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2681,6 +2681,14 @@ static int stmt_evaluate_set(struct eval_ctx *ctx, 
struct stmt *stmt)
return 0;
 }
 
+static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt)
+{
+   if (expr_evaluate(ctx, >map.map->map) < 0)
+   return -1;
+
+   return 0;
+}
+
 static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
 {
struct expr *map = stmt->objref.expr;
@@ -2822,6 +2830,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
return stmt_evaluate_set(ctx, stmt);
case STMT_OBJREF:
return stmt_evaluate_objref(ctx, stmt);
+   case STMT_MAP:
+   return stmt_evaluate_map(ctx, stmt);
default:
BUG("unknown statement type %s\n", stmt->ops->name);
}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index d65aacf..bed491a 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1151,10 +1151,10 @@ static void netlink_parse_dynset(struct 
netlink_parse_ctx *ctx,
 const struct nftnl_expr *nle)
 {
const struct nftnl_expr *dnle;
-   struct expr *expr;
+   struct expr *expr, *expr_data;
struct stmt *stmt, *dstmt;
struct set *set;
-   enum nft_registers sreg;
+   enum nft_registers sreg, sreg_data;
const char *name;
 
name = nftnl_expr_get_str(nle, NFTNL_EXPR_DYNSET_SET_NAME);
@@ -1191,11 +1191,19 @@ static void netlink_parse_dynset(struct 
netlink_parse_ctx *ctx,
dstmt = ctx->stmt;
}
 
+   sreg_data = netlink_parse_register(nle, NFTNL_EXPR_DYNSET_SREG_DATA);
+   expr_data = netlink_get_register(ctx, loc, sreg_data);
+
if (dstmt != NULL) {
stmt = meter_stmt_alloc(loc);
stmt->meter.set  = set_ref_expr_alloc(loc, set);
stmt->meter.key  = expr;
stmt->meter.stmt = dstmt;
+   } else if (expr_data != NULL) {
+   stmt = map_stmt_alloc(loc);
+   stmt->map.set   = set_ref_expr_alloc(loc, set);
+   stmt->map.map   = map_expr_al

[PATCH nft] create u32_integer type to be used as a key for sets and maps

2018-03-14 Thread Laura Garcia Liebana
Create the new type u32_integer with a fixed size in order to
be used as a key in maps and sets. The type integer cannot be
used as a key cause is a dynamic size type and is used as a
base type of some subtypes.

Without this patch we obtain the following error:

Error: unqualified key type integer specified in map definition
add map nftlb mapa { type integer : ipv4_addr; }
   ^^^

After this patch, we can use an u32 integer as a key for sets
and maps:

table ip nftlb {
map mapa {
type u32_integer : ipv4_addr
}

set conjunto {
type u32_integer
}
}

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
This is the v2 of ("fix integer type size to be used as a key
for sets and maps"), due to this approach fits better with the
current design of nft types than the previous one and avoids
possible side effects.

 include/datatype.h |  3 +++
 src/datatype.c | 10 ++
 2 files changed, 13 insertions(+)

diff --git a/include/datatype.h b/include/datatype.h
index 3f612e5..7f106cd 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -42,6 +42,7 @@
  * @TYPE_DEVGROUP: devgroup code (integer subtype)
  * @TYPE_DSCP: Differentiated Services Code Point (integer subtype)
  * @TYPE_IFNAME:   interface name (string subtype)
+ * @TYPE_U32_INTEGER:  unsigned 32 bits integer (integer subtype)
  */
 enum datatypes {
TYPE_INVALID,
@@ -86,6 +87,7 @@ enum datatypes {
TYPE_BOOLEAN,
TYPE_CT_EVENTBIT,
TYPE_IFNAME,
+   TYPE_U32_INTEGER,
__TYPE_MAX
 };
 #define TYPE_MAX   (__TYPE_MAX - 1)
@@ -240,6 +242,7 @@ extern const struct datatype icmpv6_code_type;
 extern const struct datatype icmpx_code_type;
 extern const struct datatype time_type;
 extern const struct datatype boolean_type;
+extern const struct datatype u32_integer_type;
 
 extern const struct datatype *concat_type_alloc(uint32_t type);
 extern void concat_type_destroy(const struct datatype *dtype);
diff --git a/src/datatype.c b/src/datatype.c
index 324ac80..f2d1d2b 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -69,6 +69,7 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = {
[TYPE_FIB_ADDR] = _addr_type,
[TYPE_BOOLEAN]  = _type,
[TYPE_IFNAME]   = _type,
+   [TYPE_U32_INTEGER]  = _integer_type,
 };
 
 const struct datatype *datatype_lookup(enum datatypes type)
@@ -1144,3 +1145,12 @@ const struct datatype boolean_type = {
.basetype   = _type,
.sym_tbl= _tbl,
 };
+
+const struct datatype u32_integer_type = {
+   .type   = TYPE_U32_INTEGER,
+   .name   = "u32_integer",
+   .desc   = "32 bits integer",
+   .size   = 4 * BITS_PER_BYTE,
+   .byteorder  = BYTEORDER_HOST_ENDIAN,
+   .basetype   = _type,
+};
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 0/17] netfilter: nf_flow_table: refactoring, TCP state tracking, sending flows to slow path

2018-03-13 Thread Laura Garcia
On Tue, Mar 13, 2018 at 7:16 AM, Rafał Miłecki  wrote:
> On Mon, 5 Mar 2018 23:11:38 +0100, Pablo Neira Ayuso wrote:
>> On Mon, Feb 26, 2018 at 10:15:07AM +0100, Felix Fietkau wrote:
>> > Fixes issues with connections hanging after >30 seconds idle time.
>> >
>> > Changes since v2:
>> > - Include the previous patch series
>> > - Rebase to current nf.git
>> > - Provide longer description for the teardown state and the changes
>> >   for passing flows back to the slow path
>> >
>> > Changes since v1:
>> > - Fix up connection tracking state earlier to improve processing of TCP
>> >   FIN/RST that trigger the bump to the slow path.
>> > - Fix the value of ct->proto.tcp.state, reset the window values to force
>> >   the tcp window check to resync
>>
>> Series applied, thanks Felix.
>
> Hi Pablo,
>
> I just noticed net-next.git already got net.git merged and contains
> Felix's DNAT fix.
>
> Just letting you know, in case you have a moment to look at remaining
> patches. Thanks a lot for taking care of Felix's work! I'm really
> excited about this feature hitting OpenWrt/LEDE :)

+1
Great work guys!
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] tests: shell: autogenerate dump verification

2018-03-07 Thread Laura Garcia Liebana
Complete the automated shell tests with the verification of
the test file dump, only for positive tests and if the test
execution was successful.

It's able to generate the dump file with the -g option.
Example:

 # ./run-tests.sh -g testcases/chains/0001jumps_0

The dump files are generated in the same path in the folder named
dumps/ with .nft extension.

It has been avoided the dump verification code in every test
file.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 tests/shell/README |  5 +-
 tests/shell/run-tests.sh   | 46 +---
 .../cache/dumps/0001_cache_handling_0.nft  | 12 
 .../testcases/cache/dumps/0002_interval_0.nft  |  7 +++
 tests/shell/testcases/chains/0016delete_handle_0   | 23 
 tests/shell/testcases/chains/dumps/0001jumps_0.nft | 64 ++
 .../testcases/chains/dumps/0006masquerade_0.nft|  6 ++
 .../shell/testcases/chains/dumps/0013rename_0.nft  |  4 ++
 .../testcases/chains/dumps/0016delete_handle_0.nft | 20 +++
 tests/shell/testcases/flowtable/0001flowtable_0|  8 ---
 .../testcases/flowtable/dumps/0001flowtable_0.nft  | 10 
 tests/shell/testcases/import/vm_json_import_0  |  8 ---
 .../testcases/include/dumps/0001absolute_0.nft |  2 +
 .../testcases/include/dumps/0002relative_0.nft |  2 +
 .../testcases/include/dumps/0003includepath_0.nft  |  2 +
 .../testcases/include/dumps/0006glob_single_0.nft  |  2 +
 .../testcases/include/dumps/0007glob_double_0.nft  |  4 ++
 .../include/dumps/0011glob_dependency_0.nft|  4 ++
 .../testcases/include/dumps/0013glob_dotfile_0.nft |  2 +
 .../include/dumps/0015doubleincludepath_0.nft  |  4 ++
 tests/shell/testcases/listing/0001ruleset_0| 11 
 tests/shell/testcases/listing/0002ruleset_0|  9 ---
 .../testcases/listing/dumps/0001ruleset_0.nft  |  2 +
 .../maps/0005interval_map_add_many_elements_0  | 15 -
 .../testcases/maps/0006interval_map_overlap_0  | 14 -
 .../shell/testcases/maps/0007named_ifname_dtype_0  |  7 ---
 .../dumps/0005interval_map_add_many_elements_0.nft |  8 +++
 .../maps/dumps/0006interval_map_overlap_0.nft  |  7 +++
 .../maps/dumps/0007named_ifname_dtype_0.nft| 11 
 .../testcases/maps/dumps/anonymous_snat_map_0.nft  |  5 ++
 .../testcases/maps/dumps/map_with_flags_0.nft  |  6 ++
 .../testcases/maps/dumps/named_snat_map_0.nft  | 10 
 tests/shell/testcases/maps/map_with_flags_0| 15 -
 tests/shell/testcases/nft-f/0002rollback_rule_0| 10 
 tests/shell/testcases/nft-f/0003rollback_jump_0| 10 
 tests/shell/testcases/nft-f/0004rollback_set_0 | 10 
 tests/shell/testcases/nft-f/0005rollback_map_0 | 10 
 tests/shell/testcases/nft-f/0008split_tables_0 | 19 ---
 .../testcases/nft-f/dumps/0002rollback_rule_0.nft  | 16 ++
 .../testcases/nft-f/dumps/0003rollback_jump_0.nft  | 16 ++
 .../testcases/nft-f/dumps/0004rollback_set_0.nft   | 16 ++
 .../testcases/nft-f/dumps/0005rollback_map_0.nft   | 16 ++
 .../testcases/nft-f/dumps/0008split_tables_0.nft   | 10 
 .../shell/testcases/nft-f/dumps/0009variable_0.nft |  7 +++
 .../shell/testcases/nft-f/dumps/0010variable_0.nft |  6 ++
 .../nft-f/dumps/0012different_defines_0.nft| 16 ++
 .../shell/testcases/optionals/dumps/comments_0.nft |  5 ++
 .../optionals/dumps/comments_handles_0.nft |  5 ++
 .../shell/testcases/optionals/dumps/handles_0.nft  |  5 ++
 .../testcases/rule_management/0001addposition_0| 16 --
 .../testcases/rule_management/0002insertposition_0 | 16 --
 tests/shell/testcases/rule_management/0003insert_0 | 16 --
 .../shell/testcases/rule_management/0004replace_0  | 14 -
 tests/shell/testcases/rule_management/0007delete_0 | 14 -
 .../rule_management/dumps/0001addposition_0.nft|  7 +++
 .../rule_management/dumps/0002insertposition_0.nft |  7 +++
 .../rule_management/dumps/0003insert_0.nft |  7 +++
 .../rule_management/dumps/0004replace_0.nft|  5 ++
 .../rule_management/dumps/0007delete_0.nft |  5 ++
 .../testcases/sets/0012add_delete_many_elements_0  | 13 -
 .../testcases/sets/0013add_delete_many_elements_0  | 14 -
 tests/shell/testcases/sets/0021nesting_0   | 14 -
 .../shell/testcases/sets/0029named_ifname_dtype_0  |  8 ---
 .../testcases/sets/dumps/0001named_interval_0.nft  | 34 
 .../dumps/0002named_interval_automerging_0.nft |  7 +++
 .../dumps/0003named_interval_missing_flag_0.nft|  5 ++
 .../sets/dumps/0004named_interval_shadow_0.nft |  7 +++
 .../sets/dumps/0005named_interval_shadow_0.nft |  7 +++
 .../testcases/sets/dumps/0006create_set_0.nft  |  5 ++
 .../testcases/sets/dumps/0007create_element_0.nft  |  6 ++
 .../sets/dumps/0008comments_interval_0.nft |  7 +++
 .../sets/dumps/0008create_verdict_map_0.nft| 13 +
 .../sets/dumps/0009comments_timeout

[RFC nft] tests: shell: autogenerate dump verification

2018-03-05 Thread Laura Garcia Liebana
Complete the automated shell tests with the verification of
the test file dump, only for positive tests and if the test
execution was successful.

It's able to generate the dump file with the -g option.
Example:

 # ./run-tests.sh -g testcases/chains/0001jumps_0

The dump files are generated in the same path with .dump
extension.

It has been avoided the dump verification code in every test
file.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 tests/shell/README |  5 +-
 tests/shell/run-tests.sh   | 43 ---
 .../testcases/cache/0001_cache_handling_0.dump | 12 
 tests/shell/testcases/cache/0002_interval_0.dump   |  7 +++
 tests/shell/testcases/chains/0001jumps_0.dump  | 64 ++
 tests/shell/testcases/chains/0006masquerade_0.dump |  6 ++
 tests/shell/testcases/chains/0013rename_0.dump |  4 ++
 tests/shell/testcases/include/0001absolute_0.dump  |  2 +
 tests/shell/testcases/include/0002relative_0.dump  |  2 +
 .../shell/testcases/include/0003includepath_0.dump |  2 +
 .../shell/testcases/include/0005glob_empty_0.dump  |  0
 .../shell/testcases/include/0006glob_single_0.dump |  2 +
 .../shell/testcases/include/0007glob_double_0.dump |  4 ++
 .../include/0008glob_nofile_wildcard_0.dump|  0
 .../testcases/include/0011glob_dependency_0.dump   |  4 ++
 .../testcases/include/0013glob_dotfile_0.dump  |  2 +
 .../0013input_descriptors_included_files_0.dump|  0
 .../testcases/include/0014glob_directory_0.dump|  0
 .../testcases/include/0015doubleincludepath_0.dump |  4 ++
 tests/shell/testcases/listing/0001ruleset_0| 11 
 tests/shell/testcases/listing/0001ruleset_0.dump   |  2 +
 tests/shell/testcases/listing/0002ruleset_0|  9 ---
 tests/shell/testcases/listing/0002ruleset_0.dump   |  0
 tests/shell/testcases/listing/0003table_0.dump |  2 +
 tests/shell/testcases/listing/0004table_0.dump |  4 ++
 .../shell/testcases/listing/0005ruleset_ip_0.dump  | 10 
 .../shell/testcases/listing/0006ruleset_ip6_0.dump | 10 
 .../testcases/listing/0007ruleset_inet_0.dump  | 10 
 .../shell/testcases/listing/0008ruleset_arp_0.dump | 10 
 .../testcases/listing/0009ruleset_bridge_0.dump| 10 
 tests/shell/testcases/listing/0010sets_0.dump  | 39 +
 tests/shell/testcases/listing/0011sets_0.dump  | 25 +
 tests/shell/testcases/listing/0012sets_0.dump  | 39 +
 .../maps/0005interval_map_add_many_elements_0  | 15 -
 .../maps/0005interval_map_add_many_elements_0.dump |  8 +++
 .../testcases/maps/0006interval_map_overlap_0  | 14 -
 .../testcases/maps/0006interval_map_overlap_0.dump |  7 +++
 .../shell/testcases/maps/0007named_ifname_dtype_0  |  7 ---
 .../testcases/maps/0007named_ifname_dtype_0.dump   | 11 
 .../shell/testcases/maps/anonymous_snat_map_0.dump |  5 ++
 tests/shell/testcases/maps/map_with_flags_0| 15 -
 tests/shell/testcases/maps/map_with_flags_0.dump   |  6 ++
 tests/shell/testcases/maps/named_snat_map_0.dump   | 10 
 .../shell/testcases/nft-f/0001define_slash_0.dump  |  0
 tests/shell/testcases/nft-f/0002rollback_rule_0| 10 
 .../shell/testcases/nft-f/0002rollback_rule_0.dump | 16 ++
 tests/shell/testcases/nft-f/0003rollback_jump_0| 10 
 .../shell/testcases/nft-f/0003rollback_jump_0.dump | 16 ++
 tests/shell/testcases/nft-f/0004rollback_set_0 | 10 
 .../shell/testcases/nft-f/0004rollback_set_0.dump  | 16 ++
 tests/shell/testcases/nft-f/0005rollback_map_0 | 10 
 .../shell/testcases/nft-f/0005rollback_map_0.dump  | 16 ++
 .../shell/testcases/nft-f/0006action_object_0.dump |  0
 tests/shell/testcases/nft-f/0008split_tables_0 | 19 ---
 .../shell/testcases/nft-f/0008split_tables_0.dump  | 10 
 tests/shell/testcases/nft-f/0009variable_0.dump|  7 +++
 tests/shell/testcases/nft-f/0010variable_0.dump|  6 ++
 .../testcases/nft-f/0012different_defines_0.dump   | 16 ++
 tests/shell/testcases/optionals/comments_0.dump|  5 ++
 .../testcases/optionals/comments_handles_0.dump|  5 ++
 tests/shell/testcases/optionals/handles_0.dump |  5 ++
 .../testcases/rule_management/0001addposition_0| 16 --
 .../rule_management/0001addposition_0.dump |  7 +++
 .../testcases/rule_management/0002insertposition_0 | 16 --
 .../rule_management/0002insertposition_0.dump  |  7 +++
 tests/shell/testcases/rule_management/0003insert_0 | 16 --
 .../testcases/rule_management/0003insert_0.dump|  7 +++
 .../shell/testcases/rule_management/0004replace_0  | 14 -
 .../testcases/rule_management/0004replace_0.dump   |  5 ++
 tests/shell/testcases/rule_management/0007delete_0 | 14 -
 .../testcases/rule_management/0007delete_0.dump|  5 ++
 .../shell/testcases/sets/0001named_interval_0.dump | 34 
 .../sets/0002named_interval_automerging_0.dump |  7 +++
 ..

Re: [PATCH nft] fix integer type size to be used as a key for sets and maps

2018-03-02 Thread Laura Garcia Liebana
On Fri, Mar 02, 2018 at 06:58:44PM +0100, Phil Sutter wrote:
> Hi Laura,
> 
> On Fri, Mar 02, 2018 at 05:34:02PM +0100, Laura Garcia Liebana wrote:
> [...]
> > diff --git a/src/datatype.c b/src/datatype.c
> > index 324ac80..06015bb 100644
> > --- a/src/datatype.c
> > +++ b/src/datatype.c
> > @@ -356,6 +356,7 @@ const struct datatype integer_type = {
> > .type   = TYPE_INTEGER,
> > .name   = "integer",
> > .desc   = "integer",
> > +   .size   = 4 * BITS_PER_BYTE,
> > .print  = integer_type_print,
> > .parse  = integer_type_parse,
> >  };
> 
> I'm not sure this is going to work: integer_type is used as basetype for
> many others, and there is at least lladdr_type which doesn't define a
> size on it's own (and is larger than four bytes). Are you sure this
> won't cause unexpected side-effects (like, e.g. lookups in sets
> containing lladdr_type entries returning false-positives)?

It seems that this issue requires a more elaborated fix. I'll check
it out.

Thanks Phil.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] fix integer type size to be used as a key for sets and maps

2018-03-02 Thread Laura Garcia Liebana
Includes the size of the type integer in order to be used
as a key in a map or set.

Without this patch we obtain the following error:

Error: unqualified key type integer specified in map definition
add map nftlb mapa { type integer : ipv4_addr; timeout 5s; }
   ^^^

After this patch, we can use an integer as a key for sets
and maps:

table ip nftlb {
map mapa {
type integer : ipv4_addr
}

set conjunto {
type integer
}
}

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 src/datatype.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/datatype.c b/src/datatype.c
index 324ac80..06015bb 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -356,6 +356,7 @@ const struct datatype integer_type = {
.type   = TYPE_INTEGER,
.name   = "integer",
.desc   = "integer",
+   .size   = 4 * BITS_PER_BYTE,
.print  = integer_type_print,
.parse  = integer_type_parse,
 };
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] parser: support of maps with timeout

2018-03-02 Thread Laura Garcia Liebana
Support of key and value association with a certain timeout.

Example:

nft add map nftlb mapa { type inet_service: ipv4_addr\;
 timeout 5s\; }

Results in:

table ip nftlb {
map mapa {
type inet_service : ipv4_addr
timeout 5s
}
}

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 src/parser_bison.y | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/parser_bison.y b/src/parser_bison.y
index df672b1..0c9e6c2 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1462,6 +1462,11 @@ map_block_alloc  :   /* empty */
 map_block  :   /* empty */ { $$ = $-1; }
|   map_block   common_block
|   map_block   stmt_separator
+   |   map_block   TIMEOUT time_spec   
stmt_separator
+   {
+   $1->timeout = $3 * 1000;
+   $$ = $1;
+   }
|   map_block   TYPE
data_type_expr  COLON   
data_type_expr
stmt_separator
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] src: hash: fix seed attribute not listed

2017-03-24 Thread Laura Garcia Liebana
The tests warned about a problem with the seed listing.

/tests/py# ./nft-test.py ip/hash.t
ip/hash.t: WARNING: line: 4: 'src/nft add rule --debug=netlink \
 ip test-ip4 pre ct mark set jhash ip saddr . ip daddr mod 2 \
 seed 0xdeadbeef': 'ct mark set jhash ip saddr . ip daddr mod 2 \
 seed 0xdeadbeef' mismatches 'ct mark set jhash ip saddr . ip \
 daddr mod 2'
ip/hash.t: WARNING: line: 6: 'src/nft add rule --debug=netlink \
 ip test-ip4 pre ct mark set jhash ip saddr . ip daddr mod 2 seed \
 0xdeadbeef offset 100': 'ct mark set jhash ip saddr . ip daddr \
 mod 2 seed 0xdeadbeef offset 100' mismatches 'ct mark set jhash \
 ip saddr . ip daddr mod 2 offset 100'
ip/hash.t: 6 unit tests, 0 error, 2 warning

The expression type is now treated as an unsigned int in the
hash_expr_print() function.

Fixes 3a86406 ("src: hash: support of symmetric hash")

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
 src/hash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/hash.c b/src/hash.c
index a7a9612..bec1684 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -28,7 +28,7 @@ static void hash_expr_print(const struct expr *expr)
}
 
printf(" mod %u", expr->hash.mod);
-   if (expr->hash.type & NFT_HASH_JENKINS && expr->hash.seed)
+   if ((expr->hash.type == NFT_HASH_JENKINS) && expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
if (expr->hash.offset)
printf(" offset %u", expr->hash.offset);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft] src: hash: fix seed attribute not listed

2017-03-24 Thread Laura Garcia Liebana
The tests warned about a problem with the seed listing.

/tests/py# ./nft-test.py ip/hash.t
ip/hash.t: WARNING: line: 4: 'src/nft add rule --debug=netlink \
 ip test-ip4 pre ct mark set jhash ip saddr . ip daddr mod 2 \
 seed 0xdeadbeef': 'ct mark set jhash ip saddr . ip daddr mod 2 \
 seed 0xdeadbeef' mismatches 'ct mark set jhash ip saddr . ip \
 daddr mod 2'
ip/hash.t: WARNING: line: 6: 'src/nft add rule --debug=netlink \
 ip test-ip4 pre ct mark set jhash ip saddr . ip daddr mod 2 seed \
 0xdeadbeef offset 100': 'ct mark set jhash ip saddr . ip daddr \
 mod 2 seed 0xdeadbeef offset 100' mismatches 'ct mark set jhash \
 ip saddr . ip daddr mod 2 offset 100'
ip/hash.t: 6 unit tests, 0 error, 2 warning

The expression type is now treated as an unsigned int in the
hash_expr_print() function.

Fixes 3a86406 ("src: hash: support of symmetric hash")

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
 src/hash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/hash.c b/src/hash.c
index a7a9612..bec1684 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -28,7 +28,7 @@ static void hash_expr_print(const struct expr *expr)
}
 
printf(" mod %u", expr->hash.mod);
-   if (expr->hash.type & NFT_HASH_JENKINS && expr->hash.seed)
+   if ((expr->hash.type == NFT_HASH_JENKINS) && expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
if (expr->hash.offset)
printf(" offset %u", expr->hash.offset);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nf-next v3 2/2] netfilter: nft_hash: support of symmetric hash

2017-03-02 Thread Laura Garcia Liebana
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.

For this purpose, the __skb_get_hash_symmetric() is used to
identify the flow as it uses FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL
flag by default.

The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.

The main difference between both types are:
 - jhash requires an expression with sreg, symhash doesn't.
 - symhash supports modulus and offset, but not seed.

Examples:

 nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
 nft add rule ip nat prerouting ct mark set symhash mod 2

By default, jenkins hash will be used if no hash type is
provided for compatibility reasons.

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
v2:
- Avoid warning due to 'const' from symhash eval skb
v3:
- Set jhash as default ops, according to Liping and Pablo
suggestions.

 include/uapi/linux/netfilter/nf_tables.h | 13 +
 net/netfilter/nft_hash.c | 99 +++-
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 7b730cab99bd..a444a63a9eee 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -793,6 +793,17 @@ enum nft_rt_keys {
 };
 
 /**
+ * enum nft_hash_types - nf_tables hash expression types
+ *
+ * @NFT_HASH_JENKINS: Jenkins Hash
+ * @NFT_HASH_SYM: Symmetric Hash
+ */
+enum nft_hash_types {
+   NFT_HASH_JENKINS,
+   NFT_HASH_SYM,
+};
+
+/**
  * enum nft_hash_attributes - nf_tables hash expression netlink attributes
  *
  * @NFTA_HASH_SREG: source register (NLA_U32)
@@ -801,6 +812,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
+ * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -810,6 +822,7 @@ enum nft_hash_attributes {
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+   NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index ccb834ef049b..a6a4633725bb 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -38,6 +38,25 @@ static void nft_jhash_eval(const struct nft_expr *expr,
regs->data[priv->dreg] = h + priv->offset;
 }
 
+struct nft_symhash {
+   enum nft_registers  dreg:8;
+   u32 modulus;
+   u32 offset;
+};
+
+static void nft_symhash_eval(const struct nft_expr *expr,
+struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+   u32 h;
+
+   h = reciprocal_scale(__skb_get_hash_symmetric(skb), priv->modulus);
+
+   regs->data[priv->dreg] = h + priv->offset;
+}
+
 static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_SREG]= { .type = NLA_U32 },
[NFTA_HASH_DREG]= { .type = NLA_U32 },
@@ -45,6 +64,7 @@ static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX 
+ 1] = {
[NFTA_HASH_MODULUS] = { .type = NLA_U32 },
[NFTA_HASH_SEED]= { .type = NLA_U32 },
[NFTA_HASH_OFFSET]  = { .type = NLA_U32 },
+   [NFTA_HASH_TYPE]= { .type = NLA_U32 },
 };
 
 static int nft_jhash_init(const struct nft_ctx *ctx,
@@ -92,6 +112,32 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_symhash_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+
+   if (!tb[NFTA_HASH_DREG]||
+   !tb[NFTA_HASH_MODULUS])
+   return -EINVAL;
+
+   if (tb[NFTA_HASH_OFFSET])
+   priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
+
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
+   if (priv->modulus <= 1)
+   return -ERANGE;
+
+   if (priv->offset + priv->modulus - 1 < priv->offset)
+   return -EOVERFLOW;
+
+   return nft_validate_register_store(ctx, priv->dreg, NULL,
+  NFT_DATA_VALUE, sizeof(u32));
+}
+
 static int nft_jhash_dump(struct sk_buff *skb,
   

[PATCH nft v2] src: hash: support of symmetric hash

2017-02-28 Thread Laura Garcia Liebana
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.

The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.

The main difference between both types are:
 - jhash requires an expression with sreg, symhash doesn't.
 - symhash supports modulus and offset, but not seed.

Examples:

 nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
 nft add rule ip nat prerouting ct mark set symhash mod 2

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
v2:
- Discard new line remove

 include/expression.h|  1 +
 include/hash.h  |  2 +-
 include/linux/netfilter/nf_tables.h | 13 +
 src/evaluate.c  |  3 ++-
 src/hash.c  | 28 +---
 src/netlink_delinearize.c   | 35 +--
 src/netlink_linearize.c | 19 ---
 src/parser_bison.y  | 16 ++--
 src/scanner.l   |  1 +
 tests/py/ip/hash.t  |  1 +
 tests/py/ip/hash.t.payload  |  4 
 11 files changed, 87 insertions(+), 36 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index ec90265..56cb310 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -308,6 +308,7 @@ struct expr {
uint32_tmod;
uint32_tseed;
uint32_toffset;
+   enum nft_hash_types type;
} hash;
struct {
/* EXPR_FIB */
diff --git a/include/hash.h b/include/hash.h
index 8bf53e2..7f9c6f1 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -3,6 +3,6 @@
 
 extern struct expr *hash_expr_alloc(const struct location *loc,
uint32_t modulus, uint32_t seed,
-   uint32_t offset);
+   uint32_t offset, enum nft_hash_types type);
 
 #endif /* NFTABLES_HASH_H */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index b00a05d..74a42fa 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -793,6 +793,17 @@ enum nft_rt_keys {
 };
 
 /**
+ * enum nft_hash_types - nf_tables hash expression types
+ *
+ * @NFT_HASH_JENKINS: Jenkins Hash
+ * @NFT_HASH_SYM: Symmetric Hash
+ */
+enum nft_hash_types {
+   NFT_HASH_JENKINS,
+   NFT_HASH_SYM,
+};
+
+/**
  * enum nft_hash_attributes - nf_tables hash expression netlink attributes
  *
  * @NFTA_HASH_SREG: source register (NLA_U32)
@@ -801,6 +812,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
+ * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -810,6 +822,7 @@ enum nft_hash_attributes {
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+   NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/evaluate.c b/src/evaluate.c
index 94412f2..18884be 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1249,7 +1249,8 @@ static int expr_evaluate_hash(struct eval_ctx *ctx, 
struct expr **exprp)
expr_dtype_integer_compatible(ctx, expr);
 
expr_set_context(>ectx, NULL, 0);
-   if (expr_evaluate(ctx, >hash.expr) < 0)
+   if (expr->hash.expr &&
+   expr_evaluate(ctx, >hash.expr) < 0)
return -1;
 
/* expr_evaluate_primary() sets the context to what to the input
diff --git a/src/hash.c b/src/hash.c
index d26b2ed..a7a9612 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -17,10 +17,18 @@
 
 static void hash_expr_print(const struct expr *expr)
 {
-   printf("jhash ");
-   expr_print(expr->hash.expr);
+   switch (expr->hash.type) {
+   case NFT_HASH_SYM:
+   printf("symhash");
+   break;
+   case NFT_HASH_JENKINS:
+   default:
+   printf("jhash ");
+   expr_print(expr->hash.expr);
+   }
+
printf(" mod %u", expr->hash.mod);
-   if (expr->hash.seed)
+   if (expr->hash.type & NFT_HASH_JENKINS && expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
if (expr->hash.offset)
printf(" offset %u", expr->hash.offset);
@@ -28,18 +36,22 @@ static void hash_expr_print(const struct expr *expr)
 
 static bool hash_expr_cmp(const struct expr *e1, const str

[PATCH nf-next v2 2/2] netfilter: nft_hash: support of symmetric hash

2017-02-28 Thread Laura Garcia Liebana
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.

For this purpose, the __skb_get_hash_symmetric() is used to
identify the flow as it uses FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL
flag by default.

The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.

The main difference between both types are:
 - jhash requires an expression with sreg, symhash doesn't.
 - symhash supports modulus and offset, but not seed.

Examples:

 nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
 nft add rule ip nat prerouting ct mark set symhash mod 2

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
v2:
- Avoid warning due to 'const' from symhash eval skb

 include/uapi/linux/netfilter/nf_tables.h | 13 +
 net/netfilter/nft_hash.c | 98 +++-
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 7b730cab99bd..a444a63a9eee 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -793,6 +793,17 @@ enum nft_rt_keys {
 };
 
 /**
+ * enum nft_hash_types - nf_tables hash expression types
+ *
+ * @NFT_HASH_JENKINS: Jenkins Hash
+ * @NFT_HASH_SYM: Symmetric Hash
+ */
+enum nft_hash_types {
+   NFT_HASH_JENKINS,
+   NFT_HASH_SYM,
+};
+
+/**
  * enum nft_hash_attributes - nf_tables hash expression netlink attributes
  *
  * @NFTA_HASH_SREG: source register (NLA_U32)
@@ -801,6 +812,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
+ * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -810,6 +822,7 @@ enum nft_hash_attributes {
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+   NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index ccb834ef049b..8eaf3d25b970 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -38,6 +38,25 @@ static void nft_jhash_eval(const struct nft_expr *expr,
regs->data[priv->dreg] = h + priv->offset;
 }
 
+struct nft_symhash {
+   enum nft_registers  dreg:8;
+   u32 modulus;
+   u32 offset;
+};
+
+static void nft_symhash_eval(const struct nft_expr *expr,
+struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+   struct sk_buff *skb = pkt->skb;
+   u32 h;
+
+   h = reciprocal_scale(__skb_get_hash_symmetric(skb), priv->modulus);
+
+   regs->data[priv->dreg] = h + priv->offset;
+}
+
 static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_SREG]= { .type = NLA_U32 },
[NFTA_HASH_DREG]= { .type = NLA_U32 },
@@ -45,6 +64,7 @@ static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX 
+ 1] = {
[NFTA_HASH_MODULUS] = { .type = NLA_U32 },
[NFTA_HASH_SEED]= { .type = NLA_U32 },
[NFTA_HASH_OFFSET]  = { .type = NLA_U32 },
+   [NFTA_HASH_TYPE]= { .type = NLA_U32 },
 };
 
 static int nft_jhash_init(const struct nft_ctx *ctx,
@@ -92,6 +112,32 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_symhash_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+
+   if (!tb[NFTA_HASH_DREG]||
+   !tb[NFTA_HASH_MODULUS])
+   return -EINVAL;
+
+   if (tb[NFTA_HASH_OFFSET])
+   priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
+
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
+   if (priv->modulus <= 1)
+   return -ERANGE;
+
+   if (priv->offset + priv->modulus - 1 < priv->offset)
+   return -EOVERFLOW;
+
+   return nft_validate_register_store(ctx, priv->dreg, NULL,
+  NFT_DATA_VALUE, sizeof(u32));
+}
+
 static int nft_jhash_dump(struct sk_buff *skb,
  const struct nft_expr *expr)
 {
@@ -110,6 +156,28 @@ static int nft_jhash_dump(struct sk_buff *skb,
if (priv->offset != 0)
   

[PATCH nft] src: hash: support of symmetric hash

2017-02-23 Thread Laura Garcia Liebana
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.

The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.

The main difference between both types are:
 - jhash requires an expression with sreg, symhash doesn't.
 - symhash supports modulus and offset, but not seed.

Examples:

 nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
 nft add rule ip nat prerouting ct mark set symhash mod 2

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
 include/expression.h|  1 +
 include/hash.h  |  2 +-
 include/linux/netfilter/nf_tables.h | 13 +
 src/evaluate.c  |  3 ++-
 src/hash.c  | 28 +---
 src/netlink_delinearize.c   | 35 +--
 src/netlink_linearize.c | 20 
 src/parser_bison.y  | 16 ++--
 src/scanner.l   |  1 +
 tests/py/ip/hash.t  |  1 +
 tests/py/ip/hash.t.payload  |  4 
 11 files changed, 87 insertions(+), 37 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index ec90265..56cb310 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -308,6 +308,7 @@ struct expr {
uint32_tmod;
uint32_tseed;
uint32_toffset;
+   enum nft_hash_types type;
} hash;
struct {
/* EXPR_FIB */
diff --git a/include/hash.h b/include/hash.h
index 8bf53e2..7f9c6f1 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -3,6 +3,6 @@
 
 extern struct expr *hash_expr_alloc(const struct location *loc,
uint32_t modulus, uint32_t seed,
-   uint32_t offset);
+   uint32_t offset, enum nft_hash_types type);
 
 #endif /* NFTABLES_HASH_H */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index b00a05d..74a42fa 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -793,6 +793,17 @@ enum nft_rt_keys {
 };
 
 /**
+ * enum nft_hash_types - nf_tables hash expression types
+ *
+ * @NFT_HASH_JENKINS: Jenkins Hash
+ * @NFT_HASH_SYM: Symmetric Hash
+ */
+enum nft_hash_types {
+   NFT_HASH_JENKINS,
+   NFT_HASH_SYM,
+};
+
+/**
  * enum nft_hash_attributes - nf_tables hash expression netlink attributes
  *
  * @NFTA_HASH_SREG: source register (NLA_U32)
@@ -801,6 +812,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
+ * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -810,6 +822,7 @@ enum nft_hash_attributes {
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+   NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/evaluate.c b/src/evaluate.c
index 94412f2..18884be 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1249,7 +1249,8 @@ static int expr_evaluate_hash(struct eval_ctx *ctx, 
struct expr **exprp)
expr_dtype_integer_compatible(ctx, expr);
 
expr_set_context(>ectx, NULL, 0);
-   if (expr_evaluate(ctx, >hash.expr) < 0)
+   if (expr->hash.expr &&
+   expr_evaluate(ctx, >hash.expr) < 0)
return -1;
 
/* expr_evaluate_primary() sets the context to what to the input
diff --git a/src/hash.c b/src/hash.c
index d26b2ed..a7a9612 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -17,10 +17,18 @@
 
 static void hash_expr_print(const struct expr *expr)
 {
-   printf("jhash ");
-   expr_print(expr->hash.expr);
+   switch (expr->hash.type) {
+   case NFT_HASH_SYM:
+   printf("symhash");
+   break;
+   case NFT_HASH_JENKINS:
+   default:
+   printf("jhash ");
+   expr_print(expr->hash.expr);
+   }
+
printf(" mod %u", expr->hash.mod);
-   if (expr->hash.seed)
+   if (expr->hash.type & NFT_HASH_JENKINS && expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
if (expr->hash.offset)
printf(" offset %u", expr->hash.offset);
@@ -28,18 +36,22 @@ static void hash_expr_print(const struct expr *expr)
 
 static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
-   r

[PATCH nf-next 2/2] netfilter: nft_hash: support of symmetric hash

2017-02-23 Thread Laura Garcia Liebana
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.

For this purpose, the __skb_get_hash_symmetric() is used to
identify the flow as it uses FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL
flag by default.

The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.

The main difference between both types are:
 - jhash requires an expression with sreg, symhash doesn't.
 - symhash supports modulus and offset, but not seed.

Examples:

 nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
 nft add rule ip nat prerouting ct mark set symhash mod 2

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
 include/uapi/linux/netfilter/nf_tables.h | 13 +
 net/netfilter/nft_hash.c | 98 +++-
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 7b730cab99bd..a444a63a9eee 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -793,6 +793,17 @@ enum nft_rt_keys {
 };
 
 /**
+ * enum nft_hash_types - nf_tables hash expression types
+ *
+ * @NFT_HASH_JENKINS: Jenkins Hash
+ * @NFT_HASH_SYM: Symmetric Hash
+ */
+enum nft_hash_types {
+   NFT_HASH_JENKINS,
+   NFT_HASH_SYM,
+};
+
+/**
  * enum nft_hash_attributes - nf_tables hash expression netlink attributes
  *
  * @NFTA_HASH_SREG: source register (NLA_U32)
@@ -801,6 +812,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
  * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32)
+ * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -810,6 +822,7 @@ enum nft_hash_attributes {
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
NFTA_HASH_OFFSET,
+   NFTA_HASH_TYPE,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index ccb834ef049b..da0171908f92 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -38,6 +38,25 @@ static void nft_jhash_eval(const struct nft_expr *expr,
regs->data[priv->dreg] = h + priv->offset;
 }
 
+struct nft_symhash {
+   enum nft_registers  dreg:8;
+   u32 modulus;
+   u32 offset;
+};
+
+static void nft_symhash_eval(const struct nft_expr *expr,
+struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+   const struct sk_buff *skb = pkt->skb;
+   u32 h;
+
+   h = reciprocal_scale(__skb_get_hash_symmetric(skb), priv->modulus);
+
+   regs->data[priv->dreg] = h + priv->offset;
+}
+
 static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_SREG]= { .type = NLA_U32 },
[NFTA_HASH_DREG]= { .type = NLA_U32 },
@@ -45,6 +64,7 @@ static const struct nla_policy nft_hash_policy[NFTA_HASH_MAX 
+ 1] = {
[NFTA_HASH_MODULUS] = { .type = NLA_U32 },
[NFTA_HASH_SEED]= { .type = NLA_U32 },
[NFTA_HASH_OFFSET]  = { .type = NLA_U32 },
+   [NFTA_HASH_TYPE]= { .type = NLA_U32 },
 };
 
 static int nft_jhash_init(const struct nft_ctx *ctx,
@@ -92,6 +112,32 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
+static int nft_symhash_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_symhash *priv = nft_expr_priv(expr);
+
+   if (!tb[NFTA_HASH_DREG]||
+   !tb[NFTA_HASH_MODULUS])
+   return -EINVAL;
+
+   if (tb[NFTA_HASH_OFFSET])
+   priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
+
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
+   if (priv->modulus <= 1)
+   return -ERANGE;
+
+   if (priv->offset + priv->modulus - 1 < priv->offset)
+   return -EOVERFLOW;
+
+   return nft_validate_register_store(ctx, priv->dreg, NULL,
+  NFT_DATA_VALUE, sizeof(u32));
+}
+
 static int nft_jhash_dump(struct sk_buff *skb,
  const struct nft_expr *expr)
 {
@@ -110,6 +156,28 @@ static int nft_jhash_dump(struct sk_buff *skb,
if (priv->offset != 0)
if (nla_put_be32(skb, NFTA_HASH_OFFSET, htonl(priv->offset)))

[PATCH nf-next 1/2] netfilter: nft_hash: rename nft_hash to nft_jhash

2017-02-23 Thread Laura Garcia Liebana
This patch renames the local nft_hash structure and functions
to nft_jhash in order to prepare the nft_hash module code to
add new hash functions.

Signed-off-by: Laura Garcia Liebana <laura.gar...@zevenet.com>
---
 net/netfilter/nft_hash.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index eb2721af898d..ccb834ef049b 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 
-struct nft_hash {
+struct nft_jhash {
enum nft_registers  sreg:8;
enum nft_registers  dreg:8;
u8  len;
@@ -26,11 +26,11 @@ struct nft_hash {
u32 offset;
 };
 
-static void nft_hash_eval(const struct nft_expr *expr,
- struct nft_regs *regs,
- const struct nft_pktinfo *pkt)
+static void nft_jhash_eval(const struct nft_expr *expr,
+  struct nft_regs *regs,
+  const struct nft_pktinfo *pkt)
 {
-   struct nft_hash *priv = nft_expr_priv(expr);
+   struct nft_jhash *priv = nft_expr_priv(expr);
const void *data = >data[priv->sreg];
u32 h;
 
@@ -47,11 +47,11 @@ static const struct nla_policy 
nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_OFFSET]  = { .type = NLA_U32 },
 };
 
-static int nft_hash_init(const struct nft_ctx *ctx,
-const struct nft_expr *expr,
-const struct nlattr * const tb[])
+static int nft_jhash_init(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nlattr * const tb[])
 {
-   struct nft_hash *priv = nft_expr_priv(expr);
+   struct nft_jhash *priv = nft_expr_priv(expr);
u32 len;
int err;
 
@@ -92,10 +92,10 @@ static int nft_hash_init(const struct nft_ctx *ctx,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
-static int nft_hash_dump(struct sk_buff *skb,
-const struct nft_expr *expr)
+static int nft_jhash_dump(struct sk_buff *skb,
+ const struct nft_expr *expr)
 {
-   const struct nft_hash *priv = nft_expr_priv(expr);
+   const struct nft_jhash *priv = nft_expr_priv(expr);
 
if (nft_dump_register(skb, NFTA_HASH_SREG, priv->sreg))
goto nla_put_failure;
@@ -117,17 +117,17 @@ static int nft_hash_dump(struct sk_buff *skb,
 }
 
 static struct nft_expr_type nft_hash_type;
-static const struct nft_expr_ops nft_hash_ops = {
+static const struct nft_expr_ops nft_jhash_ops = {
.type   = _hash_type,
-   .size   = NFT_EXPR_SIZE(sizeof(struct nft_hash)),
-   .eval   = nft_hash_eval,
-   .init   = nft_hash_init,
-   .dump   = nft_hash_dump,
+   .size   = NFT_EXPR_SIZE(sizeof(struct nft_jhash)),
+   .eval   = nft_jhash_eval,
+   .init   = nft_jhash_init,
+   .dump   = nft_jhash_dump,
 };
 
 static struct nft_expr_type nft_hash_type __read_mostly = {
.name   = "hash",
-   .ops= _hash_ops,
+   .ops= _jhash_ops,
.policy = nft_hash_policy,
.maxattr= NFTA_HASH_MAX,
.owner  = THIS_MODULE,
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nf-next] netfilter: nf_tables: validate maximum value of u32 netlink hash attribute

2016-11-14 Thread Laura Garcia Liebana
Use the function nft_parse_u32_check() to fetch the value and validate
the u32 attribute into the hash len u8 field.

This patch revisits 4da449ae1df9 ("netfilter: nft_exthdr: Add size check
on u8 nft_exthdr attributes").

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_hash.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 97ad8e30e4b4..eb2721af898d 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -53,6 +53,7 @@ static int nft_hash_init(const struct nft_ctx *ctx,
 {
struct nft_hash *priv = nft_expr_priv(expr);
u32 len;
+   int err;
 
if (!tb[NFTA_HASH_SREG] ||
!tb[NFTA_HASH_DREG] ||
@@ -66,8 +67,10 @@ static int nft_hash_init(const struct nft_ctx *ctx,
priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
 
-   len = ntohl(nla_get_be32(tb[NFTA_HASH_LEN]));
-   if (len == 0 || len > U8_MAX)
+   err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, );
+   if (err < 0)
+   return err;
+   if (len == 0)
return -ERANGE;
 
priv->len = len;
-- 
2.10.2

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 nft 2/4] src: add offset attribute for hash expression

2016-11-04 Thread Laura Garcia Liebana
Add support to add an offset to the hash generator, eg.

 ct mark set hash ip saddr mod 10 offset 100

This will generate marks with series between 100-109.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v3:
- This patch depends on 1/4.

 include/expression.h|  1 +
 include/hash.h  |  3 ++-
 include/linux/netfilter/nf_tables.h |  2 ++
 src/hash.c  |  9 +++--
 src/netlink_delinearize.c   |  5 +++--
 src/netlink_linearize.c |  1 +
 src/parser_bison.y  |  8 
 tests/py/ip/hash.t  |  2 ++
 tests/py/ip/hash.t.payload  | 14 ++
 9 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 3a52a45..71e9c43 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -307,6 +307,7 @@ struct expr {
struct expr *expr;
uint32_tmod;
uint32_tseed;
+   uint32_toffset;
} hash;
struct {
/* EXPR_FIB */
diff --git a/include/hash.h b/include/hash.h
index bc8c86a..8bf53e2 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -2,6 +2,7 @@
 #define NFTABLES_HASH_H
 
 extern struct expr *hash_expr_alloc(const struct location *loc,
-   uint32_t modulus, uint32_t seed);
+   uint32_t modulus, uint32_t seed,
+   uint32_t offset);
 
 #endif /* NFTABLES_HASH_H */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index c6567ac..0fb63fe 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -773,6 +773,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_LEN: source data length (NLA_U32)
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
+ * @NFTA_HASH_OFFSET: offset value (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -781,6 +782,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_OFFSET,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/hash.c b/src/hash.c
index 125b320..d26b2ed 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -22,13 +22,16 @@ static void hash_expr_print(const struct expr *expr)
printf(" mod %u", expr->hash.mod);
if (expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
+   if (expr->hash.offset)
+   printf(" offset %u", expr->hash.offset);
 }
 
 static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
return expr_cmp(e1->hash.expr, e2->hash.expr) &&
   e1->hash.mod == e2->hash.mod &&
-  e1->hash.seed == e2->hash.seed;
+  e1->hash.seed == e2->hash.seed &&
+  e1->hash.offset == e2->hash.offset;
 }
 
 static void hash_expr_clone(struct expr *new, const struct expr *expr)
@@ -36,6 +39,7 @@ static void hash_expr_clone(struct expr *new, const struct 
expr *expr)
new->hash.expr = expr_clone(expr->hash.expr);
new->hash.mod = expr->hash.mod;
new->hash.seed = expr->hash.seed;
+   new->hash.offset = expr->hash.offset;
 }
 
 static const struct expr_ops hash_expr_ops = {
@@ -47,7 +51,7 @@ static const struct expr_ops hash_expr_ops = {
 };
 
 struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod,
-uint32_t seed)
+uint32_t seed, uint32_t offset)
 {
struct expr *expr;
 
@@ -55,6 +59,7 @@ struct expr *hash_expr_alloc(const struct location *loc, 
uint32_t mod,
  BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE);
expr->hash.mod  = mod;
expr->hash.seed = seed;
+   expr->hash.offset = offset;
 
return expr;
 }
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index f0df884..434089b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -513,7 +513,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers sreg, dreg;
struct expr *expr, *hexpr;
-   uint32_t mod, seed, len;
+   uint32_t mod, seed, len, offset;
 
sreg = netlink_parse_register(nle, NFTNL_EXPR_HASH_SREG);
hexpr = netlink_get_register(ctx, loc, sreg);
@@ -521,6 +521,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
return netlink_error(ctx, loc,
 "hash statement has no expression");
 
+   offset = nftnl_expr_get_u32(nle, N

[PATCH v3 nft 1/4] src: make hash seed attribute optional

2016-11-04 Thread Laura Garcia Liebana
The hash expression requires a seed attribute to call the jhash
operation, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2 \
seed 0xdeadbeef

With this patch the seed attribute is optional and it's generated by a
random function from userspace, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2

The kernel will take care of generate a random seed.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v3:
- The random generation is done in kernel side.
- Tests included.

 src/parser_bison.y | 5 +
 tests/py/ip/hash.t | 1 +
 tests/py/ip/hash.t.payload | 7 +++
 3 files changed, 13 insertions(+)

diff --git a/src/parser_bison.y b/src/parser_bison.y
index 17f23c5..82fec99 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2585,6 +2585,11 @@ hash_expr:   JHASH   exprMOD 
NUM SEEDNUM
$$ = hash_expr_alloc(&@$, $4, $6);
$$->hash.expr = $2;
}
+   |   JHASH   exprMOD NUM
+   {
+   $$ = hash_expr_alloc(&@$, $4, 0);
+   $$->hash.expr = $2;
+   }
;
 
 rt_expr:   RT  rt_key
diff --git a/tests/py/ip/hash.t b/tests/py/ip/hash.t
index 6dfa965..306ebfd 100644
--- a/tests/py/ip/hash.t
+++ b/tests/py/ip/hash.t
@@ -2,4 +2,5 @@
 *ip;test-ip4;pre
 
 ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef;ok
+ct mark set jhash ip saddr . ip daddr mod 2;ok
 dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 
192.168.30.100 };ok
diff --git a/tests/py/ip/hash.t.payload b/tests/py/ip/hash.t.payload
index d9a22eb..1188a1b 100644
--- a/tests/py/ip/hash.t.payload
+++ b/tests/py/ip/hash.t.payload
@@ -5,6 +5,13 @@ ip test-ip4 pre
   [ hash reg 1 = jhash(reg 2, 8, 0xdeadbeef) % mod 2 ]
   [ ct set mark with reg 1 ]
 
+# ct mark set jhash ip saddr . ip daddr mod 2
+ip test-ip4 pre
+  [ payload load 4b @ network header + 12 => reg 2 ]
+  [ payload load 4b @ network header + 16 => reg 13 ]
+  [ hash reg 1 = jhash(reg 2, 8, 0x0) % mod 2 ]
+  [ ct set mark with reg 1 ]
+
 # dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 
192.168.30.100 }
 __map%d test-ip4 b
 __map%d test-ip4 0
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 nft 2/4] src: add offset attribute for hash expression

2016-11-01 Thread Laura Garcia Liebana
Add support to add an offset to the hash generator, eg.

 ct mark set hash ip saddr mod 10 offset 100

This will generate marks with series between 100-109.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Adapt the code to the repository changes.
- Include test payload.
- This patch depends on 1/4

 include/expression.h| 1 +
 include/hash.h  | 3 ++-
 include/linux/netfilter/nf_tables.h | 2 ++
 src/hash.c  | 9 +++--
 src/netlink_delinearize.c   | 5 +++--
 src/netlink_linearize.c | 1 +
 src/parser_bison.y  | 8 
 tests/py/ip/hash.t  | 1 +
 tests/py/ip/hash.t.payload  | 7 +++
 9 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 3a52a45..71e9c43 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -307,6 +307,7 @@ struct expr {
struct expr *expr;
uint32_tmod;
uint32_tseed;
+   uint32_toffset;
} hash;
struct {
/* EXPR_FIB */
diff --git a/include/hash.h b/include/hash.h
index 6d6badd..420a367 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -14,6 +14,7 @@
 #endif
 
 extern struct expr *hash_expr_alloc(const struct location *loc,
-   uint32_t modulus, uint32_t seed);
+   uint32_t modulus, uint32_t seed,
+   uint32_t offset);
 
 #endif /* NFTABLES_HASH_H */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index c6567ac..0fb63fe 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -773,6 +773,7 @@ enum nft_rt_keys {
  * @NFTA_HASH_LEN: source data length (NLA_U32)
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
+ * @NFTA_HASH_OFFSET: offset value (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -781,6 +782,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_OFFSET,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/hash.c b/src/hash.c
index 125b320..d26b2ed 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -22,13 +22,16 @@ static void hash_expr_print(const struct expr *expr)
printf(" mod %u", expr->hash.mod);
if (expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
+   if (expr->hash.offset)
+   printf(" offset %u", expr->hash.offset);
 }
 
 static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
return expr_cmp(e1->hash.expr, e2->hash.expr) &&
   e1->hash.mod == e2->hash.mod &&
-  e1->hash.seed == e2->hash.seed;
+  e1->hash.seed == e2->hash.seed &&
+  e1->hash.offset == e2->hash.offset;
 }
 
 static void hash_expr_clone(struct expr *new, const struct expr *expr)
@@ -36,6 +39,7 @@ static void hash_expr_clone(struct expr *new, const struct 
expr *expr)
new->hash.expr = expr_clone(expr->hash.expr);
new->hash.mod = expr->hash.mod;
new->hash.seed = expr->hash.seed;
+   new->hash.offset = expr->hash.offset;
 }
 
 static const struct expr_ops hash_expr_ops = {
@@ -47,7 +51,7 @@ static const struct expr_ops hash_expr_ops = {
 };
 
 struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod,
-uint32_t seed)
+uint32_t seed, uint32_t offset)
 {
struct expr *expr;
 
@@ -55,6 +59,7 @@ struct expr *hash_expr_alloc(const struct location *loc, 
uint32_t mod,
  BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE);
expr->hash.mod  = mod;
expr->hash.seed = seed;
+   expr->hash.offset = offset;
 
return expr;
 }
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index f0df884..434089b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -513,7 +513,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers sreg, dreg;
struct expr *expr, *hexpr;
-   uint32_t mod, seed, len;
+   uint32_t mod, seed, len, offset;
 
sreg = netlink_parse_register(nle, NFTNL_EXPR_HASH_SREG);
hexpr = netlink_get_register(ctx, loc, sreg);
@@ -521,6 +521,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
return netlink_error(ctx, loc,
 "hash statement has no expression&q

[PATCH v2 nft 1/4] src: make hash seed attribute optional

2016-11-01 Thread Laura Garcia Liebana
The hash expression requires a seed attribute to call the jhash
operation, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2 \
seed 0xdeadbeef

With this patch the seed attribute is optional and it's generated by a
random function from userspace, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2

In order to generate a resilient random number, the syscall
getrandom(2)[0] is used if detected. In other case, the trivial rand()
will be used.

[0] https://lwn.net/Articles/605828/

Suggested-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Use getrandom(2) syscall instead of arc4random, suggested by Pablo.
- This case hasn't a test case due to the random seed generation in
the payload won't match.

 configure.ac   | 22 +-
 include/hash.h | 12 
 src/parser_bison.y |  5 +
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7e0b75c..d21fe97 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,6 +108,24 @@ AC_DEFINE([HAVE_LIBXTABLES], [1], [0])
 AC_SUBST(with_libxtables)
 AM_CONDITIONAL([BUILD_XTABLES], [test "x$with_libxtables" == xyes])
 
+AC_COMPILE_IFELSE(
+[
+   AC_LANG_SOURCE([[
+   #include 
+   #include 
+   int main(){
+   int s;
+   syscall(SYS_getrandom, , sizeof(s), 0);
+   }
+   ]])
+], [have_random=yes
+   AC_DEFINE([HAVE_GETRANDOM], [1], [] )],
+   [have_random=no])
+
+AS_IF([test "x$have_random" != xno],
+[have_random=getrandom],
+[have_random=rand])
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_ASSERT
@@ -158,4 +176,5 @@ nft configuration:
   enable debugging:${with_debug}
   use mini-gmp:${with_mini_gmp}
   enable pdf documentation:${enable_pdf_doc}
-  libxtables support:  ${with_libxtables}"
+  libxtables support:  ${with_libxtables}
+  random used: ${have_random}"
diff --git a/include/hash.h b/include/hash.h
index bc8c86a..6d6badd 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -1,6 +1,18 @@
 #ifndef NFTABLES_HASH_H
 #define NFTABLES_HASH_H
 
+#ifdef HAVE_GETRANDOM
+#include 
+#include 
+#define selrandom()({ uint32_t s; \
+   syscall(SYS_getrandom, , sizeof(s), 0); s; })
+
+#else
+#include 
+#include 
+#define selrandom()({ srand(time(NULL)); (uint32_t)rand(); })
+#endif
+
 extern struct expr *hash_expr_alloc(const struct location *loc,
uint32_t modulus, uint32_t seed);
 
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 106df27..6a24bec 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2585,6 +2585,11 @@ hash_expr:   JHASH   exprMOD 
NUM SEEDNUM
$$ = hash_expr_alloc(&@$, $4, $6);
$$->hash.expr = $2;
}
+   |   JHASH   exprMOD NUM
+   {
+   $$ = hash_expr_alloc(&@$, $4, selrandom());
+   $$->hash.expr = $2;
+   }
;
 
 rt_expr:   RT  rt_key
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft 4/4] netlink: fix linearize numgen type

2016-10-22 Thread Laura Garcia Liebana
Avoid to treat numgen type attribute as a register.

Fixes: 345236211715 ("src: add hash expression")

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 src/netlink_linearize.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 15a8953..66552ac 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -181,7 +181,7 @@ static void netlink_gen_numgen(struct netlink_linearize_ctx 
*ctx,
 
nle = alloc_nft_expr("numgen");
netlink_put_register(nle, NFTNL_EXPR_NG_DREG, dreg);
-   netlink_put_register(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
+   nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod);
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset);
nftnl_rule_add_expr(ctx->nlr, nle);
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft 3/4] src: add offset attribute for numgen expression

2016-10-22 Thread Laura Garcia Liebana
Add support to add an offset to the numgen generated value.

Example:

 ct mark set numgen inc mod 2 offset 100

This will generate marks with serie like 100, 101, 100, ...

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/expression.h|  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 include/numgen.h|  3 ++-
 src/netlink_delinearize.c   |  5 +++--
 src/netlink_linearize.c |  1 +
 src/numgen.c| 10 --
 src/parser_bison.y  |  4 ++--
 tests/py/ip/numgen.t|  1 +
 8 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 38073ee..960c21e 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -291,6 +291,7 @@ struct expr {
/* EXPR_NUMGEN */
enum nft_ng_types   type;
uint32_tmod;
+   uint32_toffset;
} numgen;
struct {
/* EXPR_HASH */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 335102d..73cf897 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1159,12 +1159,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_OFFSET: offset value (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_OFFSET,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/include/numgen.h b/include/numgen.h
index bec18e5..b230620 100644
--- a/include/numgen.h
+++ b/include/numgen.h
@@ -2,6 +2,7 @@
 #define NFTABLES_NUMGEN_H
 
 extern struct expr *numgen_expr_alloc(const struct location *loc,
- enum nft_ng_types type, uint32_t until);
+ enum nft_ng_types type, uint32_t until,
+ uint32_t offset);
 
 #endif /* NFTABLES_NUMGEN_H */
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 7db109d..1f14456 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -591,13 +591,14 @@ static void netlink_parse_numgen(struct netlink_parse_ctx 
*ctx,
 const struct nftnl_expr *nle)
 {
enum nft_registers dreg;
-   uint32_t type, until;
+   uint32_t type, until, offset;
struct expr *expr;
 
type  = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE);
until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS);
+   offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_OFFSET);
 
-   expr = numgen_expr_alloc(loc, type, until);
+   expr = numgen_expr_alloc(loc, type, until, offset);
dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG);
netlink_set_register(ctx, dreg, expr);
 }
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 117ea8c..15a8953 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -183,6 +183,7 @@ static void netlink_gen_numgen(struct netlink_linearize_ctx 
*ctx,
netlink_put_register(nle, NFTNL_EXPR_NG_DREG, dreg);
netlink_put_register(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod);
+   nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset);
nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
diff --git a/src/numgen.c b/src/numgen.c
index d9a43aa..5c1d00a 100644
--- a/src/numgen.c
+++ b/src/numgen.c
@@ -32,18 +32,22 @@ static void numgen_expr_print(const struct expr *expr)
 {
printf("numgen %s mod %u", numgen_type_str(expr->numgen.type),
   expr->numgen.mod);
+   if (expr->numgen.offset)
+   printf(" offset %u", expr->numgen.offset);
 }
 
 static bool numgen_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
return e1->numgen.type == e2->numgen.type &&
-  e1->numgen.mod == e2->numgen.mod;
+  e1->numgen.mod == e2->numgen.mod &&
+  e1->numgen.offset == e2->numgen.offset;
 }
 
 static void numgen_expr_clone(struct expr *new, const struct expr *expr)
 {
new->numgen.type = expr->numgen.type;
new->numgen.mod = expr->numgen.mod;
+   new->numgen.offset = expr->numgen.offset;
 }
 
 static const struct expr_ops numgen_expr_ops = {
@@ -55,7 +59,8 @@ static const struct expr_ops numgen_expr_ops = {
 };
 
 struct expr *numgen_expr_alloc(const struct location *loc,
-  enum nft_ng_types type, uint32_t mod)
+  

[PATCH nft 2/4] src: add offset attribute for hash expression

2016-10-22 Thread Laura Garcia Liebana
Add support to add an offset to the hash generator.

Example:

 ct mark set hash ip saddr mod 10 offset 100

This will generate marks with series between 100-110.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/expression.h|  1 +
 include/hash.h  |  3 ++-
 include/linux/netfilter/nf_tables.h |  2 ++
 src/hash.c  |  9 +++--
 src/netlink_delinearize.c   |  5 +++--
 src/netlink_linearize.c |  1 +
 src/parser_bison.y  | 15 ++-
 src/scanner.l   |  1 +
 tests/py/ip/hash.t  |  2 ++
 9 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/include/expression.h b/include/expression.h
index 13ca315..38073ee 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -297,6 +297,7 @@ struct expr {
struct expr *expr;
uint32_tmod;
uint32_tseed;
+   uint32_toffset;
} hash;
};
 };
diff --git a/include/hash.h b/include/hash.h
index 5350cb2..7883277 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -12,6 +12,7 @@
 #endif
 
 extern struct expr *hash_expr_alloc(const struct location *loc,
-   uint32_t modulus, uint32_t seed);
+   uint32_t modulus, uint32_t seed,
+   uint32_t offset);
 
 #endif /* NFTABLES_HASH_H */
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index b21a844..335102d 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -760,6 +760,7 @@ enum nft_meta_keys {
  * @NFTA_HASH_LEN: source data length (NLA_U32)
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
+ * @NFTA_HASH_OFFSET: offset value (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -768,6 +769,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_OFFSET,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/hash.c b/src/hash.c
index 125b320..d26b2ed 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -22,13 +22,16 @@ static void hash_expr_print(const struct expr *expr)
printf(" mod %u", expr->hash.mod);
if (expr->hash.seed)
printf(" seed 0x%x", expr->hash.seed);
+   if (expr->hash.offset)
+   printf(" offset %u", expr->hash.offset);
 }
 
 static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
return expr_cmp(e1->hash.expr, e2->hash.expr) &&
   e1->hash.mod == e2->hash.mod &&
-  e1->hash.seed == e2->hash.seed;
+  e1->hash.seed == e2->hash.seed &&
+  e1->hash.offset == e2->hash.offset;
 }
 
 static void hash_expr_clone(struct expr *new, const struct expr *expr)
@@ -36,6 +39,7 @@ static void hash_expr_clone(struct expr *new, const struct 
expr *expr)
new->hash.expr = expr_clone(expr->hash.expr);
new->hash.mod = expr->hash.mod;
new->hash.seed = expr->hash.seed;
+   new->hash.offset = expr->hash.offset;
 }
 
 static const struct expr_ops hash_expr_ops = {
@@ -47,7 +51,7 @@ static const struct expr_ops hash_expr_ops = {
 };
 
 struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod,
-uint32_t seed)
+uint32_t seed, uint32_t offset)
 {
struct expr *expr;
 
@@ -55,6 +59,7 @@ struct expr *hash_expr_alloc(const struct location *loc, 
uint32_t mod,
  BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE);
expr->hash.mod  = mod;
expr->hash.seed = seed;
+   expr->hash.offset = offset;
 
return expr;
 }
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index d8d1d7d..7db109d 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -513,7 +513,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
 {
enum nft_registers sreg, dreg;
struct expr *expr, *hexpr;
-   uint32_t mod, seed, len;
+   uint32_t mod, seed, len, offset;
 
sreg = netlink_parse_register(nle, NFTNL_EXPR_HASH_SREG);
hexpr = netlink_get_register(ctx, loc, sreg);
@@ -521,6 +521,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx 
*ctx,
return netlink_error(ctx, loc,
 "hash statement has no expression");
 
+   offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_OFFSET);
seed = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_SEED);
mod  = nftnl_exp

[PATCH nft 0/4] src: changes related to numgen and hash expressions

2016-10-22 Thread Laura Garcia Liebana
This patchset provides several improvements for numgen and hash
expressions:

 - support of OFFSET attribute for numgen and hash expressions
 - makes SEED attribute optional and randomly generated
 - fix the TYPE attribute to be treated as a register

Laura Garcia Liebana (4):
  src: make hash seed attribute optional
  src: add offset attribute for hash expression
  src: add offset attribute for numgen expression
  netlink: fix linearize numgen type

 configure.ac| 14 +-
 include/expression.h|  2 ++
 include/hash.h  | 13 -
 include/linux/netfilter/nf_tables.h |  4 
 include/numgen.h|  3 ++-
 src/hash.c  |  9 +++--
 src/netlink_delinearize.c   | 10 ++
 src/netlink_linearize.c |  4 +++-
 src/numgen.c| 10 --
 src/parser_bison.y  | 20 +++-
 src/scanner.l   |  1 +
 tests/py/ip/hash.t  |  4 
 tests/py/ip/numgen.t|  1 +
 13 files changed, 78 insertions(+), 17 deletions(-)

-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH nft 1/4] src: make hash seed attribute optional

2016-10-22 Thread Laura Garcia Liebana
The hash expression requires a seed attribute to call the jhash
operation, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2 \
seed 0xdeadbeef

With this patch the seed attribute is optional and it's generated by a
random function from userspace, eg.

 # nft add rule x y meta mark set jhash ip saddr . ip daddr mod 2

To generate a secure random number it has been included the libbsd
library dependency by default, that implements the arc4random()
function generator. But it's possible to get rid of this dependency
applying the option --without-arc4random during the configure of the
package.

Suggested-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 configure.ac   | 14 +-
 include/hash.h | 10 ++
 src/parser_bison.y |  5 +
 tests/py/ip/hash.t |  2 ++
 4 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7e0b75c..8c93981 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,6 +108,17 @@ AC_DEFINE([HAVE_LIBXTABLES], [1], [0])
 AC_SUBST(with_libxtables)
 AM_CONDITIONAL([BUILD_XTABLES], [test "x$with_libxtables" == xyes])
 
+AC_ARG_WITH([arc4random], [AS_HELP_STRING([--without-arc4random],
+[disable arc4random (libbsd dev support)])],
+[], [with_arc4random=yes])
+AS_IF([test "x$with_arc4random" != xno], [
+AC_CHECK_LIB([bsd], [arc4random], ,
+AC_MSG_ERROR([No suitable version of libbsd dev found]))
+AC_DEFINE([HAVE_LIBBSD], [1], [])
+])
+AC_SUBST(with_arc4random)
+AM_CONDITIONAL([BUILD_ARC4RANDOM], [test "x$with_arc4random" != xno])
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_ASSERT
@@ -158,4 +169,5 @@ nft configuration:
   enable debugging:${with_debug}
   use mini-gmp:${with_mini_gmp}
   enable pdf documentation:${enable_pdf_doc}
-  libxtables support:  ${with_libxtables}"
+  libxtables support:  ${with_libxtables}
+  arc4random support:  ${with_arc4random}"
diff --git a/include/hash.h b/include/hash.h
index bc8c86a..5350cb2 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -1,6 +1,16 @@
 #ifndef NFTABLES_HASH_H
 #define NFTABLES_HASH_H
 
+#ifdef HAVE_LIBBSD
+#include 
+#define getrandom()(arc4random() % ((uint32_t)RAND_MAX + 1))
+
+#else
+#include 
+#include 
+#define getrandom()({ srand(time(NULL)); (uint32_t)rand(); })
+#endif
+
 extern struct expr *hash_expr_alloc(const struct location *loc,
uint32_t modulus, uint32_t seed);
 
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 36dbc8d..0fa469d 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2485,6 +2485,11 @@ hash_expr:   JHASH   exprMOD 
NUM SEEDNUM
$$ = hash_expr_alloc(&@$, $4, $6);
$$->hash.expr = $2;
}
+   |   JHASH   exprMOD NUM
+   {
+   $$ = hash_expr_alloc(&@$, $4, getrandom());
+   $$->hash.expr = $2;
+   }
;
 
 ct_expr:   CT  ct_key
diff --git a/tests/py/ip/hash.t b/tests/py/ip/hash.t
index 6dfa965..85f9b18 100644
--- a/tests/py/ip/hash.t
+++ b/tests/py/ip/hash.t
@@ -2,4 +2,6 @@
 *ip;test-ip4;pre
 
 ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef;ok
+ct mark set jhash ip saddr . ip daddr mod 2;ok
 dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 
192.168.30.100 };ok
+dnat to jhash ip saddr mod 2 map { 0 : 192.168.20.100, 1 : 192.168.30.100 };ok
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nf] netfilter: nf_tables: Ensure u8 attributes are loaded from u32 within the bounds

2016-09-22 Thread Laura Garcia
On Thu, Sep 22, 2016 at 09:16:07AM -0700, Eric Dumazet wrote:
> On Thu, 2016-09-22 at 16:58 +0200, Pablo Neira Ayuso wrote:
> > attributes")
> > 
> > Always use 12 bytes commit-ids. 4da449a is too short, given the number
> > of changes we're getting in the kernel tree, this may become ambiguous
> > at some point so it won't be unique.
> > 
> > You can achieve this via: git log --oneline --abbrev=12
> 
> and Documentation/SubmittingPatches has these tips :
> 
> 
> You should also be sure to use at least the first twelve characters of the
> SHA-1 ID.  The kernel repository holds a *lot* of objects, making
> collisions with shorter IDs a real possibility.  Bear in mind that, even if
> there is no collision with your six-character ID now, that condition may
> change five years from now.
> 
> If your patch fixes a bug in a specific commit, e.g. you found an issue using
> git-bisect, please use the 'Fixes:' tag with the first 12 characters of the
> SHA-1 ID, and the one line summary.  For example:
> 
> Fixes: e21d2170f366 ("video: remove unnecessary 
> platform_set_drvdata()")
> 
> The following git-config settings can be used to add a pretty format for
> outputting the above style in the git log or git show commands
> 
> [core]
> abbrev = 12
> [pretty]
> fixes = Fixes: %h (\"%s\")
> 
> 

Duly noted, thanks.

In this case, it was not referred to a fix but an extension of the
older patch to other files with the same problem.


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nf] netfilter: nf_tables: Ensure u8 attributes are loaded from u32 within the bounds

2016-09-22 Thread Laura Garcia
On Thu, Sep 22, 2016 at 04:58:36PM +0200, Pablo Neira Ayuso wrote:
> On Wed, Sep 14, 2016 at 03:00:02PM +0200, Laura Garcia Liebana wrote:
> > Check storage of u32 netlink attributes in smaller resources. This
> > validation is usually required when the u32 netlink attributes are being
> > stored in a private structure size of u8 in the kernel.
> 
> Applied with changes, no need to resend. If I break anything, just
> follow up on top.
> 
> I have rewritten this description and the documentation on the code a bit.
> 
> More changes:
> 
> > 4da449a ("netfilter: nft_exthdr: Add size check on u8 nft_exthdr
> > attributes")
> 
> Always use 12 bytes commit-ids. 4da449a is too short, given the number
> of changes we're getting in the kernel tree, this may become ambiguous
> at some point so it won't be unique.
> 
> You can achieve this via: git log --oneline --abbrev=12
> 
> More comments below.
> 
> > Suggested-by: Pablo Neira Ayuso <pa...@netfilter.org>
> > Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
> > ---
> >  include/net/netfilter/nf_tables.h |  2 ++
> >  net/netfilter/nf_tables_api.c | 26 ++
> >  net/netfilter/nft_bitwise.c   | 10 +-
> >  net/netfilter/nft_byteorder.c | 17 +++--
> >  net/netfilter/nft_cmp.c   |  6 +-
> >  net/netfilter/nft_exthdr.c| 19 ---
> >  net/netfilter/nft_immediate.c |  4 
> >  7 files changed, 73 insertions(+), 11 deletions(-)
> > 
> > diff --git a/include/net/netfilter/nf_tables.h 
> > b/include/net/netfilter/nf_tables.h
> > index f2f1339..608130f 100644
> > --- a/include/net/netfilter/nf_tables.h
> > +++ b/include/net/netfilter/nf_tables.h
> > @@ -127,6 +127,8 @@ static inline enum nft_registers nft_type_to_reg(enum 
> > nft_data_types type)
> > return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * 
> > NFT_REG_SIZE / NFT_REG32_SIZE;
> >  }
> >  
> > +unsigned int nft_parse_u32_check(const struct nlattr *attr, int maxlen,
> > +u32 *dest);
> 
> I have renamed maxlen to max, so this fits in one line.
> 
> >  unsigned int nft_parse_register(const struct nlattr *attr);
> >  int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int 
> > reg);
> >  
> > diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> > index 7e1c876..d7b000f 100644
> > --- a/net/netfilter/nf_tables_api.c
> > +++ b/net/netfilter/nf_tables_api.c
> > @@ -4343,6 +4343,32 @@ static int nf_tables_check_loops(const struct 
> > nft_ctx *ctx,
> >  }
> >  
> >  /**
> > + * nft_parse_u32_check - parse a u32 value to store the value into a
> > + *   smaller resource.
> > + *
> > + * @attr: netlink attribute
> > + * @maxlen: maximum value to be stored in dest
> > + * @dest: pointer to the resource
> > + *
> > + * Parse and store a given u32 value into a resource. Returns an error
> > + * ERANGE if the value will overload the maxlen, otherwise a 0 will be
> > + * returned and the value is stored into dest.
> 
> I've rewritten this a bit.
> 
> > + */
> > +unsigned int nft_parse_u32_check(const struct nlattr *attr, int maxlen,
> 
> I have rename maxlen to max. Probably maxval would have been better,
> anyway.
> 
> > +u32 *dest)
> > +{
> > +   int reg;
> 
> Variable names are important, they provide context when reading the
> code. Look, from the 'reg' name it seems we're fetching a register.
> However, we are obtaining a value, so I renamed this to val. Try to
> select the right name next time.
> 
> > +
> > +   reg = ntohl(nla_get_be32(attr));
> > +   if (reg > maxlen)
> > +   return -ERANGE;
> > +
> > +   *dest = reg;
> > +   return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(nft_parse_u32_check);
> > +
> > +/**
> >   * nft_parse_register - parse a register value from a netlink attribute
> >   *
> >   * @attr: netlink attribute
> > diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
> > index d71cc18..e7f23a1 100644
> > --- a/net/netfilter/nft_bitwise.c
> > +++ b/net/netfilter/nft_bitwise.c
> > @@ -14,6 +14,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  
> > @@ -52,6 +53,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
> >  {
> > struct nft_bitwise *priv = nft_exp

[PATCH v3 libnftnl] expr: numgen: add number generation offset

2016-09-13 Thread Laura Garcia Liebana
Add support to pass through an offset value to the counter
initialization. With this feature, the sysadmin is able to apply a value
to be added to the generated number.

Example:

meta mark set numgen inc mod 2 offset 100

This will generate marks with series 100, 101, 100, 101, ...

Suggested-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Separate offset changes with _until_ attribute renaming, as
Pablo suggested.

Changes in v3:
- Use OFFSET attribute instead of SUM.
- Add offset support for random counter.

 include/libnftnl/expr.h |  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 src/expr/numgen.c   | 39 +++--
 tests/nft-expr_numgen-test.c|  4 
 4 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 8b35203..a8206ba 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -54,6 +54,7 @@ enum {
NFTNL_EXPR_NG_DREG  = NFTNL_EXPR_BASE,
NFTNL_EXPR_NG_MODULUS,
NFTNL_EXPR_NG_TYPE,
+   NFTNL_EXPR_NG_OFFSET,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index e608054..038895b 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1130,12 +1130,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum value to be returned (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_OFFSET,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index a23be53..8b667c2 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -24,6 +24,7 @@ struct nftnl_expr_ng {
enum nft_registers  dreg;
unsigned intmodulus;
enum nft_ng_types   type;
+   unsigned intoffset;
 };
 
 static int
@@ -42,6 +43,9 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_TYPE:
ng->type = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_NG_OFFSET:
+   ng->offset = *((uint32_t *)data);
+   break;
default:
return -1;
}
@@ -64,6 +68,9 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_TYPE:
*data_len = sizeof(ng->type);
return >type;
+   case NFTNL_EXPR_NG_OFFSET:
+   *data_len = sizeof(ng->offset);
+   return >offset;
}
return NULL;
 }
@@ -80,6 +87,7 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void 
*data)
case NFTA_NG_DREG:
case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
+   case NFTA_NG_OFFSET:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -100,6 +108,8 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_NG_MODULUS, htonl(ng->modulus));
if (e->flags & (1 << NFTNL_EXPR_NG_TYPE))
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
+   if (e->flags & (1 << NFTNL_EXPR_NG_OFFSET))
+   mnl_attr_put_u32(nlh, NFTA_NG_OFFSET, htonl(ng->offset));
 }
 
 static int
@@ -124,6 +134,10 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr 
*attr)
ng->type = ntohl(mnl_attr_get_u32(tb[NFTA_NG_TYPE]));
e->flags |= (1 << NFTNL_EXPR_NG_TYPE);
}
+   if (tb[NFTA_NG_OFFSET]) {
+   ng->offset = ntohl(mnl_attr_get_u32(tb[NFTA_NG_OFFSET]));
+   e->flags |= (1 << NFTNL_EXPR_NG_OFFSET);
+   }
 
return ret;
 }
@@ -132,7 +146,7 @@ static int nftnl_expr_ng_json_parse(struct nftnl_expr *e, 
json_t *root,
struct nftnl_parse_err *err)
 {
 #ifdef JSON_PARSING
-   uint32_t dreg, modulus, type;
+   uint32_t dreg, modulus, type, offset;
 
if (nftnl_jansson_parse_reg(root, "dreg", NFTNL_TYPE_U32,
, err) == 0)
@@ -146,6 +160,10 @@ static int nftnl_expr_ng_json_parse(struct nftnl_expr *e, 
json_t *root,
, err) == 0)
nftnl_expr_set_u32(e, NFTNL_EXPR_NG_TYPE, type);
 
+   if (nftnl_jansson_parse_val(root, "offset", NFTNL_TYPE_U32,
+   , err) == 0)
+   nftnl_expr_set_u32(e, NFTNL_EXPR_NG_OFFSET, offset

[PATCH v3] netfilter: nft_numgen: add number generation offset

2016-09-13 Thread Laura Garcia Liebana
Add support of an offset value for incremental counter and random. With
this option the sysadmin is able to start the counter to a certain value
and then apply the generated number.

Example:

meta mark set numgen inc mod 2 offset 100

This will generate marks with the serie 100, 101, 100, 101, ...

Suggested-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Separate offset changes with _until_ attribute renaming, as
Pablo suggested.

Changes in v3:
- Rename SUM by OFFSET, as Pablo suggested.
- Include correct behavior for the offset feature, as Pablo
suggested.
- Include offset feature to the random operation.
- Include u32 overflow validation.

 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_numgen.c   | 30 +-
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index bc0eb6a..bcfb892 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1136,12 +1136,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_OFFSET,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index f173ebe..b39f909 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -23,6 +23,7 @@ struct nft_ng_inc {
enum nft_registers  dreg:8;
u32 modulus;
atomic_tcounter;
+   u32 offset;
 };
 
 static void nft_ng_inc_eval(const struct nft_expr *expr,
@@ -37,13 +38,14 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
nval = (oval + 1 < priv->modulus) ? oval + 1 : 0;
} while (atomic_cmpxchg(>counter, oval, nval) != oval);
 
-   regs->data[priv->dreg] = nval;
+   regs->data[priv->dreg] = nval + priv->offset;
 }
 
 static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
[NFTA_NG_DREG]  = { .type = NLA_U32 },
[NFTA_NG_MODULUS]   = { .type = NLA_U32 },
[NFTA_NG_TYPE]  = { .type = NLA_U32 },
+   [NFTA_NG_OFFSET]= { .type = NLA_U32 },
 };
 
 static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -52,10 +54,16 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
 {
struct nft_ng_inc *priv = nft_expr_priv(expr);
 
+   if (tb[NFTA_NG_OFFSET])
+   priv->offset = ntohl(nla_get_be32(tb[NFTA_NG_OFFSET]));
+
priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
if (priv->modulus == 0)
return -ERANGE;
 
+   if (priv->offset + priv->modulus - 1 < priv->offset)
+   return -EOVERFLOW;
+
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
atomic_set(>counter, 0);
 
@@ -64,7 +72,7 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
 }
 
 static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
-  u32 modulus, enum nft_ng_types type)
+  u32 modulus, enum nft_ng_types type, u32 offset)
 {
if (nft_dump_register(skb, NFTA_NG_DREG, dreg))
goto nla_put_failure;
@@ -72,6 +80,8 @@ static int nft_ng_dump(struct sk_buff *skb, enum 
nft_registers dreg,
goto nla_put_failure;
if (nla_put_be32(skb, NFTA_NG_TYPE, htonl(type)))
goto nla_put_failure;
+   if (nla_put_be32(skb, NFTA_NG_OFFSET, htonl(offset)))
+   goto nla_put_failure;
 
return 0;
 
@@ -83,12 +93,14 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const 
struct nft_expr *expr)
 {
const struct nft_ng_inc *priv = nft_expr_priv(expr);
 
-   return nft_ng_dump(skb, priv->dreg, priv->modulus, NFT_NG_INCREMENTAL);
+   return nft_ng_dump(skb, priv->dreg, priv->modulus, NFT_NG_INCREMENTAL,
+  priv->offset);
 }
 
 struct nft_ng_random {
enum nft_registers  dreg:8;
u32 modulus;
+   u32 offset;
 };
 
 static void nft_ng_random_eval(const struct nft_expr *expr,
@@ -99,7 +111,8 @@ static void nft_ng_random_eval(const struct nft_expr *expr,
struct rnd_state *state = this_cpu_ptr(_numgen_prandom_state);
 
regs->data[priv->dreg] = reciprocal_scale(prandom_u32_state(state),
-

[PATCH] netfilter: nft_hash: fix hash overflow validation

2016-09-13 Thread Laura Garcia Liebana
The overflow validation in the init() function establishes that the
maximum value that the hash could reach is less than U32_MAX, which is
likely to be true.

The fix detects the overflow when the maximum hash value is less than
the offset itself.

Fixes: 70ca767ea1b2 ("netfilter: nft_hash: Add hash offset value")

Reported-by: Liping Zhang <liping.zh...@spreadtrum.com>
Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_hash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index bd12f7a..09473b4 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -76,7 +76,7 @@ static int nft_hash_init(const struct nft_ctx *ctx,
if (priv->modulus <= 1)
return -ERANGE;
 
-   if (priv->offset + priv->modulus - 1 < U32_MAX)
+   if (priv->offset + priv->modulus - 1 < priv->offset)
return -EOVERFLOW;
 
priv->seed = ntohl(nla_get_be32(tb[NFTA_HASH_SEED]));
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] netfilter: nft_hash: Add hash offset value

2016-09-13 Thread Laura Garcia
On Tue, Sep 13, 2016 at 02:25:03PM +0800, Liping Zhang wrote:
> Hi Laura,
> 
> 2016-09-06 14:44 GMT+08:00 Laura Garcia Liebana <nev...@gmail.com>:
> >  static int nft_hash_init(const struct nft_ctx *ctx,
> > @@ -60,6 +62,11 @@ static int nft_hash_init(const struct nft_ctx *ctx,
> > !tb[NFTA_HASH_MODULUS])
> > return -EINVAL;
> >
> > +   if (tb[NFTA_HASH_SUM])
> > +   priv->sum = ntohl(nla_get_be32(tb[NFTA_HASH_SUM]));
> > +   else
> > +   priv->sum = 0;
> > +
> > priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
> > if (priv->sreg < 0)
> > return -ERANGE;
> > @@ -77,6 +84,9 @@ static int nft_hash_init(const struct nft_ctx *ctx,
> > if (priv->modulus <= 1)
> > return -ERANGE;
> >
> > +   if (priv->sum + priv->modulus - 1 < U32_MAX)
> > +   return -EOVERFLOW;
> 
> I think this judgement here is wrong, it is likely to be true...
> 
> When two integer a and b do addition operation, and the calculation
> results satisfy the
> following conditions: (a + b < a) or (a + b < b), then we can assure
> that integer overflow
> happened.
> 
> So the judgement should be converted to:
>  if (priv->sum + priv->modulus - 1 < priv->sum)
> 

Absolutely true, i'll send a patch to fix that.

Thank you!

> > +
> > priv->seed = ntohl(nla_get_be32(tb[NFTA_HASH_SEED]));
> >
> > return nft_validate_register_load(priv->sreg, priv->len) &&
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] netfilter: nft_numgen: add increment counter offset value

2016-09-12 Thread Laura Garcia
On Mon, Sep 12, 2016 at 06:45:58PM +0200, Pablo Neira Ayuso wrote:
> On Wed, Sep 07, 2016 at 07:56:49PM +0200, Laura Garcia Liebana wrote:
> > Add support for an initialization counter value. With this option the
> > sysadmin is able to start the counter when used with the increment type.
> > 
> > Example:
> > 
> > meta mark set numgen inc mod 2 sum 100
> > 
> > This will generate marks with the serie 100, 101, 100, 101, ...
> > 
> > Only supported for increment number generation.
> > 
> > Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
> > ---
> > Changes in v2:
> > - Separate _SUM_ changes with _until_ attribute renaming.
> > 
> >  include/uapi/linux/netfilter/nf_tables.h | 2 ++
> >  net/netfilter/nft_numgen.c   | 9 +++--
> >  2 files changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/uapi/linux/netfilter/nf_tables.h 
> > b/include/uapi/linux/netfilter/nf_tables.h
> > index 24161e2..00a689d 100644
> > --- a/include/uapi/linux/netfilter/nf_tables.h
> > +++ b/include/uapi/linux/netfilter/nf_tables.h
> > @@ -1128,12 +1128,14 @@ enum nft_trace_types {
> >   * @NFTA_NG_DREG: destination register (NLA_U32)
> >   * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
> >   * @NFTA_NG_TYPE: operation type (NLA_U32)
> > + * @NFTA_NG_SUM: Offset to initiate the counter (NLA_U32)
> >   */
> >  enum nft_ng_attributes {
> > NFTA_NG_UNSPEC,
> > NFTA_NG_DREG,
> > NFTA_NG_MODULUS,
> > NFTA_NG_TYPE,
> > +   NFTA_NG_SUM,
> > __NFTA_NG_MAX
> >  };
> >  #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
> > diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
> > index f51a3ed..a5ea3f7 100644
> > --- a/net/netfilter/nft_numgen.c
> > +++ b/net/netfilter/nft_numgen.c
> > @@ -44,6 +44,7 @@ static const struct nla_policy nft_ng_policy[NFTA_NG_MAX 
> > + 1] = {
> > [NFTA_NG_DREG]  = { .type = NLA_U32 },
> > [NFTA_NG_MODULUS]   = { .type = NLA_U32 },
> > [NFTA_NG_TYPE]  = { .type = NLA_U32 },
> > +   [NFTA_NG_SUM]   = { .type = NLA_U32 },
> >  };
> >  
> >  static int nft_ng_inc_init(const struct nft_ctx *ctx,
> > @@ -51,13 +52,17 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
> >const struct nlattr * const tb[])
> >  {
> > struct nft_ng_inc *priv = nft_expr_priv(expr);
> > +   u32 sum = 0;
> > +
> > +   if (tb[NFTA_NG_SUM])
> > +   sum = ntohl(nla_get_be32(tb[NFTA_NG_SUM]));
> >  
> > priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
> > -   if (priv->modulus == 0)
> > +   if (priv->modulus == 0 || sum >= priv->modulus)
> > return -ERANGE;
> >  
> > priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
> > -   atomic_set(>counter, 0);
> > +   atomic_set(>counter, sum);
> 
> Are you sure this will work?
> 
> nval = (oval + 1 < priv->modulus) ? oval + 1 : 0;
> 
> This is just setting priv->counter to an initial value, then it will
> become zero at some point.
> 

I considered that the offset in the case of 'numgen inc' will be only
applied to initialize the counter to a certain value. Do you mean to
add the offset in every generated value?

Should the random counter behave in the same way?

> I'm going to take Liping's patch that converts:
> 
> memcpy(>data[priv->dreg], >counter, sizeof(u32));
> 
> to:
> 
> reg->data[priv->dreg] = nval;
> 
> so you can change this to:
> 
> reg->data[priv->dreg] = nval + priv->offset;
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] netfilter: nft_hash: Add hash offset value

2016-09-12 Thread Laura Garcia
On Mon, Sep 12, 2016 at 06:34:59PM +0200, Pablo Neira Ayuso wrote:
> Hi Laura,
> 
> On Tue, Sep 06, 2016 at 08:44:19AM +0200, Laura Garcia Liebana wrote:
> > Add support to pass through an offset to the hash value. With this
> > feature, the sysadmin is able to generate a hash with a given
> > offset value.
> 
> We've been using 'offset' to refer to this for a while, to I'm
> renaming this to NFTA_HASH_OFFSET.
> 

Ok, I'll send a new patch to change this for libnftnl.

Thank you!

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nf-next] netfilter: nft_queue: add _SREG_FROM and _SRGE_TO to select the queue numbers

2016-09-12 Thread Laura Garcia
On Sun, Sep 11, 2016 at 11:12:26PM +0200, Florian Westphal wrote:
> Liping Zhang  wrote:
> > From: Liping Zhang 
> > 
> > Currently, the user can specify the queue numbers by _QUEUE_NUM and
> > _QUEUE_TOTAL attributes, this is enough in most situations.
> > 
> > But acctually, it is not very flexible, for example:
> >   tcp dport 80 mapped to queue0
> >   tcp dport 81 mapped to queue1
> >   tcp dport 82 mapped to queue2
> > In order to do this thing, we must add 3 nft rules, and more
> > mapping means more rules ...
> > 
> > So similer to nft_nat, take two registers to select the queue numbers,
> > then we can add one simple rule to mapping queues, maybe like this:
> >   queue num tcp dport map { 80:0, 81:1, 82:2 ... }
> 
> I like this.
> 
> My first thought was that it would be better to just support one single
> sreg (the queue number) and eventually externalize the hashing/queue
> selection:
> 
> queue num jhash ip saddr . ip daddr mod ...
> 
> Problem is that with plain jhash we won't get a symmetric hash
> for origin and reply, so for this we would need a new expression/hash
> mode.
> 
> We would also need another expression to allow distribution
> starting with a queue other than 0.

For such feature, I've already sent a patch "netfilter: nft_hash: Add
hash offset value" in order to set an initial value for the hash
expression. I think it'll be available in the tree soon.

> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH nft] src: fix compile error due to _UNTIL renamed to _MODULUS in libnftnl

2016-09-12 Thread Laura Garcia
On Sun, Sep 11, 2016 at 04:35:57PM +0800, Liping Zhang wrote:
> From: Liping Zhang 
> 
> In the latest libnftnl, NFTNL_EXPR_NG_UNTIL was renamed to
> NFTNL_EXPR_NG_MODULUS, so compile error happened:
>   netlink_linearize.c: In function ‘netlink_gen_numgen’:
>   netlink_linearize.c:184:26: error: ‘NFTNL_EXPR_NG_UNTIL’ undeclared
>   (first use in this function)
> 

In order to complete the renaming, NFTA_NG_UNTIL should be changed to
NFTA_NG_MODULUS as well.

> Signed-off-by: Liping Zhang 
> ---
>  src/netlink_delinearize.c | 2 +-
>  src/netlink_linearize.c   | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
> index 05edb01..6bb27b6 100644
> --- a/src/netlink_delinearize.c
> +++ b/src/netlink_delinearize.c
> @@ -554,7 +554,7 @@ static void netlink_parse_numgen(struct netlink_parse_ctx 
> *ctx,
>   struct expr *expr;
>  
>   type  = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE);
> - until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_UNTIL);
> + until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS);
>  
>   expr = numgen_expr_alloc(loc, type, until);
>   dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG);
> diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
> index 5204154..558deb2 100644
> --- a/src/netlink_linearize.c
> +++ b/src/netlink_linearize.c
> @@ -181,7 +181,7 @@ static void netlink_gen_numgen(struct 
> netlink_linearize_ctx *ctx,
>   nle = alloc_nft_expr("numgen");
>   netlink_put_register(nle, NFTNL_EXPR_NG_DREG, dreg);
>   netlink_put_register(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
> - nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_UNTIL, expr->numgen.mod);
> + nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod);
>   nftnl_rule_add_expr(ctx->nlr, nle);
>  }
>  
> -- 
> 2.5.5
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 libnftnl] expr: numgen: add increment counter offset value

2016-09-07 Thread Laura Garcia Liebana
Add support to pass through an offset value to the counter
initialization. With this feature, the sysadmin is able to send an
started value for the counter.

Example:

meta mark set numgen inc mod 2 sum 100

This will generate marks with series 100, 101, 100, 101, ...

Only supported for increment number generation.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Separate _SUM_ changes with _until_ attribute renaming.

include/buffer.h|  1 +
 include/libnftnl/expr.h |  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 src/expr/numgen.c   | 35 +++
 tests/nft-expr_numgen-test.c|  4 
 5 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/include/buffer.h b/include/buffer.h
index a753c78..448cccf 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -78,6 +78,7 @@ int nftnl_buf_reg(struct nftnl_buf *b, int type, union 
nftnl_data_reg *reg,
 #define SREG_KEY   "sreg_key"
 #define SREG_DATA  "sreg_data"
 #define SREG   "sreg"
+#define SUM"sum"
 #define TABLE  "table"
 #define TOTAL  "total"
 #define TYPE   "type"
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 94ce529..3cf0db1 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -54,6 +54,7 @@ enum {
NFTNL_EXPR_NG_DREG  = NFTNL_EXPR_BASE,
NFTNL_EXPR_NG_MODULUS,
NFTNL_EXPR_NG_TYPE,
+   NFTNL_EXPR_NG_SUM,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index dd8b746..ee3a4c9 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1128,12 +1128,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum value to be returned (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_SUM: offset to be added to the counter (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_SUM,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index a23be53..7e1324a 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -24,6 +24,7 @@ struct nftnl_expr_ng {
enum nft_registers  dreg;
unsigned intmodulus;
enum nft_ng_types   type;
+   unsigned intsum;
 };
 
 static int
@@ -42,6 +43,9 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_TYPE:
ng->type = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_NG_SUM:
+   ng->sum = *((uint32_t *)data);
+   break;
default:
return -1;
}
@@ -64,6 +68,9 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_TYPE:
*data_len = sizeof(ng->type);
return >type;
+   case NFTNL_EXPR_NG_SUM:
+   *data_len = sizeof(ng->sum);
+   return >sum;
}
return NULL;
 }
@@ -80,6 +87,7 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void 
*data)
case NFTA_NG_DREG:
case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
+   case NFTA_NG_SUM:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -100,6 +108,8 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_NG_MODULUS, htonl(ng->modulus));
if (e->flags & (1 << NFTNL_EXPR_NG_TYPE))
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
+   if (e->flags & (1 << NFTNL_EXPR_NG_SUM))
+   mnl_attr_put_u32(nlh, NFTA_NG_SUM, htonl(ng->sum));
 }
 
 static int
@@ -124,6 +134,10 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr 
*attr)
ng->type = ntohl(mnl_attr_get_u32(tb[NFTA_NG_TYPE]));
e->flags |= (1 << NFTNL_EXPR_NG_TYPE);
}
+   if (tb[NFTA_NG_SUM]) {
+   ng->sum = ntohl(mnl_attr_get_u32(tb[NFTA_NG_SUM]));
+   e->flags |= (1 << NFTNL_EXPR_NG_SUM);
+   }
 
return ret;
 }
@@ -132,7 +146,7 @@ static int nftnl_expr_ng_json_parse(struct nftnl_expr *e, 
json_t *root,
struct nftnl_parse_err *err)
 {
 #ifdef JSON_PARSING
-   uint32_t dreg, modulus, type;
+   uint32_t dreg, modulus, type, sum;
 
if (nftnl_jansson_parse_reg(root, "dreg", NFTNL_TYPE_U32,

[PATCH v2] netfilter: nft_numgen: add increment counter offset value

2016-09-07 Thread Laura Garcia Liebana
Add support for an initialization counter value. With this option the
sysadmin is able to start the counter when used with the increment type.

Example:

meta mark set numgen inc mod 2 sum 100

This will generate marks with the serie 100, 101, 100, 101, ...

Only supported for increment number generation.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Separate _SUM_ changes with _until_ attribute renaming.

 include/uapi/linux/netfilter/nf_tables.h | 2 ++
 net/netfilter/nft_numgen.c   | 9 +++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 24161e2..00a689d 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1128,12 +1128,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_SUM: Offset to initiate the counter (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_SUM,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index f51a3ed..a5ea3f7 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -44,6 +44,7 @@ static const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] 
= {
[NFTA_NG_DREG]  = { .type = NLA_U32 },
[NFTA_NG_MODULUS]   = { .type = NLA_U32 },
[NFTA_NG_TYPE]  = { .type = NLA_U32 },
+   [NFTA_NG_SUM]   = { .type = NLA_U32 },
 };
 
 static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -51,13 +52,17 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
   const struct nlattr * const tb[])
 {
struct nft_ng_inc *priv = nft_expr_priv(expr);
+   u32 sum = 0;
+
+   if (tb[NFTA_NG_SUM])
+   sum = ntohl(nla_get_be32(tb[NFTA_NG_SUM]));
 
priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
-   if (priv->modulus == 0)
+   if (priv->modulus == 0 || sum >= priv->modulus)
return -ERANGE;
 
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
-   atomic_set(>counter, 0);
+   atomic_set(>counter, sum);
 
return nft_validate_register_store(ctx, priv->dreg, NULL,
   NFT_DATA_VALUE, sizeof(u32));
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 libnftnl] expr: numgen: Rename until attribute by modulus

2016-09-07 Thread Laura Garcia Liebana
The _modulus_ attribute will be reused as _until_, as it's similar to
other expressions with value limits (ex. hash).

Renaming is possible according to the kernel module ntf_numgen that has
not been released yet.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Separate changes with incremental counter offset value.
Changes in v3:
- Update repo before submitting the patch.

 include/buffer.h|  1 -
 include/libnftnl/expr.h |  2 +-
 include/linux/netfilter/nf_tables.h |  4 +--
 src/expr/numgen.c   | 52 ++---
 tests/nft-expr_numgen-test.c|  8 +++---
 5 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/include/buffer.h b/include/buffer.h
index 8cfe377..a753c78 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -82,7 +82,6 @@ int nftnl_buf_reg(struct nftnl_buf *b, int type, union 
nftnl_data_reg *reg,
 #define TOTAL  "total"
 #define TYPE   "type"
 #define UNIT   "unit"
-#define UNTIL  "until"
 #define USE"use"
 #define XOR"xor"
 #define ADD"add"
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 8815154..94ce529 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -52,7 +52,7 @@ enum {
 
 enum {
NFTNL_EXPR_NG_DREG  = NFTNL_EXPR_BASE,
-   NFTNL_EXPR_NG_UNTIL,
+   NFTNL_EXPR_NG_MODULUS,
NFTNL_EXPR_NG_TYPE,
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 8a63f22..dd8b746 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1126,13 +1126,13 @@ enum nft_trace_types {
  * enum nft_ng_attributes - nf_tables number generator expression netlink 
attributes
  *
  * @NFTA_NG_DREG: destination register (NLA_U32)
- * @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
+ * @NFTA_NG_MODULUS: maximum value to be returned (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
-   NFTA_NG_UNTIL,
+   NFTA_NG_MODULUS,
NFTA_NG_TYPE,
__NFTA_NG_MAX
 };
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index 7f2b425..dad41c2 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -22,7 +22,7 @@
 
 struct nftnl_expr_ng {
enum nft_registers  dreg;
-   unsigned intuntil;
+   unsigned intmodulus;
enum nft_ng_types   type;
 };
 
@@ -36,8 +36,8 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_DREG:
ng->dreg = *((uint32_t *)data);
break;
-   case NFTNL_EXPR_NG_UNTIL:
-   ng->until = *((uint32_t *)data);
+   case NFTNL_EXPR_NG_MODULUS:
+   ng->modulus = *((uint32_t *)data);
break;
case NFTNL_EXPR_NG_TYPE:
ng->type = *((uint32_t *)data);
@@ -58,9 +58,9 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_DREG:
*data_len = sizeof(ng->dreg);
return >dreg;
-   case NFTNL_EXPR_NG_UNTIL:
-   *data_len = sizeof(ng->until);
-   return >until;
+   case NFTNL_EXPR_NG_MODULUS:
+   *data_len = sizeof(ng->modulus);
+   return >modulus;
case NFTNL_EXPR_NG_TYPE:
*data_len = sizeof(ng->type);
return >type;
@@ -78,7 +78,7 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void 
*data)
 
switch (type) {
case NFTA_NG_DREG:
-   case NFTA_NG_UNTIL:
+   case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
@@ -96,8 +96,8 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
 
if (e->flags & (1 << NFTNL_EXPR_NG_DREG))
mnl_attr_put_u32(nlh, NFTA_NG_DREG, htonl(ng->dreg));
-   if (e->flags & (1 << NFTNL_EXPR_NG_UNTIL))
-   mnl_attr_put_u32(nlh, NFTA_NG_UNTIL, htonl(ng->until));
+   if (e->flags & (1 << NFTNL_EXPR_NG_MODULUS))
+   mnl_attr_put_u32(nlh, NFTA_NG_MODULUS, htonl(ng->modulus));
if (e->flags & (1 << NFTNL_EXPR_NG_TYPE))
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
 }
@@ -116,9 +116,9 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr 
*attr)
ng->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_NG_DREG]));
e->flags |= (1 << NFTNL_EXPR_NG_DREG);
}
-   if (tb[NFTA_NG_UNTIL]) {
-  

[PATCH v2] netfilter: nft_hash: Add hash offset value

2016-09-06 Thread Laura Garcia Liebana
Add support to pass through an offset to the hash value. With this
feature, the sysadmin is able to generate a hash with a given
offset value.

Example:

meta mark set jhash ip saddr mod 2 seed 0xabcd sum 100

This option generates marks according to the source address from 100 to
101.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Add check for hash + sum overflow.

 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_hash.c | 16 ++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 4dbeeed..8026684 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -764,6 +764,7 @@ enum nft_meta_keys {
  * @NFTA_HASH_LEN: source data length (NLA_U32)
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
+ * @NFTA_HASH_SUM: Hash offset value (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -772,6 +773,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_SUM,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index b7e3b40..2102c94 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -23,6 +23,7 @@ struct nft_hash {
u8  len;
u32 modulus;
u32 seed;
+   u32 sum;
 };
 
 static void nft_hash_eval(const struct nft_expr *expr,
@@ -35,7 +36,7 @@ static void nft_hash_eval(const struct nft_expr *expr,
 
h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
 
-   regs->data[priv->dreg] = h;
+   regs->data[priv->dreg] = priv->sum + h;
 }
 
 const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
@@ -44,6 +45,7 @@ const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_LEN] = { .type = NLA_U32 },
[NFTA_HASH_MODULUS] = { .type = NLA_U32 },
[NFTA_HASH_SEED]= { .type = NLA_U32 },
+   [NFTA_HASH_SUM] = { .type = NLA_U32 },
 };
 
 static int nft_hash_init(const struct nft_ctx *ctx,
@@ -60,6 +62,11 @@ static int nft_hash_init(const struct nft_ctx *ctx,
!tb[NFTA_HASH_MODULUS])
return -EINVAL;
 
+   if (tb[NFTA_HASH_SUM])
+   priv->sum = ntohl(nla_get_be32(tb[NFTA_HASH_SUM]));
+   else
+   priv->sum = 0;
+
priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
if (priv->sreg < 0)
return -ERANGE;
@@ -77,6 +84,9 @@ static int nft_hash_init(const struct nft_ctx *ctx,
if (priv->modulus <= 1)
return -ERANGE;
 
+   if (priv->sum + priv->modulus - 1 < U32_MAX)
+   return -EOVERFLOW;
+
priv->seed = ntohl(nla_get_be32(tb[NFTA_HASH_SEED]));
 
return nft_validate_register_load(priv->sreg, priv->len) &&
@@ -99,7 +109,9 @@ static int nft_hash_dump(struct sk_buff *skb,
goto nla_put_failure;
if (nft_dump_register(skb, NFTA_HASH_SEED, priv->seed))
goto nla_put_failure;
-
+   if (priv->sum != 0)
+   if (nla_put_be32(skb, NFTA_HASH_SUM, htonl(priv->sum)))
+   goto nla_put_failure;
return 0;
 
 nla_put_failure:
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netfilter: nft_hash: Add hash offset value

2016-09-05 Thread Laura Garcia
On Mon, Sep 05, 2016 at 11:10:28AM +0200, Pablo Neira Ayuso wrote:
> On Mon, Sep 05, 2016 at 10:36:57AM +0200, Laura Garcia Liebana wrote:
> > Add support to pass through an offset to the hash value. With this
> > feature, the sysadmin is able to generate a hash with a given
> > offset value.
> > 
> > Example:
> > 
> > meta mark set jhash ip saddr mod 2 seed 0xabcd sum 100
> > 
> > This option generates marks according to the source address from 100 to
> > 101.
> > 
> > Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
> > ---
> >  include/uapi/linux/netfilter/nf_tables.h |  2 ++
> >  net/netfilter/nft_hash.c | 13 +++--
> >  2 files changed, 13 insertions(+), 2 deletions(-)
> > 
> > diff --git a/include/uapi/linux/netfilter/nf_tables.h 
> > b/include/uapi/linux/netfilter/nf_tables.h
> > index 4dbeeed..8026684 100644
> > --- a/include/uapi/linux/netfilter/nf_tables.h
> > +++ b/include/uapi/linux/netfilter/nf_tables.h
> > @@ -764,6 +764,7 @@ enum nft_meta_keys {
> >   * @NFTA_HASH_LEN: source data length (NLA_U32)
> >   * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
> >   * @NFTA_HASH_SEED: seed value (NLA_U32)
> > + * @NFTA_HASH_SUM: Hash offset value (NLA_U32)
> >   */
> >  enum nft_hash_attributes {
> > NFTA_HASH_UNSPEC,
> > @@ -772,6 +773,7 @@ enum nft_hash_attributes {
> > NFTA_HASH_LEN,
> > NFTA_HASH_MODULUS,
> > NFTA_HASH_SEED,
> > +   NFTA_HASH_SUM,
> > __NFTA_HASH_MAX,
> >  };
> >  #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
> > diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
> > index b7e3b40..8ab04d9 100644
> > --- a/net/netfilter/nft_hash.c
> > +++ b/net/netfilter/nft_hash.c
> > @@ -23,6 +23,7 @@ struct nft_hash {
> > u8  len;
> > u32 modulus;
> > u32 seed;
> > +   u32 sum;
> >  };
> >  
> >  static void nft_hash_eval(const struct nft_expr *expr,
> > @@ -35,7 +36,7 @@ static void nft_hash_eval(const struct nft_expr *expr,
> >  
> > h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
> >  
> > -   regs->data[priv->dreg] = h;
> > +   regs->data[priv->dreg] = priv->sum + h;
> >  }
> >  
> >  const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
> > @@ -44,6 +45,7 @@ const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 
> > 1] = {
> > [NFTA_HASH_LEN] = { .type = NLA_U32 },
> > [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
> > [NFTA_HASH_SEED]= { .type = NLA_U32 },
> > +   [NFTA_HASH_SUM] = { .type = NLA_U32 },
> >  };
> >  
> >  static int nft_hash_init(const struct nft_ctx *ctx,
> > @@ -60,6 +62,11 @@ static int nft_hash_init(const struct nft_ctx *ctx,
> > !tb[NFTA_HASH_MODULUS])
> > return -EINVAL;
> >  
> > +   if (tb[NFTA_HASH_SUM])
> > +   priv->sum = ntohl(nla_get_be32(tb[NFTA_HASH_SUM]));
> > +   else
> > +   priv->sum = 0;
> 
> There is a corner case that we should reject from the kernel, I think
> this is:
> 
> if (priv->sum + priv->modulus - 1 < priv->sum)
> return -EOVERFLOW;
> 
> We'll handle this from userspace anyway too, but I think it's easy to
> reject this crazy this.

Such case shouldn't happen cause the modulus must be > 1. The init()
provides:

priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
if (priv->modulus <= 1)
return -ERANGE;


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libnftnl] expr: hash: Add offset to hash value

2016-09-05 Thread Laura Garcia Liebana
Add support to pass through an offset to the hash value. With this
feature, the sysadmin is able to generate a hash with a given
started value.

Example:

meta mark set jhash ip saddr mod 2 seed 0xabcd sum 100

This option generates marks according to the source address from 100 to
101.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/libnftnl/expr.h |  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 src/expr/hash.c | 39 +++--
 tests/nft-expr_hash-test.c  |  4 
 4 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 3cf0db1..9188364 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -211,6 +211,7 @@ enum {
NFTNL_EXPR_HASH_LEN,
NFTNL_EXPR_HASH_MODULUS,
NFTNL_EXPR_HASH_SEED,
+   NFTNL_EXPR_HASH_SUM,
 };
 
 /*
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 2718832..65d9fe8 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1139,6 +1139,7 @@ enum nft_trace_types {
  * @NFTA_HASH_LEN: data length (NLA_U32)
  * @NFTA_HASH_MODULUS: Modulus value (NLA_U32)
  * @NFTA_HASH_SEED: hash initial value (NLA_U32)
+ * @NFTA_HASH_SUM: offset value to be added (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -1147,6 +1148,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_SUM,
__NFTA_HASH_MAX
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/src/expr/hash.c b/src/expr/hash.c
index 2d61508..54c6dbc 100644
--- a/src/expr/hash.c
+++ b/src/expr/hash.c
@@ -26,6 +26,7 @@ struct nftnl_expr_hash {
unsigned intlen;
unsigned intmodulus;
unsigned intseed;
+   unsigned intsum;
 };
 
 static int
@@ -50,6 +51,9 @@ nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_HASH_SEED:
hash->seed = *((uint32_t *)data);
break;
+   case NFTNL_EXPR_HASH_SUM:
+   hash->sum = *((uint32_t *)data);
+   break;
default:
return -1;
}
@@ -78,6 +82,9 @@ nftnl_expr_hash_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_HASH_SEED:
*data_len = sizeof(hash->seed);
return >seed;
+   case NFTNL_EXPR_HASH_SUM:
+   *data_len = sizeof(hash->sum);
+   return >sum;
}
return NULL;
 }
@@ -96,6 +103,7 @@ static int nftnl_expr_hash_cb(const struct nlattr *attr, 
void *data)
case NFTA_HASH_LEN:
case NFTA_HASH_MODULUS:
case NFTA_HASH_SEED:
+   case NFTA_HASH_SUM:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
@@ -120,7 +128,8 @@ nftnl_expr_hash_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
mnl_attr_put_u32(nlh, NFTA_HASH_MODULUS, htonl(hash->modulus));
if (e->flags & (1 << NFTNL_EXPR_HASH_SEED))
mnl_attr_put_u32(nlh, NFTA_HASH_SEED, htonl(hash->seed));
-
+   if (e->flags & (1 << NFTNL_EXPR_HASH_SUM))
+   mnl_attr_put_u32(nlh, NFTA_HASH_SUM, htonl(hash->sum));
 }
 
 static int
@@ -153,6 +162,10 @@ nftnl_expr_hash_parse(struct nftnl_expr *e, struct nlattr 
*attr)
hash->seed = ntohl(mnl_attr_get_u32(tb[NFTA_HASH_SEED]));
e->flags |= (1 << NFTNL_EXPR_HASH_SEED);
}
+   if (tb[NFTA_HASH_SUM]) {
+   hash->sum = ntohl(mnl_attr_get_u32(tb[NFTA_HASH_SUM]));
+   e->flags |= (1 << NFTNL_EXPR_HASH_SUM);
+   }
 
return ret;
 }
@@ -161,7 +174,7 @@ static int nftnl_expr_hash_json_parse(struct nftnl_expr *e, 
json_t *root,
  struct nftnl_parse_err *err)
 {
 #ifdef JSON_PARSING
-   uint32_t sreg, dreg, len, modulus, seed;
+   uint32_t sreg, dreg, len, modulus, seed, sum;
 
if (nftnl_jansson_parse_reg(root, "sreg", NFTNL_TYPE_U32,
, err) == 0)
@@ -183,6 +196,10 @@ static int nftnl_expr_hash_json_parse(struct nftnl_expr 
*e, json_t *root,
, err) == 0)
nftnl_expr_set_u32(e, NFTNL_EXPR_HASH_SEED, seed);
 
+   if (nftnl_jansson_parse_val(root, "sum", NFTNL_TYPE_U32,
+   , err) == 0)
+   nftnl_expr_set_u32(e, NFTNL_EXPR_HASH_SUM, sum);
+
return 0;
 #else
errno = EOPNOTSUPP;
@@ -196,7 +213,7 @@ static int nftnl_expr_hash_xml_parse(struct nftnl_expr *e,
 struct nftnl_parse_err *err)
 {
 #ifdef XM

[PATCH] netfilter: nft_hash: Add hash offset value

2016-09-05 Thread Laura Garcia Liebana
Add support to pass through an offset to the hash value. With this
feature, the sysadmin is able to generate a hash with a given
offset value.

Example:

meta mark set jhash ip saddr mod 2 seed 0xabcd sum 100

This option generates marks according to the source address from 100 to
101.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_hash.c | 13 +++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 4dbeeed..8026684 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -764,6 +764,7 @@ enum nft_meta_keys {
  * @NFTA_HASH_LEN: source data length (NLA_U32)
  * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
  * @NFTA_HASH_SEED: seed value (NLA_U32)
+ * @NFTA_HASH_SUM: Hash offset value (NLA_U32)
  */
 enum nft_hash_attributes {
NFTA_HASH_UNSPEC,
@@ -772,6 +773,7 @@ enum nft_hash_attributes {
NFTA_HASH_LEN,
NFTA_HASH_MODULUS,
NFTA_HASH_SEED,
+   NFTA_HASH_SUM,
__NFTA_HASH_MAX,
 };
 #define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index b7e3b40..8ab04d9 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -23,6 +23,7 @@ struct nft_hash {
u8  len;
u32 modulus;
u32 seed;
+   u32 sum;
 };
 
 static void nft_hash_eval(const struct nft_expr *expr,
@@ -35,7 +36,7 @@ static void nft_hash_eval(const struct nft_expr *expr,
 
h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
 
-   regs->data[priv->dreg] = h;
+   regs->data[priv->dreg] = priv->sum + h;
 }
 
 const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
@@ -44,6 +45,7 @@ const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
[NFTA_HASH_LEN] = { .type = NLA_U32 },
[NFTA_HASH_MODULUS] = { .type = NLA_U32 },
[NFTA_HASH_SEED]= { .type = NLA_U32 },
+   [NFTA_HASH_SUM] = { .type = NLA_U32 },
 };
 
 static int nft_hash_init(const struct nft_ctx *ctx,
@@ -60,6 +62,11 @@ static int nft_hash_init(const struct nft_ctx *ctx,
!tb[NFTA_HASH_MODULUS])
return -EINVAL;
 
+   if (tb[NFTA_HASH_SUM])
+   priv->sum = ntohl(nla_get_be32(tb[NFTA_HASH_SUM]));
+   else
+   priv->sum = 0;
+
priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
if (priv->sreg < 0)
return -ERANGE;
@@ -99,7 +106,9 @@ static int nft_hash_dump(struct sk_buff *skb,
goto nla_put_failure;
if (nft_dump_register(skb, NFTA_HASH_SEED, priv->seed))
goto nla_put_failure;
-
+   if (priv->sum != 0)
+   if (nft_dump_register(skb, NFTA_HASH_SUM, priv->sum))
+   goto nla_put_failure;
return 0;
 
 nla_put_failure:
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 libnftnl] expr: numgen: Rename until attribute by modulus

2016-09-02 Thread Laura Garcia Liebana
The _modulus_ attribute will be reused as _until_, as it's similar to
other expressions with value limits (ex. hash).

Renaming is possible according to the kernel module ntf_numgen that has
not been released yet.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V2:
- Separate changes with incremental counter offset value.

 include/buffer.h|  1 -
 include/libnftnl/expr.h |  2 +-
 include/linux/netfilter/nf_tables.h |  4 +--
 src/expr/numgen.c   | 54 ++---
 tests/nft-expr_numgen-test.c|  8 +++---
 5 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/include/buffer.h b/include/buffer.h
index 8cfe377..a753c78 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -82,7 +82,6 @@ int nftnl_buf_reg(struct nftnl_buf *b, int type, union 
nftnl_data_reg *reg,
 #define TOTAL  "total"
 #define TYPE   "type"
 #define UNIT   "unit"
-#define UNTIL  "until"
 #define USE"use"
 #define XOR"xor"
 #define ADD"add"
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 8815154..94ce529 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -52,7 +52,7 @@ enum {
 
 enum {
NFTNL_EXPR_NG_DREG  = NFTNL_EXPR_BASE,
-   NFTNL_EXPR_NG_UNTIL,
+   NFTNL_EXPR_NG_MODULUS,
NFTNL_EXPR_NG_TYPE,
 };
 
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 0b11abf..a3dbac2 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -670,13 +670,13 @@ enum nft_exthdr_attributes {
  * enum nft_ng_attributes - nf_tables number generator expression attributes
  *
  * @NFTA_NG_DREG: destination register (NLA_U32)
- * @NFTA_NG_UNTIL: limit value (NLA_U32)
+ * @NFTA_NG_MODULUS: maximum value to be returned (NLA_U32)
  * @NFTA_NG_TYPE: type of operation (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
-   NFTA_NG_UNTIL,
+   NFTA_NG_MODULUS,
NFTA_NG_TYPE,
__NFTA_NG_MAX
 };
diff --git a/src/expr/numgen.c b/src/expr/numgen.c
index 0669eda..a008c75 100644
--- a/src/expr/numgen.c
+++ b/src/expr/numgen.c
@@ -22,7 +22,7 @@
 
 struct nftnl_expr_ng {
enum nft_registers  dreg;
-   unsigned intuntil;
+   unsigned intmodulus;
enum nft_ng_typetype;
 };
 
@@ -36,8 +36,8 @@ nftnl_expr_ng_set(struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_DREG:
ng->dreg = *((uint32_t *)data);
break;
-   case NFTNL_EXPR_NG_UNTIL:
-   ng->until = *((uint32_t *)data);
+   case NFTNL_EXPR_NG_MODULUS:
+   ng->modulus = *((uint32_t *)data);
break;
case NFTNL_EXPR_NG_TYPE:
ng->type = *((uint32_t *)data);
@@ -58,9 +58,9 @@ nftnl_expr_ng_get(const struct nftnl_expr *e, uint16_t type,
case NFTNL_EXPR_NG_DREG:
*data_len = sizeof(ng->dreg);
return >dreg;
-   case NFTNL_EXPR_NG_UNTIL:
-   *data_len = sizeof(ng->until);
-   return >until;
+   case NFTNL_EXPR_NG_MODULUS:
+   *data_len = sizeof(ng->modulus);
+   return >modulus;
case NFTNL_EXPR_NG_TYPE:
*data_len = sizeof(ng->type);
return >type;
@@ -78,7 +78,7 @@ static int nftnl_expr_ng_cb(const struct nlattr *attr, void 
*data)
 
switch (type) {
case NFTA_NG_DREG:
-   case NFTA_NG_UNTIL:
+   case NFTA_NG_MODULUS:
case NFTA_NG_TYPE:
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
@@ -96,8 +96,8 @@ nftnl_expr_ng_build(struct nlmsghdr *nlh, const struct 
nftnl_expr *e)
 
if (e->flags & (1 << NFTNL_EXPR_NG_DREG))
mnl_attr_put_u32(nlh, NFTA_NG_DREG, htonl(ng->dreg));
-   if (e->flags & (1 << NFTNL_EXPR_NG_UNTIL))
-   mnl_attr_put_u32(nlh, NFTA_NG_UNTIL, htonl(ng->until));
+   if (e->flags & (1 << NFTNL_EXPR_NG_MODULUS))
+   mnl_attr_put_u32(nlh, NFTA_NG_MODULUS, htonl(ng->modulus));
if (e->flags & (1 << NFTNL_EXPR_NG_TYPE))
mnl_attr_put_u32(nlh, NFTA_NG_TYPE, htonl(ng->type));
 }
@@ -116,9 +116,9 @@ nftnl_expr_ng_parse(struct nftnl_expr *e, struct nlattr 
*attr)
ng->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_NG_DREG]));
e->flags |= (1 << NFTNL_EXPR_NG_DREG);
}
-   if (tb[NFTA_NG_UNTIL]) {
-   ng->until = ntohl(mnl_attr_get_u32(tb[NFTA_NG_UNTIL]));
-   e->flags 

[PATCH v2] netfilter: nft_numgen: rename until attribute by modulus

2016-09-02 Thread Laura Garcia Liebana
The _until_ attribute is renamed to _modulus_ as the behaviour is similar to
other expresions with number limits (ex. nft_hash).

Renaming is possible because there isn't a kernel release yet with these
changes.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V2:
- Separate changes with offset support

 include/uapi/linux/netfilter/nf_tables.h |  4 ++--
 net/netfilter/nft_numgen.c   | 30 +++---
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index e941139..366ef7d 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1151,13 +1151,13 @@ enum nft_trace_types {
  * attributes
  *
  * @NFTA_NG_DREG: destination register (NLA_U32)
- * @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
+ * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
-   NFTA_NG_UNTIL,
+   NFTA_NG_MODULUS,
NFTA_NG_TYPE,
__NFTA_NG_MAX
 };
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index e1d5a11..04d14a5 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU(struct rnd_state, 
nft_numgen_prandom_state);
 
 struct nft_ng_inc {
enum nft_registers  dreg:8;
-   u32 until;
+   u32 modulus;
atomic_tcounter;
 };
 
@@ -34,7 +34,7 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
 
do {
oval = atomic_read(>counter);
-   nval = (oval + 1 < priv->until) ? oval + 1 : 0;
+   nval = (oval + 1 < priv->modulus) ? oval + 1 : 0;
} while (atomic_cmpxchg(>counter, oval, nval) != oval);
 
memcpy(>data[priv->dreg], >counter, sizeof(u32));
@@ -42,7 +42,7 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
 
 const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
[NFTA_NG_DREG]  = { .type = NLA_U32 },
-   [NFTA_NG_UNTIL] = { .type = NLA_U32 },
+   [NFTA_NG_MODULUS]   = { .type = NLA_U32 },
[NFTA_NG_TYPE]  = { .type = NLA_U32 },
 };
 
@@ -52,8 +52,8 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
 {
struct nft_ng_inc *priv = nft_expr_priv(expr);
 
-   priv->until = ntohl(nla_get_be32(tb[NFTA_NG_UNTIL]));
-   if (priv->until == 0)
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
+   if (priv->modulus == 0)
return -ERANGE;
 
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
@@ -67,11 +67,11 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
 }
 
 static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
-  u32 until, enum nft_ng_types type)
+  u32 modulus, enum nft_ng_types type)
 {
if (nft_dump_register(skb, NFTA_NG_DREG, dreg))
goto nla_put_failure;
-   if (nft_dump_register(skb, NFTA_NG_UNTIL, until))
+   if (nft_dump_register(skb, NFTA_NG_MODULUS, modulus))
goto nla_put_failure;
if (nft_dump_register(skb, NFTA_NG_TYPE, type))
goto nla_put_failure;
@@ -86,12 +86,12 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const 
struct nft_expr *expr)
 {
const struct nft_ng_inc *priv = nft_expr_priv(expr);
 
-   return nft_ng_dump(skb, priv->dreg, priv->until, NFT_NG_INCREMENTAL);
+   return nft_ng_dump(skb, priv->dreg, priv->modulus, NFT_NG_INCREMENTAL);
 }
 
 struct nft_ng_random {
enum nft_registers  dreg:8;
-   u32 until;
+   u32 modulus;
 };
 
 static void nft_ng_random_eval(const struct nft_expr *expr,
@@ -102,7 +102,7 @@ static void nft_ng_random_eval(const struct nft_expr *expr,
struct rnd_state *state = this_cpu_ptr(_numgen_prandom_state);
 
regs->data[priv->dreg] = reciprocal_scale(prandom_u32_state(state),
- priv->until);
+ priv->modulus);
 }
 
 static int nft_ng_random_init(const struct nft_ctx *ctx,
@@ -111,8 +111,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
 {
struct nft_ng_random *priv = nft_expr_priv(expr);
 
-   priv->until = ntohl(nla_get_be32(tb[NFTA_NG_UNTIL]));
-   if (priv->until == 0)
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
+   if (priv->modulus == 0)
return -ERANGE;
 
prandom_init_once(_numgen_prandom_state);
@@ -129,7 +129,7 @@ static int nft_ng_random_dump(struct sk_buff *skb, const 
str

[PATCH] netfilter: nft_numgen: add counter offset value and rename until by modulus

2016-09-02 Thread Laura Garcia Liebana
Add support for an initialization counter value. With this option the
sysadmin is able to start the counter when used with the increment
type.

Example:

meta mark set numgen inc mod 2 sum 100

This will generate marks with the serie 100, 101, 100, 101, ...

The _until_ attribute is renamed to _modulus_ as the behaviour is similar to
other expresions with number limits(ex. nft_hash).

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  6 --
 net/netfilter/nft_numgen.c   | 37 ++--
 2 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index e941139..4dbeeed 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1151,14 +1151,16 @@ enum nft_trace_types {
  * attributes
  *
  * @NFTA_NG_DREG: destination register (NLA_U32)
- * @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
+ * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_SUM: Offset to initiate the counter (NLA_U32)
  */
 enum nft_ng_attributes {
NFTA_NG_UNSPEC,
NFTA_NG_DREG,
-   NFTA_NG_UNTIL,
+   NFTA_NG_MODULUS,
NFTA_NG_TYPE,
+   NFTA_NG_SUM,
__NFTA_NG_MAX
 };
 #define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
index e1d5a11..bfde6d0 100644
--- a/net/netfilter/nft_numgen.c
+++ b/net/netfilter/nft_numgen.c
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU(struct rnd_state, 
nft_numgen_prandom_state);
 
 struct nft_ng_inc {
enum nft_registers  dreg:8;
-   u32 until;
+   u32 modulus;
atomic_tcounter;
 };
 
@@ -34,7 +34,7 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
 
do {
oval = atomic_read(>counter);
-   nval = (oval + 1 < priv->until) ? oval + 1 : 0;
+   nval = (oval + 1 < priv->modulus) ? oval + 1 : 0;
} while (atomic_cmpxchg(>counter, oval, nval) != oval);
 
memcpy(>data[priv->dreg], >counter, sizeof(u32));
@@ -42,8 +42,9 @@ static void nft_ng_inc_eval(const struct nft_expr *expr,
 
 const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
[NFTA_NG_DREG]  = { .type = NLA_U32 },
-   [NFTA_NG_UNTIL] = { .type = NLA_U32 },
+   [NFTA_NG_MODULUS]   = { .type = NLA_U32 },
[NFTA_NG_TYPE]  = { .type = NLA_U32 },
+   [NFTA_NG_SUM]   = { .type = NLA_U32 },
 };
 
 static int nft_ng_inc_init(const struct nft_ctx *ctx,
@@ -51,27 +52,31 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
   const struct nlattr * const tb[])
 {
struct nft_ng_inc *priv = nft_expr_priv(expr);
+   u32 sum = 0;
 
-   priv->until = ntohl(nla_get_be32(tb[NFTA_NG_UNTIL]));
-   if (priv->until == 0)
+   if (tb[NFTA_NG_SUM])
+   sum = ntohl(nla_get_be32(tb[NFTA_NG_SUM]));
+
+   priv->modulus = ntohl(nla_get_be32(tb[NFTA_NG_MODULUS]));
+   if (priv->modulus == 0 || sum >= priv->modulus)
return -ERANGE;
 
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
if (priv->dreg < 0)
return -ERANGE;
 
-   atomic_set(>counter, 0);
+   atomic_set(>counter, sum);
 
return nft_validate_register_store(ctx, priv->dreg, NULL,
   NFT_DATA_VALUE, sizeof(u32));
 }
 
 static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
-  u32 until, enum nft_ng_types type)
+  u32 modulus, enum nft_ng_types type)
 {
if (nft_dump_register(skb, NFTA_NG_DREG, dreg))
goto nla_put_failure;
-   if (nft_dump_register(skb, NFTA_NG_UNTIL, until))
+   if (nft_dump_register(skb, NFTA_NG_MODULUS, modulus))
goto nla_put_failure;
if (nft_dump_register(skb, NFTA_NG_TYPE, type))
goto nla_put_failure;
@@ -86,12 +91,12 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const 
struct nft_expr *expr)
 {
const struct nft_ng_inc *priv = nft_expr_priv(expr);
 
-   return nft_ng_dump(skb, priv->dreg, priv->until, NFT_NG_INCREMENTAL);
+   return nft_ng_dump(skb, priv->dreg, priv->modulus, NFT_NG_INCREMENTAL);
 }
 
 struct nft_ng_random {
enum nft_registers  dreg:8;
-   u32 until;
+   u32 modulus;
 };
 
 static void nft_ng_random_eval(const struct nft_expr *expr,
@@ -102,7 +107,7 @@ static void nft_ng_random_eval(const struct nft_expr *expr,
struct rnd_state *state = this_cpu_ptr(_numgen_prandom_st

Re: [PATCH v3] netfilter: nf_tables: Ensure init attributes are within the bounds

2016-08-22 Thread Laura Garcia
On Mon, Aug 22, 2016 at 05:10:02PM +0800, kbuild test robot wrote:
> Hi Laura,
> 
> [auto build test ERROR on nf-next/master]
> [also build test ERROR on v4.8-rc3 next-20160822]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> [Suggest to use git(>=2.9.0) format-patch --base= (or --base=auto for 
> convenience) to record what (public, well-known) commit your patch series was 
> built on]
> [Check https://git-scm.com/docs/git-format-patch for more information]
> 
> url:
> https://github.com/0day-ci/linux/commits/Laura-Garcia-Liebana/netfilter-nf_tables-Ensure-init-attributes-are-within-the-bounds/20160818-194709
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git 
> master
> config: x86_64-rhel (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
>net/netfilter/nft_cmp.c: In function 'nft_cmp_init':
> >> net/netfilter/nft_cmp.c:91:18: error: 'NFT_CMP_MAX' undeclared (first use 
> >> in this function)
>  if (priv->op >= NFT_CMP_MAX)
>  ^~~
>net/netfilter/nft_cmp.c:91:18: note: each undeclared identifier is 
> reported only once for each function it appears in
> 
> vim +/NFT_CMP_MAX +91 net/netfilter/nft_cmp.c
> 
> 85return err;
> 86
> 87if (desc.len > U8_MAX)
> 88return -ERANGE;
> 89priv->len = desc.len;
> 90priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
>   > 91if (priv->op >= NFT_CMP_MAX)
> 92return -ERANGE;
> 93
> 94return 0;
>

A later patch version (v4) was sent to fix that.

Thanks.

> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] netfilter: nf_tables: Ensure init attributes are within the bounds

2016-08-18 Thread Laura Garcia Liebana
Check for overflow of u8 fields from u32 netlink attributes and maximum
values.

Refer to 4da449ae1df

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
(was: netfilter: nf_tables: Check for overflow of u8 fields from u32
netlink attributes)

Changes in V4:
- Define NFT_CMP_MAX

 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_bitwise.c  |  7 ++-
 net/netfilter/nft_byteorder.c| 13 +++--
 net/netfilter/nft_cmp.c  |  9 -
 net/netfilter/nft_immediate.c|  3 +++
 5 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 0ddefb1..ce12a20 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -528,7 +528,9 @@ enum nft_cmp_ops {
NFT_CMP_LTE,
NFT_CMP_GT,
NFT_CMP_GTE,
+   __NFT_CMP_MAX
 };
+#define NFT_CMP_MAX(__NFT_CMP_MAX - 1)
 
 /**
  * enum nft_cmp_attributes - nf_tables cmp expression netlink attributes
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d71cc18..6e09b1e 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -53,6 +53,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
struct nft_bitwise *priv = nft_expr_priv(expr);
struct nft_data_desc d1, d2;
int err;
+   u32 len;
 
if (tb[NFTA_BITWISE_SREG] == NULL ||
tb[NFTA_BITWISE_DREG] == NULL ||
@@ -61,7 +62,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
 
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   if (len > U8_MAX)
+   return -ERANGE;
+   priv->len = len;
+
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index b78c28b..763cf15 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -100,6 +100,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
 {
struct nft_byteorder *priv = nft_expr_priv(expr);
int err;
+   u32 len, size;
 
if (tb[NFTA_BYTEORDER_SREG] == NULL ||
tb[NFTA_BYTEORDER_DREG] == NULL ||
@@ -117,7 +118,10 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
 
-   priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   if (size > U8_MAX)
+   return -ERANGE;
+   priv->size = size;
switch (priv->size) {
case 2:
case 4:
@@ -128,7 +132,12 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
}
 
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+
+   len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+   if (len > U8_MAX)
+   return -ERANGE;
+   priv->len = len;
+
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e25b35d..cb9cfab 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -55,6 +55,8 @@ static void nft_cmp_eval(const struct nft_expr *expr,
if (d < 0)
goto mismatch;
break;
+   default:
+   break;
}
return;
 
@@ -84,8 +86,13 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
if (err < 0)
return err;
 
-   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (desc.len > U8_MAX)
+   return -ERANGE;
priv->len = desc.len;
+   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (priv->op > NFT_CMP_MAX)
+   return -ERANGE;
+
return 0;
 }
 
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index db3b746..b5f899c 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -53,6 +53,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
+
+   if (desc.len > U8_MAX)
+   return -ERANGE;
priv->dlen = desc.len;
 
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] netfilter: nf_tables: Ensure init attributes are within the bounds

2016-08-18 Thread Laura Garcia Liebana
Check for overflow of u8 fields from u32 netlink attributes and maximum
values.

Refer to 4da449ae1df

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
(was: netfilter: nf_tables: Check for overflow of u8 fields from u32
netlink attributes)

Changes in V3:
- Use ERANGE instead of EINVAL when validating the value is
within the bounds.
- Add op verification in nft_cmp_init().
- Remove additional bounds verification for family attribute in
nft_nat_init().

 net/netfilter/nft_bitwise.c   |  7 ++-
 net/netfilter/nft_byteorder.c | 13 +++--
 net/netfilter/nft_cmp.c   |  7 ++-
 net/netfilter/nft_immediate.c |  3 +++
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d71cc18..6e09b1e 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -53,6 +53,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
struct nft_bitwise *priv = nft_expr_priv(expr);
struct nft_data_desc d1, d2;
int err;
+   u32 len;
 
if (tb[NFTA_BITWISE_SREG] == NULL ||
tb[NFTA_BITWISE_DREG] == NULL ||
@@ -61,7 +62,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
 
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   if (len > U8_MAX)
+   return -ERANGE;
+   priv->len = len;
+
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index b78c28b..763cf15 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -100,6 +100,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
 {
struct nft_byteorder *priv = nft_expr_priv(expr);
int err;
+   u32 len, size;
 
if (tb[NFTA_BYTEORDER_SREG] == NULL ||
tb[NFTA_BYTEORDER_DREG] == NULL ||
@@ -117,7 +118,10 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
 
-   priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   if (size > U8_MAX)
+   return -ERANGE;
+   priv->size = size;
switch (priv->size) {
case 2:
case 4:
@@ -128,7 +132,12 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
}
 
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+
+   len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+   if (len > U8_MAX)
+   return -ERANGE;
+   priv->len = len;
+
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e25b35d..7412c82 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -84,8 +84,13 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
if (err < 0)
return err;
 
-   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (desc.len > U8_MAX)
+   return -ERANGE;
priv->len = desc.len;
+   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (priv->op >= NFT_CMP_MAX)
+   return -ERANGE;
+
return 0;
 }
 
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index db3b746..b5f899c 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -53,6 +53,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
+
+   if (desc.len > U8_MAX)
+   return -ERANGE;
priv->dlen = desc.len;
 
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5] netfilter: nft_numgen: add number generator expression

2016-08-18 Thread Laura Garcia Liebana
Add support for the number generator expression in netfilter.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V5:
- Reorder the functions
- Add attributes checks
- Use switch instead of if statements

 include/uapi/linux/netfilter/nf_tables.h |  25 
 net/netfilter/Kconfig|   6 +
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_numgen.c   | 192 +++
 4 files changed, 224 insertions(+)
 create mode 100644 net/netfilter/nft_numgen.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index c674ba2..38fd1ef 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1082,4 +1082,29 @@ enum nft_trace_types {
__NFT_TRACETYPE_MAX
 };
 #define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
+
+/**
+ * enum nft_ng_attributes - nf_tables number generator expression netlink
+ * attributes
+ *
+ * @NFTA_NG_DREG: destination register (NLA_U32)
+ * @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
+ * @NFTA_NG_TYPE: operation type (NLA_U32)
+ */
+enum nft_ng_attributes {
+   NFTA_NG_UNSPEC,
+   NFTA_NG_DREG,
+   NFTA_NG_UNTIL,
+   NFTA_NG_TYPE,
+   __NFTA_NG_MAX
+};
+#define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
+
+enum nft_ng_types {
+   NFT_NG_INCREMENTAL,
+   NFT_NG_RANDOM,
+   __NFT_NG_MAX
+};
+#define NFT_NG_MAX (__NFT_NG_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9266cee..31def7d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,12 @@ config NFT_META
  This option adds the "meta" expression that you can use to match and
  to set packet metainformation such as the packet mark.
 
+config NFT_NUMGEN
+   tristate "Netfilter nf_tables number generator module"
+   help
+ This option adds the number generator expression used to perform
+ operations like the incremental counter until a reset value or random.
+
 config NFT_CT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables conntrack module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6913454..81f22c3 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_NF_TABLES_NETDEV)+= nf_tables_netdev.o
 obj-$(CONFIG_NFT_COMPAT)   += nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)   += nft_exthdr.o
 obj-$(CONFIG_NFT_META) += nft_meta.o
+obj-$(CONFIG_NFT_NUMGEN)   += nft_numgen.o
 obj-$(CONFIG_NFT_CT)   += nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)+= nft_limit.o
 obj-$(CONFIG_NFT_NAT)  += nft_nat.o
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
new file mode 100644
index 000..b096c55
--- /dev/null
+++ b/net/netfilter/nft_numgen.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
+
+struct nft_ng_inc {
+   enum nft_registers  dreg:8;
+   u32 until;
+   atomic_tcounter;
+};
+
+static void nft_ng_inc_eval(const struct nft_expr *expr,
+   struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+   u32 nval, oval;
+
+   do {
+   oval = atomic_read(>counter);
+   nval = (oval + 1 < priv->until) ? oval + 1 : 0;
+   } while (atomic_cmpxchg(>counter, oval, nval) != oval);
+
+   memcpy(>data[priv->dreg], >counter, sizeof(u32));
+}
+
+const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
+   [NFTA_NG_DREG]  = { .type = NLA_U32 },
+   [NFTA_NG_UNTIL] = { .type = NLA_U32 },
+   [NFTA_NG_TYPE]  = { .type = NLA_U32 },
+};
+
+static int nft_ng_inc_init(const struct nft_ctx *ctx,
+  const struct nft_expr *expr,
+  const struct nlattr * const tb[])
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+
+   priv->until = ntohl(nla_get_be32(tb[NFTA_NG_UNTIL]));
+   if (priv->until == 0)
+   return -ERANGE;
+
+   priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
+   atomic_set(>counter, 0);
+
+   return nft_validate_register_store(ctx, priv->dreg, NULL,
+  NFT_DATA_VALUE, sizeof(u3

[PATCH v4] netfilter: nft_numgen: add number generator expression

2016-08-17 Thread Laura Garcia Liebana
Add support for the number generator expression in netfilter.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V4:
- Rename prandom state identifier

 include/uapi/linux/netfilter/nf_tables.h |  25 
 net/netfilter/Kconfig|   6 +
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_numgen.c   | 193 +++
 4 files changed, 225 insertions(+)
 create mode 100644 net/netfilter/nft_numgen.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index c674ba2..38fd1ef 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1082,4 +1082,29 @@ enum nft_trace_types {
__NFT_TRACETYPE_MAX
 };
 #define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
+
+/**
+ * enum nft_ng_attributes - nf_tables number generator expression netlink
+ * attributes
+ *
+ * @NFTA_NG_DREG: destination register (NLA_U32)
+ * @NFTA_NG_UNTIL: source value to increment the counter until reset (NLA_U32)
+ * @NFTA_NG_TYPE: operation type (NLA_U32)
+ */
+enum nft_ng_attributes {
+   NFTA_NG_UNSPEC,
+   NFTA_NG_DREG,
+   NFTA_NG_UNTIL,
+   NFTA_NG_TYPE,
+   __NFTA_NG_MAX
+};
+#define NFTA_NG_MAX(__NFTA_NG_MAX - 1)
+
+enum nft_ng_types {
+   NFT_NG_INCREMENTAL,
+   NFT_NG_RANDOM,
+   __NFT_NG_MAX
+};
+#define NFT_NG_MAX (__NFT_NG_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9266cee..31def7d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,12 @@ config NFT_META
  This option adds the "meta" expression that you can use to match and
  to set packet metainformation such as the packet mark.
 
+config NFT_NUMGEN
+   tristate "Netfilter nf_tables number generator module"
+   help
+ This option adds the number generator expression used to perform
+ operations like the incremental counter until a reset value or random.
+
 config NFT_CT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables conntrack module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6913454..81f22c3 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_NF_TABLES_NETDEV)+= nf_tables_netdev.o
 obj-$(CONFIG_NFT_COMPAT)   += nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)   += nft_exthdr.o
 obj-$(CONFIG_NFT_META) += nft_meta.o
+obj-$(CONFIG_NFT_NUMGEN)   += nft_numgen.o
 obj-$(CONFIG_NFT_CT)   += nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)+= nft_limit.o
 obj-$(CONFIG_NFT_NAT)  += nft_nat.o
diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c
new file mode 100644
index 000..0b44c6a
--- /dev/null
+++ b/net/netfilter/nft_numgen.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
+
+struct nft_ng_inc {
+   enum nft_registers  dreg:8;
+   u32 until;
+   atomic_tcounter;
+};
+
+struct nft_ng_random {
+   enum nft_registers  dreg:8;
+   u32 until;
+};
+
+static void nft_ng_inc_eval(const struct nft_expr *expr,
+   struct nft_regs *regs,
+   const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_inc *priv = nft_expr_priv(expr);
+   u32 nval, oval;
+
+   do {
+   oval = atomic_read(>counter);
+   nval = (oval + 1 < priv->until) ? oval + 1 : 0;
+   } while (atomic_cmpxchg(>counter, oval, nval) != oval);
+
+   memcpy(>data[priv->dreg], >counter, sizeof(u32));
+}
+
+static void nft_ng_random_eval(const struct nft_expr *expr,
+  struct nft_regs *regs,
+  const struct nft_pktinfo *pkt)
+{
+   struct nft_ng_random *priv = nft_expr_priv(expr);
+   struct rnd_state *state = this_cpu_ptr(_numgen_prandom_state);
+   u32 p;
+
+   p = reciprocal_scale(prandom_u32_state(state), priv->until);
+
+   regs->data[priv->dreg] = p;
+}
+
+const struct nla_policy nft_ng_policy[NFTA_NG_MAX + 1] = {
+   [NFTA_NG_DREG]  = { .type = NLA_U32 },
+   [NFTA_NG_UNTIL] = { .type = NLA_U32 },
+   [NFTA_NG_TYPE]  = { .type = NLA_U32 },
+};
+
+static int nft_ng_inc_init(const struct nft_ctx *ctx,
+  const struct nft_expr *expr,
+ 

Re: [PATCH v3] netfilter: nft_numgen: add number generator expression

2016-08-17 Thread Laura Garcia
On Mon, Aug 15, 2016 at 12:03:19AM +0800, kbuild test robot wrote:
> Hi Laura,
> 
> [auto build test ERROR on nf-next/master]
> [also build test ERROR on v4.8-rc1 next-20160812]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Laura-Garcia-Liebana/netfilter-nft_numgen-add-number-generator-expression/20160814-185132
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git 
> master
> config: i386-allyesconfig (attached as .config)
> compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386 
> 
> All errors (new ones prefixed by >>):
> 
> >> net/netfilter/nft_numgen.o:(.discard+0x0): multiple definition of 
> >> `__pcpu_unique_nft_prandom_state'
>net/netfilter/nft_meta.o:(.discard+0x0): first defined here
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation

Hi, I've been compiling with several options like:

CONFIG_NFT_META=m
CONFIG_NFT_NUMGEN=m

and

CONFIG_NFT_META=y
CONFIG_NFT_NUMGEN=y

but I was unable to reproduce it.

Anyway, I'll rename the identifier in a new patch.

Thanks.

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] netfilter: nf_tables: Check for overflow of u8 fields from u32 netlink attributes

2016-08-14 Thread Laura Garcia Liebana
Fix the direct assignment from u32 data input into an attribute with a
size of u8.

Refer to 4da449ae1df

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V2:
- Collapse the 5 independent patches in just one
- Change description and subject
- Add bug link

 net/netfilter/nft_bitwise.c   |  7 ++-
 net/netfilter/nft_byteorder.c | 13 +++--
 net/netfilter/nft_cmp.c   |  5 -
 net/netfilter/nft_immediate.c |  3 +++
 net/netfilter/nft_nat.c   |  2 ++
 5 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d71cc18..2c49f69 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -53,6 +53,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
struct nft_bitwise *priv = nft_expr_priv(expr);
struct nft_data_desc d1, d2;
int err;
+   u32 len;
 
if (tb[NFTA_BITWISE_SREG] == NULL ||
tb[NFTA_BITWISE_DREG] == NULL ||
@@ -61,7 +62,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
 
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   if (len > U8_MAX)
+   return -EINVAL;
+   priv->len = len;
+
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index b78c28b..fdd23d5 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -100,6 +100,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
 {
struct nft_byteorder *priv = nft_expr_priv(expr);
int err;
+   u32 len, size;
 
if (tb[NFTA_BYTEORDER_SREG] == NULL ||
tb[NFTA_BYTEORDER_DREG] == NULL ||
@@ -117,7 +118,10 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL;
}
 
-   priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
+   if (size > U8_MAX)
+   return -EINVAL;
+   priv->size = size;
switch (priv->size) {
case 2:
case 4:
@@ -128,7 +132,12 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
}
 
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+
+   len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+   if (len > U8_MAX)
+   return -EINVAL;
+   priv->len = len;
+
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
return err;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e25b35d..ca247e5 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -84,8 +84,11 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
if (err < 0)
return err;
 
-   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (desc.len > U8_MAX)
+   return -EINVAL;
priv->len = desc.len;
+   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+
return 0;
 }
 
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index db3b746..6de590c 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -53,6 +53,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
+
+   if (desc.len > U8_MAX)
+   return -EINVAL;
priv->dlen = desc.len;
 
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index ee2d717..74f8293 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -148,6 +148,8 @@ static int nft_nat_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
if (family != ctx->afi->family)
return -EOPNOTSUPP;
+   if (family > U8_MAX)
+   return -EINVAL;
 
switch (family) {
case NFPROTO_IPV4:
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5] netfilter: nf_tables: add hash expression

2016-08-11 Thread Laura Garcia Liebana
This patch adds a new hash expression, this provides jhash support but
this can be extended to support for other hash functions.

The modulus and seed already comes embedded into this new expression.

Use case example:
meta mark set hash ip saddr mod 10

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V2:
- Define len as u8 instead of u32
- Improved module description
- Remove unnecessary includes
Changes in V3:
- Add null checks in init()
- Include registers load validation
Changes in V4:
- Use ERANGE in some cases according to the lib/nlattr.c policy
- Typo fixed
- Use nft_validate_register_load instead of nft_validate_register_store
Changes in V5:
- Use nft_validate_register_store for dreg in init()

 include/uapi/linux/netfilter/nf_tables.h |  20 +
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_hash.c | 137 +++
 4 files changed, 164 insertions(+)
 create mode 100644 net/netfilter/nft_hash.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 533507b..13d25b9 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -724,6 +724,26 @@ enum nft_meta_keys {
 };
 
 /**
+ * enum nft_hash_attributes - nf_tables hash expression netlink attributes
+ *
+ * @NFTA_HASH_SREG: source register (NLA_U32)
+ * @NFTA_HASH_DREG: destination register (NLA_U32)
+ * @NFTA_HASH_LEN: source data length (NLA_U32)
+ * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
+ * @NFTA_HASH_SEED: seed value (NLA_U32)
+ */
+enum nft_hash_attributes {
+   NFTA_HASH_UNSPEC,
+   NFTA_HASH_SREG,
+   NFTA_HASH_DREG,
+   NFTA_HASH_LEN,
+   NFTA_HASH_MODULUS,
+   NFTA_HASH_SEED,
+   __NFTA_HASH_MAX,
+};
+#define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
+
+/**
  * enum nft_meta_attributes - nf_tables meta expression netlink attributes
  *
  * @NFTA_META_DREG: destination register (NLA_U32)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a2e4cf6..1074700 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -569,6 +569,12 @@ config NFT_COMPAT
  x_tables match/target extensions over the nf_tables
  framework.
 
+config NFT_HASH
+   tristate "Netfilter nf_tables hash module"
+   help
+ This option adds the "hash" expression that you can use to perform
+ a hash operation on registers.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 441a3c0..faa277e 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
 obj-$(CONFIG_NFT_LOG)  += nft_log.o
 obj-$(CONFIG_NFT_MASQ) += nft_masq.o
 obj-$(CONFIG_NFT_REDIR)+= nft_redir.o
+obj-$(CONFIG_NFT_HASH) += nft_hash.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
new file mode 100644
index 000..d15b686
--- /dev/null
+++ b/net/netfilter/nft_hash.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct nft_hash {
+   enum nft_registers  sreg:8;
+   enum nft_registers  dreg:8;
+   u8  len;
+   u32 modulus;
+   u32 seed;
+};
+
+static void nft_hash_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   const void *data = >data[priv->sreg];
+   u32 h;
+
+   h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
+
+   regs->data[priv->dreg] = h;
+}
+
+const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
+   [NFTA_HASH_SREG]= { .type = NLA_U32 },
+   [NFTA_HASH_DREG]= { .type = NLA_U32 },
+   [NFTA_HASH_LEN] = { .type = NLA_U32 },
+   [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
+   [NFTA_HASH_SEED]= { .type = NLA_U32 },
+};
+
+static int nft_hash_init(const struct nft_ctx *ctx,
+const struct nft_expr *expr,
+const struct nlattr * const tb[])
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   u32 len;
+
+   if (!tb[NFTA_HASH_SREG] ||
+  

[PATCH v4] netfilter: nf_tables: add hash expression

2016-08-11 Thread Laura Garcia Liebana
This patch adds a new hash expression, this provides jhash support but
this can be extended to support for other hash functions.

The modulus and seed already comes embedded into this new expression.

Use case example:
meta mark set hash ip saddr mod 10

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V4:
- Use ERANGE in some cases according to the lib/nlattr.c policy
- Typo fixed
- Use nft_validate_register_load instead of nft_validate_register_store

 include/uapi/linux/netfilter/nf_tables.h |  20 +
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_hash.c | 136 +++
 4 files changed, 163 insertions(+)
 create mode 100644 net/netfilter/nft_hash.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 0e7928e..1399946 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -724,6 +724,26 @@ enum nft_meta_keys {
 };
 
 /**
+ * enum nft_hash_attributes - nf_tables hash expression netlink attributes
+ *
+ * @NFTA_HASH_SREG: source register (NLA_U32)
+ * @NFTA_HASH_DREG: destination register (NLA_U32)
+ * @NFTA_HASH_LEN: source data length (NLA_U32)
+ * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
+ * @NFTA_HASH_SEED: seed value (NLA_U32)
+ */
+enum nft_hash_attributes {
+   NFTA_HASH_UNSPEC,
+   NFTA_HASH_SREG,
+   NFTA_HASH_DREG,
+   NFTA_HASH_LEN,
+   NFTA_HASH_MODULUS,
+   NFTA_HASH_SEED,
+   __NFTA_HASH_MAX,
+};
+#define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
+
+/**
  * enum nft_meta_attributes - nf_tables meta expression netlink attributes
  *
  * @NFTA_META_DREG: destination register (NLA_U32)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a2e4cf6..1074700 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -569,6 +569,12 @@ config NFT_COMPAT
  x_tables match/target extensions over the nf_tables
  framework.
 
+config NFT_HASH
+   tristate "Netfilter nf_tables hash module"
+   help
+ This option adds the "hash" expression that you can use to perform
+ a hash operation on registers.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 441a3c0..faa277e 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
 obj-$(CONFIG_NFT_LOG)  += nft_log.o
 obj-$(CONFIG_NFT_MASQ) += nft_masq.o
 obj-$(CONFIG_NFT_REDIR)+= nft_redir.o
+obj-$(CONFIG_NFT_HASH) += nft_hash.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
new file mode 100644
index 000..eb05527
--- /dev/null
+++ b/net/netfilter/nft_hash.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct nft_hash {
+   enum nft_registers  sreg:8;
+   enum nft_registers  dreg:8;
+   u8  len;
+   u32 modulus;
+   u32 seed;
+};
+
+static void nft_hash_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   const void *data = >data[priv->sreg];
+   u32 h;
+
+   h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
+
+   regs->data[priv->dreg] = h;
+}
+
+const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
+   [NFTA_HASH_SREG]= { .type = NLA_U32 },
+   [NFTA_HASH_DREG]= { .type = NLA_U32 },
+   [NFTA_HASH_LEN] = { .type = NLA_U32 },
+   [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
+   [NFTA_HASH_SEED]= { .type = NLA_U32 },
+};
+
+static int nft_hash_init(const struct nft_ctx *ctx,
+const struct nft_expr *expr,
+const struct nlattr * const tb[])
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   u32 len;
+
+   if (!tb[NFTA_HASH_SREG] ||
+   !tb[NFTA_HASH_DREG] ||
+   !tb[NFTA_HASH_LEN]  ||
+   !tb[NFTA_HASH_SEED] ||
+   !tb[NFTA_HASH_MODULUS])
+   return -EINVAL;
+
+   priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   le

[PATCH 3/5] netfilter: nf_tables: Check u32 load in u8 nft_cmp attribute

2016-08-10 Thread Laura Garcia Liebana
Fix the direct assignment from u32 data input into the len attribute
with a size of u8.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_cmp.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e25b35d..ca247e5 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -84,8 +84,11 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
if (err < 0)
return err;
 
-   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+   if (desc.len > U8_MAX)
+   return -EINVAL;
priv->len = desc.len;
+   priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
+
return 0;
 }
 
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] netfilter: nf_tables: Check u32 load in u8 nft_nat attribute

2016-08-10 Thread Laura Garcia Liebana
Fix the direct assignment from u32 data input into the family
attribute with a size of u8.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_nat.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index ee2d717..74f8293 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -148,6 +148,8 @@ static int nft_nat_init(const struct nft_ctx *ctx, const 
struct nft_expr *expr,
family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
if (family != ctx->afi->family)
return -EOPNOTSUPP;
+   if (family > U8_MAX)
+   return -EINVAL;
 
switch (family) {
case NFPROTO_IPV4:
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] netfilter: nf_tables: Check u32 load in u8 nft_immediate attribute

2016-08-10 Thread Laura Garcia Liebana
Fix the direct assignment from u32 data input into the dlen attribute
with a size of u8.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_immediate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index db3b746..6de590c 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -53,6 +53,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
tb[NFTA_IMMEDIATE_DATA]);
if (err < 0)
return err;
+
+   if (desc.len > U8_MAX)
+   return -EINVAL;
priv->dlen = desc.len;
 
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] netfilter: nf_tables: Check u32 load in u8 nft_bitwise attribute

2016-08-10 Thread Laura Garcia Liebana
Fix the direct assignment from u32 data input into the len attribute
with a size of u8.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_bitwise.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index d71cc18..2c49f69 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -53,6 +53,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
struct nft_bitwise *priv = nft_expr_priv(expr);
struct nft_data_desc d1, d2;
int err;
+   u32 len;
 
if (tb[NFTA_BITWISE_SREG] == NULL ||
tb[NFTA_BITWISE_DREG] == NULL ||
@@ -61,7 +62,11 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
tb[NFTA_BITWISE_XOR] == NULL)
return -EINVAL;
 
-   priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
+   if (len > U8_MAX)
+   return -EINVAL;
+   priv->len = len;
+
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
err = nft_validate_register_load(priv->sreg, priv->len);
if (err < 0)
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] netfilter: nf_tables: add hash expression

2016-08-10 Thread Laura Garcia
On Wed, Aug 10, 2016 at 10:38:08AM +0800, Liping Zhang wrote:
> Hi Laura,
> 
> 2016-08-10 2:22 GMT+08:00 Laura Garcia Liebana <nev...@gmail.com>:
> > This patch adds a new hash expression, this provides jhash support but
> > this can be extended to support for other hash functions.
> >
> > The modulus and seed already comes embedded into this new expression.
> >
> > Use case example:
> > meta mark set hash ip saddr mod 10
> >
> > +static int nft_hash_init(const struct nft_ctx *ctx,
> > +const struct nft_expr *expr,
> > +const struct nlattr * const tb[])
> > +{
> > +   struct nft_hash *priv = nft_expr_priv(expr);
> > +   u32 len;
> > +
> > +   if (!tb[NFTA_HASH_SREG] ||
> > +   !tb[NFTA_HASH_DREG] ||
> > +   !tb[NFTA_HASH_LEN])
> > +   return -EINVAL;
> 
> I think tb[NFTA_HASH_MODULUS] and tb[NFTA_HASH_SEED] should also be
> checked is NULL or not? :)
> 

tb[NFTA_HASH_MODULUS] is not optional now so we can check it here, but
tb[NFTA_HASH_SEED] is optional so we can check and if it's null, then
assign 0 to the seed value.

> > +
> > +   priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
> > +   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
> 
> Should we use nft_validate_register_load and
> nft_validate_register_store here to check the validity ?
> 

Yes, I'll include that.

Thank you Liping.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] Check u32 load in u8 attributes

2016-08-10 Thread Laura Garcia Liebana
The following patchset adds a check during the load of an u32 value
into an u8 attribute which can cause an overflow.


Laura Garcia Liebana (5):
  netfilter: nf_tables: Check u32 load in u8 nft_bitwise attribute
  netfilter: nf_tables: Check u32 load in u8 nft_byteorder attribute
  netfilter: nf_tables: Check u32 load in u8 nft_cmp attribute
  netfilter: nf_tables: Check u32 load in u8 nft_immediate attribute
  netfilter: nf_tables: Check u32 load in u8 nft_nat attribute

 net/netfilter/nft_bitwise.c   |  7 ++-
 net/netfilter/nft_byteorder.c | 13 +++--
 net/netfilter/nft_cmp.c   |  5 -
 net/netfilter/nft_immediate.c |  3 +++
 net/netfilter/nft_nat.c   |  2 ++
 5 files changed, 26 insertions(+), 4 deletions(-)

-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] netfilter: nf_tables: Add size check on u8 nft_exthdr attributes

2016-08-09 Thread Laura Garcia Liebana
Fix the direct assignment of offset and length attributes included in
nft_exthdr structure from u32 data to u8.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 net/netfilter/nft_exthdr.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index ba7aed1..dec3c36 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -59,6 +59,7 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
   const struct nlattr * const tb[])
 {
struct nft_exthdr *priv = nft_expr_priv(expr);
+   u32 offset, len;
 
if (tb[NFTA_EXTHDR_DREG] == NULL ||
tb[NFTA_EXTHDR_TYPE] == NULL ||
@@ -67,8 +68,16 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
return -EINVAL;
 
priv->type   = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
-   priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
-   priv->len= ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
+
+   offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
+   len= ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
+
+   if (offset > U8_MAX || len > U8_MAX)
+   return -EINVAL;
+
+   priv->offset = offset;
+   priv->len = len;
+
priv->dreg   = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
 
return nft_validate_register_store(ctx, priv->dreg, NULL,
-- 
2.8.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] netfilter: nf_tables: add hash expression

2016-08-09 Thread Laura Garcia Liebana
This patch adds a new hash expression, this provides jhash support but
this can be extended to support for other hash functions.

The modulus and seed already comes embedded into this new expression.

Use case example:
meta mark set hash ip saddr mod 10

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in V2:
- Define len as u8 instead of u32
- Improved module description
- Remove unnecessary includes

 include/uapi/linux/netfilter/nf_tables.h |  20 +
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_hash.c | 133 +++
 4 files changed, 160 insertions(+)
 create mode 100644 net/netfilter/nft_hash.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 0e7928e..1399946 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -724,6 +724,26 @@ enum nft_meta_keys {
 };
 
 /**
+ * enum nft_hash_attributes - nf_tables hash expression netlink attributes
+ *
+ * @NFTA_HASH_SREG: source register (NLA_U32)
+ * @NFTA_HASH_DREG: destination register (NLA_U32)
+ * @NFTA_HASH_LEN: source data length (NLA_U32)
+ * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
+ * @NFTA_HASH_SEED: seed value (NLA_U32)
+ */
+enum nft_hash_attributes {
+   NFTA_HASH_UNSPEC,
+   NFTA_HASH_SREG,
+   NFTA_HASH_DREG,
+   NFTA_HASH_LEN,
+   NFTA_HASH_MODULUS,
+   NFTA_HASH_SEED,
+   __NFTA_HASH_MAX,
+};
+#define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
+
+/**
  * enum nft_meta_attributes - nf_tables meta expression netlink attributes
  *
  * @NFTA_META_DREG: destination register (NLA_U32)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a2e4cf6..1074700 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -569,6 +569,12 @@ config NFT_COMPAT
  x_tables match/target extensions over the nf_tables
  framework.
 
+config NFT_HASH
+   tristate "Netfilter nf_tables hash module"
+   help
+ This option adds the "hash" expression that you can use to perform
+ a hash operation on registers.
+
 if NF_TABLES_NETDEV
 
 config NF_DUP_NETDEV
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 441a3c0..faa277e 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
 obj-$(CONFIG_NFT_LOG)  += nft_log.o
 obj-$(CONFIG_NFT_MASQ) += nft_masq.o
 obj-$(CONFIG_NFT_REDIR)+= nft_redir.o
+obj-$(CONFIG_NFT_HASH) += nft_hash.o
 
 # nf_tables netdev
 obj-$(CONFIG_NFT_DUP_NETDEV)   += nft_dup_netdev.o
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
new file mode 100644
index 000..c3e8263
--- /dev/null
+++ b/net/netfilter/nft_hash.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+
+struct nft_hash {
+   enum nft_registers  sreg:8;
+   enum nft_registers  dreg:8;
+   u8  len;
+   u32 modulus;
+   u32 seed;
+};
+
+static void nft_hash_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   const void *data = >data[priv->sreg];
+   u32 h;
+
+   h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
+
+   regs->data[priv->dreg] = h;
+}
+
+const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
+   [NFTA_HASH_SREG]= { .type = NLA_U32 },
+   [NFTA_HASH_DREG]= { .type = NLA_U32 },
+   [NFTA_HASH_LEN] = { .type = NLA_U32 },
+   [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
+   [NFTA_HASH_SEED]= { .type = NLA_U32 },
+};
+
+static int nft_hash_init(const struct nft_ctx *ctx,
+const struct nft_expr *expr,
+const struct nlattr * const tb[])
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   u32 len;
+
+   if (!tb[NFTA_HASH_SREG] ||
+   !tb[NFTA_HASH_DREG] ||
+   !tb[NFTA_HASH_LEN])
+   return -EINVAL;
+
+   priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   len = ntohl(nla_get_be32(tb[NFTA_HASH_LEN]));
+   if (len == 0 || len > U8_MAX)
+   return -EINVAL;
+
+   pr

Re: [PATCH v2] netfilter: nft_nth: match every n packets

2016-08-09 Thread Laura Garcia
On Tue, Aug 09, 2016 at 12:52:53PM +0200, Pablo Neira Ayuso wrote:
> On Thu, Jul 28, 2016 at 11:20:59AM +0200, Florian Westphal wrote:
> > Laura Garcia <nev...@gmail.com> wrote:
> > > On Thu, Jul 28, 2016 at 01:01:05AM +0200, Florian Westphal wrote:
> > > > How exactly is this used by nftables?
> > > > 
> > > > AFAIU usespace will check if ->dreg is 0 or not, but does that make
> > > > sense?
> > > > 
> > > > Seems to me it would be more straightforward to not use a dreg at all
> > > > and just NFT_BREAK if nval != 0?
> > > > 
> > > 
> > > The main idea is to provide a round robin like scheduling method, for
> > > example:
> > > 
> > > ip daddr  dnat nth 3 map {
> > > 0: ,
> > > 1: ,
> > > 2: 
> > > }
> > > 
> > 
> > That makes sense, would be nice to place a small blurb in the commit
> > message.
> 
> I'd suggest you rename this to nft_numgen.c where numgen stands for
> 'number generator', then rename 'every' to 'until' (this sets the
> upper limit in the generator) and add support for random too, so we
> provide incremental and random number generators to start with and we
> leave room to extend this with more number generators in the future if
> needed.
> 
> Florian added random to meta, but I don't see an easy way to reuse
> this with maps unless we introduce another modulus/scale expression,
> and we should skip oversplitting expressions in way too basic
> operations.

So, do you mean something like this?

ip daddr  dnat numgen nth 3 map {
0: ,
1: ,
2: 
}

and

ip daddr  dnat numgen random 3 map {
0: ,
1: ,
2: 
}

Maybe _math_ could be a better name?
The counter expression could be included as well.

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH libnftnl] expr: hash: Jenkins hash expression support

2016-08-09 Thread Laura Garcia Liebana
Support for the nft hash expression within libnftnl.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/buffer.h|   2 +
 include/libnftnl/expr.h |  16 ++
 include/linux/netfilter/nf_tables.h |  20 +++
 src/Makefile.am |   1 +
 src/expr/hash.c | 295 
 src/expr_ops.c  |   2 +
 6 files changed, 336 insertions(+)
 create mode 100644 src/expr/hash.c

diff --git a/include/buffer.h b/include/buffer.h
index 36f0ee3..c76bd4d 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -90,5 +90,7 @@ int nftnl_buf_reg(struct nftnl_buf *b, int type, union 
nftnl_data_reg *reg,
 #define REPLACE"replace"
 #define FLUSH  "flush"
 #define EVERY  "every"
+#define MODULUS"modulus"
+#define SEED   "seed"
 
 #endif
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 6aa7756..811c254 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -54,6 +54,14 @@ enum {
 };
 
 enum {
+   NFTNL_EXPR_HASH_SREG= NFTNL_EXPR_BASE,
+   NFTNL_EXPR_HASH_DREG,
+   NFTNL_EXPR_HASH_LEN,
+   NFTNL_EXPR_HASH_MODULUS,
+   NFTNL_EXPR_HASH_SEED,
+};
+
+enum {
NFTNL_EXPR_META_KEY = NFTNL_EXPR_BASE,
NFTNL_EXPR_META_DREG,
NFTNL_EXPR_META_SREG,
@@ -245,6 +253,14 @@ enum {
 };
 
 enum {
+   NFT_EXPR_HASH_SREG  = NFT_RULE_EXPR_ATTR_BASE,
+   NFT_EXPR_HASH_DREG,
+   NFT_EXPR_HASH_LEN,
+   NFT_EXPR_HASH_MODULUS,
+   NFT_EXPR_HASH_SEED,
+};
+
+enum {
NFT_EXPR_META_KEY   = NFT_RULE_EXPR_ATTR_BASE,
NFT_EXPR_META_DREG,
NFT_EXPR_META_SREG,
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 6fe5fc8..7b574c7 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -681,6 +681,26 @@ enum nft_nth_attributes {
 #define NFTA_NTH_MAX   (__NFTA_NTH_MAX - 1)
 
 /**
+ * enum nft_hash_attributes - nf_tables hash expression attributes
+ *
+ * @NFTA_HASH_SREG: source register (NLA_U32)
+ * @NFTA_HASH_DREG: destination register (NLA_U32)
+ * @NFTA_HASH_LEN: data length (NLA_U32)
+ * @NFTA_HASH_MODULUS: Modulus value (NLA_U32)
+ * @NFTA_HASH_SEED: hash initial value (NLA_U32)
+ */
+enum nft_hash_attributes {
+   NFTA_HASH_UNSPEC,
+   NFTA_HASH_SREG,
+   NFTA_HASH_DREG,
+   NFTA_HASH_LEN,
+   NFTA_HASH_MODULUS,
+   NFTA_HASH_SEED,
+   __NFTA_HASH_MAX
+};
+#define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
+
+/**
  * enum nft_meta_keys - nf_tables meta expression keys
  *
  * @NFT_META_LEN: packet length (skb->len)
diff --git a/src/Makefile.am b/src/Makefile.am
index 69b61ef..a01970d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,6 +39,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/match.c  \
  expr/meta.c   \
  expr/nth.c\
+ expr/hash.c   \
  expr/nat.c\
  expr/payload.c\
  expr/queue.c  \
diff --git a/src/expr/hash.c b/src/expr/hash.c
new file mode 100644
index 000..1383b07
--- /dev/null
+++ b/src/expr/hash.c
@@ -0,0 +1,295 @@
+/*
+ * (C) 2016 by Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+
+struct nftnl_expr_hash {
+   enum nft_registers  sreg;
+   enum nft_registers  dreg;
+   unsigned intlen;
+   unsigned intmodulus;
+   unsigned intseed;
+};
+
+static int
+nftnl_expr_hash_set(struct nftnl_expr *e, uint16_t type,
+   const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_hash *hash = nftnl_expr_data(e);
+
+   switch (type) {
+   case NFTNL_EXPR_HASH_SREG:
+   hash->sreg = *((uint32_t *)data);
+   break;
+   case NFTNL_EXPR_HASH_DREG:
+   hash->dreg = *((uint32_t *)data);
+   break;
+   case NFTNL_EXPR_HASH_LEN:
+   hash->len = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_HASH_MODULUS:
+   hash->modulus = *((unsigned int *)data);
+   break;
+   case NFTNL_EXPR_HASH_SEED:
+   hash->seed = *((unsigned int *)data);
+   break;
+   default:
+   return -1;
+   }
+   return 0

[PATCH] netfilter: nft_hash: generate Jenkins Hash per source register

2016-08-09 Thread Laura Garcia Liebana
This patch adds a new hash expression, this provides jhash support but
this can be extended to support for other hash functions.

The modulus and seed comes already come embedded into this new
expression.

Use case example:
meta mark set hash ip saddr mod 10

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  20 +
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_hash.c | 134 +++
 4 files changed, 161 insertions(+)
 create mode 100644 net/netfilter/nft_hash.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 0e7928e..5e74c05 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1097,4 +1097,24 @@ enum nft_nth_attributes {
 };
 #define NFTA_NTH_MAX   (__NFTA_NTH_MAX - 1)
 
+/**
+ * enum nft_hash_attributes - nf_tables hash expression netlink attributes
+ * @NFTA_HASH_UNSPEC: unspecified attribute
+ * @NFTA_HASH_SREG: source register (NLA_U32)
+ * @NFTA_HASH_DREG: destination register (NLA_U32)
+ * @NFTA_HASH_LEN: source data length (NLA_U32)
+ * @NFTA_HASH_MODULUS: modulus value (NLA_U32)
+ * @NFTA_HASH_SEED: seed value (NLA_U32)
+ */
+enum nft_hash_attributes {
+   NFTA_HASH_UNSPEC,
+   NFTA_HASH_SREG,
+   NFTA_HASH_DREG,
+   NFTA_HASH_LEN,
+   NFTA_HASH_MODULUS,
+   NFTA_HASH_SEED,
+   __NFTA_HASH_MAX,
+};
+#define NFTA_HASH_MAX  (__NFTA_HASH_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a2e4cf6..f821902 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -480,6 +480,12 @@ config NFT_NTH
  This option adds the "nth" expression that you can use to match a
  packet every a specific given value.
 
+config NFT_HASH
+   tristate "Netfilter nf_tables hash module"
+   help
+ This option adds the "hash" expression that you can use to perform
+ a hash operation on registers.
+
 config NFT_CT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables conntrack module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 441a3c0..fd11c6d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_NFT_COMPAT)  += nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)   += nft_exthdr.o
 obj-$(CONFIG_NFT_META) += nft_meta.o
 obj-$(CONFIG_NFT_NTH)  += nft_nth.o
+obj-$(CONFIG_NFT_HASH) += nft_hash.o
 obj-$(CONFIG_NFT_CT)   += nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)+= nft_limit.o
 obj-$(CONFIG_NFT_NAT)  += nft_nat.o
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
new file mode 100644
index 000..bb124aa
--- /dev/null
+++ b/net/netfilter/nft_hash.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nft_hash {
+   enum nft_registers  sreg:8;
+   enum nft_registers  dreg:8;
+   u32 len:8;
+   u32 modulus;
+   u32 seed;
+};
+
+static void nft_hash_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+   const void *data = >data[priv->sreg];
+   u32 h;
+
+   h = reciprocal_scale(jhash(data, priv->len, priv->seed), priv->modulus);
+
+   regs->data[priv->dreg] = h;
+}
+
+const struct nla_policy nft_hash_policy[NFTA_HASH_MAX + 1] = {
+   [NFTA_HASH_SREG]= { .type = NLA_U32 },
+   [NFTA_HASH_DREG]= { .type = NLA_U32 },
+   [NFTA_HASH_LEN] = { .type = NLA_U32 },
+   [NFTA_HASH_MODULUS] = { .type = NLA_U32 },
+   [NFTA_HASH_SEED]= { .type = NLA_U32 },
+};
+
+static int nft_hash_init(const struct nft_ctx *ctx,
+const struct nft_expr *expr,
+const struct nlattr * const tb[])
+{
+   struct nft_hash *priv = nft_expr_priv(expr);
+
+   if (!tb[NFTA_HASH_SREG] ||
+   !tb[NFTA_HASH_DREG] ||
+   !tb[NFTA_HASH_LEN])
+   return -EINVAL;
+
+   priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
+   priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
+
+   priv->len = ntohl(nla_get_be32(tb[NFTA_HASH_LEN]));
+   i

[PATCH v2] netfilter: nft_nth: match every n packets

2016-07-27 Thread Laura Garcia Liebana
Add support for the nth expression in netfilter.

A nft_nth structure is created with dreg (to store the result into a
given register), every (to store the input value that indicates when the
counter is going to be reset) and the counter (to store atomically the
current counter value).

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  15 
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_nth.c  | 123 +++
 4 files changed, 145 insertions(+)
 create mode 100644 net/netfilter/nft_nth.c

diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 6a4dbe0..610e037 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1076,4 +1076,19 @@ enum nft_trace_types {
__NFT_TRACETYPE_MAX
 };
 #define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
+
+/**
+ * enum nft_nth_attributes - nf_tables nth expression netlink attributes
+ * @NFTA_NTH_UNSPEC: unspecified attribute
+ * @NFTA_NTH_DREG: destination register (NLA_U32)
+ * @NFTA_NTH_EVERY: source value for every counter reset (NLA_U32)
+ */
+enum nft_nth_attributes {
+   NFTA_NTH_UNSPEC,
+   NFTA_NTH_DREG,
+   NFTA_NTH_EVERY,
+   __NFTA_NTH_MAX
+};
+#define NFTA_NTH_MAX   (__NFTA_NTH_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 95e757c..6f00d01 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,12 @@ config NFT_META
  This option adds the "meta" expression that you can use to match and
  to set packet metainformation such as the packet mark.
 
+config NFT_NTH
+   tristate "Netfilter nf_tables nth module"
+   help
+ This option adds the "nth" expression that you can use to match a
+ packet every a specific given value.
+
 config NFT_CT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables conntrack module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6913454..2378f00 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_NF_TABLES_NETDEV)+= nf_tables_netdev.o
 obj-$(CONFIG_NFT_COMPAT)   += nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)   += nft_exthdr.o
 obj-$(CONFIG_NFT_META) += nft_meta.o
+obj-$(CONFIG_NFT_NTH)  += nft_nth.o
 obj-$(CONFIG_NFT_CT)   += nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)+= nft_limit.o
 obj-$(CONFIG_NFT_NAT)  += nft_nat.o
diff --git a/net/netfilter/nft_nth.c b/net/netfilter/nft_nth.c
new file mode 100644
index 000..525da7a
--- /dev/null
+++ b/net/netfilter/nft_nth.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct nft_nth {
+   enum nft_registers  dreg:8;
+   u32 every;
+   atomic_tcounter;
+};
+
+static void nft_nth_eval(const struct nft_expr *expr,
+struct nft_regs *regs,
+const struct nft_pktinfo *pkt)
+{
+   struct nft_nth *nth = nft_expr_priv(expr);
+   u32 nval, oval;
+
+   do {
+   oval = atomic_read(>counter);
+   nval = (oval+1 < nth->every) ? oval+1 : 0;
+   } while (atomic_cmpxchg(>counter, oval, nval) != oval);
+
+   memcpy(>data[nth->dreg], >counter, sizeof(u32));
+}
+
+const struct nla_policy nft_nth_policy[NFTA_NTH_MAX + 1] = {
+   [NFTA_NTH_DREG] = { .type = NLA_U32 },
+   [NFTA_NTH_EVERY]= { .type = NLA_U32 },
+};
+
+static int nft_nth_init(const struct nft_ctx *ctx,
+   const struct nft_expr *expr,
+   const struct nlattr * const tb[])
+{
+   struct nft_nth *nth = nft_expr_priv(expr);
+
+   nth->every = ntohl(nla_get_be32(tb[NFTA_NTH_EVERY]));
+   if (nth->every == 0)
+   return -EINVAL;
+
+   nth->dreg = nft_parse_register(tb[NFTA_NTH_DREG]);
+   atomic_set(>counter, 0);
+
+   return 0;
+}
+
+static int nft_nth_dump(struct sk_buff *skb,
+   const struct nft_expr *expr)
+{
+   const struct nft_nth *nth = nft_expr_priv(expr);
+
+   if (nft_dump_register(skb, NFTA_NTH_DREG, nth->dreg))
+   goto nla_put_failure;
+   if (nft_dump_register(skb, NFTA_NTH_EVERY, nth->every))
+   goto nla_put_failure;
+
+   return 0;
+
+nla_pu

[PATCH libnftnl] expr: nth: match every n packets

2016-07-26 Thread Laura Garcia Liebana
Support for the nft nth expression within libnftnl.

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/libnftnl/expr.h |  10 ++
 include/linux/netfilter/nf_tables.h |  14 +++
 src/Makefile.am |   1 +
 src/expr/nth.c  | 239 
 src/expr_ops.c  |   2 +
 5 files changed, 266 insertions(+)
 create mode 100644 src/expr/nth.c

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 17f60bd..6d245cd 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -49,6 +49,11 @@ enum {
 };
 
 enum {
+   NFTNL_EXPR_NTH_DREG = NFTNL_EXPR_BASE,
+   NFTNL_EXPR_NTH_DATA,
+};
+
+enum {
NFTNL_EXPR_META_KEY = NFTNL_EXPR_BASE,
NFTNL_EXPR_META_DREG,
NFTNL_EXPR_META_SREG,
@@ -235,6 +240,11 @@ enum {
 };
 
 enum {
+   NFT_EXPR_NTH_DREG   = NFT_RULE_EXPR_ATTR_BASE,
+   NFT_EXPR_NTH_DATA,
+};
+
+enum {
NFT_EXPR_META_KEY   = NFT_RULE_EXPR_ATTR_BASE,
NFT_EXPR_META_DREG,
NFT_EXPR_META_SREG,
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 01751fa..f90ef48 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -667,6 +667,20 @@ enum nft_exthdr_attributes {
 #define NFTA_EXTHDR_MAX(__NFTA_EXTHDR_MAX - 1)
 
 /**
+ * enum nft_nth_attributes - nf_tables nth expression attributes
+ *
+ * @NFTA_NTH_DREG: destination register (NLA_U32)
+ * @NFTA_NTH_DATA: data input (NLA_NESTED)
+ */
+enum nft_nth_attributes {
+   NFTA_NTH_UNSPEC,
+   NFTA_NTH_DREG,
+   NFTA_NTH_DATA,
+   __NFTA_NTH_MAX
+};
+#define NFTA_NTH_MAX   (__NFTA_NTH_MAX - 1)
+
+/**
  * enum nft_meta_keys - nf_tables meta expression keys
  *
  * @NFT_META_LEN: packet length (skb->len)
diff --git a/src/Makefile.am b/src/Makefile.am
index 7e580e4..69b61ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@ libnftnl_la_SOURCES = utils.c \
  expr/immediate.c  \
  expr/match.c  \
  expr/meta.c   \
+ expr/nth.c\
  expr/nat.c\
  expr/payload.c\
  expr/queue.c  \
diff --git a/src/expr/nth.c b/src/expr/nth.c
new file mode 100644
index 000..4da2968
--- /dev/null
+++ b/src/expr/nth.c
@@ -0,0 +1,239 @@
+/*
+ * (C) 2016 by Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include 
+#include 
+#include 
+
+
+struct nftnl_expr_nth {
+   enum nft_registers  dreg;
+   union nftnl_data_regdata;
+};
+
+static int
+nftnl_expr_nth_set(struct nftnl_expr *e, uint16_t type,
+  const void *data, uint32_t data_len)
+{
+   struct nftnl_expr_nth *nth = nftnl_expr_data(e);
+
+   switch (type) {
+   case NFTNL_EXPR_NTH_DREG:
+   nth->dreg = *((uint32_t *)data);
+   break;
+   case NFTNL_EXPR_NTH_DATA:
+   memcpy(>data.val, data, data_len);
+   nth->data.len = data_len;
+   break;
+   default:
+   return -1;
+   }
+   return 0;
+}
+
+static const void *
+nftnl_expr_nth_get(const struct nftnl_expr *e, uint16_t type,
+  uint32_t *data_len)
+{
+   struct nftnl_expr_nth *nth = nftnl_expr_data(e);
+
+   switch (type) {
+   case NFTNL_EXPR_NTH_DREG:
+   *data_len = sizeof(nth->dreg);
+   return >dreg;
+   case NFTNL_EXPR_NTH_DATA:
+   *data_len = nth->data.len;
+   return >data.val;
+   }
+   return NULL;
+}
+
+static int nftnl_expr_nth_cb(const struct nlattr *attr, void *data)
+{
+   const struct nlattr **tb = data;
+   int type = mnl_attr_get_type(attr);
+
+   if (mnl_attr_type_valid(attr, NFTA_NTH_MAX) < 0)
+   return MNL_CB_OK;
+
+   switch (type) {
+   case NFTA_NTH_DREG:
+   if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+   abi_breakage();
+   break;
+   case NFTA_NTH_DATA:
+   if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+   abi_breakage();
+   break;
+   }
+
+   tb[type] = attr;
+   return MNL_CB_OK;
+}
+
+static void
+nftnl_expr_nth_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
+{
+   struct nftnl_expr_nth *nth = nftnl_expr_data(e);
+
+   if (e->flags & (1 << NFTNL_EXPR_NTH_DREG))

[PATCH] netfilter: nft_nth: match every n packets

2016-07-26 Thread Laura Garcia Liebana
Add support for the nth expression in netfilter. A nft_nth structure is created 
with dreg (to store the result into a given register), data (a nft_data 
structure to store the input value, it must be > 0), every (to store the data) 
and counter (to store atomically the current value).

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 include/net/netfilter/nft_nth.h  |  31 +++
 include/uapi/linux/netfilter/nf_tables.h |  15 
 net/netfilter/Kconfig|   6 ++
 net/netfilter/Makefile   |   1 +
 net/netfilter/nft_nth.c  | 145 +++
 5 files changed, 198 insertions(+)
 create mode 100644 include/net/netfilter/nft_nth.h
 create mode 100644 net/netfilter/nft_nth.c

diff --git a/include/net/netfilter/nft_nth.h b/include/net/netfilter/nft_nth.h
new file mode 100644
index 000..0d8788d
--- /dev/null
+++ b/include/net/netfilter/nft_nth.h
@@ -0,0 +1,31 @@
+#ifndef _NFT_NTH_H_
+#define _NFT_NTH_H_
+
+struct nft_nth {
+   enum nft_registers  dreg:8;
+   struct nft_data data;
+   u32 every;
+   struct nft_nth_priv *master __attribute__((aligned(8)));
+};
+
+struct nft_nth_priv {
+   atomic_t counter;
+} cacheline_aligned_in_smp;
+
+extern const struct nla_policy nft_nth_policy[];
+
+int nft_nth_init(const struct nft_ctx *ctx,
+const struct nft_expr *expr,
+const struct nlattr * const tb[]);
+
+int nft_nth_dump(struct sk_buff *skb,
+const struct nft_expr *expr);
+
+void nft_nth_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+
+void nft_nth_destroy(const struct nft_ctx *ctx,
+const struct nft_expr *expr);
+
+#endif
diff --git a/include/uapi/linux/netfilter/nf_tables.h 
b/include/uapi/linux/netfilter/nf_tables.h
index 6a4dbe0..5ba075a 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -1076,4 +1076,19 @@ enum nft_trace_types {
__NFT_TRACETYPE_MAX
 };
 #define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
+
+/**
+ * enum nft_nth_attributes - nf_tables nth expression netlink attributes
+ * @NFTA_NTH_UNSPEC: unspecified attribute
+ * @NFTA_NTH_DREG: destination register (NLA_U32)
+ * @NFTA_NTH_DATA: source data (NLA_NESTED)
+ */
+enum nft_nth_attributes {
+   NFTA_NTH_UNSPEC,
+   NFTA_NTH_DREG,
+   NFTA_NTH_DATA,
+   __NFTA_NTH_MAX
+};
+#define NFTA_NTH_MAX   (__NFTA_NTH_MAX - 1)
+
 #endif /* _LINUX_NF_TABLES_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 95e757c..6f00d01 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,12 @@ config NFT_META
  This option adds the "meta" expression that you can use to match and
  to set packet metainformation such as the packet mark.
 
+config NFT_NTH
+   tristate "Netfilter nf_tables nth module"
+   help
+ This option adds the "nth" expression that you can use to match a
+ packet every a specific given value.
+
 config NFT_CT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables conntrack module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 6913454..2378f00 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_NF_TABLES_NETDEV)+= nf_tables_netdev.o
 obj-$(CONFIG_NFT_COMPAT)   += nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)   += nft_exthdr.o
 obj-$(CONFIG_NFT_META) += nft_meta.o
+obj-$(CONFIG_NFT_NTH)  += nft_nth.o
 obj-$(CONFIG_NFT_CT)   += nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)+= nft_limit.o
 obj-$(CONFIG_NFT_NAT)  += nft_nat.o
diff --git a/net/netfilter/nft_nth.c b/net/netfilter/nft_nth.c
new file mode 100644
index 000..d0a5387
--- /dev/null
+++ b/net/netfilter/nft_nth.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016 Laura Garcia <nev...@gmail.com>
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void nft_nth_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+   struct nft_nth *nth = nft_expr_priv(expr);
+   u32 nval, oval;
+
+   do {
+   oval = atomic_read(>master->counter);
+   nval = (oval+1 < nth->every) ? oval+1 : 0;
+   } while (atomic_cmpxchg(>master->counter, oval, nval) != oval);
+
+   memcpy(>data[nth->dreg], >master->counter, sizeof(u32));
+}
+EXPORT_SYMBOL_GPL(nft_nth_eval);
+

Re: [PATCH] extensions: libxt_conntrack: Add translation to nft

2016-06-15 Thread Laura Garcia
On Wed, Jun 15, 2016 at 02:21:27PM +0200, Pablo Neira Ayuso wrote:
> On Tue, Jun 14, 2016 at 08:02:45PM +0200, Laura Garcia Liebana wrote:
> > Add translation of conntrack to nftables.
> > 
> > Examples:
> > 
> > $ sudo iptables-translate -t filter -A INPUT -m conntrack --ctstate 
> > NEW,RELATED -j ACCEPT
> > nft add rule ip filter INPUT ct state { new,related } counter accept
> 
> No need to use a set here, instead:
> 
> nft add rule ip filter INPUT ct state new,related counter accept
> 
> > $ sudo ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate 
> > NEW,RELATED -j ACCEPT
> > nft add rule ip6 filter INPUT ct state != { new,related } counter accept
> 
> Same thing here.
> 
> Thanks.

Ok, this will simplify the code.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] extensions: libxt_cgroup: Add translation to nft

2016-06-15 Thread Laura Garcia
On Tue, Jun 14, 2016 at 06:48:51PM +0200, Pablo Neira Ayuso wrote:
> Please, document on the wikipage that we don't support yet the new
> cgroup2 path-based on nft so we don't forget to discuss about this at
> some point.

Just included in the wiki.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] extensions: libxt_conntrack: Add translation to nft

2016-06-14 Thread Laura Garcia Liebana
Add translation of conntrack to nftables.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW,RELATED 
-j ACCEPT
nft add rule ip filter INPUT ct state { new,related } counter accept

$ sudo ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate 
NEW,RELATED -j ACCEPT
nft add rule ip6 filter INPUT ct state != { new,related } counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctproto UDP -j 
ACCEPT
nft add rule ip filter INPUT ct proto 17 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack ! --ctproto UDP -j 
ACCEPT
nft add rule ip filter INPUT ct proto != 17 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 
10.100.2.131 -j ACCEPT
nft add rule ip filter INPUT ct original saddr 10.100.2.131 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctorigsrc 
10.100.0.0/255.255.0.0 -j ACCEPT
nft add rule ip filter INPUT ct original saddr 10.100.0.0/16 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctorigdst 
10.100.2.131 -j ACCEPT
nft add rule ip filter INPUT ct original daddr 10.100.2.131 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctreplsrc 
10.100.2.131 -j ACCEPT
nft add rule ip filter INPUT ct reply saddr 10.100.2.131 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctrepldst 
10.100.2.131 -j ACCEPT
nft add rule ip filter INPUT ct reply daddr 10.100.2.131 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctproto tcp 
--ctorigsrcport 443:444 -j ACCEPT
nft add rule ip filter INPUT ct original protocol 6 ct original proto-src 
443-444 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack ! --ctstatus 
CONFIRMED -j ACCEPT
nft add rule ip filter INPUT ct status != confirmed counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctexpire 3 -j ACCEPT
nft add rule ip filter INPUT ct expiration 3 counter accept

$ sudo iptables-translate -t filter -A INPUT -m conntrack --ctdir ORIGINAL -j 
ACCEPT
nft add rule ip filter INPUT ct direction original counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 extensions/libxt_conntrack.c | 247 +++
 1 file changed, 247 insertions(+)

diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c
index 310a468..cf6c03d 100644
--- a/extensions/libxt_conntrack.c
+++ b/extensions/libxt_conntrack.c
@@ -1182,6 +1182,28 @@ static void state_xlate_print(struct xt_xlate *xl, 
unsigned int statemask)
}
 }
 
+static int state_xlate_counter(unsigned int statemask)
+{
+   int bcounter = 0;
+
+   if (statemask & XT_CONNTRACK_STATE_INVALID)
+   bcounter++;
+
+   if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_NEW))
+   bcounter++;
+
+   if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_RELATED))
+   bcounter++;
+
+   if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED))
+   bcounter++;
+
+   if (statemask & XT_CONNTRACK_STATE_UNTRACKED)
+   bcounter++;
+
+   return bcounter;
+}
+
 static int state_xlate(const void *ip, const struct xt_entry_match *match,
   struct xt_xlate *xl, int numeric)
 {
@@ -1194,6 +1216,229 @@ static int state_xlate(const void *ip, const struct 
xt_entry_match *match,
return 1;
 }
 
+static void status_xlate_print(struct xt_xlate *xl, unsigned int statusmask)
+{
+   const char *sep = "";
+
+   if (statusmask & IPS_EXPECTED) {
+   xt_xlate_add(xl, "%s%s", sep, "expected");
+   sep = ",";
+   }
+   if (statusmask & IPS_SEEN_REPLY) {
+   xt_xlate_add(xl, "%s%s", sep, "seen-reply");
+   sep = ",";
+   }
+   if (statusmask & IPS_ASSURED) {
+   xt_xlate_add(xl, "%s%s", sep, "assured");
+   sep = ",";
+   }
+   if (statusmask & IPS_CONFIRMED) {
+   xt_xlate_add(xl, "%s%s", sep, "confirmed");
+   sep = ",";
+   }
+}
+
+static int status_xlate_counter(unsigned int statusmask)
+{
+   int bcounter = 0;
+
+   if (statusmask & IPS_EXPECTED)
+   bcounter++;
+
+   if (statusmask & IPS_SEEN_REPLY)
+   bcounter++;
+
+   if (statusmask & IPS_ASSURED)
+   bcounter++;
+
+   if (statusmask & IPS_CONFIRMED)
+   bcounter++;
+
+   return bcounter;
+}
+
+static void addr_xlate_print(struct xt_xlate *xl,
+const union nf_inet_addr *addr,
+const union nf_inet_addr *mask,
+unsigned int family)
+{
+   if (family == NFPROTO_IPV4) {
+   

[PATCH] extensions: libxt_cgroup: Add translation to nft

2016-06-09 Thread Laura Garcia Liebana
Add translation for cgroup to nft. Path parameter not supported in nft
yet.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m cgroup --cgroup 0 -j ACCEPT
nft add rule ip filter INPUT meta cgroup 0 counter accept

$ sudo iptables-translate -t filter -A INPUT -m cgroup ! --cgroup 0 -j ACCEPT
nft add rule ip filter INPUT meta cgroup != 0 counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 extensions/libxt_cgroup.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/extensions/libxt_cgroup.c b/extensions/libxt_cgroup.c
index 3be42ad..1191815 100644
--- a/extensions/libxt_cgroup.c
+++ b/extensions/libxt_cgroup.c
@@ -121,6 +121,32 @@ static void cgroup_save_v1(const void *ip, const struct 
xt_entry_match *match)
   info->classid);
 }
 
+static int cgroup_xlate_v0(const void *ip, const struct xt_entry_match *match,
+  struct xt_xlate *xl, int numeric)
+{
+   const struct xt_cgroup_info_v0 *info = (void *)match->data;
+
+   xt_xlate_add(xl, "meta cgroup %s%u ", info->invert ? "!= " : "",
+info->id);
+   return 1;
+}
+
+static int cgroup_xlate_v1(const void *ip, const struct xt_entry_match *match,
+  struct xt_xlate *xl, int numeric)
+{
+   const struct xt_cgroup_info_v1 *info = (void *)match->data;
+
+   if (info->has_path)
+   return 0;
+
+   if (info->has_classid)
+   xt_xlate_add(xl, "meta cgroup %s%u ",
+info->invert_classid ? "!= " : "",
+info->classid);
+
+   return 1;
+}
+
 static struct xtables_match cgroup_match[] = {
{
.family = NFPROTO_UNSPEC,
@@ -134,6 +160,7 @@ static struct xtables_match cgroup_match[] = {
.save   = cgroup_save_v0,
.x6_parse   = cgroup_parse_v0,
.x6_options = cgroup_opts_v0,
+   .xlate  = cgroup_xlate_v0,
},
{
.family = NFPROTO_UNSPEC,
@@ -147,6 +174,7 @@ static struct xtables_match cgroup_match[] = {
.save   = cgroup_save_v1,
.x6_parse   = cgroup_parse_v1,
.x6_options = cgroup_opts_v1,
+   .xlate  = cgroup_xlate_v1,
},
 };
 
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4] extensions: libip6t_frag: Add translation to nft

2016-06-08 Thread Laura Garcia Liebana
Add translation for frag to nftables. According to the --fraglen code:

case O_FRAGLEN:
/*
 * As of Linux 3.0, the kernel does not check for
 * fraglen at all.
 */

In addition, the kernel code doesn't show any reference to the flag
IP6T_FRAG_LEN, so this option is deprecated and won't be translated to
nft.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100 --fragres 
--fragmore -j ACCEPT
nft add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 
counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag ! --fragid 100:200 -j 
ACCEPT
nft add rule ip6 filter INPUT frag id != 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fraglast -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag more-fragments 1 counter 
accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fragfirst -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fraglast -j ACCEPT
nft add rule ip6 filter INPUT frag more-fragments 0 counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Include translation for fragfirst and fraglast.
- fraglen is marked as deprecated.
Changes in v3:
- Ignore completely IP6T_FRAG_LEN.
Changes in v4:
- Traduce fraglast as no more fragments.

 extensions/libip6t_frag.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c
index 023df62..57487c4 100644
--- a/extensions/libip6t_frag.c
+++ b/extensions/libip6t_frag.c
@@ -173,6 +173,37 @@ static void frag_save(const void *ip, const struct 
xt_entry_match *match)
printf(" --fraglast");
 }
 
+static int frag_xlate(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data;
+
+   if (!(fraginfo->ids[0] == 0 && fraginfo->ids[1] == 0x)) {
+   xt_xlate_add(xl, "frag id %s",
+(fraginfo->invflags & IP6T_FRAG_INV_IDS) ?
+"!= " : "");
+   if (fraginfo->ids[0] != fraginfo->ids[1])
+   xt_xlate_add(xl, "%u-%u ", fraginfo->ids[0],
+fraginfo->ids[1]);
+   else
+   xt_xlate_add(xl, "%u ", fraginfo->ids[0]);
+   }
+
+   if (fraginfo->flags & IP6T_FRAG_RES)
+   xt_xlate_add(xl, "frag reserved 1 ");
+
+   if (fraginfo->flags & IP6T_FRAG_FST)
+   xt_xlate_add(xl, "frag frag-off 0 ");
+
+   if (fraginfo->flags & IP6T_FRAG_MF)
+   xt_xlate_add(xl, "frag more-fragments 1 ");
+
+   if (fraginfo->flags & IP6T_FRAG_NMF)
+   xt_xlate_add(xl, "frag more-fragments 0 ");
+
+   return 1;
+}
+
 static struct xtables_match frag_mt6_reg = {
.name  = "frag",
.version   = XTABLES_VERSION,
@@ -185,6 +216,7 @@ static struct xtables_match frag_mt6_reg = {
.save  = frag_save,
.x6_parse  = frag_parse,
.x6_options= frag_opts,
+   .xlate = frag_xlate,
 };
 
 void
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3] extensions: libip6t_frag: Add translation to nft

2016-06-07 Thread Laura Garcia Liebana
Add translation for frag to nftables. According to the --fraglen code:

case O_FRAGLEN:
/*
 * As of Linux 3.0, the kernel does not check for
 * fraglen at all.
 */

In addition, the kernel code doesn't show any reference to the flag
IP6T_FRAG_LEN, so this option is deprecated and won't be translated to
nft.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100 --fragres 
--fragmore -j ACCEPT
nft add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 
counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag ! --fragid 100:200 -j 
ACCEPT
nft add rule ip6 filter INPUT frag id != 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fraglast -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag more-fragments 1 counter 
accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fragfirst -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Include translation for fragfirst and fraglast.
- fraglen is marked as deprecated.
Changes in v3:
- Ignore completely IP6T_FRAG_LEN.

 extensions/libip6t_frag.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c
index 023df62..7871fb9 100644
--- a/extensions/libip6t_frag.c
+++ b/extensions/libip6t_frag.c
@@ -173,6 +173,35 @@ static void frag_save(const void *ip, const struct 
xt_entry_match *match)
printf(" --fraglast");
 }
 
+static int frag_xlate(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data;
+
+   if (!(fraginfo->ids[0] == 0 && fraginfo->ids[1] == 0x)) {
+   xt_xlate_add(xl, "frag id %s",
+(fraginfo->invflags & IP6T_FRAG_INV_IDS) ?
+"!= " : "");
+   if (fraginfo->ids[0] != fraginfo->ids[1])
+   xt_xlate_add(xl, "%u-%u ", fraginfo->ids[0],
+fraginfo->ids[1]);
+   else
+   xt_xlate_add(xl, "%u ", fraginfo->ids[0]);
+   }
+
+   if (fraginfo->flags & IP6T_FRAG_RES)
+   xt_xlate_add(xl, "frag reserved 1 ");
+
+   if (fraginfo->flags & IP6T_FRAG_FST)
+   xt_xlate_add(xl, "frag frag-off 0 ");
+
+   if ((fraginfo->flags & IP6T_FRAG_MF) ||
+   (fraginfo->flags & IP6T_FRAG_NMF))
+   xt_xlate_add(xl, "frag more-fragments 1 ");
+
+   return 1;
+}
+
 static struct xtables_match frag_mt6_reg = {
.name  = "frag",
.version   = XTABLES_VERSION,
@@ -185,6 +214,7 @@ static struct xtables_match frag_mt6_reg = {
.save  = frag_save,
.x6_parse  = frag_parse,
.x6_options= frag_opts,
+   .xlate = frag_xlate,
 };
 
 void
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv2] extensions: libip6t_frag: Add translation to nft

2016-06-06 Thread Laura Garcia Liebana
Add translation for frag to nftables. According to the --fraglen code:

case O_FRAGLEN:
/*
 * As of Linux 3.0, the kernel does not check for
 * fraglen at all.
 */

In addition, the kernel code doesn't show any reference to the flag
IP6T_FRAG_LEN, so this option is deprecated and won't be translated to
nft.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100 --fragres 
--fragmore -j ACCEPT
nft add rule ip6 filter INPUT frag id 100 frag reserved 1 frag more-fragments 1 
counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag ! --fragid 100:200 -j 
ACCEPT
nft add rule ip6 filter INPUT frag id != 100-200 counter accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fraglast -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag more-fragments 1 counter 
accept

$ sudo iptables-translate -t filter -A INPUT -m frag --fragid 100:200 
--fragfirst -j ACCEPT
nft add rule ip6 filter INPUT frag id 100-200 frag frag-off 0 counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
Changes in v2:
- Include translation for fragfirst and fraglast.
- fraglen is marked as deprecated.

 extensions/libip6t_frag.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/extensions/libip6t_frag.c b/extensions/libip6t_frag.c
index 023df62..0a24eae 100644
--- a/extensions/libip6t_frag.c
+++ b/extensions/libip6t_frag.c
@@ -173,6 +173,38 @@ static void frag_save(const void *ip, const struct 
xt_entry_match *match)
printf(" --fraglast");
 }
 
+static int frag_xlate(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   const struct ip6t_frag *fraginfo = (struct ip6t_frag *)match->data;
+
+   if (fraginfo->flags & IP6T_FRAG_LEN)
+   return 0;
+
+   if (!(fraginfo->ids[0] == 0 && fraginfo->ids[1] == 0x)) {
+   xt_xlate_add(xl, "frag id %s",
+(fraginfo->invflags & IP6T_FRAG_INV_IDS) ?
+"!= " : "");
+   if (fraginfo->ids[0] != fraginfo->ids[1])
+   xt_xlate_add(xl, "%u-%u ", fraginfo->ids[0],
+fraginfo->ids[1]);
+   else
+   xt_xlate_add(xl, "%u ", fraginfo->ids[0]);
+   }
+
+   if (fraginfo->flags & IP6T_FRAG_RES)
+   xt_xlate_add(xl, "frag reserved 1 ");
+
+   if (fraginfo->flags & IP6T_FRAG_FST)
+   xt_xlate_add(xl, "frag frag-off 0 ");
+
+   if ((fraginfo->flags & IP6T_FRAG_MF) ||
+   (fraginfo->flags & IP6T_FRAG_NMF))
+   xt_xlate_add(xl, "frag more-fragments 1 ");
+
+   return 1;
+}
+
 static struct xtables_match frag_mt6_reg = {
.name  = "frag",
.version   = XTABLES_VERSION,
@@ -185,6 +217,7 @@ static struct xtables_match frag_mt6_reg = {
.save  = frag_save,
.x6_parse  = frag_parse,
.x6_options= frag_opts,
+   .xlate = frag_xlate,
 };
 
 void
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] extensions: libxt_dscp: Add translation to nft

2016-06-05 Thread Laura Garcia Liebana
Add translation for dscp to nftables, for both ipv4 and ipv6.

Examples:

$ sudo iptables-translate -t filter -A INPUT -m dscp --dscp 0x32 -j ACCEPT
nft add rule ip filter INPUT ip dscp 0x32 counter accept

$ sudo ip6tables-translate -t filter -A INPUT -m dscp --dscp 0x32 -j ACCEPT
nft add rule ip6 filter INPUT ip6 dscp != 0x32 counter accept

Signed-off-by: Laura Garcia Liebana <nev...@gmail.com>
---
 extensions/libxt_dscp.c | 92 ++---
 1 file changed, 79 insertions(+), 13 deletions(-)

diff --git a/extensions/libxt_dscp.c b/extensions/libxt_dscp.c
index 02b22a4..4b88c5a 100644
--- a/extensions/libxt_dscp.c
+++ b/extensions/libxt_dscp.c
@@ -91,21 +91,87 @@ static void dscp_save(const void *ip, const struct 
xt_entry_match *match)
printf("%s --dscp 0x%02x", dinfo->invert ? " !" : "", dinfo->dscp);
 }
 
-static struct xtables_match dscp_match = {
-   .family = NFPROTO_UNSPEC,
-   .name   = "dscp",
-   .version= XTABLES_VERSION,
-   .size   = XT_ALIGN(sizeof(struct xt_dscp_info)),
-   .userspacesize  = XT_ALIGN(sizeof(struct xt_dscp_info)),
-   .help   = dscp_help,
-   .print  = dscp_print,
-   .save   = dscp_save,
-   .x6_parse   = dscp_parse,
-   .x6_fcheck  = dscp_check,
-   .x6_options = dscp_opts,
+static int __dscp_xlate(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   const struct xt_dscp_info *dinfo =
+   (const struct xt_dscp_info *)match->data;
+
+   xt_xlate_add(xl, "dscp %s0x%02x ",
+dinfo->invert ? "!= " : "",
+dinfo->dscp);
+
+   return 1;
+}
+
+static int dscp_xlate(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   xt_xlate_add(xl, "ip ");
+
+   return __dscp_xlate(ip, match, xl, numeric);
+}
+
+static int dscp_xlate6(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   xt_xlate_add(xl, "ip6 ");
+
+   return __dscp_xlate(ip, match, xl, numeric);
+}
+
+static int dscp_xlate_uns(const void *ip, const struct xt_entry_match *match,
+ struct xt_xlate *xl, int numeric)
+{
+   return 0;
+}
+
+static struct xtables_match dscp_mt_reg[] = {
+   {
+   .family = NFPROTO_IPV4,
+   .name   = "dscp",
+   .version= XTABLES_VERSION,
+   .size   = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .userspacesize  = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .help   = dscp_help,
+   .print  = dscp_print,
+   .save   = dscp_save,
+   .x6_parse   = dscp_parse,
+   .x6_fcheck  = dscp_check,
+   .x6_options = dscp_opts,
+   .xlate  = dscp_xlate,
+   },
+   {
+   .family = NFPROTO_IPV6,
+   .name   = "dscp",
+   .version= XTABLES_VERSION,
+   .size   = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .userspacesize  = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .help   = dscp_help,
+   .print  = dscp_print,
+   .save   = dscp_save,
+   .x6_parse   = dscp_parse,
+   .x6_fcheck  = dscp_check,
+   .x6_options = dscp_opts,
+   .xlate  = dscp_xlate6,
+   },
+   {
+   .family = NFPROTO_UNSPEC,
+   .name   = "dscp",
+   .version= XTABLES_VERSION,
+   .size   = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .userspacesize  = XT_ALIGN(sizeof(struct xt_dscp_info)),
+   .help   = dscp_help,
+   .print  = dscp_print,
+   .save   = dscp_save,
+   .x6_parse   = dscp_parse,
+   .x6_fcheck  = dscp_check,
+   .x6_options = dscp_opts,
+   .xlate  = dscp_xlate_uns,
+   },
 };
 
 void _init(void)
 {
-   xtables_register_match(_match);
+   xtables_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg));
 }
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >