netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: kaber@trash.net
To: davem@davemloft.net
Cc: netfilter-devel@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH 25/26] netfilter: ipset: send error message manually
Date: Thu,  3 Feb 2011 00:12:03 +0100	[thread overview]
Message-ID: <1296688324-7830-26-git-send-email-kaber@trash.net> (raw)
In-Reply-To: <1296688324-7830-1-git-send-email-kaber@trash.net>

From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>

When a message carries multiple commands and one of them triggers
an error, we have to report to the userspace which one was that.
The line number of the command plays this role and there's an attribute
reserved in the header part of the message to be filled out with the error
line number. In order not to modify the original message received from
the userspace, we construct a new, complete netlink error message and
modifies the attribute there, then send it.
Netlink is notified not to send its ACK/error message.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 net/netfilter/ipset/ip_set_core.c |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index ae0f8b5..8b1a54c 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1098,7 +1098,7 @@ static const struct nla_policy ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] = {
 };
 
 static int
-call_ad(struct sk_buff *skb, struct ip_set *set,
+call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
 	struct nlattr *tb[], enum ipset_adt adt,
 	u32 flags, bool use_lineno)
 {
@@ -1118,12 +1118,25 @@ call_ad(struct sk_buff *skb, struct ip_set *set,
 		return 0;
 	if (lineno && use_lineno) {
 		/* Error in restore/batch mode: send back lineno */
-		struct nlmsghdr *nlh = nlmsg_hdr(skb);
+		struct nlmsghdr *rep, *nlh = nlmsg_hdr(skb);
+		struct sk_buff *skb2;
+		struct nlmsgerr *errmsg;
+		size_t payload = sizeof(*errmsg) + nlmsg_len(nlh);
 		int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
 		struct nlattr *cda[IPSET_ATTR_CMD_MAX+1];
-		struct nlattr *cmdattr = (void *)nlh + min_len;
+		struct nlattr *cmdattr;
 		u32 *errline;
 
+		skb2 = nlmsg_new(payload, GFP_KERNEL);
+		if (skb2 == NULL)
+			return -ENOMEM;
+		rep = __nlmsg_put(skb2, NETLINK_CB(skb).pid,
+				  nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
+		errmsg = nlmsg_data(rep);
+		errmsg->error = ret;
+		memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
+		cmdattr = (void *)&errmsg->msg + min_len;
+
 		nla_parse(cda, IPSET_ATTR_CMD_MAX,
 			  cmdattr, nlh->nlmsg_len - min_len,
 			  ip_set_adt_policy);
@@ -1131,6 +1144,10 @@ call_ad(struct sk_buff *skb, struct ip_set *set,
 		errline = nla_data(cda[IPSET_ATTR_LINENO]);
 
 		*errline = lineno;
+
+		netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+		/* Signal netlink not to send its ACK/errmsg.  */
+		return -EINTR;
 	}
 
 	return ret;
@@ -1169,7 +1186,8 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
 				     attr[IPSET_ATTR_DATA],
 				     set->type->adt_policy))
 			return -IPSET_ERR_PROTOCOL;
-		ret = call_ad(skb, set, tb, IPSET_ADD, flags, use_lineno);
+		ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, flags,
+			      use_lineno);
 	} else {
 		int nla_rem;
 
@@ -1180,7 +1198,7 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
 			    nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla,
 					     set->type->adt_policy))
 				return -IPSET_ERR_PROTOCOL;
-			ret = call_ad(skb, set, tb, IPSET_ADD,
+			ret = call_ad(ctnl, skb, set, tb, IPSET_ADD,
 				      flags, use_lineno);
 			if (ret < 0)
 				return ret;
@@ -1222,7 +1240,8 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
 				     attr[IPSET_ATTR_DATA],
 				     set->type->adt_policy))
 			return -IPSET_ERR_PROTOCOL;
-		ret = call_ad(skb, set, tb, IPSET_DEL, flags, use_lineno);
+		ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, flags,
+			      use_lineno);
 	} else {
 		int nla_rem;
 
@@ -1233,7 +1252,7 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
 			    nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, nla,
 					     set->type->adt_policy))
 				return -IPSET_ERR_PROTOCOL;
-			ret = call_ad(skb, set, tb, IPSET_DEL,
+			ret = call_ad(ctnl, skb, set, tb, IPSET_DEL,
 				      flags, use_lineno);
 			if (ret < 0)
 				return ret;
-- 
1.7.2.3


  parent reply	other threads:[~2011-02-02 23:12 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-02 23:11 [PATCH 00/26] netfilter: netfilter update kaber
2011-02-02 23:11 ` [PATCH 01/26] netfilter: NFNL_SUBSYS_IPSET id and NLA_PUT_NET* macros kaber
2011-02-02 23:11 ` [PATCH 02/26] netfilter: ipset: IP set core support kaber
2011-02-02 23:11 ` [PATCH 03/26] netfilter: ipset: bitmap:ip set type support kaber
2011-02-02 23:11 ` [PATCH 04/26] netfilter: ipset: bitmap:ip,mac " kaber
2011-02-02 23:11 ` [PATCH 05/26] netfilter: ipset; bitmap:port set " kaber
2011-02-02 23:11 ` [PATCH 06/26] netfilter: ipset: hash:ip " kaber
2011-02-02 23:11 ` [PATCH 07/26] netfilter: ipset: hash:ip,port " kaber
2011-02-02 23:11 ` [PATCH 08/26] netfilter: ipset: hash:ip,port,ip " kaber
2011-02-02 23:11 ` [PATCH 09/26] netfilter: ipset: hash:ip,port,net " kaber
2011-02-02 23:11 ` [PATCH 10/26] netfilter: ipset: hash:net " kaber
2011-02-02 23:11 ` [PATCH 11/26] netfilter: ipset: hash:net,port " kaber
2011-02-02 23:11 ` [PATCH 12/26] netfilter: ipset: list:set " kaber
2011-02-02 23:11 ` [PATCH 13/26] netfilter: xtables: "set" match and "SET" target support kaber
2011-02-02 23:11 ` [PATCH 14/26] netfilter: ipset: use nla_parse_nested() kaber
2011-02-02 23:11 ` [PATCH 15/26] netfilter: ipset: remove unnecessary includes kaber
2011-02-02 23:11 ` [PATCH 16/26] netfilter: ctnetlink: fix ctnetlink_parse_tuple() warning kaber
2011-02-02 23:11 ` [PATCH 17/26] IPVS: use z modifier for sizeof() argument kaber
2011-02-02 23:11 ` [PATCH 18/26] IPVS: remove duplicate initialisation or rs_table kaber
2011-02-02 23:11 ` [PATCH 19/26] IPVS: Remove unused variables kaber
2011-02-02 23:11 ` [PATCH 20/26] IPVS: Allow compilation with CONFIG_SYSCTL disabled kaber
2011-02-02 23:11 ` [PATCH 21/26] IPVS: Remove ip_vs_sync_cleanup from section __exit kaber
2011-02-02 23:12 ` [PATCH 22/26] netfilter: ipset: install ipset related header files kaber
2011-02-02 23:12 ` [PATCH 23/26] netfilter: ipset: add missing break statemtns in ip_set_get_ip_port() kaber
2011-02-02 23:12 ` [PATCH 24/26] netfilter: ipset: fix linking with CONFIG_IPV6=n kaber
2011-02-02 23:12 ` kaber [this message]
2011-02-02 23:12 ` [PATCH 26/26] netfilter: xtables: add device group match kaber
2011-02-02 23:24 ` [PATCH 00/26] netfilter: netfilter update David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1296688324-7830-26-git-send-email-kaber@trash.net \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).