Commit c273a20c authored by Jakub Kicinski's avatar Jakub Kicinski

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
Netfilter/IPVS updates for net-next

1) Remove indirection and use nf_ct_get() instead from nfnetlink_log
   and nfnetlink_queue, from Florian Westphal.

2) Add weighted random twos choice least-connection scheduling for IPVS,
   from Darby Payne.

3) Add a __hash placeholder in the flow tuple structure to identify
   the field to be included in the rhashtable key hash calculation.

4) Add a new nft_parse_register_load() and nft_parse_register_store()
   to consolidate register load and store in the core.

5) Statify nft_parse_register() since it has no more module clients.

6) Remove redundant assignment in nft_cmp, from Colin Ian King.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next:
  netfilter: nftables: remove redundant assignment of variable err
  netfilter: nftables: statify nft_parse_register()
  netfilter: nftables: add nft_parse_register_store() and use it
  netfilter: nftables: add nft_parse_register_load() and use it
  netfilter: flowtable: add hash offset field to tuple
  ipvs: add weighted random twos choice algorithm
  netfilter: ctnetlink: remove get_ct indirection
====================

Link: https://lore.kernel.org/r/20210206015005.23037-1-pablo@netfilter.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7274c414 626899a0
...@@ -463,8 +463,6 @@ extern struct nf_ct_hook __rcu *nf_ct_hook; ...@@ -463,8 +463,6 @@ extern struct nf_ct_hook __rcu *nf_ct_hook;
struct nlattr; struct nlattr;
struct nfnl_ct_hook { struct nfnl_ct_hook {
struct nf_conn *(*get_ct)(const struct sk_buff *skb,
enum ip_conntrack_info *ctinfo);
size_t (*build_size)(const struct nf_conn *ct); size_t (*build_size)(const struct nf_conn *ct);
int (*build)(struct sk_buff *skb, struct nf_conn *ct, int (*build)(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
......
...@@ -107,6 +107,10 @@ struct flow_offload_tuple { ...@@ -107,6 +107,10 @@ struct flow_offload_tuple {
u8 l3proto; u8 l3proto;
u8 l4proto; u8 l4proto;
/* All members above are keys for lookups, see flow_offload_hash(). */
struct { } __hash;
u8 dir; u8 dir;
u16 mtu; u16 mtu;
......
...@@ -200,12 +200,11 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) ...@@ -200,12 +200,11 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
} }
int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
unsigned int nft_parse_register(const struct nlattr *attr);
int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
int nft_validate_register_load(enum nft_registers reg, unsigned int len); int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
int nft_validate_register_store(const struct nft_ctx *ctx, int nft_parse_register_store(const struct nft_ctx *ctx,
enum nft_registers reg, const struct nlattr *attr, u8 *dreg,
const struct nft_data *data, const struct nft_data *data,
enum nft_data_types type, unsigned int len); enum nft_data_types type, unsigned int len);
......
...@@ -26,21 +26,21 @@ void nf_tables_core_module_exit(void); ...@@ -26,21 +26,21 @@ void nf_tables_core_module_exit(void);
struct nft_bitwise_fast_expr { struct nft_bitwise_fast_expr {
u32 mask; u32 mask;
u32 xor; u32 xor;
enum nft_registers sreg:8; u8 sreg;
enum nft_registers dreg:8; u8 dreg;
}; };
struct nft_cmp_fast_expr { struct nft_cmp_fast_expr {
u32 data; u32 data;
u32 mask; u32 mask;
enum nft_registers sreg:8; u8 sreg;
u8 len; u8 len;
bool inv; bool inv;
}; };
struct nft_immediate_expr { struct nft_immediate_expr {
struct nft_data data; struct nft_data data;
enum nft_registers dreg:8; u8 dreg;
u8 dlen; u8 dlen;
}; };
...@@ -60,14 +60,14 @@ struct nft_payload { ...@@ -60,14 +60,14 @@ struct nft_payload {
enum nft_payload_bases base:8; enum nft_payload_bases base:8;
u8 offset; u8 offset;
u8 len; u8 len;
enum nft_registers dreg:8; u8 dreg;
}; };
struct nft_payload_set { struct nft_payload_set {
enum nft_payload_bases base:8; enum nft_payload_bases base:8;
u8 offset; u8 offset;
u8 len; u8 len;
enum nft_registers sreg:8; u8 sreg;
u8 csum_type; u8 csum_type;
u8 csum_offset; u8 csum_offset;
u8 csum_flags; u8 csum_flags;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
struct nft_fib { struct nft_fib {
enum nft_registers dreg:8; u8 dreg;
u8 result; u8 result;
u32 flags; u32 flags;
}; };
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
struct nft_meta { struct nft_meta {
enum nft_meta_keys key:8; enum nft_meta_keys key:8;
union { union {
enum nft_registers dreg:8; u8 dreg;
enum nft_registers sreg:8; u8 sreg;
}; };
}; };
......
...@@ -87,9 +87,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, ...@@ -87,9 +87,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
return nft_meta_get_init(ctx, expr, tb); return nft_meta_get_init(ctx, expr, tb);
} }
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
return nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, len);
NFT_DATA_VALUE, len);
} }
static struct nft_expr_type nft_meta_bridge_type; static struct nft_expr_type nft_meta_bridge_type;
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#include <net/netfilter/ipv4/nf_dup_ipv4.h> #include <net/netfilter/ipv4/nf_dup_ipv4.h>
struct nft_dup_ipv4 { struct nft_dup_ipv4 {
enum nft_registers sreg_addr:8; u8 sreg_addr;
enum nft_registers sreg_dev:8; u8 sreg_dev;
}; };
static void nft_dup_ipv4_eval(const struct nft_expr *expr, static void nft_dup_ipv4_eval(const struct nft_expr *expr,
...@@ -40,16 +40,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx, ...@@ -40,16 +40,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,
if (tb[NFTA_DUP_SREG_ADDR] == NULL) if (tb[NFTA_DUP_SREG_ADDR] == NULL)
return -EINVAL; return -EINVAL;
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]); err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in_addr)); sizeof(struct in_addr));
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_DUP_SREG_DEV] != NULL) { if (tb[NFTA_DUP_SREG_DEV])
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
return nft_validate_register_load(priv->sreg_dev, sizeof(int)); &priv->sreg_dev, sizeof(int));
}
return 0; return err;
} }
static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#include <net/netfilter/ipv6/nf_dup_ipv6.h> #include <net/netfilter/ipv6/nf_dup_ipv6.h>
struct nft_dup_ipv6 { struct nft_dup_ipv6 {
enum nft_registers sreg_addr:8; u8 sreg_addr;
enum nft_registers sreg_dev:8; u8 sreg_dev;
}; };
static void nft_dup_ipv6_eval(const struct nft_expr *expr, static void nft_dup_ipv6_eval(const struct nft_expr *expr,
...@@ -38,16 +38,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx, ...@@ -38,16 +38,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,
if (tb[NFTA_DUP_SREG_ADDR] == NULL) if (tb[NFTA_DUP_SREG_ADDR] == NULL)
return -EINVAL; return -EINVAL;
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]); err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in6_addr)); sizeof(struct in6_addr));
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_DUP_SREG_DEV] != NULL) { if (tb[NFTA_DUP_SREG_DEV])
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
return nft_validate_register_load(priv->sreg_dev, sizeof(int)); &priv->sreg_dev, sizeof(int));
}
return 0; return err;
} }
static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -271,6 +271,17 @@ config IP_VS_NQ ...@@ -271,6 +271,17 @@ config IP_VS_NQ
If you want to compile it in kernel, say Y. To compile it as a If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N. module, choose M here. If unsure, say N.
config IP_VS_TWOS
tristate "weighted random twos choice least-connection scheduling"
help
The weighted random twos choice least-connection scheduling
algorithm picks two random real servers and directs network
connections to the server with the least active connections
normalized by the server weight.
If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N.
comment 'IPVS SH scheduler' comment 'IPVS SH scheduler'
config IP_VS_SH_TAB_BITS config IP_VS_SH_TAB_BITS
......
...@@ -36,6 +36,7 @@ obj-$(CONFIG_IP_VS_SH) += ip_vs_sh.o ...@@ -36,6 +36,7 @@ obj-$(CONFIG_IP_VS_SH) += ip_vs_sh.o
obj-$(CONFIG_IP_VS_MH) += ip_vs_mh.o obj-$(CONFIG_IP_VS_MH) += ip_vs_mh.o
obj-$(CONFIG_IP_VS_SED) += ip_vs_sed.o obj-$(CONFIG_IP_VS_SED) += ip_vs_sed.o
obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o
obj-$(CONFIG_IP_VS_TWOS) += ip_vs_twos.o
# IPVS application helpers # IPVS application helpers
obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* IPVS: Power of Twos Choice Scheduling module
*
* Authors: Darby Payne <darby.payne@applovin.com>
*/
#define KMSG_COMPONENT "IPVS"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
#include <net/ip_vs.h>
/* Power of Twos Choice scheduling, algorithm originally described by
* Michael Mitzenmacher.
*
* Randomly picks two destinations and picks the one with the least
* amount of connections
*
* The algorithm calculates a few variables
* - total_weight = sum of all weights
* - rweight1 = random number between [0,total_weight]
* - rweight2 = random number between [0,total_weight]
*
* For each destination
* decrement rweight1 and rweight2 by the destination weight
* pick choice1 when rweight1 is <= 0
* pick choice2 when rweight2 is <= 0
*
* Return choice2 if choice2 has less connections than choice 1 normalized
* by weight
*
* References
* ----------
*
* [Mitzenmacher 2016]
* The Power of Two Random Choices: A Survey of Techniques and Results
* Michael Mitzenmacher, Andrea W. Richa y, Ramesh Sitaraman
* http://www.eecs.harvard.edu/~michaelm/NEWWORK/postscripts/twosurvey.pdf
*
*/
static struct ip_vs_dest *ip_vs_twos_schedule(struct ip_vs_service *svc,
const struct sk_buff *skb,
struct ip_vs_iphdr *iph)
{
struct ip_vs_dest *dest, *choice1 = NULL, *choice2 = NULL;
int rweight1, rweight2, weight1 = -1, weight2 = -1, overhead1 = 0;
int overhead2, total_weight = 0, weight;
IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
/* Generate a random weight between [0,sum of all weights) */
list_for_each_entry_rcu(dest, &svc->destinations, n_list) {
if (!(dest->flags & IP_VS_DEST_F_OVERLOAD)) {
weight = atomic_read(&dest->weight);
if (weight > 0) {
total_weight += weight;
choice1 = dest;
}
}
}
if (!choice1) {
ip_vs_scheduler_err(svc, "no destination available");
return NULL;
}
/* Add 1 to total_weight so that the random weights are inclusive
* from 0 to total_weight
*/
total_weight += 1;
rweight1 = prandom_u32() % total_weight;
rweight2 = prandom_u32() % total_weight;
/* Pick two weighted servers */
list_for_each_entry_rcu(dest, &svc->destinations, n_list) {
if (dest->flags & IP_VS_DEST_F_OVERLOAD)
continue;
weight = atomic_read(&dest->weight);
if (weight <= 0)
continue;
rweight1 -= weight;
rweight2 -= weight;
if (rweight1 <= 0 && weight1 == -1) {
choice1 = dest;
weight1 = weight;
overhead1 = ip_vs_dest_conn_overhead(dest);
}
if (rweight2 <= 0 && weight2 == -1) {
choice2 = dest;
weight2 = weight;
overhead2 = ip_vs_dest_conn_overhead(dest);
}
if (weight1 != -1 && weight2 != -1)
goto nextstage;
}
nextstage:
if (choice2 && (weight2 * overhead1) > (weight1 * overhead2))
choice1 = choice2;
IP_VS_DBG_BUF(6, "twos: server %s:%u conns %d refcnt %d weight %d\n",
IP_VS_DBG_ADDR(choice1->af, &choice1->addr),
ntohs(choice1->port), atomic_read(&choice1->activeconns),
refcount_read(&choice1->refcnt),
atomic_read(&choice1->weight));
return choice1;
}
static struct ip_vs_scheduler ip_vs_twos_scheduler = {
.name = "twos",
.refcnt = ATOMIC_INIT(0),
.module = THIS_MODULE,
.n_list = LIST_HEAD_INIT(ip_vs_twos_scheduler.n_list),
.schedule = ip_vs_twos_schedule,
};
static int __init ip_vs_twos_init(void)
{
return register_ip_vs_scheduler(&ip_vs_twos_scheduler);
}
static void __exit ip_vs_twos_cleanup(void)
{
unregister_ip_vs_scheduler(&ip_vs_twos_scheduler);
synchronize_rcu();
}
module_init(ip_vs_twos_init);
module_exit(ip_vs_twos_cleanup);
MODULE_LICENSE("GPL");
...@@ -2686,12 +2686,6 @@ ctnetlink_glue_build_size(const struct nf_conn *ct) ...@@ -2686,12 +2686,6 @@ ctnetlink_glue_build_size(const struct nf_conn *ct)
; ;
} }
static struct nf_conn *ctnetlink_glue_get_ct(const struct sk_buff *skb,
enum ip_conntrack_info *ctinfo)
{
return nf_ct_get(skb, ctinfo);
}
static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct) static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
{ {
const struct nf_conntrack_zone *zone; const struct nf_conntrack_zone *zone;
...@@ -2925,7 +2919,6 @@ static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct, ...@@ -2925,7 +2919,6 @@ static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
} }
static struct nfnl_ct_hook ctnetlink_glue_hook = { static struct nfnl_ct_hook ctnetlink_glue_hook = {
.get_ct = ctnetlink_glue_get_ct,
.build_size = ctnetlink_glue_build_size, .build_size = ctnetlink_glue_build_size,
.build = ctnetlink_glue_build, .build = ctnetlink_glue_build,
.parse = ctnetlink_glue_parse, .parse = ctnetlink_glue_parse,
......
...@@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void *data, u32 len, u32 seed) ...@@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void *data, u32 len, u32 seed)
{ {
const struct flow_offload_tuple *tuple = data; const struct flow_offload_tuple *tuple = data;
return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); return jhash(tuple, offsetof(struct flow_offload_tuple, __hash), seed);
} }
static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed)
{ {
const struct flow_offload_tuple_rhash *tuplehash = data; const struct flow_offload_tuple_rhash *tuplehash = data;
return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, __hash), seed);
} }
static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg,
...@@ -207,7 +207,7 @@ static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, ...@@ -207,7 +207,7 @@ static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg,
const struct flow_offload_tuple *tuple = arg->key; const struct flow_offload_tuple *tuple = arg->key;
const struct flow_offload_tuple_rhash *x = ptr; const struct flow_offload_tuple_rhash *x = ptr;
if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, __hash)))
return 1; return 1;
return 0; return 0;
......
...@@ -4438,6 +4438,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, ...@@ -4438,6 +4438,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
return nft_delset(&ctx, set); return nft_delset(&ctx, set);
} }
static int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg,
const struct nft_data *data,
enum nft_data_types type,
unsigned int len);
static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
struct nft_set *set, struct nft_set *set,
const struct nft_set_iter *iter, const struct nft_set_iter *iter,
...@@ -8588,7 +8594,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check); ...@@ -8588,7 +8594,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check);
* Registers used to be 128 bit wide, these register numbers will be * Registers used to be 128 bit wide, these register numbers will be
* mapped to the corresponding 32 bit register numbers. * mapped to the corresponding 32 bit register numbers.
*/ */
unsigned int nft_parse_register(const struct nlattr *attr) static unsigned int nft_parse_register(const struct nlattr *attr)
{ {
unsigned int reg; unsigned int reg;
...@@ -8600,7 +8606,6 @@ unsigned int nft_parse_register(const struct nlattr *attr) ...@@ -8600,7 +8606,6 @@ unsigned int nft_parse_register(const struct nlattr *attr)
return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
} }
} }
EXPORT_SYMBOL_GPL(nft_parse_register);
/** /**
* nft_dump_register - dump a register value to a netlink attribute * nft_dump_register - dump a register value to a netlink attribute
...@@ -8633,7 +8638,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register); ...@@ -8633,7 +8638,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register);
* Validate that the input register is one of the general purpose * Validate that the input register is one of the general purpose
* registers and that the length of the load is within the bounds. * registers and that the length of the load is within the bounds.
*/ */
int nft_validate_register_load(enum nft_registers reg, unsigned int len) static int nft_validate_register_load(enum nft_registers reg, unsigned int len)
{ {
if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
return -EINVAL; return -EINVAL;
...@@ -8644,7 +8649,21 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len) ...@@ -8644,7 +8649,21 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(nft_validate_register_load);
int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)
{
u32 reg;
int err;
reg = nft_parse_register(attr);
err = nft_validate_register_load(reg, len);
if (err < 0)
return err;
*sreg = reg;
return 0;
}
EXPORT_SYMBOL_GPL(nft_parse_register_load);
/** /**
* nft_validate_register_store - validate an expressions' register store * nft_validate_register_store - validate an expressions' register store
...@@ -8660,10 +8679,11 @@ EXPORT_SYMBOL_GPL(nft_validate_register_load); ...@@ -8660,10 +8679,11 @@ EXPORT_SYMBOL_GPL(nft_validate_register_load);
* A value of NULL for the data means that its runtime gathered * A value of NULL for the data means that its runtime gathered
* data. * data.
*/ */
int nft_validate_register_store(const struct nft_ctx *ctx, static int nft_validate_register_store(const struct nft_ctx *ctx,
enum nft_registers reg, enum nft_registers reg,
const struct nft_data *data, const struct nft_data *data,
enum nft_data_types type, unsigned int len) enum nft_data_types type,
unsigned int len)
{ {
int err; int err;
...@@ -8695,7 +8715,24 @@ int nft_validate_register_store(const struct nft_ctx *ctx, ...@@ -8695,7 +8715,24 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
return 0; return 0;
} }
} }
EXPORT_SYMBOL_GPL(nft_validate_register_store);
int nft_parse_register_store(const struct nft_ctx *ctx,
const struct nlattr *attr, u8 *dreg,
const struct nft_data *data,
enum nft_data_types type, unsigned int len)
{
int err;
u32 reg;
reg = nft_parse_register(attr);
err = nft_validate_register_store(ctx, reg, data, type, len);
if (err < 0)
return err;
*dreg = reg;
return 0;
}
EXPORT_SYMBOL_GPL(nft_parse_register_store);
static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = { static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
[NFTA_VERDICT_CODE] = { .type = NLA_U32 }, [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
......
...@@ -43,6 +43,10 @@ ...@@ -43,6 +43,10 @@
#include "../bridge/br_private.h" #include "../bridge/br_private.h"
#endif #endif
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h>
#endif
#define NFULNL_COPY_DISABLED 0xff #define NFULNL_COPY_DISABLED 0xff
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
...@@ -733,14 +737,16 @@ nfulnl_log_packet(struct net *net, ...@@ -733,14 +737,16 @@ nfulnl_log_packet(struct net *net,
size += nla_total_size(sizeof(u_int32_t)); size += nla_total_size(sizeof(u_int32_t));
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
size += nla_total_size(sizeof(u_int32_t)); size += nla_total_size(sizeof(u_int32_t));
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
if (inst->flags & NFULNL_CFG_F_CONNTRACK) { if (inst->flags & NFULNL_CFG_F_CONNTRACK) {
nfnl_ct = rcu_dereference(nfnl_ct_hook); nfnl_ct = rcu_dereference(nfnl_ct_hook);
if (nfnl_ct != NULL) { if (nfnl_ct != NULL) {
ct = nfnl_ct->get_ct(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
if (ct != NULL) if (ct != NULL)
size += nfnl_ct->build_size(ct); size += nfnl_ct->build_size(ct);
} }
} }
#endif
if (pf == NFPROTO_NETDEV || pf == NFPROTO_BRIDGE) if (pf == NFPROTO_NETDEV || pf == NFPROTO_BRIDGE)
size += nfulnl_get_bridge_size(skb); size += nfulnl_get_bridge_size(skb);
......
...@@ -444,13 +444,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, ...@@ -444,13 +444,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
nfnl_ct = rcu_dereference(nfnl_ct_hook); nfnl_ct = rcu_dereference(nfnl_ct_hook);
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
if (queue->flags & NFQA_CFG_F_CONNTRACK) { if (queue->flags & NFQA_CFG_F_CONNTRACK) {
if (nfnl_ct != NULL) { if (nfnl_ct != NULL) {
ct = nfnl_ct->get_ct(entskb, &ctinfo); ct = nf_ct_get(entskb, &ctinfo);
if (ct != NULL) if (ct != NULL)
size += nfnl_ct->build_size(ct); size += nfnl_ct->build_size(ct);
} }
} }
#endif
if (queue->flags & NFQA_CFG_F_UID_GID) { if (queue->flags & NFQA_CFG_F_UID_GID) {
size += (nla_total_size(sizeof(u_int32_t)) /* uid */ size += (nla_total_size(sizeof(u_int32_t)) /* uid */
...@@ -1104,9 +1106,10 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct, ...@@ -1104,9 +1106,10 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
struct nf_queue_entry *entry, struct nf_queue_entry *entry,
enum ip_conntrack_info *ctinfo) enum ip_conntrack_info *ctinfo)
{ {
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
struct nf_conn *ct; struct nf_conn *ct;
ct = nfnl_ct->get_ct(entry->skb, ctinfo); ct = nf_ct_get(entry->skb, ctinfo);
if (ct == NULL) if (ct == NULL)
return NULL; return NULL;
...@@ -1118,6 +1121,9 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct, ...@@ -1118,6 +1121,9 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
NETLINK_CB(entry->skb).portid, NETLINK_CB(entry->skb).portid,
nlmsg_report(nlh)); nlmsg_report(nlh));
return ct; return ct;
#else
return NULL;
#endif
} }
static int nfqa_parse_bridge(struct nf_queue_entry *entry, static int nfqa_parse_bridge(struct nf_queue_entry *entry,
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <net/netfilter/nf_tables_offload.h> #include <net/netfilter/nf_tables_offload.h>
struct nft_bitwise { struct nft_bitwise {
enum nft_registers sreg:8; u8 sreg;
enum nft_registers dreg:8; u8 dreg;
enum nft_bitwise_ops op:8; enum nft_bitwise_ops op:8;
u8 len; u8 len;
struct nft_data mask; struct nft_data mask;
...@@ -169,14 +169,14 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, ...@@ -169,14 +169,14 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
priv->len = len; priv->len = len;
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]); err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
err = nft_validate_register_load(priv->sreg, priv->len); priv->len);
if (err < 0) if (err < 0)
return err; return err;
priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG],
err = nft_validate_register_store(ctx, priv->dreg, NULL, &priv->dreg, NULL, NFT_DATA_VALUE,
NFT_DATA_VALUE, priv->len); priv->len);
if (err < 0) if (err < 0)
return err; return err;
...@@ -315,14 +315,13 @@ static int nft_bitwise_fast_init(const struct nft_ctx *ctx, ...@@ -315,14 +315,13 @@ static int nft_bitwise_fast_init(const struct nft_ctx *ctx,
struct nft_bitwise_fast_expr *priv = nft_expr_priv(expr); struct nft_bitwise_fast_expr *priv = nft_expr_priv(expr);
int err; int err;
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]); err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
err = nft_validate_register_load(priv->sreg, sizeof(u32)); sizeof(u32));
if (err < 0) if (err < 0)
return err; return err;
priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG], &priv->dreg,
err = nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, sizeof(u32));
NFT_DATA_VALUE, sizeof(u32));
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
struct nft_byteorder { struct nft_byteorder {
enum nft_registers sreg:8; u8 sreg;
enum nft_registers dreg:8; u8 dreg;
enum nft_byteorder_ops op:8; enum nft_byteorder_ops op:8;
u8 len; u8 len;
u8 size; u8 size;
...@@ -131,20 +131,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, ...@@ -131,20 +131,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
return -EINVAL; return -EINVAL;
} }
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
err = nft_parse_u32_check(tb[NFTA_BYTEORDER_LEN], U8_MAX, &len); err = nft_parse_u32_check(tb[NFTA_BYTEORDER_LEN], U8_MAX, &len);
if (err < 0) if (err < 0)
return err; return err;
priv->len = len; priv->len = len;
err = nft_validate_register_load(priv->sreg, priv->len); err = nft_parse_register_load(tb[NFTA_BYTEORDER_SREG], &priv->sreg,
priv->len);
if (err < 0) if (err < 0)
return err; return err;
priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]); return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
return nft_validate_register_store(ctx, priv->dreg, NULL, &priv->dreg, NULL, NFT_DATA_VALUE,
NFT_DATA_VALUE, priv->len); priv->len);
} }
static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
struct nft_cmp_expr { struct nft_cmp_expr {
struct nft_data data; struct nft_data data;
enum nft_registers sreg:8; u8 sreg;
u8 len; u8 len;
enum nft_cmp_ops op:8; enum nft_cmp_ops op:8;
}; };
...@@ -87,8 +87,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -87,8 +87,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return err; return err;
} }
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
err = nft_validate_register_load(priv->sreg, desc.len);
if (err < 0) if (err < 0)
return err; return err;
...@@ -174,8 +173,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, ...@@ -174,8 +173,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
if (err < 0) if (err < 0)
return err; return err;
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
err = nft_validate_register_load(priv->sreg, desc.len);
if (err < 0) if (err < 0)
return err; return err;
...@@ -268,10 +266,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) ...@@ -268,10 +266,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
if (err < 0) if (err < 0)
return ERR_PTR(err); return ERR_PTR(err);
if (desc.type != NFT_DATA_VALUE) { if (desc.type != NFT_DATA_VALUE)
err = -EINVAL;
goto err1; goto err1;
}
if (desc.len <= sizeof(u32) && (op == NFT_CMP_EQ || op == NFT_CMP_NEQ)) if (desc.len <= sizeof(u32) && (op == NFT_CMP_EQ || op == NFT_CMP_NEQ))
return &nft_cmp_fast_ops; return &nft_cmp_fast_ops;
......
...@@ -27,8 +27,8 @@ struct nft_ct { ...@@ -27,8 +27,8 @@ struct nft_ct {
enum nft_ct_keys key:8; enum nft_ct_keys key:8;
enum ip_conntrack_dir dir:8; enum ip_conntrack_dir dir:8;
union { union {
enum nft_registers dreg:8; u8 dreg;
enum nft_registers sreg:8; u8 sreg;
}; };
}; };
...@@ -498,8 +498,7 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, ...@@ -498,8 +498,7 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
} }
} }
priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
err = nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, len); NFT_DATA_VALUE, len);
if (err < 0) if (err < 0)
return err; return err;
...@@ -600,8 +599,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, ...@@ -600,8 +599,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
} }
} }
priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]); err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len);
err = nft_validate_register_load(priv->sreg, len);
if (err < 0) if (err < 0)
goto err1; goto err1;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <net/netfilter/nf_dup_netdev.h> #include <net/netfilter/nf_dup_netdev.h>
struct nft_dup_netdev { struct nft_dup_netdev {
enum nft_registers sreg_dev:8; u8 sreg_dev;
}; };
static void nft_dup_netdev_eval(const struct nft_expr *expr, static void nft_dup_netdev_eval(const struct nft_expr *expr,
...@@ -40,8 +40,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx, ...@@ -40,8 +40,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,
if (tb[NFTA_DUP_SREG_DEV] == NULL) if (tb[NFTA_DUP_SREG_DEV] == NULL)
return -EINVAL; return -EINVAL;
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev,
return nft_validate_register_load(priv->sreg_dev, sizeof(int)); sizeof(int));
} }
static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -16,8 +16,8 @@ struct nft_dynset { ...@@ -16,8 +16,8 @@ struct nft_dynset {
struct nft_set *set; struct nft_set *set;
struct nft_set_ext_tmpl tmpl; struct nft_set_ext_tmpl tmpl;
enum nft_dynset_ops op:8; enum nft_dynset_ops op:8;
enum nft_registers sreg_key:8; u8 sreg_key;
enum nft_registers sreg_data:8; u8 sreg_data;
bool invert; bool invert;
bool expr; bool expr;
u8 num_exprs; u8 num_exprs;
...@@ -219,8 +219,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, ...@@ -219,8 +219,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
return err; return err;
} }
priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]); err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key,
err = nft_validate_register_load(priv->sreg_key, set->klen); set->klen);
if (err < 0) if (err < 0)
return err; return err;
...@@ -230,8 +230,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, ...@@ -230,8 +230,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
if (set->dtype == NFT_DATA_VERDICT) if (set->dtype == NFT_DATA_VERDICT)
return -EOPNOTSUPP; return -EOPNOTSUPP;
priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]); err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA],
err = nft_validate_register_load(priv->sreg_data, set->dlen); &priv->sreg_data, set->dlen);
if (err < 0) if (err < 0)
return err; return err;
} else if (set->flags & NFT_SET_MAP) } else if (set->flags & NFT_SET_MAP)
......
...@@ -19,8 +19,8 @@ struct nft_exthdr { ...@@ -19,8 +19,8 @@ struct nft_exthdr {
u8 offset; u8 offset;
u8 len; u8 len;
u8 op; u8 op;
enum nft_registers dreg:8; u8 dreg;
enum nft_registers sreg:8; u8 sreg;
u8 flags; u8 flags;
}; };
...@@ -350,12 +350,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, ...@@ -350,12 +350,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
priv->offset = offset; priv->offset = offset;
priv->len = len; priv->len = len;
priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
priv->flags = flags; priv->flags = flags;
priv->op = op; priv->op = op;
return nft_validate_register_store(ctx, priv->dreg, NULL, return nft_parse_register_store(ctx, tb[NFTA_EXTHDR_DREG],
NFT_DATA_VALUE, priv->len); &priv->dreg, NULL, NFT_DATA_VALUE,
priv->len);
} }
static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
...@@ -400,11 +400,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, ...@@ -400,11 +400,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
priv->offset = offset; priv->offset = offset;
priv->len = len; priv->len = len;
priv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]);
priv->flags = flags; priv->flags = flags;
priv->op = op; priv->op = op;
return nft_validate_register_load(priv->sreg, priv->len); return nft_parse_register_load(tb[NFTA_EXTHDR_SREG], &priv->sreg,
priv->len);
} }
static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx, static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx,
......
...@@ -86,7 +86,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -86,7 +86,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return -EINVAL; return -EINVAL;
priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT])); priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]);
switch (priv->result) { switch (priv->result) {
case NFT_FIB_RESULT_OIF: case NFT_FIB_RESULT_OIF:
...@@ -106,8 +105,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -106,8 +105,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return -EINVAL; return -EINVAL;
} }
err = nft_validate_register_store(ctx, priv->dreg, NULL, err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg,
NFT_DATA_VALUE, len); NULL, NFT_DATA_VALUE, len);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include <net/ip.h> #include <net/ip.h>
struct nft_fwd_netdev { struct nft_fwd_netdev {
enum nft_registers sreg_dev:8; u8 sreg_dev;
}; };
static void nft_fwd_netdev_eval(const struct nft_expr *expr, static void nft_fwd_netdev_eval(const struct nft_expr *expr,
...@@ -50,8 +50,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx, ...@@ -50,8 +50,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx,
if (tb[NFTA_FWD_SREG_DEV] == NULL) if (tb[NFTA_FWD_SREG_DEV] == NULL)
return -EINVAL; return -EINVAL;
priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]); return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
return nft_validate_register_load(priv->sreg_dev, sizeof(int)); sizeof(int));
} }
static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
...@@ -78,8 +78,8 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx, ...@@ -78,8 +78,8 @@ static int nft_fwd_netdev_offload(struct nft_offload_ctx *ctx,
} }
struct nft_fwd_neigh { struct nft_fwd_neigh {
enum nft_registers sreg_dev:8; u8 sreg_dev;
enum nft_registers sreg_addr:8; u8 sreg_addr;
u8 nfproto; u8 nfproto;
}; };
...@@ -157,8 +157,6 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx, ...@@ -157,8 +157,6 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,
!tb[NFTA_FWD_NFPROTO]) !tb[NFTA_FWD_NFPROTO])
return -EINVAL; return -EINVAL;
priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]);
priv->sreg_addr = nft_parse_register(tb[NFTA_FWD_SREG_ADDR]);
priv->nfproto = ntohl(nla_get_be32(tb[NFTA_FWD_NFPROTO])); priv->nfproto = ntohl(nla_get_be32(tb[NFTA_FWD_NFPROTO]));
switch (priv->nfproto) { switch (priv->nfproto) {
...@@ -172,11 +170,13 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx, ...@@ -172,11 +170,13 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
err = nft_validate_register_load(priv->sreg_dev, sizeof(int)); err = nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
sizeof(int));
if (err < 0) if (err < 0)
return err; return err;
return nft_validate_register_load(priv->sreg_addr, addr_len); return nft_parse_register_load(tb[NFTA_FWD_SREG_ADDR], &priv->sreg_addr,
addr_len);
} }
static int nft_fwd_neigh_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_fwd_neigh_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <linux/jhash.h> #include <linux/jhash.h>
struct nft_jhash { struct nft_jhash {
enum nft_registers sreg:8; u8 sreg;
enum nft_registers dreg:8; u8 dreg;
u8 len; u8 len;
bool autogen_seed:1; bool autogen_seed:1;
u32 modulus; u32 modulus;
...@@ -38,7 +38,7 @@ static void nft_jhash_eval(const struct nft_expr *expr, ...@@ -38,7 +38,7 @@ static void nft_jhash_eval(const struct nft_expr *expr,
} }
struct nft_symhash { struct nft_symhash {
enum nft_registers dreg:8; u8 dreg;
u32 modulus; u32 modulus;
u32 offset; u32 offset;
}; };
...@@ -83,9 +83,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx, ...@@ -83,9 +83,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
if (tb[NFTA_HASH_OFFSET]) if (tb[NFTA_HASH_OFFSET])
priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET])); priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET]));
priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]);
priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]);
err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len); err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len);
if (err < 0) if (err < 0)
return err; return err;
...@@ -94,6 +91,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx, ...@@ -94,6 +91,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
priv->len = len; priv->len = len;
err = nft_parse_register_load(tb[NFTA_HASH_SREG], &priv->sreg, len);
if (err < 0)
return err;
priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS])); priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
if (priv->modulus < 1) if (priv->modulus < 1)
return -ERANGE; return -ERANGE;
...@@ -108,9 +109,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx, ...@@ -108,9 +109,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
get_random_bytes(&priv->seed, sizeof(priv->seed)); get_random_bytes(&priv->seed, sizeof(priv->seed));
} }
return nft_validate_register_load(priv->sreg, len) && return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG], &priv->dreg,
nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, sizeof(u32));
NFT_DATA_VALUE, sizeof(u32));
} }
static int nft_symhash_init(const struct nft_ctx *ctx, static int nft_symhash_init(const struct nft_ctx *ctx,
...@@ -126,8 +126,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx, ...@@ -126,8 +126,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
if (tb[NFTA_HASH_OFFSET]) if (tb[NFTA_HASH_OFFSET])
priv->offset = ntohl(nla_get_be32(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])); priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS]));
if (priv->modulus < 1) if (priv->modulus < 1)
return -ERANGE; return -ERANGE;
...@@ -135,8 +133,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx, ...@@ -135,8 +133,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
if (priv->offset + priv->modulus - 1 < priv->offset) if (priv->offset + priv->modulus - 1 < priv->offset)
return -EOVERFLOW; return -EOVERFLOW;
return nft_validate_register_store(ctx, priv->dreg, NULL, return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG],
NFT_DATA_VALUE, sizeof(u32)); &priv->dreg, NULL, NFT_DATA_VALUE,
sizeof(u32));
} }
static int nft_jhash_dump(struct sk_buff *skb, static int nft_jhash_dump(struct sk_buff *skb,
......
...@@ -48,9 +48,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx, ...@@ -48,9 +48,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
priv->dlen = desc.len; priv->dlen = desc.len;
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_IMMEDIATE_DREG],
err = nft_validate_register_store(ctx, priv->dreg, &priv->data, &priv->dreg, &priv->data, desc.type,
desc.type, desc.len); desc.len);
if (err < 0) if (err < 0)
goto err1; goto err1;
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
struct nft_lookup { struct nft_lookup {
struct nft_set *set; struct nft_set *set;
enum nft_registers sreg:8; u8 sreg;
enum nft_registers dreg:8; u8 dreg;
bool invert; bool invert;
struct nft_set_binding binding; struct nft_set_binding binding;
}; };
...@@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, ...@@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
if (IS_ERR(set)) if (IS_ERR(set))
return PTR_ERR(set); return PTR_ERR(set);
priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]); err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg,
err = nft_validate_register_load(priv->sreg, set->klen); set->klen);
if (err < 0) if (err < 0)
return err; return err;
...@@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx, ...@@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
if (!(set->flags & NFT_SET_MAP)) if (!(set->flags & NFT_SET_MAP))
return -EINVAL; return -EINVAL;
priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG],
err = nft_validate_register_store(ctx, priv->dreg, NULL, &priv->dreg, NULL, set->dtype,
set->dtype, set->dlen); set->dlen);
if (err < 0) if (err < 0)
return err; return err;
} else if (set->flags & NFT_SET_MAP) } else if (set->flags & NFT_SET_MAP)
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
struct nft_masq { struct nft_masq {
u32 flags; u32 flags;
enum nft_registers sreg_proto_min:8; u8 sreg_proto_min;
enum nft_registers sreg_proto_max:8; u8 sreg_proto_max;
}; };
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = { static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
...@@ -54,18 +54,14 @@ static int nft_masq_init(const struct nft_ctx *ctx, ...@@ -54,18 +54,14 @@ static int nft_masq_init(const struct nft_ctx *ctx,
} }
if (tb[NFTA_MASQ_REG_PROTO_MIN]) { if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
priv->sreg_proto_min = err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]); &priv->sreg_proto_min, plen);
err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_MASQ_REG_PROTO_MAX]) { if (tb[NFTA_MASQ_REG_PROTO_MAX]) {
priv->sreg_proto_max = err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX],
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]); &priv->sreg_proto_max,
err = nft_validate_register_load(priv->sreg_proto_max,
plen); plen);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -535,9 +535,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx, ...@@ -535,9 +535,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
return nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, len);
NFT_DATA_VALUE, len);
} }
EXPORT_SYMBOL_GPL(nft_meta_get_init); EXPORT_SYMBOL_GPL(nft_meta_get_init);
...@@ -661,8 +660,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx, ...@@ -661,8 +660,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
err = nft_validate_register_load(priv->sreg, len);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#include <net/ip.h> #include <net/ip.h>
struct nft_nat { struct nft_nat {
enum nft_registers sreg_addr_min:8; u8 sreg_addr_min;
enum nft_registers sreg_addr_max:8; u8 sreg_addr_max;
enum nft_registers sreg_proto_min:8; u8 sreg_proto_min;
enum nft_registers sreg_proto_max:8; u8 sreg_proto_max;
enum nf_nat_manip_type type:8; enum nf_nat_manip_type type:8;
u8 family; u8 family;
u16 flags; u16 flags;
...@@ -206,17 +206,14 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -206,17 +206,14 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
priv->family = family; priv->family = family;
if (tb[NFTA_NAT_REG_ADDR_MIN]) { if (tb[NFTA_NAT_REG_ADDR_MIN]) {
priv->sreg_addr_min = err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN],
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]); &priv->sreg_addr_min, alen);
err = nft_validate_register_load(priv->sreg_addr_min, alen);
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_NAT_REG_ADDR_MAX]) { if (tb[NFTA_NAT_REG_ADDR_MAX]) {
priv->sreg_addr_max = err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX],
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]); &priv->sreg_addr_max,
err = nft_validate_register_load(priv->sreg_addr_max,
alen); alen);
if (err < 0) if (err < 0)
return err; return err;
...@@ -229,18 +226,14 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -229,18 +226,14 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
plen = sizeof_field(struct nf_nat_range, min_addr.all); plen = sizeof_field(struct nf_nat_range, min_addr.all);
if (tb[NFTA_NAT_REG_PROTO_MIN]) { if (tb[NFTA_NAT_REG_PROTO_MIN]) {
priv->sreg_proto_min = err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]); &priv->sreg_proto_min, plen);
err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_NAT_REG_PROTO_MAX]) { if (tb[NFTA_NAT_REG_PROTO_MAX]) {
priv->sreg_proto_max = err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX],
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]); &priv->sreg_proto_max,
err = nft_validate_register_load(priv->sreg_proto_max,
plen); plen);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state); static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
struct nft_ng_inc { struct nft_ng_inc {
enum nft_registers dreg:8; u8 dreg;
u32 modulus; u32 modulus;
atomic_t counter; atomic_t counter;
u32 offset; u32 offset;
...@@ -66,11 +66,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx, ...@@ -66,11 +66,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
if (priv->offset + priv->modulus - 1 < priv->offset) if (priv->offset + priv->modulus - 1 < priv->offset)
return -EOVERFLOW; return -EOVERFLOW;
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
atomic_set(&priv->counter, priv->modulus - 1); atomic_set(&priv->counter, priv->modulus - 1);
return nft_validate_register_store(ctx, priv->dreg, NULL, return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
NFT_DATA_VALUE, sizeof(u32)); NULL, NFT_DATA_VALUE, sizeof(u32));
} }
static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg, static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
...@@ -100,7 +99,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -100,7 +99,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr)
} }
struct nft_ng_random { struct nft_ng_random {
enum nft_registers dreg:8; u8 dreg;
u32 modulus; u32 modulus;
u32 offset; u32 offset;
}; };
...@@ -140,10 +139,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx, ...@@ -140,10 +139,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
prandom_init_once(&nft_numgen_prandom_state); prandom_init_once(&nft_numgen_prandom_state);
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]); return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
NULL, NFT_DATA_VALUE, sizeof(u32));
return nft_validate_register_store(ctx, priv->dreg, NULL,
NFT_DATA_VALUE, sizeof(u32));
} }
static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -95,7 +95,7 @@ static const struct nft_expr_ops nft_objref_ops = { ...@@ -95,7 +95,7 @@ static const struct nft_expr_ops nft_objref_ops = {
struct nft_objref_map { struct nft_objref_map {
struct nft_set *set; struct nft_set *set;
enum nft_registers sreg:8; u8 sreg;
struct nft_set_binding binding; struct nft_set_binding binding;
}; };
...@@ -137,8 +137,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx, ...@@ -137,8 +137,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,
if (!(set->flags & NFT_SET_OBJECT)) if (!(set->flags & NFT_SET_OBJECT))
return -EINVAL; return -EINVAL;
priv->sreg = nft_parse_register(tb[NFTA_OBJREF_SET_SREG]); err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
err = nft_validate_register_load(priv->sreg, set->klen); set->klen);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <linux/netfilter/nfnetlink_osf.h> #include <linux/netfilter/nfnetlink_osf.h>
struct nft_osf { struct nft_osf {
enum nft_registers dreg:8; u8 dreg;
u8 ttl; u8 ttl;
u32 flags; u32 flags;
}; };
...@@ -78,9 +78,9 @@ static int nft_osf_init(const struct nft_ctx *ctx, ...@@ -78,9 +78,9 @@ static int nft_osf_init(const struct nft_ctx *ctx,
priv->flags = flags; priv->flags = flags;
} }
priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]); err = nft_parse_register_store(ctx, tb[NFTA_OSF_DREG], &priv->dreg,
err = nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE,
NFT_DATA_VALUE, NFT_OSF_MAXGENRELEN); NFT_OSF_MAXGENRELEN);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -144,10 +144,10 @@ static int nft_payload_init(const struct nft_ctx *ctx, ...@@ -144,10 +144,10 @@ static int nft_payload_init(const struct nft_ctx *ctx,
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
return nft_validate_register_store(ctx, priv->dreg, NULL, return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
NFT_DATA_VALUE, priv->len); &priv->dreg, NULL, NFT_DATA_VALUE,
priv->len);
} }
static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
...@@ -658,7 +658,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, ...@@ -658,7 +658,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
priv->sreg = nft_parse_register(tb[NFTA_PAYLOAD_SREG]);
if (tb[NFTA_PAYLOAD_CSUM_TYPE]) if (tb[NFTA_PAYLOAD_CSUM_TYPE])
priv->csum_type = priv->csum_type =
...@@ -691,7 +690,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, ...@@ -691,7 +690,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
return nft_validate_register_load(priv->sreg, priv->len); return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,
priv->len);
} }
static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr) static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
static u32 jhash_initval __read_mostly; static u32 jhash_initval __read_mostly;
struct nft_queue { struct nft_queue {
enum nft_registers sreg_qnum:8; u8 sreg_qnum;
u16 queuenum; u16 queuenum;
u16 queues_total; u16 queues_total;
u16 flags; u16 flags;
...@@ -111,8 +111,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx, ...@@ -111,8 +111,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,
struct nft_queue *priv = nft_expr_priv(expr); struct nft_queue *priv = nft_expr_priv(expr);
int err; int err;
priv->sreg_qnum = nft_parse_register(tb[NFTA_QUEUE_SREG_QNUM]); err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM],
err = nft_validate_register_load(priv->sreg_qnum, sizeof(u32)); &priv->sreg_qnum, sizeof(u32));
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
struct nft_range_expr { struct nft_range_expr {
struct nft_data data_from; struct nft_data data_from;
struct nft_data data_to; struct nft_data data_to;
enum nft_registers sreg:8; u8 sreg;
u8 len; u8 len;
enum nft_range_ops op:8; enum nft_range_ops op:8;
}; };
...@@ -86,8 +86,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr ...@@ -86,8 +86,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
goto err2; goto err2;
} }
priv->sreg = nft_parse_register(tb[NFTA_RANGE_SREG]); err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg,
err = nft_validate_register_load(priv->sreg, desc_from.len); desc_from.len);
if (err < 0) if (err < 0)
goto err2; goto err2;
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
struct nft_redir { struct nft_redir {
enum nft_registers sreg_proto_min:8; u8 sreg_proto_min;
enum nft_registers sreg_proto_max:8; u8 sreg_proto_max;
u16 flags; u16 flags;
}; };
...@@ -50,18 +50,14 @@ static int nft_redir_init(const struct nft_ctx *ctx, ...@@ -50,18 +50,14 @@ static int nft_redir_init(const struct nft_ctx *ctx,
plen = sizeof_field(struct nf_nat_range, min_addr.all); plen = sizeof_field(struct nf_nat_range, min_addr.all);
if (tb[NFTA_REDIR_REG_PROTO_MIN]) { if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
priv->sreg_proto_min = err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]); &priv->sreg_proto_min, plen);
err = nft_validate_register_load(priv->sreg_proto_min, plen);
if (err < 0) if (err < 0)
return err; return err;
if (tb[NFTA_REDIR_REG_PROTO_MAX]) { if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
priv->sreg_proto_max = err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX],
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]); &priv->sreg_proto_max,
err = nft_validate_register_load(priv->sreg_proto_max,
plen); plen);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
struct nft_rt { struct nft_rt {
enum nft_rt_keys key:8; enum nft_rt_keys key:8;
enum nft_registers dreg:8; u8 dreg;
}; };
static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skbdst) static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skbdst)
...@@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx, ...@@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]); return nft_parse_register_store(ctx, tb[NFTA_RT_DREG], &priv->dreg,
return nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, len);
NFT_DATA_VALUE, len);
} }
static int nft_rt_get_dump(struct sk_buff *skb, static int nft_rt_get_dump(struct sk_buff *skb,
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
struct nft_socket { struct nft_socket {
enum nft_socket_keys key:8; enum nft_socket_keys key:8;
union { union {
enum nft_registers dreg:8; u8 dreg;
}; };
}; };
...@@ -133,9 +133,8 @@ static int nft_socket_init(const struct nft_ctx *ctx, ...@@ -133,9 +133,8 @@ static int nft_socket_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
priv->dreg = nft_parse_register(tb[NFTA_SOCKET_DREG]); return nft_parse_register_store(ctx, tb[NFTA_SOCKET_DREG], &priv->dreg,
return nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, len);
NFT_DATA_VALUE, len);
} }
static int nft_socket_dump(struct sk_buff *skb, static int nft_socket_dump(struct sk_buff *skb,
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#endif #endif
struct nft_tproxy { struct nft_tproxy {
enum nft_registers sreg_addr:8; u8 sreg_addr;
enum nft_registers sreg_port:8; u8 sreg_port;
u8 family; u8 family;
}; };
...@@ -247,15 +247,15 @@ static int nft_tproxy_init(const struct nft_ctx *ctx, ...@@ -247,15 +247,15 @@ static int nft_tproxy_init(const struct nft_ctx *ctx,
} }
if (tb[NFTA_TPROXY_REG_ADDR]) { if (tb[NFTA_TPROXY_REG_ADDR]) {
priv->sreg_addr = nft_parse_register(tb[NFTA_TPROXY_REG_ADDR]); err = nft_parse_register_load(tb[NFTA_TPROXY_REG_ADDR],
err = nft_validate_register_load(priv->sreg_addr, alen); &priv->sreg_addr, alen);
if (err < 0) if (err < 0)
return err; return err;
} }
if (tb[NFTA_TPROXY_REG_PORT]) { if (tb[NFTA_TPROXY_REG_PORT]) {
priv->sreg_port = nft_parse_register(tb[NFTA_TPROXY_REG_PORT]); err = nft_parse_register_load(tb[NFTA_TPROXY_REG_PORT],
err = nft_validate_register_load(priv->sreg_port, sizeof(u16)); &priv->sreg_port, sizeof(u16));
if (err < 0) if (err < 0)
return err; return err;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
struct nft_tunnel { struct nft_tunnel {
enum nft_tunnel_keys key:8; enum nft_tunnel_keys key:8;
enum nft_registers dreg:8; u8 dreg;
enum nft_tunnel_mode mode:8; enum nft_tunnel_mode mode:8;
}; };
...@@ -93,8 +93,6 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx, ...@@ -93,8 +93,6 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
priv->dreg = nft_parse_register(tb[NFTA_TUNNEL_DREG]);
if (tb[NFTA_TUNNEL_MODE]) { if (tb[NFTA_TUNNEL_MODE]) {
priv->mode = ntohl(nla_get_be32(tb[NFTA_TUNNEL_MODE])); priv->mode = ntohl(nla_get_be32(tb[NFTA_TUNNEL_MODE]));
if (priv->mode > NFT_TUNNEL_MODE_MAX) if (priv->mode > NFT_TUNNEL_MODE_MAX)
...@@ -103,8 +101,8 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx, ...@@ -103,8 +101,8 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,
priv->mode = NFT_TUNNEL_MODE_NONE; priv->mode = NFT_TUNNEL_MODE_NONE;
} }
return nft_validate_register_store(ctx, priv->dreg, NULL, return nft_parse_register_store(ctx, tb[NFTA_TUNNEL_DREG], &priv->dreg,
NFT_DATA_VALUE, len); NULL, NFT_DATA_VALUE, len);
} }
static int nft_tunnel_get_dump(struct sk_buff *skb, static int nft_tunnel_get_dump(struct sk_buff *skb,
......
...@@ -24,7 +24,7 @@ static const struct nla_policy nft_xfrm_policy[NFTA_XFRM_MAX + 1] = { ...@@ -24,7 +24,7 @@ static const struct nla_policy nft_xfrm_policy[NFTA_XFRM_MAX + 1] = {
struct nft_xfrm { struct nft_xfrm {
enum nft_xfrm_keys key:8; enum nft_xfrm_keys key:8;
enum nft_registers dreg:8; u8 dreg;
u8 dir; u8 dir;
u8 spnum; u8 spnum;
}; };
...@@ -86,9 +86,8 @@ static int nft_xfrm_get_init(const struct nft_ctx *ctx, ...@@ -86,9 +86,8 @@ static int nft_xfrm_get_init(const struct nft_ctx *ctx,
priv->spnum = spnum; priv->spnum = spnum;
priv->dreg = nft_parse_register(tb[NFTA_XFRM_DREG]); return nft_parse_register_store(ctx, tb[NFTA_XFRM_DREG], &priv->dreg,
return nft_validate_register_store(ctx, priv->dreg, NULL, NULL, NFT_DATA_VALUE, len);
NFT_DATA_VALUE, len);
} }
/* Return true if key asks for daddr/saddr and current /* Return true if key asks for daddr/saddr and current
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment