summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-11-07 00:16:55 -0500
committerDavid S. Miller <davem@davemloft.net>2019-11-07 00:16:55 -0500
commit53ba60afb165a09559f254dfa89fe300882f31d1 (patch)
treeee8b83d01ad0ad65f17b16e56d6957b507d82302
parent98f3375505b8d6517bd6710bc6d4f6289eeb30aa (diff)
parent774e4d34dbebc9dc441535c4712794d336a9478c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Missing register size validation in bitwise and cmp offloads. 2) Fix error code in ip_set_sockfn_get() when copy_to_user() fails, from Dan Carpenter. 3) Oneliner to copy MAC address in IPv6 hash:ip,mac sets, from Stefano Brivio. 4) Missing policy validation in ipset with NL_VALIDATE_STRICT, from Jozsef Kadlecsik. 5) Fix unaligned access to private data area of nf_tables instructions, from Lukas Wunner. 6) Relax check for object updates, reported as a regression by Eric Garver, patch from Fernando Fernandez Mancera. 7) Crash on ebtables dnat extension when used from the output path. From Florian Westphal. 8) Fix bogus EOPNOTSUPP when updating basechain flags. 9) Fix bogus EBUSY when updating a basechain that is already offloaded. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/netfilter/nf_tables.h3
-rw-r--r--net/bridge/netfilter/ebt_dnat.c19
-rw-r--r--net/netfilter/ipset/ip_set_core.c49
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipmac.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_net.c1
-rw-r--r--net/netfilter/ipset/ip_set_hash_netnet.c1
-rw-r--r--net/netfilter/nf_tables_api.c7
-rw-r--r--net/netfilter/nf_tables_offload.c3
-rw-r--r--net/netfilter/nft_bitwise.c5
-rw-r--r--net/netfilter/nft_cmp.c2
10 files changed, 62 insertions, 30 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 001d294edf57..2d0275f13bbf 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -820,7 +820,8 @@ struct nft_expr_ops {
820 */ 820 */
821struct nft_expr { 821struct nft_expr {
822 const struct nft_expr_ops *ops; 822 const struct nft_expr_ops *ops;
823 unsigned char data[]; 823 unsigned char data[]
824 __attribute__((aligned(__alignof__(u64))));
824}; 825};
825 826
826static inline void *nft_expr_priv(const struct nft_expr *expr) 827static inline void *nft_expr_priv(const struct nft_expr *expr)
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index ed91ea31978a..12a4f4d93681 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -20,7 +20,6 @@ static unsigned int
20ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) 20ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
21{ 21{
22 const struct ebt_nat_info *info = par->targinfo; 22 const struct ebt_nat_info *info = par->targinfo;
23 struct net_device *dev;
24 23
25 if (skb_ensure_writable(skb, ETH_ALEN)) 24 if (skb_ensure_writable(skb, ETH_ALEN))
26 return EBT_DROP; 25 return EBT_DROP;
@@ -33,10 +32,22 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par)
33 else 32 else
34 skb->pkt_type = PACKET_MULTICAST; 33 skb->pkt_type = PACKET_MULTICAST;
35 } else { 34 } else {
36 if (xt_hooknum(par) != NF_BR_BROUTING) 35 const struct net_device *dev;
37 dev = br_port_get_rcu(xt_in(par))->br->dev; 36
38 else 37 switch (xt_hooknum(par)) {
38 case NF_BR_BROUTING:
39 dev = xt_in(par); 39 dev = xt_in(par);
40 break;
41 case NF_BR_PRE_ROUTING:
42 dev = br_port_get_rcu(xt_in(par))->br->dev;
43 break;
44 default:
45 dev = NULL;
46 break;
47 }
48
49 if (!dev) /* NF_BR_LOCAL_OUT */
50 return info->target;
40 51
41 if (ether_addr_equal(info->mac, dev->dev_addr)) 52 if (ether_addr_equal(info->mac, dev->dev_addr))
42 skb->pkt_type = PACKET_HOST; 53 skb->pkt_type = PACKET_HOST;
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index e64d5f9a89dd..d73d1828216a 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -296,7 +296,8 @@ ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr)
296 296
297 if (unlikely(!flag_nested(nla))) 297 if (unlikely(!flag_nested(nla)))
298 return -IPSET_ERR_PROTOCOL; 298 return -IPSET_ERR_PROTOCOL;
299 if (nla_parse_nested_deprecated(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy, NULL)) 299 if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla,
300 ipaddr_policy, NULL))
300 return -IPSET_ERR_PROTOCOL; 301 return -IPSET_ERR_PROTOCOL;
301 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4))) 302 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV4)))
302 return -IPSET_ERR_PROTOCOL; 303 return -IPSET_ERR_PROTOCOL;
@@ -314,7 +315,8 @@ ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
314 if (unlikely(!flag_nested(nla))) 315 if (unlikely(!flag_nested(nla)))
315 return -IPSET_ERR_PROTOCOL; 316 return -IPSET_ERR_PROTOCOL;
316 317
317 if (nla_parse_nested_deprecated(tb, IPSET_ATTR_IPADDR_MAX, nla, ipaddr_policy, NULL)) 318 if (nla_parse_nested(tb, IPSET_ATTR_IPADDR_MAX, nla,
319 ipaddr_policy, NULL))
318 return -IPSET_ERR_PROTOCOL; 320 return -IPSET_ERR_PROTOCOL;
319 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6))) 321 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_IPADDR_IPV6)))
320 return -IPSET_ERR_PROTOCOL; 322 return -IPSET_ERR_PROTOCOL;
@@ -934,7 +936,8 @@ static int ip_set_create(struct net *net, struct sock *ctnl,
934 936
935 /* Without holding any locks, create private part. */ 937 /* Without holding any locks, create private part. */
936 if (attr[IPSET_ATTR_DATA] && 938 if (attr[IPSET_ATTR_DATA] &&
937 nla_parse_nested_deprecated(tb, IPSET_ATTR_CREATE_MAX, attr[IPSET_ATTR_DATA], set->type->create_policy, NULL)) { 939 nla_parse_nested(tb, IPSET_ATTR_CREATE_MAX, attr[IPSET_ATTR_DATA],
940 set->type->create_policy, NULL)) {
938 ret = -IPSET_ERR_PROTOCOL; 941 ret = -IPSET_ERR_PROTOCOL;
939 goto put_out; 942 goto put_out;
940 } 943 }
@@ -1281,6 +1284,14 @@ dump_attrs(struct nlmsghdr *nlh)
1281 } 1284 }
1282} 1285}
1283 1286
1287static const struct nla_policy
1288ip_set_dump_policy[IPSET_ATTR_CMD_MAX + 1] = {
1289 [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 },
1290 [IPSET_ATTR_SETNAME] = { .type = NLA_NUL_STRING,
1291 .len = IPSET_MAXNAMELEN - 1 },
1292 [IPSET_ATTR_FLAGS] = { .type = NLA_U32 },
1293};
1294
1284static int 1295static int
1285dump_init(struct netlink_callback *cb, struct ip_set_net *inst) 1296dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
1286{ 1297{
@@ -1292,9 +1303,9 @@ dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
1292 ip_set_id_t index; 1303 ip_set_id_t index;
1293 int ret; 1304 int ret;
1294 1305
1295 ret = nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, attr, 1306 ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, attr,
1296 nlh->nlmsg_len - min_len, 1307 nlh->nlmsg_len - min_len,
1297 ip_set_setname_policy, NULL); 1308 ip_set_dump_policy, NULL);
1298 if (ret) 1309 if (ret)
1299 return ret; 1310 return ret;
1300 1311
@@ -1543,9 +1554,9 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
1543 memcpy(&errmsg->msg, nlh, nlh->nlmsg_len); 1554 memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
1544 cmdattr = (void *)&errmsg->msg + min_len; 1555 cmdattr = (void *)&errmsg->msg + min_len;
1545 1556
1546 ret = nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, cmdattr, 1557 ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr,
1547 nlh->nlmsg_len - min_len, 1558 nlh->nlmsg_len - min_len, ip_set_adt_policy,
1548 ip_set_adt_policy, NULL); 1559 NULL);
1549 1560
1550 if (ret) { 1561 if (ret) {
1551 nlmsg_free(skb2); 1562 nlmsg_free(skb2);
@@ -1596,7 +1607,9 @@ static int ip_set_ad(struct net *net, struct sock *ctnl,
1596 1607
1597 use_lineno = !!attr[IPSET_ATTR_LINENO]; 1608 use_lineno = !!attr[IPSET_ATTR_LINENO];
1598 if (attr[IPSET_ATTR_DATA]) { 1609 if (attr[IPSET_ATTR_DATA]) {
1599 if (nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA], set->type->adt_policy, NULL)) 1610 if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX,
1611 attr[IPSET_ATTR_DATA],
1612 set->type->adt_policy, NULL))
1600 return -IPSET_ERR_PROTOCOL; 1613 return -IPSET_ERR_PROTOCOL;
1601 ret = call_ad(ctnl, skb, set, tb, adt, flags, 1614 ret = call_ad(ctnl, skb, set, tb, adt, flags,
1602 use_lineno); 1615 use_lineno);
@@ -1606,7 +1619,8 @@ static int ip_set_ad(struct net *net, struct sock *ctnl,
1606 nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) { 1619 nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) {
1607 if (nla_type(nla) != IPSET_ATTR_DATA || 1620 if (nla_type(nla) != IPSET_ATTR_DATA ||
1608 !flag_nested(nla) || 1621 !flag_nested(nla) ||
1609 nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, nla, set->type->adt_policy, NULL)) 1622 nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla,
1623 set->type->adt_policy, NULL))
1610 return -IPSET_ERR_PROTOCOL; 1624 return -IPSET_ERR_PROTOCOL;
1611 ret = call_ad(ctnl, skb, set, tb, adt, 1625 ret = call_ad(ctnl, skb, set, tb, adt,
1612 flags, use_lineno); 1626 flags, use_lineno);
@@ -1655,7 +1669,8 @@ static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1655 if (!set) 1669 if (!set)
1656 return -ENOENT; 1670 return -ENOENT;
1657 1671
1658 if (nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA], set->type->adt_policy, NULL)) 1672 if (nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA],
1673 set->type->adt_policy, NULL))
1659 return -IPSET_ERR_PROTOCOL; 1674 return -IPSET_ERR_PROTOCOL;
1660 1675
1661 rcu_read_lock_bh(); 1676 rcu_read_lock_bh();
@@ -1961,7 +1976,7 @@ static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] = {
1961 [IPSET_CMD_LIST] = { 1976 [IPSET_CMD_LIST] = {
1962 .call = ip_set_dump, 1977 .call = ip_set_dump,
1963 .attr_count = IPSET_ATTR_CMD_MAX, 1978 .attr_count = IPSET_ATTR_CMD_MAX,
1964 .policy = ip_set_setname_policy, 1979 .policy = ip_set_dump_policy,
1965 }, 1980 },
1966 [IPSET_CMD_SAVE] = { 1981 [IPSET_CMD_SAVE] = {
1967 .call = ip_set_dump, 1982 .call = ip_set_dump,
@@ -2069,8 +2084,9 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
2069 } 2084 }
2070 2085
2071 req_version->version = IPSET_PROTOCOL; 2086 req_version->version = IPSET_PROTOCOL;
2072 ret = copy_to_user(user, req_version, 2087 if (copy_to_user(user, req_version,
2073 sizeof(struct ip_set_req_version)); 2088 sizeof(struct ip_set_req_version)))
2089 ret = -EFAULT;
2074 goto done; 2090 goto done;
2075 } 2091 }
2076 case IP_SET_OP_GET_BYNAME: { 2092 case IP_SET_OP_GET_BYNAME: {
@@ -2129,7 +2145,8 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
2129 } /* end of switch(op) */ 2145 } /* end of switch(op) */
2130 2146
2131copy: 2147copy:
2132 ret = copy_to_user(user, data, copylen); 2148 if (copy_to_user(user, data, copylen))
2149 ret = -EFAULT;
2133 2150
2134done: 2151done:
2135 vfree(data); 2152 vfree(data);
diff --git a/net/netfilter/ipset/ip_set_hash_ipmac.c b/net/netfilter/ipset/ip_set_hash_ipmac.c
index 24d8f4df4230..4ce563eb927d 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmac.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmac.c
@@ -209,7 +209,7 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
209 (skb_mac_header(skb) + ETH_HLEN) > skb->data) 209 (skb_mac_header(skb) + ETH_HLEN) > skb->data)
210 return -EINVAL; 210 return -EINVAL;
211 211
212 if (opt->flags & IPSET_DIM_ONE_SRC) 212 if (opt->flags & IPSET_DIM_TWO_SRC)
213 ether_addr_copy(e.ether, eth_hdr(skb)->h_source); 213 ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
214 else 214 else
215 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest); 215 ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index c259cbc3ef45..3d932de0ad29 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -368,6 +368,7 @@ static struct ip_set_type hash_net_type __read_mostly = {
368 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 368 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
369 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 369 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
370 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 370 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
371 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
371 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 372 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
372 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 373 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
373 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 374 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index a3ae69bfee66..4398322fad59 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -476,6 +476,7 @@ static struct ip_set_type hash_netnet_type __read_mostly = {
476 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 476 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
477 [IPSET_ATTR_CIDR2] = { .type = NLA_U8 }, 477 [IPSET_ATTR_CIDR2] = { .type = NLA_U8 },
478 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 478 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
479 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
479 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 480 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
480 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 481 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
481 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 482 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d481f9baca2f..712a428509ad 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1922,6 +1922,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1922 if (nlh->nlmsg_flags & NLM_F_REPLACE) 1922 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1923 return -EOPNOTSUPP; 1923 return -EOPNOTSUPP;
1924 1924
1925 flags |= chain->flags & NFT_BASE_CHAIN;
1925 return nf_tables_updchain(&ctx, genmask, policy, flags); 1926 return nf_tables_updchain(&ctx, genmask, policy, flags);
1926 } 1927 }
1927 1928
@@ -5143,9 +5144,6 @@ static int nf_tables_updobj(const struct nft_ctx *ctx,
5143 struct nft_trans *trans; 5144 struct nft_trans *trans;
5144 int err; 5145 int err;
5145 5146
5146 if (!obj->ops->update)
5147 return -EOPNOTSUPP;
5148
5149 trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ, 5147 trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ,
5150 sizeof(struct nft_trans_obj)); 5148 sizeof(struct nft_trans_obj));
5151 if (!trans) 5149 if (!trans)
@@ -6499,7 +6497,8 @@ static void nft_obj_commit_update(struct nft_trans *trans)
6499 obj = nft_trans_obj(trans); 6497 obj = nft_trans_obj(trans);
6500 newobj = nft_trans_obj_newobj(trans); 6498 newobj = nft_trans_obj_newobj(trans);
6501 6499
6502 obj->ops->update(obj, newobj); 6500 if (obj->ops->update)
6501 obj->ops->update(obj, newobj);
6503 6502
6504 kfree(newobj); 6503 kfree(newobj);
6505} 6504}
diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c
index ad783f4840ef..e25dab8128db 100644
--- a/net/netfilter/nf_tables_offload.c
+++ b/net/netfilter/nf_tables_offload.c
@@ -334,7 +334,8 @@ int nft_flow_rule_offload_commit(struct net *net)
334 334
335 switch (trans->msg_type) { 335 switch (trans->msg_type) {
336 case NFT_MSG_NEWCHAIN: 336 case NFT_MSG_NEWCHAIN:
337 if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) 337 if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) ||
338 nft_trans_chain_update(trans))
338 continue; 339 continue;
339 340
340 policy = nft_trans_chain_policy(trans); 341 policy = nft_trans_chain_policy(trans);
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 974300178fa9..02afa752dd2e 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -134,12 +134,13 @@ static int nft_bitwise_offload(struct nft_offload_ctx *ctx,
134 const struct nft_expr *expr) 134 const struct nft_expr *expr)
135{ 135{
136 const struct nft_bitwise *priv = nft_expr_priv(expr); 136 const struct nft_bitwise *priv = nft_expr_priv(expr);
137 struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
137 138
138 if (memcmp(&priv->xor, &zero, sizeof(priv->xor)) || 139 if (memcmp(&priv->xor, &zero, sizeof(priv->xor)) ||
139 priv->sreg != priv->dreg) 140 priv->sreg != priv->dreg || priv->len != reg->len)
140 return -EOPNOTSUPP; 141 return -EOPNOTSUPP;
141 142
142 memcpy(&ctx->regs[priv->dreg].mask, &priv->mask, sizeof(priv->mask)); 143 memcpy(&reg->mask, &priv->mask, sizeof(priv->mask));
143 144
144 return 0; 145 return 0;
145} 146}
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index bd173b1824c6..0744b2bb46da 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -116,7 +116,7 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
116 u8 *mask = (u8 *)&flow->match.mask; 116 u8 *mask = (u8 *)&flow->match.mask;
117 u8 *key = (u8 *)&flow->match.key; 117 u8 *key = (u8 *)&flow->match.key;
118 118
119 if (priv->op != NFT_CMP_EQ) 119 if (priv->op != NFT_CMP_EQ || reg->len != priv->len)
120 return -EOPNOTSUPP; 120 return -EOPNOTSUPP;
121 121
122 memcpy(key + reg->offset, &priv->data, priv->len); 122 memcpy(key + reg->offset, &priv->data, priv->len);