[ANNOUNCE] nftlb 0.3 release
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
On Tue, Mar 13, 2018 at 7:16 AM, Rafał Miłeckiwrote: > 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
On Sun, Sep 11, 2016 at 11:12:26PM +0200, Florian Westphal wrote: > Liping Zhangwrote: > > 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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