netfilter pull request 24-01-24
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEN9lkrMBJgcdVAPub1V2XiooUIOQFAmWxX0UACgkQ1V2XiooU IOTN2xAAq60JXo1A05dnma3DzXxIsCQKmum+ph1ii8gvZ2qqJT5+CVk0pMuHXEfi UPt/FfGIC3WZQ7yOLLxkGeUv8g7rxCncIsJtjxQSTh1gaQhePiATMUpwIhJ5W5tq QUw6DrZfv3Y95Gth61BDokBEhGVntWTV2ra608gx5PrpXQvCid7CJqKeg3hzaoSr cWonnRsxlwHdu1R4vqrZwnEMj6BBJfviOvS9HPGEul9LRQneXNRMuEJ0L73vjU9h gdh8oQHxoAgOHsK1KczNK9no9rnGgmLS9K98tBjRYdJwfxsI4YSjL3/+FnxTgWgp GsGZP+/+aQD+GKAN/eAO7cjfaSZweqhr8JxaUdyOZRqeQYw2v3SV2zyEKTw2hahM 1JvY7oEtthMMylPxJac075jbeizoNRU9J5AeJNqWexMZK5P6Yb0BC5DRUeHC0+RN y99Yj5z4fwMmBgWdTBXnIm0k87bouQsQBDS3Rn7QTD2b1RhQTTEar+W816QyOBng 8tllV25b4SOtXc6xouqP4YgCB1wuYN74Bvxb+vgGK2mj9oTLpTMEtFXXduenqoGl wQutx0fumJMAHTIHz77RDlTAanEbFOEq35R0PV+cfm9173inI77bZyGcznWlM+Zn fM+Gr1ka4JmO6RegYJHh3kUrM2l43zVmN8O1gQCnkRuJJZ6BwVk= =SirU -----END PGP SIGNATURE----- Merge tag 'nf-24-01-24' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Update nf_tables kdoc to keep it in sync with the code, from George Guo. 2) Handle NETDEV_UNREGISTER event for inet/ingress basechain. 3) Reject configuration that cause nft_limit to overflow, from Florian Westphal. 4) Restrict anonymous set/map names to 16 bytes, from Florian Westphal. 5) Disallow to encode queue number and error in verdicts. This reverts a patch which seems to have introduced an early attempt to support for nfqueue maps, which is these days supported via nft_queue expression. 6) Sanitize family via .validate for expressions that explicitly refer to NF_INET_* hooks. * tag 'nf-24-01-24' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nf_tables: validate NFPROTO_* family netfilter: nf_tables: reject QUEUE/DROP verdict parameters netfilter: nf_tables: restrict anonymous set and map names to 16 bytes netfilter: nft_limit: reject configurations that cause integer overflow netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress basechain netfilter: nf_tables: cleanup documentation ==================== Link: https://lore.kernel.org/r/20240124191248.75463-1-pablo@netfilter.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
a717932db1
@ -205,6 +205,7 @@ static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
|
||||
* @nla: netlink attributes
|
||||
* @portid: netlink portID of the original message
|
||||
* @seq: netlink sequence number
|
||||
* @flags: modifiers to new request
|
||||
* @family: protocol family
|
||||
* @level: depth of the chains
|
||||
* @report: notify via unicast netlink message
|
||||
@ -282,6 +283,7 @@ struct nft_elem_priv { };
|
||||
*
|
||||
* @key: element key
|
||||
* @key_end: closing element key
|
||||
* @data: element data
|
||||
* @priv: element private data and extensions
|
||||
*/
|
||||
struct nft_set_elem {
|
||||
@ -325,10 +327,10 @@ struct nft_set_iter {
|
||||
* @dtype: data type
|
||||
* @dlen: data length
|
||||
* @objtype: object type
|
||||
* @flags: flags
|
||||
* @size: number of set elements
|
||||
* @policy: set policy
|
||||
* @gc_int: garbage collector interval
|
||||
* @timeout: element timeout
|
||||
* @field_len: length of each field in concatenation, bytes
|
||||
* @field_count: number of concatenated fields in element
|
||||
* @expr: set must support for expressions
|
||||
@ -351,9 +353,9 @@ struct nft_set_desc {
|
||||
/**
|
||||
* enum nft_set_class - performance class
|
||||
*
|
||||
* @NFT_LOOKUP_O_1: constant, O(1)
|
||||
* @NFT_LOOKUP_O_LOG_N: logarithmic, O(log N)
|
||||
* @NFT_LOOKUP_O_N: linear, O(N)
|
||||
* @NFT_SET_CLASS_O_1: constant, O(1)
|
||||
* @NFT_SET_CLASS_O_LOG_N: logarithmic, O(log N)
|
||||
* @NFT_SET_CLASS_O_N: linear, O(N)
|
||||
*/
|
||||
enum nft_set_class {
|
||||
NFT_SET_CLASS_O_1,
|
||||
@ -422,9 +424,13 @@ struct nft_set_ext;
|
||||
* @remove: remove element from set
|
||||
* @walk: iterate over all set elements
|
||||
* @get: get set elements
|
||||
* @commit: commit set elements
|
||||
* @abort: abort set elements
|
||||
* @privsize: function to return size of set private data
|
||||
* @estimate: estimate the required memory size and the lookup complexity class
|
||||
* @init: initialize private data of new set instance
|
||||
* @destroy: destroy private data of set instance
|
||||
* @gc_init: initialize garbage collection
|
||||
* @elemsize: element private size
|
||||
*
|
||||
* Operations lookup, update and delete have simpler interfaces, are faster
|
||||
@ -540,13 +546,16 @@ struct nft_set_elem_expr {
|
||||
* @policy: set parameterization (see enum nft_set_policies)
|
||||
* @udlen: user data length
|
||||
* @udata: user data
|
||||
* @expr: stateful expression
|
||||
* @pending_update: list of pending update set element
|
||||
* @ops: set ops
|
||||
* @flags: set flags
|
||||
* @dead: set will be freed, never cleared
|
||||
* @genmask: generation mask
|
||||
* @klen: key length
|
||||
* @dlen: data length
|
||||
* @num_exprs: numbers of exprs
|
||||
* @exprs: stateful expression
|
||||
* @catchall_list: list of catch-all set element
|
||||
* @data: private set data
|
||||
*/
|
||||
struct nft_set {
|
||||
@ -692,6 +701,7 @@ extern const struct nft_set_ext_type nft_set_ext_types[];
|
||||
*
|
||||
* @len: length of extension area
|
||||
* @offset: offsets of individual extension types
|
||||
* @ext_len: length of the expected extension(used to sanity check)
|
||||
*/
|
||||
struct nft_set_ext_tmpl {
|
||||
u16 len;
|
||||
@ -840,6 +850,7 @@ struct nft_expr_ops;
|
||||
* @select_ops: function to select nft_expr_ops
|
||||
* @release_ops: release nft_expr_ops
|
||||
* @ops: default ops, used when no select_ops functions is present
|
||||
* @inner_ops: inner ops, used for inner packet operation
|
||||
* @list: used internally
|
||||
* @name: Identifier
|
||||
* @owner: module reference
|
||||
@ -881,14 +892,22 @@ struct nft_offload_ctx;
|
||||
* struct nft_expr_ops - nf_tables expression operations
|
||||
*
|
||||
* @eval: Expression evaluation function
|
||||
* @clone: Expression clone function
|
||||
* @size: full expression size, including private data size
|
||||
* @init: initialization function
|
||||
* @activate: activate expression in the next generation
|
||||
* @deactivate: deactivate expression in next generation
|
||||
* @destroy: destruction function, called after synchronize_rcu
|
||||
* @destroy_clone: destruction clone function
|
||||
* @dump: function to dump parameters
|
||||
* @type: expression type
|
||||
* @validate: validate expression, called during loop detection
|
||||
* @reduce: reduce expression
|
||||
* @gc: garbage collection expression
|
||||
* @offload: hardware offload expression
|
||||
* @offload_action: function to report true/false to allocate one slot or not in the flow
|
||||
* offload array
|
||||
* @offload_stats: function to synchronize hardware stats via updating the counter expression
|
||||
* @type: expression type
|
||||
* @data: extra data to attach to this expression operation
|
||||
*/
|
||||
struct nft_expr_ops {
|
||||
@ -1041,14 +1060,21 @@ struct nft_rule_blob {
|
||||
/**
|
||||
* struct nft_chain - nf_tables chain
|
||||
*
|
||||
* @blob_gen_0: rule blob pointer to the current generation
|
||||
* @blob_gen_1: rule blob pointer to the future generation
|
||||
* @rules: list of rules in the chain
|
||||
* @list: used internally
|
||||
* @rhlhead: used internally
|
||||
* @table: table that this chain belongs to
|
||||
* @handle: chain handle
|
||||
* @use: number of jump references to this chain
|
||||
* @flags: bitmask of enum nft_chain_flags
|
||||
* @flags: bitmask of enum NFTA_CHAIN_FLAGS
|
||||
* @bound: bind or not
|
||||
* @genmask: generation mask
|
||||
* @name: name of the chain
|
||||
* @udlen: user data length
|
||||
* @udata: user data in the chain
|
||||
* @blob_next: rule blob pointer to the next in the chain
|
||||
*/
|
||||
struct nft_chain {
|
||||
struct nft_rule_blob __rcu *blob_gen_0;
|
||||
@ -1146,6 +1172,7 @@ struct nft_hook {
|
||||
* @hook_list: list of netfilter hooks (for NFPROTO_NETDEV family)
|
||||
* @type: chain type
|
||||
* @policy: default policy
|
||||
* @flags: indicate the base chain disabled or not
|
||||
* @stats: per-cpu chain stats
|
||||
* @chain: the chain
|
||||
* @flow_block: flow block (for hardware offload)
|
||||
@ -1274,11 +1301,13 @@ struct nft_object_hash_key {
|
||||
* struct nft_object - nf_tables stateful object
|
||||
*
|
||||
* @list: table stateful object list node
|
||||
* @key: keys that identify this object
|
||||
* @rhlhead: nft_objname_ht node
|
||||
* @key: keys that identify this object
|
||||
* @genmask: generation mask
|
||||
* @use: number of references to this stateful object
|
||||
* @handle: unique object handle
|
||||
* @udlen: length of user data
|
||||
* @udata: user data
|
||||
* @ops: object operations
|
||||
* @data: object data, layout depends on type
|
||||
*/
|
||||
@ -1344,6 +1373,7 @@ struct nft_object_type {
|
||||
* @destroy: release existing stateful object
|
||||
* @dump: netlink dump stateful object
|
||||
* @update: update stateful object
|
||||
* @type: pointer to object type
|
||||
*/
|
||||
struct nft_object_ops {
|
||||
void (*eval)(struct nft_object *obj,
|
||||
@ -1379,9 +1409,8 @@ void nft_unregister_obj(struct nft_object_type *obj_type);
|
||||
* @genmask: generation mask
|
||||
* @use: number of references to this flow table
|
||||
* @handle: unique object handle
|
||||
* @dev_name: array of device names
|
||||
* @hook_list: hook list for hooks per net_device in flowtables
|
||||
* @data: rhashtable and garbage collector
|
||||
* @ops: array of hooks
|
||||
*/
|
||||
struct nft_flowtable {
|
||||
struct list_head list;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <net/sock.h>
|
||||
|
||||
#define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
|
||||
#define NFT_SET_MAX_ANONLEN 16
|
||||
|
||||
unsigned int nf_tables_net_id __read_mostly;
|
||||
|
||||
@ -4413,6 +4414,9 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
|
||||
if (p[1] != 'd' || strchr(p + 2, '%'))
|
||||
return -EINVAL;
|
||||
|
||||
if (strnlen(name, NFT_SET_MAX_ANONLEN) >= NFT_SET_MAX_ANONLEN)
|
||||
return -EINVAL;
|
||||
|
||||
inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
|
||||
if (inuse == NULL)
|
||||
return -ENOMEM;
|
||||
@ -10988,16 +10992,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
||||
data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
|
||||
|
||||
switch (data->verdict.code) {
|
||||
default:
|
||||
switch (data->verdict.code & NF_VERDICT_MASK) {
|
||||
case NF_ACCEPT:
|
||||
case NF_DROP:
|
||||
case NF_QUEUE:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
fallthrough;
|
||||
case NF_ACCEPT:
|
||||
case NF_DROP:
|
||||
case NF_QUEUE:
|
||||
break;
|
||||
case NFT_CONTINUE:
|
||||
case NFT_BREAK:
|
||||
case NFT_RETURN:
|
||||
@ -11032,6 +11030,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
||||
|
||||
data->verdict.chain = chain;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->len = sizeof(data->verdict);
|
||||
|
@ -357,9 +357,10 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct nft_base_chain *basechain;
|
||||
struct nftables_pernet *nft_net;
|
||||
struct nft_table *table;
|
||||
struct nft_chain *chain, *nr;
|
||||
struct nft_table *table;
|
||||
struct nft_ctx ctx = {
|
||||
.net = dev_net(dev),
|
||||
};
|
||||
@ -371,7 +372,8 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
||||
nft_net = nft_pernet(ctx.net);
|
||||
mutex_lock(&nft_net->commit_mutex);
|
||||
list_for_each_entry(table, &nft_net->tables, list) {
|
||||
if (table->family != NFPROTO_NETDEV)
|
||||
if (table->family != NFPROTO_NETDEV &&
|
||||
table->family != NFPROTO_INET)
|
||||
continue;
|
||||
|
||||
ctx.family = table->family;
|
||||
@ -380,6 +382,11 @@ static int nf_tables_netdev_event(struct notifier_block *this,
|
||||
if (!nft_is_base_chain(chain))
|
||||
continue;
|
||||
|
||||
basechain = nft_base_chain(chain);
|
||||
if (table->family == NFPROTO_INET &&
|
||||
basechain->ops.hooknum != NF_INET_INGRESS)
|
||||
continue;
|
||||
|
||||
ctx.chain = chain;
|
||||
nft_netdev_event(event, dev, &ctx);
|
||||
}
|
||||
|
@ -350,6 +350,12 @@ static int nft_target_validate(const struct nft_ctx *ctx,
|
||||
unsigned int hook_mask = 0;
|
||||
int ret;
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_BRIDGE &&
|
||||
ctx->family != NFPROTO_ARP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (nft_is_base_chain(ctx->chain)) {
|
||||
const struct nft_base_chain *basechain =
|
||||
nft_base_chain(ctx->chain);
|
||||
@ -595,6 +601,12 @@ static int nft_match_validate(const struct nft_ctx *ctx,
|
||||
unsigned int hook_mask = 0;
|
||||
int ret;
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_BRIDGE &&
|
||||
ctx->family != NFPROTO_ARP)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (nft_is_base_chain(ctx->chain)) {
|
||||
const struct nft_base_chain *basechain =
|
||||
nft_base_chain(ctx->chain);
|
||||
|
@ -384,6 +384,11 @@ static int nft_flow_offload_validate(const struct nft_ctx *ctx,
|
||||
{
|
||||
unsigned int hook_mask = (1 << NF_INET_FORWARD);
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain, hook_mask);
|
||||
}
|
||||
|
||||
|
@ -58,17 +58,19 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
|
||||
static int nft_limit_init(struct nft_limit_priv *priv,
|
||||
const struct nlattr * const tb[], bool pkts)
|
||||
{
|
||||
u64 unit, tokens, rate_with_burst;
|
||||
bool invert = false;
|
||||
u64 unit, tokens;
|
||||
|
||||
if (tb[NFTA_LIMIT_RATE] == NULL ||
|
||||
tb[NFTA_LIMIT_UNIT] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE]));
|
||||
if (priv->rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT]));
|
||||
priv->nsecs = unit * NSEC_PER_SEC;
|
||||
if (priv->rate == 0 || priv->nsecs < unit)
|
||||
if (check_mul_overflow(unit, NSEC_PER_SEC, &priv->nsecs))
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (tb[NFTA_LIMIT_BURST])
|
||||
@ -77,18 +79,25 @@ static int nft_limit_init(struct nft_limit_priv *priv,
|
||||
if (pkts && priv->burst == 0)
|
||||
priv->burst = NFT_LIMIT_PKT_BURST_DEFAULT;
|
||||
|
||||
if (priv->rate + priv->burst < priv->rate)
|
||||
if (check_add_overflow(priv->rate, priv->burst, &rate_with_burst))
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (pkts) {
|
||||
tokens = div64_u64(priv->nsecs, priv->rate) * priv->burst;
|
||||
u64 tmp = div64_u64(priv->nsecs, priv->rate);
|
||||
|
||||
if (check_mul_overflow(tmp, priv->burst, &tokens))
|
||||
return -EOVERFLOW;
|
||||
} else {
|
||||
u64 tmp;
|
||||
|
||||
/* The token bucket size limits the number of tokens can be
|
||||
* accumulated. tokens_max specifies the bucket size.
|
||||
* tokens_max = unit * (rate + burst) / rate.
|
||||
*/
|
||||
tokens = div64_u64(priv->nsecs * (priv->rate + priv->burst),
|
||||
priv->rate);
|
||||
if (check_mul_overflow(priv->nsecs, rate_with_burst, &tmp))
|
||||
return -EOVERFLOW;
|
||||
|
||||
tokens = div64_u64(tmp, priv->rate);
|
||||
}
|
||||
|
||||
if (tb[NFTA_LIMIT_FLAGS]) {
|
||||
|
@ -143,6 +143,11 @@ static int nft_nat_validate(const struct nft_ctx *ctx,
|
||||
struct nft_nat *priv = nft_expr_priv(expr);
|
||||
int err;
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -166,6 +166,11 @@ static int nft_rt_validate(const struct nft_ctx *ctx, const struct nft_expr *exp
|
||||
const struct nft_rt *priv = nft_expr_priv(expr);
|
||||
unsigned int hooks;
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (priv->key) {
|
||||
case NFT_RT_NEXTHOP4:
|
||||
case NFT_RT_NEXTHOP6:
|
||||
|
@ -242,6 +242,11 @@ static int nft_socket_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain,
|
||||
(1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_LOCAL_IN) |
|
||||
|
@ -186,7 +186,6 @@ static int nft_synproxy_do_init(const struct nft_ctx *ctx,
|
||||
break;
|
||||
#endif
|
||||
case NFPROTO_INET:
|
||||
case NFPROTO_BRIDGE:
|
||||
err = nf_synproxy_ipv4_init(snet, ctx->net);
|
||||
if (err)
|
||||
goto nf_ct_failure;
|
||||
@ -219,7 +218,6 @@ static void nft_synproxy_do_destroy(const struct nft_ctx *ctx)
|
||||
break;
|
||||
#endif
|
||||
case NFPROTO_INET:
|
||||
case NFPROTO_BRIDGE:
|
||||
nf_synproxy_ipv4_fini(snet, ctx->net);
|
||||
nf_synproxy_ipv6_fini(snet, ctx->net);
|
||||
break;
|
||||
@ -253,6 +251,11 @@ static int nft_synproxy_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_LOCAL_IN) |
|
||||
(1 << NF_INET_FORWARD));
|
||||
}
|
||||
|
@ -316,6 +316,11 @@ static int nft_tproxy_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING);
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,11 @@ static int nft_xfrm_validate(const struct nft_ctx *ctx, const struct nft_expr *e
|
||||
const struct nft_xfrm *priv = nft_expr_priv(expr);
|
||||
unsigned int hooks;
|
||||
|
||||
if (ctx->family != NFPROTO_IPV4 &&
|
||||
ctx->family != NFPROTO_IPV6 &&
|
||||
ctx->family != NFPROTO_INET)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (priv->dir) {
|
||||
case XFRM_POLICY_IN:
|
||||
hooks = (1 << NF_INET_FORWARD) |
|
||||
|
Loading…
x
Reference in New Issue
Block a user