mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-16 12:14:06 +00:00
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.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
c273a20c30
44 changed files with 406 additions and 247 deletions
|
@ -463,8 +463,6 @@ extern struct nf_ct_hook __rcu *nf_ct_hook;
|
|||
struct nlattr;
|
||||
|
||||
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);
|
||||
int (*build)(struct sk_buff *skb, struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo,
|
||||
|
|
|
@ -107,6 +107,10 @@ struct flow_offload_tuple {
|
|||
|
||||
u8 l3proto;
|
||||
u8 l4proto;
|
||||
|
||||
/* All members above are keys for lookups, see flow_offload_hash(). */
|
||||
struct { } __hash;
|
||||
|
||||
u8 dir;
|
||||
|
||||
u16 mtu;
|
||||
|
|
|
@ -200,14 +200,13 @@ 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);
|
||||
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_validate_register_load(enum nft_registers reg, unsigned int len);
|
||||
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);
|
||||
int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
|
||||
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);
|
||||
|
||||
/**
|
||||
* struct nft_userdata - user defined data associated with an object
|
||||
|
|
|
@ -26,21 +26,21 @@ void nf_tables_core_module_exit(void);
|
|||
struct nft_bitwise_fast_expr {
|
||||
u32 mask;
|
||||
u32 xor;
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
struct nft_cmp_fast_expr {
|
||||
u32 data;
|
||||
u32 mask;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
bool inv;
|
||||
};
|
||||
|
||||
struct nft_immediate_expr {
|
||||
struct nft_data data;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 dlen;
|
||||
};
|
||||
|
||||
|
@ -60,14 +60,14 @@ struct nft_payload {
|
|||
enum nft_payload_bases base:8;
|
||||
u8 offset;
|
||||
u8 len;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
};
|
||||
|
||||
struct nft_payload_set {
|
||||
enum nft_payload_bases base:8;
|
||||
u8 offset;
|
||||
u8 len;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 csum_type;
|
||||
u8 csum_offset;
|
||||
u8 csum_flags;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_fib {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 result;
|
||||
u32 flags;
|
||||
};
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
struct nft_meta {
|
||||
enum nft_meta_keys key:8;
|
||||
union {
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -87,9 +87,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
|
|||
return nft_meta_get_init(ctx, expr, tb);
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_meta_bridge_type;
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include <net/netfilter/ipv4/nf_dup_ipv4.h>
|
||||
|
||||
struct nft_dup_ipv4 {
|
||||
enum nft_registers sreg_addr:8;
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_addr;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
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,
|
|||
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]);
|
||||
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in_addr));
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
|
||||
sizeof(struct in_addr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_DUP_SREG_DEV] != NULL) {
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
}
|
||||
return 0;
|
||||
if (tb[NFTA_DUP_SREG_DEV])
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
|
||||
&priv->sreg_dev, sizeof(int));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include <net/netfilter/ipv6/nf_dup_ipv6.h>
|
||||
|
||||
struct nft_dup_ipv6 {
|
||||
enum nft_registers sreg_addr:8;
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_addr;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
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,
|
|||
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]);
|
||||
err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in6_addr));
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr,
|
||||
sizeof(struct in6_addr));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_DUP_SREG_DEV] != NULL) {
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
}
|
||||
return 0;
|
||||
if (tb[NFTA_DUP_SREG_DEV])
|
||||
err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV],
|
||||
&priv->sreg_dev, sizeof(int));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
|
|
@ -271,6 +271,17 @@ config IP_VS_NQ
|
|||
If you want to compile it in kernel, say Y. To compile it as a
|
||||
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'
|
||||
|
||||
config IP_VS_SH_TAB_BITS
|
||||
|
|
|
@ -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_SED) += ip_vs_sed.o
|
||||
obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o
|
||||
obj-$(CONFIG_IP_VS_TWOS) += ip_vs_twos.o
|
||||
|
||||
# IPVS application helpers
|
||||
obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o
|
||||
|
|
139
net/netfilter/ipvs/ip_vs_twos.c
Normal file
139
net/netfilter/ipvs/ip_vs_twos.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
// 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)
|
|||
;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const struct nf_conntrack_zone *zone;
|
||||
|
@ -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 = {
|
||||
.get_ct = ctnetlink_glue_get_ct,
|
||||
.build_size = ctnetlink_glue_build_size,
|
||||
.build = ctnetlink_glue_build,
|
||||
.parse = ctnetlink_glue_parse,
|
||||
|
|
|
@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void *data, u32 len, u32 seed)
|
|||
{
|
||||
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)
|
||||
{
|
||||
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,
|
||||
|
@ -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_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 0;
|
||||
|
|
|
@ -4438,6 +4438,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
|
|||
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,
|
||||
struct nft_set *set,
|
||||
const struct nft_set_iter *iter,
|
||||
|
@ -8588,7 +8594,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check);
|
|||
* Registers used to be 128 bit wide, these register numbers will be
|
||||
* 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;
|
||||
|
||||
|
@ -8600,7 +8606,6 @@ unsigned int nft_parse_register(const struct nlattr *attr)
|
|||
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
|
||||
|
@ -8633,7 +8638,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register);
|
|||
* Validate that the input register is one of the general purpose
|
||||
* 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)
|
||||
return -EINVAL;
|
||||
|
@ -8644,7 +8649,21 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)
|
|||
|
||||
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
|
||||
|
@ -8660,10 +8679,11 @@ EXPORT_SYMBOL_GPL(nft_validate_register_load);
|
|||
* A value of NULL for the data means that its runtime gathered
|
||||
* data.
|
||||
*/
|
||||
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 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)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -8695,7 +8715,24 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
|
|||
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] = {
|
||||
[NFTA_VERDICT_CODE] = { .type = NLA_U32 },
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#include "../bridge/br_private.h"
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#endif
|
||||
|
||||
#define NFULNL_COPY_DISABLED 0xff
|
||||
#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
|
||||
#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
|
||||
|
@ -733,14 +737,16 @@ nfulnl_log_packet(struct net *net,
|
|||
size += nla_total_size(sizeof(u_int32_t));
|
||||
if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
|
||||
size += nla_total_size(sizeof(u_int32_t));
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
if (inst->flags & NFULNL_CFG_F_CONNTRACK) {
|
||||
nfnl_ct = rcu_dereference(nfnl_ct_hook);
|
||||
if (nfnl_ct != NULL) {
|
||||
ct = nfnl_ct->get_ct(skb, &ctinfo);
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct != NULL)
|
||||
size += nfnl_ct->build_size(ct);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (pf == NFPROTO_NETDEV || pf == NFPROTO_BRIDGE)
|
||||
size += nfulnl_get_bridge_size(skb);
|
||||
|
||||
|
|
|
@ -444,13 +444,15 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
|||
|
||||
nfnl_ct = rcu_dereference(nfnl_ct_hook);
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
if (queue->flags & NFQA_CFG_F_CONNTRACK) {
|
||||
if (nfnl_ct != NULL) {
|
||||
ct = nfnl_ct->get_ct(entskb, &ctinfo);
|
||||
ct = nf_ct_get(entskb, &ctinfo);
|
||||
if (ct != NULL)
|
||||
size += nfnl_ct->build_size(ct);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (queue->flags & NFQA_CFG_F_UID_GID) {
|
||||
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,
|
|||
struct nf_queue_entry *entry,
|
||||
enum ip_conntrack_info *ctinfo)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
struct nf_conn *ct;
|
||||
|
||||
ct = nfnl_ct->get_ct(entry->skb, ctinfo);
|
||||
ct = nf_ct_get(entry->skb, ctinfo);
|
||||
if (ct == NULL)
|
||||
return NULL;
|
||||
|
||||
|
@ -1118,6 +1121,9 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
|
|||
NETLINK_CB(entry->skb).portid,
|
||||
nlmsg_report(nlh));
|
||||
return ct;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int nfqa_parse_bridge(struct nf_queue_entry *entry,
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <net/netfilter/nf_tables_offload.h>
|
||||
|
||||
struct nft_bitwise {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
enum nft_bitwise_ops op:8;
|
||||
u8 len;
|
||||
struct nft_data mask;
|
||||
|
@ -169,14 +169,14 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
|
|||
|
||||
priv->len = len;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, priv->len);
|
||||
err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -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);
|
||||
int err;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, sizeof(u32));
|
||||
err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg,
|
||||
sizeof(u32));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_byteorder {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
enum nft_byteorder_ops op:8;
|
||||
u8 len;
|
||||
u8 size;
|
||||
|
@ -131,20 +131,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
|
||||
err = nft_parse_u32_check(tb[NFTA_BYTEORDER_LEN], U8_MAX, &len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
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)
|
||||
return err;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
struct nft_cmp_expr {
|
||||
struct nft_data data;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
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,
|
|||
return err;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc.len);
|
||||
err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -174,8 +173,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc.len);
|
||||
err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -268,10 +266,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
|
|||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (desc.type != NFT_DATA_VALUE) {
|
||||
err = -EINVAL;
|
||||
if (desc.type != NFT_DATA_VALUE)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (desc.len <= sizeof(u32) && (op == NFT_CMP_EQ || op == NFT_CMP_NEQ))
|
||||
return &nft_cmp_fast_ops;
|
||||
|
|
|
@ -27,8 +27,8 @@ struct nft_ct {
|
|||
enum nft_ct_keys key:8;
|
||||
enum ip_conntrack_dir dir:8;
|
||||
union {
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -498,9 +498,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -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_validate_register_load(priv->sreg, len);
|
||||
err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <net/netfilter/nf_dup_netdev.h>
|
||||
|
||||
struct nft_dup_netdev {
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
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,
|
|||
if (tb[NFTA_DUP_SREG_DEV] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev,
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||
|
|
|
@ -16,8 +16,8 @@ struct nft_dynset {
|
|||
struct nft_set *set;
|
||||
struct nft_set_ext_tmpl tmpl;
|
||||
enum nft_dynset_ops op:8;
|
||||
enum nft_registers sreg_key:8;
|
||||
enum nft_registers sreg_data:8;
|
||||
u8 sreg_key;
|
||||
u8 sreg_data;
|
||||
bool invert;
|
||||
bool expr;
|
||||
u8 num_exprs;
|
||||
|
@ -219,8 +219,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
|||
return err;
|
||||
}
|
||||
|
||||
priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
|
||||
err = nft_validate_register_load(priv->sreg_key, set->klen);
|
||||
err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -230,8 +230,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
|||
if (set->dtype == NFT_DATA_VERDICT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
|
||||
err = nft_validate_register_load(priv->sreg_data, set->dlen);
|
||||
err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA],
|
||||
&priv->sreg_data, set->dlen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (set->flags & NFT_SET_MAP)
|
||||
|
|
|
@ -19,8 +19,8 @@ struct nft_exthdr {
|
|||
u8 offset;
|
||||
u8 len;
|
||||
u8 op;
|
||||
enum nft_registers dreg:8;
|
||||
enum nft_registers sreg:8;
|
||||
u8 dreg;
|
||||
u8 sreg;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
|
@ -350,12 +350,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
|
|||
priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
|
||||
priv->offset = offset;
|
||||
priv->len = len;
|
||||
priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
|
||||
priv->flags = flags;
|
||||
priv->op = op;
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_EXTHDR_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
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->offset = offset;
|
||||
priv->len = len;
|
||||
priv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]);
|
||||
priv->flags = flags;
|
||||
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,
|
||||
|
|
|
@ -86,7 +86,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
|||
return -EINVAL;
|
||||
|
||||
priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
|
||||
priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]);
|
||||
|
||||
switch (priv->result) {
|
||||
case NFT_FIB_RESULT_OIF:
|
||||
|
@ -106,8 +105,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <net/ip.h>
|
||||
|
||||
struct nft_fwd_netdev {
|
||||
enum nft_registers sreg_dev:8;
|
||||
u8 sreg_dev;
|
||||
};
|
||||
|
||||
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,
|
|||
if (tb[NFTA_FWD_SREG_DEV] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]);
|
||||
return nft_validate_register_load(priv->sreg_dev, sizeof(int));
|
||||
return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev,
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
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,
|
|||
}
|
||||
|
||||
struct nft_fwd_neigh {
|
||||
enum nft_registers sreg_dev:8;
|
||||
enum nft_registers sreg_addr:8;
|
||||
u8 sreg_dev;
|
||||
u8 sreg_addr;
|
||||
u8 nfproto;
|
||||
};
|
||||
|
||||
|
@ -157,8 +157,6 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,
|
|||
!tb[NFTA_FWD_NFPROTO])
|
||||
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]));
|
||||
|
||||
switch (priv->nfproto) {
|
||||
|
@ -172,11 +170,13 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,
|
|||
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)
|
||||
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)
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include <linux/jhash.h>
|
||||
|
||||
struct nft_jhash {
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
u8 len;
|
||||
bool autogen_seed:1;
|
||||
u32 modulus;
|
||||
|
@ -38,7 +38,7 @@ static void nft_jhash_eval(const struct nft_expr *expr,
|
|||
}
|
||||
|
||||
struct nft_symhash {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
u32 offset;
|
||||
};
|
||||
|
@ -83,9 +83,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
|||
if (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);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -94,6 +91,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
|||
|
||||
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]));
|
||||
if (priv->modulus < 1)
|
||||
return -ERANGE;
|
||||
|
@ -108,9 +109,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx,
|
|||
get_random_bytes(&priv->seed, sizeof(priv->seed));
|
||||
}
|
||||
|
||||
return nft_validate_register_load(priv->sreg, len) &&
|
||||
nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
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])
|
||||
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;
|
||||
|
@ -135,8 +133,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx,
|
|||
if (priv->offset + priv->modulus - 1 < priv->offset)
|
||||
return -EOVERFLOW;
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
static int nft_jhash_dump(struct sk_buff *skb,
|
||||
|
|
|
@ -48,9 +48,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
|
|||
|
||||
priv->dlen = desc.len;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
|
||||
desc.type, desc.len);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_IMMEDIATE_DREG],
|
||||
&priv->dreg, &priv->data, desc.type,
|
||||
desc.len);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
struct nft_lookup {
|
||||
struct nft_set *set;
|
||||
enum nft_registers sreg:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 sreg;
|
||||
u8 dreg;
|
||||
bool invert;
|
||||
struct nft_set_binding binding;
|
||||
};
|
||||
|
@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
|||
if (IS_ERR(set))
|
||||
return PTR_ERR(set);
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, set->klen);
|
||||
err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
|||
if (!(set->flags & NFT_SET_MAP))
|
||||
return -EINVAL;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
set->dtype, set->dlen);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG],
|
||||
&priv->dreg, NULL, set->dtype,
|
||||
set->dlen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (set->flags & NFT_SET_MAP)
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
struct nft_masq {
|
||||
u32 flags;
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
};
|
||||
|
||||
static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX + 1] = {
|
||||
|
@ -54,19 +54,15 @@ static int nft_masq_init(const struct nft_ctx *ctx,
|
|||
}
|
||||
|
||||
if (tb[NFTA_MASQ_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_MASQ_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
|
|
@ -535,9 +535,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nft_meta_get_init);
|
||||
|
||||
|
@ -661,8 +660,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, len);
|
||||
err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
#include <net/ip.h>
|
||||
|
||||
struct nft_nat {
|
||||
enum nft_registers sreg_addr_min:8;
|
||||
enum nft_registers sreg_addr_max:8;
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_addr_min;
|
||||
u8 sreg_addr_max;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
enum nf_nat_manip_type type:8;
|
||||
u8 family;
|
||||
u16 flags;
|
||||
|
@ -206,18 +206,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
|
|||
priv->family = family;
|
||||
|
||||
if (tb[NFTA_NAT_REG_ADDR_MIN]) {
|
||||
priv->sreg_addr_min =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
|
||||
err = nft_validate_register_load(priv->sreg_addr_min, alen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN],
|
||||
&priv->sreg_addr_min, alen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_NAT_REG_ADDR_MAX]) {
|
||||
priv->sreg_addr_max =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_addr_max,
|
||||
alen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX],
|
||||
&priv->sreg_addr_max,
|
||||
alen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
@ -229,19 +226,15 @@ 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);
|
||||
if (tb[NFTA_NAT_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_NAT_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);
|
||||
|
||||
struct nft_ng_inc {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
atomic_t counter;
|
||||
u32 offset;
|
||||
|
@ -66,11 +66,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,
|
|||
if (priv->offset + priv->modulus - 1 < priv->offset)
|
||||
return -EOVERFLOW;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
|
||||
atomic_set(&priv->counter, priv->modulus - 1);
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
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)
|
|||
}
|
||||
|
||||
struct nft_ng_random {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u32 modulus;
|
||||
u32 offset;
|
||||
};
|
||||
|
@ -140,10 +139,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
|
|||
|
||||
prandom_init_once(&nft_numgen_prandom_state);
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]);
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, sizeof(u32));
|
||||
return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, sizeof(u32));
|
||||
}
|
||||
|
||||
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 = {
|
|||
|
||||
struct nft_objref_map {
|
||||
struct nft_set *set;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
struct nft_set_binding binding;
|
||||
};
|
||||
|
||||
|
@ -137,8 +137,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,
|
|||
if (!(set->flags & NFT_SET_OBJECT))
|
||||
return -EINVAL;
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_OBJREF_SET_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, set->klen);
|
||||
err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
|
||||
set->klen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <linux/netfilter/nfnetlink_osf.h>
|
||||
|
||||
struct nft_osf {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 ttl;
|
||||
u32 flags;
|
||||
};
|
||||
|
@ -78,9 +78,9 @@ static int nft_osf_init(const struct nft_ctx *ctx,
|
|||
priv->flags = flags;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
|
||||
err = nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, NFT_OSF_MAXGENRELEN);
|
||||
err = nft_parse_register_store(ctx, tb[NFTA_OSF_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE,
|
||||
NFT_OSF_MAXGENRELEN);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -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->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
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,
|
||||
NFT_DATA_VALUE, priv->len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG],
|
||||
&priv->dreg, NULL, NFT_DATA_VALUE,
|
||||
priv->len);
|
||||
}
|
||||
|
||||
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,
|
|||
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
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])
|
||||
priv->csum_type =
|
||||
|
@ -691,7 +690,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
|||
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)
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
static u32 jhash_initval __read_mostly;
|
||||
|
||||
struct nft_queue {
|
||||
enum nft_registers sreg_qnum:8;
|
||||
u16 queuenum;
|
||||
u16 queues_total;
|
||||
u16 flags;
|
||||
u8 sreg_qnum;
|
||||
u16 queuenum;
|
||||
u16 queues_total;
|
||||
u16 flags;
|
||||
};
|
||||
|
||||
static void nft_queue_eval(const struct nft_expr *expr,
|
||||
|
@ -111,8 +111,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,
|
|||
struct nft_queue *priv = nft_expr_priv(expr);
|
||||
int err;
|
||||
|
||||
priv->sreg_qnum = nft_parse_register(tb[NFTA_QUEUE_SREG_QNUM]);
|
||||
err = nft_validate_register_load(priv->sreg_qnum, sizeof(u32));
|
||||
err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM],
|
||||
&priv->sreg_qnum, sizeof(u32));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
struct nft_range_expr {
|
||||
struct nft_data data_from;
|
||||
struct nft_data data_to;
|
||||
enum nft_registers sreg:8;
|
||||
u8 sreg;
|
||||
u8 len;
|
||||
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
|
|||
goto err2;
|
||||
}
|
||||
|
||||
priv->sreg = nft_parse_register(tb[NFTA_RANGE_SREG]);
|
||||
err = nft_validate_register_load(priv->sreg, desc_from.len);
|
||||
err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg,
|
||||
desc_from.len);
|
||||
if (err < 0)
|
||||
goto err2;
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_redir {
|
||||
enum nft_registers sreg_proto_min:8;
|
||||
enum nft_registers sreg_proto_max:8;
|
||||
u8 sreg_proto_min;
|
||||
u8 sreg_proto_max;
|
||||
u16 flags;
|
||||
};
|
||||
|
||||
|
@ -50,19 +50,15 @@ static int nft_redir_init(const struct nft_ctx *ctx,
|
|||
|
||||
plen = sizeof_field(struct nf_nat_range, min_addr.all);
|
||||
if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
|
||||
priv->sreg_proto_min =
|
||||
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_min, plen);
|
||||
err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN],
|
||||
&priv->sreg_proto_min, plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
|
||||
priv->sreg_proto_max =
|
||||
nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]);
|
||||
|
||||
err = nft_validate_register_load(priv->sreg_proto_max,
|
||||
plen);
|
||||
err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX],
|
||||
&priv->sreg_proto_max,
|
||||
plen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
struct nft_rt {
|
||||
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)
|
||||
|
@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_RT_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
static int nft_rt_get_dump(struct sk_buff *skb,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
struct nft_socket {
|
||||
enum nft_socket_keys key:8;
|
||||
union {
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -133,9 +133,8 @@ static int nft_socket_init(const struct nft_ctx *ctx,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_SOCKET_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_SOCKET_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
static int nft_socket_dump(struct sk_buff *skb,
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#endif
|
||||
|
||||
struct nft_tproxy {
|
||||
enum nft_registers sreg_addr:8;
|
||||
enum nft_registers sreg_port:8;
|
||||
u8 family;
|
||||
u8 sreg_addr;
|
||||
u8 sreg_port;
|
||||
u8 family;
|
||||
};
|
||||
|
||||
static void nft_tproxy_eval_v4(const struct nft_expr *expr,
|
||||
|
@ -247,15 +247,15 @@ static int nft_tproxy_init(const struct nft_ctx *ctx,
|
|||
}
|
||||
|
||||
if (tb[NFTA_TPROXY_REG_ADDR]) {
|
||||
priv->sreg_addr = nft_parse_register(tb[NFTA_TPROXY_REG_ADDR]);
|
||||
err = nft_validate_register_load(priv->sreg_addr, alen);
|
||||
err = nft_parse_register_load(tb[NFTA_TPROXY_REG_ADDR],
|
||||
&priv->sreg_addr, alen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (tb[NFTA_TPROXY_REG_PORT]) {
|
||||
priv->sreg_port = nft_parse_register(tb[NFTA_TPROXY_REG_PORT]);
|
||||
err = nft_validate_register_load(priv->sreg_port, sizeof(u16));
|
||||
err = nft_parse_register_load(tb[NFTA_TPROXY_REG_PORT],
|
||||
&priv->sreg_port, sizeof(u16));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
struct nft_tunnel {
|
||||
enum nft_tunnel_keys key:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
enum nft_tunnel_mode mode:8;
|
||||
};
|
||||
|
||||
|
@ -93,8 +93,6 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_TUNNEL_DREG]);
|
||||
|
||||
if (tb[NFTA_TUNNEL_MODE]) {
|
||||
priv->mode = ntohl(nla_get_be32(tb[NFTA_TUNNEL_MODE]));
|
||||
if (priv->mode > NFT_TUNNEL_MODE_MAX)
|
||||
|
@ -103,8 +101,8 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,
|
|||
priv->mode = NFT_TUNNEL_MODE_NONE;
|
||||
}
|
||||
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_TUNNEL_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
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] = {
|
|||
|
||||
struct nft_xfrm {
|
||||
enum nft_xfrm_keys key:8;
|
||||
enum nft_registers dreg:8;
|
||||
u8 dreg;
|
||||
u8 dir;
|
||||
u8 spnum;
|
||||
};
|
||||
|
@ -86,9 +86,8 @@ static int nft_xfrm_get_init(const struct nft_ctx *ctx,
|
|||
|
||||
priv->spnum = spnum;
|
||||
|
||||
priv->dreg = nft_parse_register(tb[NFTA_XFRM_DREG]);
|
||||
return nft_validate_register_store(ctx, priv->dreg, NULL,
|
||||
NFT_DATA_VALUE, len);
|
||||
return nft_parse_register_store(ctx, tb[NFTA_XFRM_DREG], &priv->dreg,
|
||||
NULL, NFT_DATA_VALUE, len);
|
||||
}
|
||||
|
||||
/* Return true if key asks for daddr/saddr and current
|
||||
|
|
Loading…
Add table
Reference in a new issue