* [PATCH nf-next] netfilter: use nfnetlink_unicast()
@ 2021-05-17 12:43 Pablo Neira Ayuso
0 siblings, 0 replies; only message in thread
From: Pablo Neira Ayuso @ 2021-05-17 12:43 UTC (permalink / raw
To: netfilter-devel; +Cc: kadlec
Replace netlink_unicast() calls by nfnetlink_unicast() which already
deals with translating EAGAIN to ENOBUFS as the nfnetlink core expects.
nfnetlink_unicast() calls nlmsg_unicast() which also sets the return
value to zero in case of success, otherwise the netlink core function
netlink_rcv_skb() turns err > 0 into an acknowlegment.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
@Jozsef: I skipped ipset conversion to nfnetlink_unicast(),
ip_set_header(), ip_set_type() and ip_set_protocol() use netlink_unicast()
which returns > 0 in case of success. I think this triggers an acknowlegment
message when netlink_rcv_skb() is called.
I can see lib/mnl.c in ipset userspace do not set NLM_F_ACK.
static const uint16_t cmdflags[] = {
[IPSET_CMD_CREATE-1] = NLM_F_REQUEST|NLM_F_ACK|
NLM_F_CREATE|NLM_F_EXCL,
[IPSET_CMD_DESTROY-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL,
[IPSET_CMD_FLUSH-1] = NLM_F_REQUEST|NLM_F_ACK,
[IPSET_CMD_RENAME-1] = NLM_F_REQUEST|NLM_F_ACK,
[IPSET_CMD_SWAP-1] = NLM_F_REQUEST|NLM_F_ACK,
[IPSET_CMD_LIST-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_DUMP,
[IPSET_CMD_SAVE-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_DUMP,
[IPSET_CMD_ADD-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL,
[IPSET_CMD_DEL-1] = NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL,
[IPSET_CMD_TEST-1] = NLM_F_REQUEST|NLM_F_ACK,
[IPSET_CMD_HEADER-1] = NLM_F_REQUEST,
[IPSET_CMD_TYPE-1] = NLM_F_REQUEST,
[IPSET_CMD_PROTOCOL-1] = NLM_F_REQUEST,
I did not test but maybe userspace is expecting the NLM_F_ACK message
as reply to the IPSET_CMD_HEADER, IPSET_CMD_TYPE and IPSET_CMD_PROTOCOL
commands.
net/netfilter/nf_conntrack_netlink.c | 41 ++++++++++------------------
net/netfilter/nfnetlink_acct.c | 9 ++----
net/netfilter/nfnetlink_cthelper.c | 10 ++-----
net/netfilter/nfnetlink_cttimeout.c | 34 +++++++----------------
4 files changed, 31 insertions(+), 63 deletions(-)
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 8690fc07030f..3b2aacaa75d4 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1643,18 +1643,15 @@ static int ctnetlink_get_conntrack(struct sk_buff *skb,
if (err <= 0)
goto free;
- err = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
+ err = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
if (err < 0)
- goto out;
+ return err;
return 0;
-
free:
kfree_skb(skb2);
-out:
- /* this avoids a loop in nfnetlink. */
- return err == -EAGAIN ? -ENOBUFS : err;
+
+ return -ENOMEM;
}
static int ctnetlink_done_list(struct netlink_callback *cb)
@@ -2593,18 +2590,15 @@ static int ctnetlink_stat_ct(struct sk_buff *skb, const struct nfnl_info *info,
if (err <= 0)
goto free;
- err = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
+ err = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
if (err < 0)
- goto out;
+ return err;
return 0;
-
free:
kfree_skb(skb2);
-out:
- /* this avoids a loop in nfnetlink. */
- return err == -EAGAIN ? -ENOBUFS : err;
+
+ return -ENOMEM;
}
static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
@@ -3333,7 +3327,7 @@ static int ctnetlink_get_expect(struct sk_buff *skb,
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (skb2 == NULL) {
nf_ct_expect_put(exp);
- goto out;
+ return -ENOMEM;
}
rcu_read_lock();
@@ -3342,21 +3336,16 @@ static int ctnetlink_get_expect(struct sk_buff *skb,
exp);
rcu_read_unlock();
nf_ct_expect_put(exp);
- if (err <= 0)
- goto free;
+ if (err <= 0) {
+ kfree_skb(skb2);
+ return -ENOMEM;
+ }
- err = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
+ err = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
if (err < 0)
- goto out;
+ return err;
return 0;
-
-free:
- kfree_skb(skb2);
-out:
- /* this avoids a loop in nfnetlink. */
- return err == -EAGAIN ? -ENOBUFS : err;
}
static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index 3c8cf8748cfb..505f46a32173 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -314,14 +314,11 @@ static int nfnl_acct_get(struct sk_buff *skb, const struct nfnl_info *info,
kfree_skb(skb2);
break;
}
- ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
- if (ret > 0)
- ret = 0;
- /* this avoids a loop in nfnetlink. */
- return ret == -EAGAIN ? -ENOBUFS : ret;
+ ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
+ break;
}
+
return ret;
}
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index 322ac5dd5402..df58cd534ff5 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -663,14 +663,10 @@ static int nfnl_cthelper_get(struct sk_buff *skb, const struct nfnl_info *info,
break;
}
- ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
- if (ret > 0)
- ret = 0;
-
- /* this avoids a loop in nfnetlink. */
- return ret == -EAGAIN ? -ENOBUFS : ret;
+ ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
+ break;
}
+
return ret;
}
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 38848ad68899..5d72b3055378 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -287,14 +287,11 @@ static int cttimeout_get_timeout(struct sk_buff *skb,
kfree_skb(skb2);
break;
}
- ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
- if (ret > 0)
- ret = 0;
- /* this avoids a loop in nfnetlink. */
- return ret == -EAGAIN ? -ENOBUFS : ret;
+ ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
+ break;
}
+
return ret;
}
@@ -427,9 +424,9 @@ static int cttimeout_default_get(struct sk_buff *skb,
const struct nf_conntrack_l4proto *l4proto;
unsigned int *timeouts = NULL;
struct sk_buff *skb2;
- int ret, err;
__u16 l3num;
__u8 l4num;
+ int ret;
if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
return -EINVAL;
@@ -438,9 +435,8 @@ static int cttimeout_default_get(struct sk_buff *skb,
l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
l4proto = nf_ct_l4proto_find(l4num);
- err = -EOPNOTSUPP;
if (l4proto->l4proto != l4num)
- goto err;
+ return -EOPNOTSUPP;
switch (l4proto->l4proto) {
case IPPROTO_ICMP:
@@ -480,13 +476,11 @@ static int cttimeout_default_get(struct sk_buff *skb,
}
if (!timeouts)
- goto err;
+ return -EOPNOTSUPP;
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (skb2 == NULL) {
- err = -ENOMEM;
- goto err;
- }
+ if (skb2 == NULL)
+ return -ENOMEM;
ret = cttimeout_default_fill_info(info->net, skb2,
NETLINK_CB(skb).portid,
@@ -496,18 +490,10 @@ static int cttimeout_default_get(struct sk_buff *skb,
l3num, l4proto, timeouts);
if (ret <= 0) {
kfree_skb(skb2);
- err = -ENOMEM;
- goto err;
+ return -ENOMEM;
}
- ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
- MSG_DONTWAIT);
- if (ret > 0)
- ret = 0;
- /* this avoids a loop in nfnetlink. */
- return ret == -EAGAIN ? -ENOBUFS : ret;
-err:
- return err;
+ return nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
}
static struct nf_ct_timeout *ctnl_timeout_find_get(struct net *net,
--
2.20.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2021-05-17 12:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-17 12:43 [PATCH nf-next] netfilter: use nfnetlink_unicast() Pablo Neira Ayuso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.