From xiyou.wangcong at gmail.com  Wed Mar 12 19:42:39 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Wed, 12 Mar 2014 16:42:39 -0700
Subject: [Patch] fill prio and protocol attr bits when parsing cls message
Message-ID: <1394667759-4333-1-git-send-email-xiyou.wangcong@gmail.com>

Otherwise, the filter we get from a cls cache can't be used
for removal.

Cc: Thomas Haller <thaller at redhat.com>
Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

---
diff --git a/lib/route/cls.c b/lib/route/cls.c
index 7a809bb..b7860c3 100644
--- a/lib/route/cls.c
+++ b/lib/route/cls.c
@@ -368,7 +368,11 @@ static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 		goto errout;
 
 	cls->c_prio = TC_H_MAJ(cls->c_info) >> 16;
+	if (cls->c_prio)
+		cls->ce_mask |= CLS_ATTR_PRIO;
 	cls->c_protocol = ntohs(TC_H_MIN(cls->c_info));
+	if (cls->c_protocol)
+		cls->ce_mask |= CLS_ATTR_PROTOCOL;
 
 	err = pp->pp_cb(OBJ_CAST(cls), pp);
 errout:


From tgraf at suug.ch  Thu Mar 13 04:53:39 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 08:53:39 +0000
Subject: [Patch] fill prio and protocol attr bits when parsing cls message
In-Reply-To: <1394667759-4333-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1394667759-4333-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140313085339.GD31759@casper.infradead.org>

On 03/12/14 at 04:42pm, Cong Wang wrote:
> Otherwise, the filter we get from a cls cache can't be used
> for removal.
> 
> Cc: Thomas Haller <thaller at redhat.com>
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From thaller at redhat.com  Thu Mar 13 05:01:13 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 13 Mar 2014 10:01:13 +0100
Subject: [Patch] fill prio and protocol attr bits when parsing cls message
In-Reply-To: <1394667759-4333-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1394667759-4333-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1394701273.2257.11.camel@hal>

On Wed, 2014-03-12 at 16:42 -0700, Cong Wang wrote:
> Otherwise, the filter we get from a cls cache can't be used
> for removal.
> 
> Cc: Thomas Haller <thaller at redhat.com>
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> 

Pushed to (github) master as 

https://github.com/thom311/libnl/commit/a126d66b5835280c995657c8348f2a4fa7b9cb8c


Thank you, Cong.

Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140313/dcbc15c5/attachment.sig>

From tgraf at suug.ch  Thu Mar 13 07:49:08 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 11:49:08 +0000
Subject: [PATCH 1/2] utils: add nl_has_capability() function
In-Reply-To: <1393156897-18524-2-git-send-email-thaller@redhat.com>
References: <1393156897-18524-1-git-send-email-thaller@redhat.com>
 <1393156897-18524-2-git-send-email-thaller@redhat.com>
Message-ID: <20140313114908.GE31759@casper.infradead.org>

On 02/23/14 at 01:01pm, Thomas Haller wrote:
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 13 07:49:58 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 11:49:58 +0000
Subject: [PATCH 2/2] utils: indicate capability
 NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE
In-Reply-To: <1393156897-18524-3-git-send-email-thaller@redhat.com>
References: <1393156897-18524-1-git-send-email-thaller@redhat.com>
 <1393156897-18524-3-git-send-email-thaller@redhat.com>
Message-ID: <20140313114958.GF31759@casper.infradead.org>

On 02/23/14 at 01:01pm, Thomas Haller wrote:
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 13 07:53:34 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 11:53:34 +0000
Subject: Traffic control for multimedia devices
In-Reply-To: <20140227104849.273ae058@rainbow.cbg.collabora.co.uk>
References: <20140227104849.273ae058@rainbow.cbg.collabora.co.uk>
Message-ID: <20140313115334.GG31759@casper.infradead.org>

On 02/27/14 at 10:48am, Alban Crequy wrote:
> Hi,
> 
> I have been working on an approach to improve bandwidth
> management using ingress traffic control on multimedia devices when the
> users are both watching streamed videos and downloading other contents.
> 
> I wrote about it there:
> http://alban-apinc.blogspot.co.uk/2014/02/traffic-control-for-multimedia-devices.html

Very nice blog post.
> 
> The implemented demo (license LGPL) partially uses libnl but still has
> lots of ugly calls to /sbin/tc. My goal is to eventually uses libnl
> completely. 
> 
> I am curious whether other projects use libnl for similar purposes.

Cong has been working in this field a lot recently and any
addition to libnl in this regard is highly welcome.


From tgraf at suug.ch  Thu Mar 13 08:02:10 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 12:02:10 +0000
Subject: IFLA_NUM_VF not set or improperly parsed
In-Reply-To: <8c6393c71b02ee183ffcfffef3878398@eljef.me>
References: <b2198fd00196a719ef3cdb52c11a9795@eljef.me>
 <20140220150319.GE1109@casper.infradead.org>
 <46629c60cbd8438ac107e037a2bddecb@eljef.me>
 <8c6393c71b02ee183ffcfffef3878398@eljef.me>
Message-ID: <20140313120210.GH31759@casper.infradead.org>

On 02/20/14 at 05:03pm, Jef Oliver wrote:
> I have this patched and working per your suggestion, and the
> definition of RTEXT_FILTER_VF. I want to make sure that
> rtnl_link_build_get_request() is the right area to do this in.
> Patching here allows rtnl_link_get_kernel() to properly report VFs
> on the system. However, it does not allow for cache operations to
> see that there are VFs. I'd imagine that being able to do this in
> cache operations is useful in some way, but I could be wrong.

Extending rtnl_link_build_get_request() will fix
rtnl_link_get_kernel() as you have confirmed. In order to also
fix it for cache operations, the function link_request_update()
needs to be extended to something like this:

static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
{
        struct ifinfomsg ifi;
        struct nl_msg *msg;
	int err = 0;

        memset(&ifi, 0, sizeof(ifi));

        if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP)))
                return -NLE_NOMEM;

	ifi.ifi_family = cache->c_iarg1;

        if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) {
		err = -NLE_MSGSIZE;
                goto nla_put_failure;
	}

	NLA_PUT_U32(msg, IFLA_EXT_MASK, RTEXT_FILTER_VF);

	nl_send_auto(sk, msg);

nla_put_failure:
        nlmsg_free(msg);
        return err;
}


From thaller at redhat.com  Thu Mar 13 08:22:55 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 13 Mar 2014 13:22:55 +0100
Subject: [PATCH 2/2] utils: indicate capability
 NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE
In-Reply-To: <20140313114958.GF31759@casper.infradead.org>
References: <1393156897-18524-1-git-send-email-thaller@redhat.com>
 <1393156897-18524-3-git-send-email-thaller@redhat.com>
 <20140313114958.GF31759@casper.infradead.org>
Message-ID: <1394713375.11273.14.camel@hal>

On Thu, 2014-03-13 at 11:49 +0000, Thomas Graf wrote:
> On 02/23/14 at 01:01pm, Thomas Haller wrote:
> > Signed-off-by: Thomas Haller <thaller at redhat.com>
> 
> Acked-by: Thomas Graf <tgraf at suug.ch>
> 

Hi Thomas,

I pushed both commits, after rewording of commit messages and
documentation.

Thank you.
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140313/5bcad80d/attachment.sig>

From jef at eljef.me  Thu Mar 13 13:00:30 2014
From: jef at eljef.me (Jef Oliver)
Date: Thu, 13 Mar 2014 10:00:30 -0700
Subject: =?UTF-8?Q?IFLA=5FNUM=5FVF=20not=20set=20or=20improperly=20par?=
 =?UTF-8?Q?sed?=
In-Reply-To: <20140313120210.GH31759@casper.infradead.org>
References: <b2198fd00196a719ef3cdb52c11a9795@eljef.me>
 <20140220150319.GE1109@casper.infradead.org>
 <46629c60cbd8438ac107e037a2bddecb@eljef.me>
 <8c6393c71b02ee183ffcfffef3878398@eljef.me>
 <20140313120210.GH31759@casper.infradead.org>
Message-ID: <d4003a30199cf747ce7d667f0d717de2@eljef.me>

On 03/13/2014 05:02 AM, Thomas Graf wrote:
> Extending rtnl_link_build_get_request() will fix
> rtnl_link_get_kernel() as you have confirmed. In order to also
> fix it for cache operations, the function link_request_update()
> needs to be extended to something like this:
> 
> static int link_request_update(struct nl_cache *cache, struct nl_sock 
> *sk)
> {
>         struct ifinfomsg ifi;
>         struct nl_msg *msg;
> 	int err = 0;
> 
>         memset(&ifi, 0, sizeof(ifi));
> 
>         if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP)))
>                 return -NLE_NOMEM;
> 
> 	ifi.ifi_family = cache->c_iarg1;
> 
>         if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) {
> 		err = -NLE_MSGSIZE;
>                 goto nla_put_failure;
> 	}
> 
> 	NLA_PUT_U32(msg, IFLA_EXT_MASK, RTEXT_FILTER_VF);
> 
> 	nl_send_auto(sk, msg);
> 
> nla_put_failure:
>         nlmsg_free(msg);
>         return err;
> }

I am bringing together a patch that includes this and the previous 
suggestion, as well as functionality to get information for a VF. I 
appreciate the information and answers.

Jef Oliver


From xiyou.wangcong at gmail.com  Thu Mar 13 13:07:21 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 13 Mar 2014 10:07:21 -0700
Subject: Traffic control for multimedia devices
In-Reply-To: <20140313115334.GG31759@casper.infradead.org>
References: <20140227104849.273ae058@rainbow.cbg.collabora.co.uk>
 <20140313115334.GG31759@casper.infradead.org>
Message-ID: <CAM_iQpVo_CaLZM78jLNfJqXdO4qPAN1ggSJCs4eUhJt-S5Sytg@mail.gmail.com>

On Thu, Mar 13, 2014 at 4:53 AM, Thomas Graf <tgraf at suug.ch> wrote:
> On 02/27/14 at 10:48am, Alban Crequy wrote:
>> Hi,
>>
>> I have been working on an approach to improve bandwidth
>> management using ingress traffic control on multimedia devices when the
>> users are both watching streamed videos and downloading other contents.
>>
>> I wrote about it there:
>> http://alban-apinc.blogspot.co.uk/2014/02/traffic-control-for-multimedia-devices.html
>
> Very nice blog post.

+1

>>
>> The implemented demo (license LGPL) partially uses libnl but still has
>> lots of ugly calls to /sbin/tc. My goal is to eventually uses libnl
>> completely.
>>
>> I am curious whether other projects use libnl for similar purposes.
>
> Cong has been working in this field a lot recently and any
> addition to libnl in this regard is highly welcome.

I don't use ifb since I only need to filter traffic on ingress, so
the ingress qdisc is enough for me.

It seems libnl still doesn't support ifb, but it is probably very
easy to add it. Good news is libnl has cbq qdisc support.

Thanks.


From tgraf at suug.ch  Thu Mar 13 13:29:58 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 17:29:58 +0000
Subject: IFLA_NUM_VF not set or improperly parsed
In-Reply-To: <d4003a30199cf747ce7d667f0d717de2@eljef.me>
References: <b2198fd00196a719ef3cdb52c11a9795@eljef.me>
 <20140220150319.GE1109@casper.infradead.org>
 <46629c60cbd8438ac107e037a2bddecb@eljef.me>
 <8c6393c71b02ee183ffcfffef3878398@eljef.me>
 <20140313120210.GH31759@casper.infradead.org>
 <d4003a30199cf747ce7d667f0d717de2@eljef.me>
Message-ID: <20140313172958.GJ31759@casper.infradead.org>

On 03/13/14 at 10:00am, Jef Oliver wrote:
> I am bringing together a patch that includes this and the previous
> suggestion, as well as functionality to get information for a VF. I
> appreciate the information and answers.

Sounds awesome, thanks!


From tgraf at suug.ch  Thu Mar 13 13:30:33 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 13 Mar 2014 17:30:33 +0000
Subject: Traffic control for multimedia devices
In-Reply-To: <CAM_iQpVo_CaLZM78jLNfJqXdO4qPAN1ggSJCs4eUhJt-S5Sytg@mail.gmail.com>
References: <20140227104849.273ae058@rainbow.cbg.collabora.co.uk>
 <20140313115334.GG31759@casper.infradead.org>
 <CAM_iQpVo_CaLZM78jLNfJqXdO4qPAN1ggSJCs4eUhJt-S5Sytg@mail.gmail.com>
Message-ID: <20140313173033.GK31759@casper.infradead.org>

On 03/13/14 at 10:07am, Cong Wang wrote:
> I don't use ifb since I only need to filter traffic on ingress, so
> the ingress qdisc is enough for me.

Right, adding support for it should be very trivial.


From thaller at redhat.com  Wed Mar 19 09:49:05 2014
From: thaller at redhat.com (Thomas Haller)
Date: Wed, 19 Mar 2014 14:49:05 +0100
Subject: [PATCH 0/2] make parsing in inet6_parse_protinfo() and
 inet_parse_af() more liberal
Message-ID: <1395236947-15965-1-git-send-email-thaller@redhat.com>

Noteworthy:

 - .minlen is now set to 4 bytes, i.e. to at least one entry.
 - rtnl_link_inet_get_conf() can now fail with error -NLE_INVAL

Thomas Haller (2):
  route: do not enforce minlen in inet6_parse_protinfo() when parsing
    IFLA_INET6_CONF
  route: detect missing cfgid in rtnl_link_inet_get_conf()

 lib/route/link/inet.c  | 20 +++++++++++++++++---
 lib/route/link/inet6.c |  8 ++++++--
 2 files changed, 23 insertions(+), 5 deletions(-)

-- 
1.8.5.3



From thaller at redhat.com  Wed Mar 19 09:49:06 2014
From: thaller at redhat.com (Thomas Haller)
Date: Wed, 19 Mar 2014 14:49:06 +0100
Subject: [PATCH 1/2] route: do not enforce minlen in inet6_parse_protinfo()
 when parsing IFLA_INET6_CONF
In-Reply-To: <1395236947-15965-1-git-send-email-thaller@redhat.com>
References: <1395236947-15965-1-git-send-email-thaller@redhat.com>
Message-ID: <1395236947-15965-2-git-send-email-thaller@redhat.com>

Before, the attribute IFLA_INET6_CONF expected .minlen = DEVCONF_MAX * 4, where
DEVCONF_MAX was defined in a libnl internal header file. If the running
kernel was compiled using a different size (having fewer DEVCONF_* values), libnl
would reject the netlink messages as invalid.

Analog, do not require minlength IPV4_DEVCONF_MAX * 4 for inet_parse_af()
when parsing IFLA_INET_CONF.

https://bugzilla.redhat.com/show_bug.cgi?id=1062533

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c  | 10 ++++++++--
 lib/route/link/inet6.c |  8 ++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index e2c867d..d29ada3 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -92,7 +92,7 @@ static void inet_free(struct rtnl_link *link, void *data)
 }
 
 static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = {
-	[IFLA_INET_CONF]	= { .minlen = IPV4_DEVCONF_MAX * 4 },
+	[IFLA_INET_CONF]	= { .minlen = 4 },
 };
 
 static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data)
@@ -105,8 +105,14 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 	if (err < 0)
 		return err;
 
-	if (tb[IFLA_INET_CONF])
+	if (tb[IFLA_INET_CONF]) {
+		int len = nla_len(tb[IFLA_INET_CONF]);
+
+		if (len % sizeof(id->i_conf[0]))
+			return -EINVAL;
+		memset(&id->i_conf, 0, sizeof(id->i_conf));
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
+	}
 
 	return 0;
 }
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index 4c627bd..9c8f7a7 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -45,7 +45,7 @@ static void inet6_free(struct rtnl_link *link, void *data)
 static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
 	[IFLA_INET6_FLAGS]	= { .type = NLA_U32 },
 	[IFLA_INET6_CACHEINFO]	= { .minlen = sizeof(struct ifla_cacheinfo) },
-	[IFLA_INET6_CONF]	= { .minlen = DEVCONF_MAX * 4 },
+	[IFLA_INET6_CONF]	= { .minlen = 4 },
 	[IFLA_INET6_STATS]	= { .minlen = __IPSTATS_MIB_MAX * 8 },
 	[IFLA_INET6_ICMP6STATS]	= { .minlen = __ICMP6_MIB_MAX * 8 },
 };
@@ -68,9 +68,13 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 		nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
 			   sizeof(i6->i6_cacheinfo));
 
-	if (tb[IFLA_INET6_CONF])
+	if (tb[IFLA_INET6_CONF]) {
+		if (nla_len(tb[IFLA_INET6_CONF]) % sizeof(i6->i6_conf[0]))
+			return -EINVAL;
+		memset (&i6->i6_conf, 0, sizeof(i6->i6_conf));
 		nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
 			   sizeof(i6->i6_conf));
+	}
  
 	/*
 	 * Due to 32bit data alignment, these addresses must be copied to an
-- 
1.8.5.3



From thaller at redhat.com  Wed Mar 19 09:49:07 2014
From: thaller at redhat.com (Thomas Haller)
Date: Wed, 19 Mar 2014 14:49:07 +0100
Subject: [PATCH 2/2] route: detect missing cfgid in rtnl_link_inet_get_conf()
In-Reply-To: <1395236947-15965-1-git-send-email-thaller@redhat.com>
References: <1395236947-15965-1-git-send-email-thaller@redhat.com>
Message-ID: <1395236947-15965-3-git-send-email-thaller@redhat.com>

If the netlink message for IFLA_INET_CONF contains less then
IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset.
Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing
an unset cfgid.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index d29ada3..c8e72c4 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -106,13 +106,17 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 		return err;
 
 	if (tb[IFLA_INET_CONF]) {
-		int len = nla_len(tb[IFLA_INET_CONF]);
+		int i, len = nla_len(tb[IFLA_INET_CONF]);
 
 		if (len % sizeof(id->i_conf[0]))
 			return -EINVAL;
-		memset(&id->i_conf, 0, sizeof(id->i_conf));
+		len /= sizeof(id->i_conf[0]);
+
+		for (i = 0; i < IPV4_DEVCONF_MAX; i++)
+			id->i_confset[i] = (i < len);
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
-	}
+	} else
+		memset(&id->i_confset, 0, sizeof(id->i_confset));
 
 	return 0;
 }
@@ -190,7 +194,7 @@ static void inet_dump_details(struct rtnl_link *link,
 	for (i = 0; i < IPV4_DEVCONF_MAX; i++) {
 		nl_dump_line(p, "%-19s %3u",
 			rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)),
-			id->i_conf[i]);
+			id->i_confset[i] ? id->i_conf[i] : 0);
 
 		if (++n == 3) {
 			nl_dump(p, "\n");
@@ -226,6 +230,8 @@ static struct rtnl_link_af_ops inet_ops = {
  * @return 0 on success or a negative error code.
  * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX
  * @return -NLE_NOATTR configuration setting not available
+ * @return -NLE_INVAL cfgid not set. If the link was received via netlink,
+ *                    it means that the cfgid is not supported.
  */
 int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 			    uint32_t *res)
@@ -238,6 +244,8 @@ int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 	if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
 		return -NLE_NOATTR;
 
+	if (!id->i_confset[cfgid - 1])
+		return -NLE_INVAL;
 	*res = id->i_conf[cfgid - 1];
 
 	return 0;
-- 
1.8.5.3



From tgraf at suug.ch  Thu Mar 20 03:36:12 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 07:36:12 +0000
Subject: [PATCH 1/2] route: do not enforce minlen in
 inet6_parse_protinfo() when parsing IFLA_INET6_CONF
In-Reply-To: <1395236947-15965-2-git-send-email-thaller@redhat.com>
References: <1395236947-15965-1-git-send-email-thaller@redhat.com>
 <1395236947-15965-2-git-send-email-thaller@redhat.com>
Message-ID: <20140320073612.GA16640@casper.infradead.org>

On 03/19/14 at 02:49pm, Thomas Haller wrote:
> Before, the attribute IFLA_INET6_CONF expected .minlen = DEVCONF_MAX * 4, where
> DEVCONF_MAX was defined in a libnl internal header file. If the running
> kernel was compiled using a different size (having fewer DEVCONF_* values), libnl
> would reject the netlink messages as invalid.
> 
> Analog, do not require minlength IPV4_DEVCONF_MAX * 4 for inet_parse_af()
> when parsing IFLA_INET_CONF.
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1062533
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 03:36:38 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 07:36:38 +0000
Subject: [PATCH 2/2] route: detect missing cfgid in
 rtnl_link_inet_get_conf()
In-Reply-To: <1395236947-15965-3-git-send-email-thaller@redhat.com>
References: <1395236947-15965-1-git-send-email-thaller@redhat.com>
 <1395236947-15965-3-git-send-email-thaller@redhat.com>
Message-ID: <20140320073638.GB16640@casper.infradead.org>

On 03/19/14 at 02:49pm, Thomas Haller wrote:
> If the netlink message for IFLA_INET_CONF contains less then
> IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset.
> Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing
> an unset cfgid.
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From xiyou.wangcong at gmail.com  Thu Mar 20 13:24:12 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 20 Mar 2014 10:24:12 -0700
Subject: [Patch] u32: add const to rtnl_u32_add_key_in*_addr()
Message-ID: <1395336252-20893-1-git-send-email-xiyou.wangcong@gmail.com>

Cc: Thomas Haller <thaller at redhat.com>
Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
diff --git a/include/netlink/route/cls/u32.h b/include/netlink/route/cls/u32.h
index a74bfcd..f35d37a 100644
--- a/include/netlink/route/cls/u32.h
+++ b/include/netlink/route/cls/u32.h
@@ -40,9 +40,9 @@ extern int	rtnl_u32_add_key_uint16(struct rtnl_cls *, uint16_t, uint16_t,
 					int, int);
 extern int	rtnl_u32_add_key_uint32(struct rtnl_cls *, uint32_t, uint32_t,
 					int, int);
-extern int	rtnl_u32_add_key_in_addr(struct rtnl_cls *, struct in_addr *,
+extern int	rtnl_u32_add_key_in_addr(struct rtnl_cls *, const struct in_addr *,
 					 uint8_t, int, int);
-extern int	rtnl_u32_add_key_in6_addr(struct rtnl_cls *, struct in6_addr *,
+extern int	rtnl_u32_add_key_in6_addr(struct rtnl_cls *, const struct in6_addr *,
 					  uint8_t, int, int);
 extern int	rtnl_u32_add_action(struct rtnl_cls *, struct rtnl_act *);
 extern int	rtnl_u32_del_action(struct rtnl_cls *, struct rtnl_act *);
diff --git a/lib/route/cls/u32.c b/lib/route/cls/u32.c
index d303d4b..52ab263 100644
--- a/lib/route/cls/u32.c
+++ b/lib/route/cls/u32.c
@@ -645,14 +645,14 @@ int rtnl_u32_add_key_uint32(struct rtnl_cls *cls, uint32_t val, uint32_t mask,
 				off & ~3, offmask);
 }
 
-int rtnl_u32_add_key_in_addr(struct rtnl_cls *cls, struct in_addr *addr,
+int rtnl_u32_add_key_in_addr(struct rtnl_cls *cls, const struct in_addr *addr,
 			     uint8_t bitmask, int off, int offmask)
 {
 	uint32_t mask = 0xFFFFFFFF << (32 - bitmask);
 	return rtnl_u32_add_key(cls, addr->s_addr, htonl(mask), off, offmask);
 }
 
-int rtnl_u32_add_key_in6_addr(struct rtnl_cls *cls, struct in6_addr *addr,
+int rtnl_u32_add_key_in6_addr(struct rtnl_cls *cls, const struct in6_addr *addr,
 			      uint8_t bitmask, int off, int offmask)
 {
 	int i, err;


From xiyou.wangcong at gmail.com  Thu Mar 20 13:45:45 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 20 Mar 2014 10:45:45 -0700
Subject: [Patch] document sk == NULL case for rtnl_link_alloc_cache()
Message-ID: <1395337545-27526-1-git-send-email-xiyou.wangcong@gmail.com>

When sk == NULL, rtnl_link_alloc_cache() returns 0 but the cache
is still empty. We should document this behavior, otherwise it is confusing.

Cc: Thomas Haller <thaller at redhat.com>
Cc: Thomas Graf <tgraf at suug.ch>
Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

---
diff --git a/lib/route/link.c b/lib/route/link.c
index 9979b5b..936cfe6 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -997,11 +997,12 @@ static char *link_attrs2str(int attrs, char *buf, size_t len)
  * @arg family		Link address family or AF_UNSPEC
  * @arg result		Pointer to store resulting cache.
  *
- * Allocates and initializes a new link cache. A netlink message is sent to
- * the kernel requesting a full dump of all configured links. The returned
- * messages are parsed and filled into the cache. If the operation succeeds
- * the resulting cache will a link object for each link configured in the
- * kernel.
+ * Allocates and initializes a new link cache. If \c sk is valid, a netlink
+ * message is sent to the kernel requesting a full dump of all configured
+ * links. The returned messages are parsed and filled into the cache. If
+ * the operation succeeds the resulting cache will a link object for each
+ * link configured in the kernel. If \c sk is NULL, returns 0 but the cache
+ * is still empty.
  *
  * If \c family is set to an address family other than \c AF_UNSPEC the
  * contents of the cache can be limited to a specific address family.


From thaller at redhat.com  Thu Mar 20 14:18:41 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:41 +0100
Subject: [PATCH 0/5 v2] make parsing in inet6_parse_protinfo() and
 inet_parse_af() more liberal
Message-ID: <1395339526-3510-1-git-send-email-thaller@redhat.com>

This obsoletes my two patches from yesterdays email
'[PATCH 0/2] make parsing in inet6_parse_protinfo() and inet_parse_af() more liberal'

Thomas Haller (5):
  route: don't enforce minlen in inet6_parse_protinfo() (IFLA_PROTINFO)
    and inet_parse_af() (IFLA_AF_SPEC)
  route: detect missing cfgid in rtnl_link_inet_get_conf()
  route: update kernel header snmp.h and fix inet6_parse_protinfo()
    after kernel API breakage
  route: rename internal copy of kernel header file 'inetdevice.h' to
    'ip.h'
  route: update copy of kernel header 'ip.h'

 include/Makefile.am               |   2 +-
 include/linux/inetdevice.h        |  36 --------
 include/linux/ip.h                | 172 ++++++++++++++++++++++++++++++++++++++
 include/linux/snmp.h              |  43 ++++++++--
 include/netlink-private/netlink.h |   2 +-
 include/netlink/route/link.h      |   6 ++
 lib/route/link.c                  |   6 ++
 lib/route/link/inet.c             |  21 ++++-
 lib/route/link/inet6.c            | 133 ++++++++++++++++++++++++++---
 9 files changed, 360 insertions(+), 61 deletions(-)
 delete mode 100644 include/linux/inetdevice.h
 create mode 100644 include/linux/ip.h

-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:18:43 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:43 +0100
Subject: [PATCH 2/5] route: detect missing cfgid in rtnl_link_inet_get_conf()
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395339526-3510-3-git-send-email-thaller@redhat.com>

If the netlink message for IFLA_INET_CONF contains less then
IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset.
Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing
an unset cfgid.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index eb2e8ae..2e61323 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -107,8 +107,14 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 	if (tb[IFLA_INET_CONF] && nla_len(tb[IFLA_INET_CONF]) % 4)
 		return -EINVAL;
 
-	if (tb[IFLA_INET_CONF])
+	if (tb[IFLA_INET_CONF]) {
+		int i;
+		int len = min_t(int, IPV4_DEVCONF_MAX, nla_len(tb[IFLA_INET_CONF]) / 4);
+
+		for (i = 0; i < len; i++)
+			id->i_confset[i] = 1;
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
+	}
 
 	return 0;
 }
@@ -186,7 +192,7 @@ static void inet_dump_details(struct rtnl_link *link,
 	for (i = 0; i < IPV4_DEVCONF_MAX; i++) {
 		nl_dump_line(p, "%-19s %3u",
 			rtnl_link_inet_devconf2str(i+1, buf, sizeof(buf)),
-			id->i_conf[i]);
+			id->i_confset[i] ? id->i_conf[i] : 0);
 
 		if (++n == 3) {
 			nl_dump(p, "\n");
@@ -222,6 +228,8 @@ static struct rtnl_link_af_ops inet_ops = {
  * @return 0 on success or a negative error code.
  * @return -NLE_RANGE cfgid is out of range, 1..IPV4_DEVCONF_MAX
  * @return -NLE_NOATTR configuration setting not available
+ * @return -NLE_INVAL cfgid not set. If the link was received via netlink,
+ *                    it means that the cfgid is not supported.
  */
 int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 			    uint32_t *res)
@@ -234,6 +242,8 @@ int rtnl_link_inet_get_conf(struct rtnl_link *link, const unsigned int cfgid,
 	if (!(id = rtnl_link_af_alloc(link, &inet_ops)))
 		return -NLE_NOATTR;
 
+	if (!id->i_confset[cfgid - 1])
+		return -NLE_INVAL;
 	*res = id->i_conf[cfgid - 1];
 
 	return 0;
-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:18:42 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:42 +0100
Subject: [PATCH 1/5] route: don't enforce minlen in inet6_parse_protinfo()
 (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC)
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395339526-3510-2-git-send-email-thaller@redhat.com>

Older kernel version might have fewer values defined, so they would send
netlink messages that got rejected. Only check that at least one value
got sent.

This is especially grave as libnl uses an internal copy of the
kernel header files. Thus not only it is bound to the installed kernel
headers but to the libnl internal header copies that might easily be out
of sync with the kernel.

This affects IFLA_PROTINFO, inet6_parse_protinfo():
  - tb[IFLA_INET6_CONF], expecting DEVCONF_MAX
  - tb[IFLA_INET6_STATS], expecting __IPSTATS_MIB_MAX
  - tb[IFLA_INET6_ICMP6STATS], expecting __ICMP6_MIB_MAX
and IFLA_AF_SPEC, inet_parse_af():
  - tb[IFLA_INET_CONF], expecting IPV4_DEVCONF_MAX

https://bugzilla.redhat.com/show_bug.cgi?id=1062533

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/route/link/inet.c  |  4 +++-
 lib/route/link/inet6.c | 18 +++++++++++++-----
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index e2c867d..eb2e8ae 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -92,7 +92,7 @@ static void inet_free(struct rtnl_link *link, void *data)
 }
 
 static struct nla_policy inet_policy[IFLA_INET6_MAX+1] = {
-	[IFLA_INET_CONF]	= { .minlen = IPV4_DEVCONF_MAX * 4 },
+	[IFLA_INET_CONF]	= { .minlen = 4 },
 };
 
 static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data)
@@ -104,6 +104,8 @@ static int inet_parse_af(struct rtnl_link *link, struct nlattr *attr, void *data
 	err = nla_parse_nested(tb, IFLA_INET_MAX, attr, inet_policy);
 	if (err < 0)
 		return err;
+	if (tb[IFLA_INET_CONF] && nla_len(tb[IFLA_INET_CONF]) % 4)
+		return -EINVAL;
 
 	if (tb[IFLA_INET_CONF])
 		nla_memcpy(&id->i_conf, tb[IFLA_INET_CONF], sizeof(id->i_conf));
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index 4c627bd..f171fed 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -45,9 +45,9 @@ static void inet6_free(struct rtnl_link *link, void *data)
 static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
 	[IFLA_INET6_FLAGS]	= { .type = NLA_U32 },
 	[IFLA_INET6_CACHEINFO]	= { .minlen = sizeof(struct ifla_cacheinfo) },
-	[IFLA_INET6_CONF]	= { .minlen = DEVCONF_MAX * 4 },
-	[IFLA_INET6_STATS]	= { .minlen = __IPSTATS_MIB_MAX * 8 },
-	[IFLA_INET6_ICMP6STATS]	= { .minlen = __ICMP6_MIB_MAX * 8 },
+	[IFLA_INET6_CONF]	= { .minlen = 4 },
+	[IFLA_INET6_STATS]	= { .minlen = 8 },
+	[IFLA_INET6_ICMP6STATS]	= { .minlen = 8 },
 };
 
 static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
@@ -60,6 +60,12 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 	err = nla_parse_nested(tb, IFLA_INET6_MAX, attr, inet6_policy);
 	if (err < 0)
 		return err;
+	if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4)
+		return -EINVAL;
+	if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8)
+		return -EINVAL;
+	if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8)
+		return -EINVAL;
 
 	if (tb[IFLA_INET6_FLAGS])
 		i6->i6_flags = nla_get_u32(tb[IFLA_INET6_FLAGS]);
@@ -80,8 +86,9 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 		unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]);
 		uint64_t stat;
 		int i;
+		int len = min_t(int, __IPSTATS_MIB_MAX, nla_len(tb[IFLA_INET6_STATS]) / 8);
 
-		for (i = 1; i < __IPSTATS_MIB_MAX; i++) {
+		for (i = 1; i < len; i++) {
 			memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
 			rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1,
 					   stat);
@@ -92,8 +99,9 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 		unsigned char *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]);
 		uint64_t stat;
 		int i;
+		int len = min_t(int, __ICMP6_MIB_MAX, nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8);
 
-		for (i = 1; i < __ICMP6_MIB_MAX; i++) {
+		for (i = 1; i < len; i++) {
 			memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
 			rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1,
 					   stat);
-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:18:44 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:44 +0100
Subject: [PATCH 3/5] route: update kernel header snmp.h and fix
 inet6_parse_protinfo() after kernel API breakage
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395339526-3510-4-git-send-email-thaller@redhat.com>

Take 'include/uapi/linux/snmp.h' from current kernel v3.13
(commit d8ec26d7f8287f5788a494f56e8814210f0e64be).

The header file added new values for IPSTATS_MIB_* and ICMP6_MIB_*, but
more importantly, the kernel broke user space API by reordering enum values in
IPSTATS_MIB_*. Add a workaround when parsing IFLA_PROTINFO trying to
be compatible with both older and newer kernels.

Note that this workaround might fail for some specific kernel versions by
assuming the old enum value mapping, although the kernel version already
contains the API change. In this case rtnl_link_get_stat() mixes up
values.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 include/linux/snmp.h         |  43 +++++++++++++---
 include/netlink/route/link.h |   6 +++
 lib/route/link.c             |   6 +++
 lib/route/link/inet6.c       | 117 +++++++++++++++++++++++++++++++++++++++----
 4 files changed, 156 insertions(+), 16 deletions(-)

diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 12b2b18..1bdb4a3 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -18,7 +18,14 @@
 enum
 {
 	IPSTATS_MIB_NUM = 0,
+/* frequently written fields in fast path, kept in same cache line */
 	IPSTATS_MIB_INPKTS,			/* InReceives */
+	IPSTATS_MIB_INOCTETS,			/* InOctets */
+	IPSTATS_MIB_INDELIVERS,			/* InDelivers */
+	IPSTATS_MIB_OUTFORWDATAGRAMS,		/* OutForwDatagrams */
+	IPSTATS_MIB_OUTPKTS,			/* OutRequests */
+	IPSTATS_MIB_OUTOCTETS,			/* OutOctets */
+/* other fields */
 	IPSTATS_MIB_INHDRERRORS,		/* InHdrErrors */
 	IPSTATS_MIB_INTOOBIGERRORS,		/* InTooBigErrors */
 	IPSTATS_MIB_INNOROUTES,			/* InNoRoutes */
@@ -26,9 +33,6 @@ enum
 	IPSTATS_MIB_INUNKNOWNPROTOS,		/* InUnknownProtos */
 	IPSTATS_MIB_INTRUNCATEDPKTS,		/* InTruncatedPkts */
 	IPSTATS_MIB_INDISCARDS,			/* InDiscards */
-	IPSTATS_MIB_INDELIVERS,			/* InDelivers */
-	IPSTATS_MIB_OUTFORWDATAGRAMS,		/* OutForwDatagrams */
-	IPSTATS_MIB_OUTPKTS,			/* OutRequests */
 	IPSTATS_MIB_OUTDISCARDS,		/* OutDiscards */
 	IPSTATS_MIB_OUTNOROUTES,		/* OutNoRoutes */
 	IPSTATS_MIB_REASMTIMEOUT,		/* ReasmTimeout */
@@ -42,12 +46,15 @@ enum
 	IPSTATS_MIB_OUTMCASTPKTS,		/* OutMcastPkts */
 	IPSTATS_MIB_INBCASTPKTS,		/* InBcastPkts */
 	IPSTATS_MIB_OUTBCASTPKTS,		/* OutBcastPkts */
-	IPSTATS_MIB_INOCTETS,			/* InOctets */
-	IPSTATS_MIB_OUTOCTETS,			/* OutOctets */
 	IPSTATS_MIB_INMCASTOCTETS,		/* InMcastOctets */
 	IPSTATS_MIB_OUTMCASTOCTETS,		/* OutMcastOctets */
 	IPSTATS_MIB_INBCASTOCTETS,		/* InBcastOctets */
 	IPSTATS_MIB_OUTBCASTOCTETS,		/* OutBcastOctets */
+	IPSTATS_MIB_CSUMERRORS,			/* InCsumErrors */
+	IPSTATS_MIB_NOECTPKTS,			/* InNoECTPkts */
+	IPSTATS_MIB_ECT1PKTS,			/* InECT1Pkts */
+	IPSTATS_MIB_ECT0PKTS,			/* InECT0Pkts */
+	IPSTATS_MIB_CEPKTS,			/* InCEPkts */
 	__IPSTATS_MIB_MAX
 };
 
@@ -85,6 +92,7 @@ enum
 	ICMP_MIB_OUTTIMESTAMPREPS,		/* OutTimestampReps */
 	ICMP_MIB_OUTADDRMASKS,			/* OutAddrMasks */
 	ICMP_MIB_OUTADDRMASKREPS,		/* OutAddrMaskReps */
+	ICMP_MIB_CSUMERRORS,			/* InCsumErrors */
 	__ICMP_MIB_MAX
 };
 
@@ -101,6 +109,7 @@ enum
 	ICMP6_MIB_INERRORS,			/* InErrors */
 	ICMP6_MIB_OUTMSGS,			/* OutMsgs */
 	ICMP6_MIB_OUTERRORS,			/* OutErrors */
+	ICMP6_MIB_CSUMERRORS,			/* InCsumErrors */
 	__ICMP6_MIB_MAX
 };
 
@@ -128,6 +137,7 @@ enum
 	TCP_MIB_RETRANSSEGS,			/* RetransSegs */
 	TCP_MIB_INERRS,				/* InErrs */
 	TCP_MIB_OUTRSTS,			/* OutRsts */
+	TCP_MIB_CSUMERRORS,			/* InCsumErrors */
 	__TCP_MIB_MAX
 };
 
@@ -145,6 +155,7 @@ enum
 	UDP_MIB_OUTDATAGRAMS,			/* OutDatagrams */
 	UDP_MIB_RCVBUFERRORS,			/* RcvbufErrors */
 	UDP_MIB_SNDBUFERRORS,			/* SndbufErrors */
+	UDP_MIB_CSUMERRORS,			/* InCsumErrors */
 	__UDP_MIB_MAX
 };
 
@@ -192,7 +203,6 @@ enum
 	LINUX_MIB_TCPPARTIALUNDO,		/* TCPPartialUndo */
 	LINUX_MIB_TCPDSACKUNDO,			/* TCPDSACKUndo */
 	LINUX_MIB_TCPLOSSUNDO,			/* TCPLossUndo */
-	LINUX_MIB_TCPLOSS,			/* TCPLoss */
 	LINUX_MIB_TCPLOSTRETRANSMIT,		/* TCPLostRetransmit */
 	LINUX_MIB_TCPRENOFAILURES,		/* TCPRenoFailures */
 	LINUX_MIB_TCPSACKFAILURES,		/* TCPSackFailures */
@@ -201,6 +211,8 @@ enum
 	LINUX_MIB_TCPFORWARDRETRANS,		/* TCPForwardRetrans */
 	LINUX_MIB_TCPSLOWSTARTRETRANS,		/* TCPSlowStartRetrans */
 	LINUX_MIB_TCPTIMEOUTS,			/* TCPTimeouts */
+	LINUX_MIB_TCPLOSSPROBES,		/* TCPLossProbes */
+	LINUX_MIB_TCPLOSSPROBERECOVERY,		/* TCPLossProbeRecovery */
 	LINUX_MIB_TCPRENORECOVERYFAIL,		/* TCPRenoRecoveryFail */
 	LINUX_MIB_TCPSACKRECOVERYFAIL,		/* TCPSackRecoveryFail */
 	LINUX_MIB_TCPSCHEDULERFAILED,		/* TCPSchedulerFailed */
@@ -209,7 +221,6 @@ enum
 	LINUX_MIB_TCPDSACKOFOSENT,		/* TCPDSACKOfoSent */
 	LINUX_MIB_TCPDSACKRECV,			/* TCPDSACKRecv */
 	LINUX_MIB_TCPDSACKOFORECV,		/* TCPDSACKOfoRecv */
-	LINUX_MIB_TCPABORTONSYN,		/* TCPAbortOnSyn */
 	LINUX_MIB_TCPABORTONDATA,		/* TCPAbortOnData */
 	LINUX_MIB_TCPABORTONCLOSE,		/* TCPAbortOnClose */
 	LINUX_MIB_TCPABORTONMEMORY,		/* TCPAbortOnMemory */
@@ -231,6 +242,22 @@ enum
 	LINUX_MIB_TCPDEFERACCEPTDROP,
 	LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
 	LINUX_MIB_TCPTIMEWAITOVERFLOW,		/* TCPTimeWaitOverflow */
+	LINUX_MIB_TCPREQQFULLDOCOOKIES,		/* TCPReqQFullDoCookies */
+	LINUX_MIB_TCPREQQFULLDROP,		/* TCPReqQFullDrop */
+	LINUX_MIB_TCPRETRANSFAIL,		/* TCPRetransFail */
+	LINUX_MIB_TCPRCVCOALESCE,		/* TCPRcvCoalesce */
+	LINUX_MIB_TCPOFOQUEUE,			/* TCPOFOQueue */
+	LINUX_MIB_TCPOFODROP,			/* TCPOFODrop */
+	LINUX_MIB_TCPOFOMERGE,			/* TCPOFOMerge */
+	LINUX_MIB_TCPCHALLENGEACK,		/* TCPChallengeACK */
+	LINUX_MIB_TCPSYNCHALLENGE,		/* TCPSYNChallenge */
+	LINUX_MIB_TCPFASTOPENACTIVE,		/* TCPFastOpenActive */
+	LINUX_MIB_TCPFASTOPENPASSIVE,		/* TCPFastOpenPassive*/
+	LINUX_MIB_TCPFASTOPENPASSIVEFAIL,	/* TCPFastOpenPassiveFail */
+	LINUX_MIB_TCPFASTOPENLISTENOVERFLOW,	/* TCPFastOpenListenOverflow */
+	LINUX_MIB_TCPFASTOPENCOOKIEREQD,	/* TCPFastOpenCookieReqd */
+	LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES, /* TCPSpuriousRtxHostQueues */
+	LINUX_MIB_BUSYPOLLRXPACKETS,		/* BusyPollRxPackets */
 	__LINUX_MIB_MAX
 };
 
@@ -264,6 +291,8 @@ enum
 	LINUX_MIB_XFRMOUTPOLDEAD,		/* XfrmOutPolDead */
 	LINUX_MIB_XFRMOUTPOLERROR,		/* XfrmOutPolError */
 	LINUX_MIB_XFRMFWDHDRERROR,		/* XfrmFwdHdrError*/
+	LINUX_MIB_XFRMOUTSTATEINVALID,		/* XfrmOutStateInvalid */
+	LINUX_MIB_XFRMACQUIREERROR,		/* XfrmAcquireError */
 	__LINUX_MIB_XFRMMAX
 };
 
diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h
index 3345787..a7aa88b 100644
--- a/include/netlink/route/link.h
+++ b/include/netlink/route/link.h
@@ -93,6 +93,12 @@ typedef enum {
 	RTNL_LINK_ICMP6_INERRORS,	/*!< ICMPv6 SNMP InErrors */
 	RTNL_LINK_ICMP6_OUTMSGS,	/*!< ICMPv6 SNMP OutMsgs */
 	RTNL_LINK_ICMP6_OUTERRORS,	/*!< ICMPv6 SNMP OutErrors */
+	RTNL_LINK_ICMP6_CSUMERRORS,	/*!< ICMPv6 SNMP InCsumErrors */
+	RTNL_LINK_IP6_CSUMERRORS,	/*!< IPv6 SNMP InCsumErrors */
+	RTNL_LINK_IP6_NOECTPKTS,	/*!< IPv6 SNMP InNoECTPkts */
+	RTNL_LINK_IP6_ECT1PKTS,		/*!< IPv6 SNMP InECT1Pkts */
+	RTNL_LINK_IP6_ECT0PKTS,		/*!< IPv6 SNMP InECT0Pkts */
+	RTNL_LINK_IP6_CEPKTS,		/*!< IPv6 SNMP InCEPkts */
 	__RTNL_LINK_STATS_MAX,
 } rtnl_link_stat_id_t;
 
diff --git a/lib/route/link.c b/lib/route/link.c
index 9979b5b..c6095b9 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -2598,6 +2598,12 @@ static const struct trans_tbl link_stats[] = {
 	__ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors)
 	__ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs)
 	__ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors)
+	__ADD(RTNL_LINK_ICMP6_CSUMERRORS, ICMP6_InCsumErrors)
+	__ADD(RTNL_LINK_IP6_CSUMERRORS, Ip6_InCsumErrors)
+	__ADD(RTNL_LINK_IP6_NOECTPKTS, Ip6_InNoECTPkts)
+	__ADD(RTNL_LINK_IP6_ECT1PKTS, Ip6_InECT1Pkts)
+	__ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts)
+	__ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts)
 };
 
 char *rtnl_link_stat2str(int st, char *buf, size_t len)
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index f171fed..598c444 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -50,6 +50,84 @@ static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
 	[IFLA_INET6_ICMP6STATS]	= { .minlen = 8 },
 };
 
+static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = {
+	/* 14a196807482e6fc74f15fc03176d5c08880588f^:include/linux/snmp.h
+	 * version before the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f.
+	 * This version was valid since commit edf391ff17232f097d72441c9ad467bcb3b5db18, which
+	 * predates support for parsing IFLA_PROTINFO in libnl3. An even meaning of
+	 * the flags is not supported in libnl3. */
+	[ 1] = RTNL_LINK_IP6_INPKTS,                    /* IPSTATS_MIB_INPKTS                   */
+	[ 2] = RTNL_LINK_IP6_INHDRERRORS,               /* IPSTATS_MIB_INHDRERRORS              */
+	[ 3] = RTNL_LINK_IP6_INTOOBIGERRORS,            /* IPSTATS_MIB_INTOOBIGERRORS           */
+	[ 4] = RTNL_LINK_IP6_INNOROUTES,                /* IPSTATS_MIB_INNOROUTES               */
+	[ 5] = RTNL_LINK_IP6_INADDRERRORS,              /* IPSTATS_MIB_INADDRERRORS             */
+	[ 6] = RTNL_LINK_IP6_INUNKNOWNPROTOS,           /* IPSTATS_MIB_INUNKNOWNPROTOS          */
+	[ 7] = RTNL_LINK_IP6_INTRUNCATEDPKTS,           /* IPSTATS_MIB_INTRUNCATEDPKTS          */
+	[ 8] = RTNL_LINK_IP6_INDISCARDS,                /* IPSTATS_MIB_INDISCARDS               */
+	[ 9] = RTNL_LINK_IP6_INDELIVERS,                /* IPSTATS_MIB_INDELIVERS               */
+	[10] = RTNL_LINK_IP6_OUTFORWDATAGRAMS,          /* IPSTATS_MIB_OUTFORWDATAGRAMS         */
+	[11] = RTNL_LINK_IP6_OUTPKTS,                   /* IPSTATS_MIB_OUTPKTS                  */
+	[12] = RTNL_LINK_IP6_OUTDISCARDS,               /* IPSTATS_MIB_OUTDISCARDS              */
+	[13] = RTNL_LINK_IP6_OUTNOROUTES,               /* IPSTATS_MIB_OUTNOROUTES              */
+	[14] = RTNL_LINK_IP6_REASMTIMEOUT,              /* IPSTATS_MIB_REASMTIMEOUT             */
+	[15] = RTNL_LINK_IP6_REASMREQDS,                /* IPSTATS_MIB_REASMREQDS               */
+	[16] = RTNL_LINK_IP6_REASMOKS,                  /* IPSTATS_MIB_REASMOKS                 */
+	[17] = RTNL_LINK_IP6_REASMFAILS,                /* IPSTATS_MIB_REASMFAILS               */
+	[18] = RTNL_LINK_IP6_FRAGOKS,                   /* IPSTATS_MIB_FRAGOKS                  */
+	[19] = RTNL_LINK_IP6_FRAGFAILS,                 /* IPSTATS_MIB_FRAGFAILS                */
+	[20] = RTNL_LINK_IP6_FRAGCREATES,               /* IPSTATS_MIB_FRAGCREATES              */
+	[21] = RTNL_LINK_IP6_INMCASTPKTS,               /* IPSTATS_MIB_INMCASTPKTS              */
+	[22] = RTNL_LINK_IP6_OUTMCASTPKTS,              /* IPSTATS_MIB_OUTMCASTPKTS             */
+	[23] = RTNL_LINK_IP6_INBCASTPKTS,               /* IPSTATS_MIB_INBCASTPKTS              */
+	[24] = RTNL_LINK_IP6_OUTBCASTPKTS,              /* IPSTATS_MIB_OUTBCASTPKTS             */
+	[25] = RTNL_LINK_IP6_INOCTETS,                  /* IPSTATS_MIB_INOCTETS                 */
+	[26] = RTNL_LINK_IP6_OUTOCTETS,                 /* IPSTATS_MIB_OUTOCTETS                */
+	[27] = RTNL_LINK_IP6_INMCASTOCTETS,             /* IPSTATS_MIB_INMCASTOCTETS            */
+	[28] = RTNL_LINK_IP6_OUTMCASTOCTETS,            /* IPSTATS_MIB_OUTMCASTOCTETS           */
+	[29] = RTNL_LINK_IP6_INBCASTOCTETS,             /* IPSTATS_MIB_INBCASTOCTETS            */
+	[30] = RTNL_LINK_IP6_OUTBCASTOCTETS,            /* IPSTATS_MIB_OUTBCASTOCTETS           */
+};
+
+static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = {
+	/* d8ec26d7f8287f5788a494f56e8814210f0e64be:include/uapi/linux/snmp.h
+	 * version since the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f */
+	[ 1] = RTNL_LINK_IP6_INPKTS,                    /* IPSTATS_MIB_INPKTS                   */
+	[ 2] = RTNL_LINK_IP6_INOCTETS,                  /* IPSTATS_MIB_INOCTETS                 */
+	[ 3] = RTNL_LINK_IP6_INDELIVERS,                /* IPSTATS_MIB_INDELIVERS               */
+	[ 4] = RTNL_LINK_IP6_OUTFORWDATAGRAMS,          /* IPSTATS_MIB_OUTFORWDATAGRAMS         */
+	[ 5] = RTNL_LINK_IP6_OUTPKTS,                   /* IPSTATS_MIB_OUTPKTS                  */
+	[ 6] = RTNL_LINK_IP6_OUTOCTETS,                 /* IPSTATS_MIB_OUTOCTETS                */
+	[ 7] = RTNL_LINK_IP6_INHDRERRORS,               /* IPSTATS_MIB_INHDRERRORS              */
+	[ 8] = RTNL_LINK_IP6_INTOOBIGERRORS,            /* IPSTATS_MIB_INTOOBIGERRORS           */
+	[ 9] = RTNL_LINK_IP6_INNOROUTES,                /* IPSTATS_MIB_INNOROUTES               */
+	[10] = RTNL_LINK_IP6_INADDRERRORS,              /* IPSTATS_MIB_INADDRERRORS             */
+	[11] = RTNL_LINK_IP6_INUNKNOWNPROTOS,           /* IPSTATS_MIB_INUNKNOWNPROTOS          */
+	[12] = RTNL_LINK_IP6_INTRUNCATEDPKTS,           /* IPSTATS_MIB_INTRUNCATEDPKTS          */
+	[13] = RTNL_LINK_IP6_INDISCARDS,                /* IPSTATS_MIB_INDISCARDS               */
+	[14] = RTNL_LINK_IP6_OUTDISCARDS,               /* IPSTATS_MIB_OUTDISCARDS              */
+	[15] = RTNL_LINK_IP6_OUTNOROUTES,               /* IPSTATS_MIB_OUTNOROUTES              */
+	[16] = RTNL_LINK_IP6_REASMTIMEOUT,              /* IPSTATS_MIB_REASMTIMEOUT             */
+	[17] = RTNL_LINK_IP6_REASMREQDS,                /* IPSTATS_MIB_REASMREQDS               */
+	[18] = RTNL_LINK_IP6_REASMOKS,                  /* IPSTATS_MIB_REASMOKS                 */
+	[19] = RTNL_LINK_IP6_REASMFAILS,                /* IPSTATS_MIB_REASMFAILS               */
+	[20] = RTNL_LINK_IP6_FRAGOKS,                   /* IPSTATS_MIB_FRAGOKS                  */
+	[21] = RTNL_LINK_IP6_FRAGFAILS,                 /* IPSTATS_MIB_FRAGFAILS                */
+	[22] = RTNL_LINK_IP6_FRAGCREATES,               /* IPSTATS_MIB_FRAGCREATES              */
+	[23] = RTNL_LINK_IP6_INMCASTPKTS,               /* IPSTATS_MIB_INMCASTPKTS              */
+	[24] = RTNL_LINK_IP6_OUTMCASTPKTS,              /* IPSTATS_MIB_OUTMCASTPKTS             */
+	[25] = RTNL_LINK_IP6_INBCASTPKTS,               /* IPSTATS_MIB_INBCASTPKTS              */
+	[26] = RTNL_LINK_IP6_OUTBCASTPKTS,              /* IPSTATS_MIB_OUTBCASTPKTS             */
+	[27] = RTNL_LINK_IP6_INMCASTOCTETS,             /* IPSTATS_MIB_INMCASTOCTETS            */
+	[28] = RTNL_LINK_IP6_OUTMCASTOCTETS,            /* IPSTATS_MIB_OUTMCASTOCTETS           */
+	[29] = RTNL_LINK_IP6_INBCASTOCTETS,             /* IPSTATS_MIB_INBCASTOCTETS            */
+	[30] = RTNL_LINK_IP6_OUTBCASTOCTETS,            /* IPSTATS_MIB_OUTBCASTOCTETS           */
+	[31] = RTNL_LINK_IP6_CSUMERRORS,                /* IPSTATS_MIB_CSUMERRORS               */
+	[32] = RTNL_LINK_IP6_NOECTPKTS,                 /* IPSTATS_MIB_NOECTPKTS                */
+	[33] = RTNL_LINK_IP6_ECT1PKTS,                  /* IPSTATS_MIB_ECT1PKTS                 */
+	[34] = RTNL_LINK_IP6_ECT0PKTS,                  /* IPSTATS_MIB_ECT0PKTS                 */
+	[35] = RTNL_LINK_IP6_CEPKTS,                    /* IPSTATS_MIB_CEPKTS                   */
+};
+
 static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 				void *data)
 {
@@ -86,12 +164,23 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 		unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]);
 		uint64_t stat;
 		int i;
-		int len = min_t(int, __IPSTATS_MIB_MAX, nla_len(tb[IFLA_INET6_STATS]) / 8);
+		int len = nla_len(tb[IFLA_INET6_STATS]) / 8;
+		const uint8_t *map_stat_id = map_stat_id_from_IPSTATS_MIB_v2;
+
+		if (len < 32 ||
+		    (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) < 6)) {
+			/* kernel commit 14a196807482e6fc74f15fc03176d5c08880588f reordered the values.
+			 * The later commit 6a5dc9e598fe90160fee7de098fa319665f5253e added values
+			 * IPSTATS_MIB_CSUMERRORS/ICMP6_MIB_CSUMERRORS. If the netlink is shorter
+			 * then this, assume that the kernel uses the previous meaning of the
+			 * enumeration. */
+			map_stat_id = map_stat_id_from_IPSTATS_MIB_v1;
+		}
 
+		len = min_t(int, __IPSTATS_MIB_MAX, len);
 		for (i = 1; i < len; i++) {
 			memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
-			rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1,
-					   stat);
+			rtnl_link_set_stat(link, map_stat_id[i], stat);
 		}
 	}
 
@@ -343,19 +432,29 @@ static void inet6_dump_stats(struct rtnl_link *link,
 		link->l_stats[RTNL_LINK_IP6_INADDRERRORS]);
 
 	nl_dump(p, "       InUnknownProtos     InTruncatedPkts   "
-		   "    OutNoRoutes\n");
-	nl_dump(p, "    %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
+		   "    OutNoRoutes       InCsumErrors\n");
+	nl_dump(p, "    %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
 		link->l_stats[RTNL_LINK_IP6_INUNKNOWNPROTOS],
 		link->l_stats[RTNL_LINK_IP6_INTRUNCATEDPKTS],
-		link->l_stats[RTNL_LINK_IP6_OUTNOROUTES]);
+		link->l_stats[RTNL_LINK_IP6_OUTNOROUTES],
+		link->l_stats[RTNL_LINK_IP6_CSUMERRORS]);
 
-	nl_dump(p, "    ICMPv6:     InMsgs           InErrors        "
-		   "    OutMsgs          OutErrors\n");
+	nl_dump(p, "           InNoECTPkts          InECT1Pkts   "
+		   "     InECT0Pkts           InCEPkts\n");
 	nl_dump(p, "    %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
+		link->l_stats[RTNL_LINK_IP6_NOECTPKTS],
+		link->l_stats[RTNL_LINK_IP6_ECT1PKTS],
+		link->l_stats[RTNL_LINK_IP6_ECT0PKTS],
+		link->l_stats[RTNL_LINK_IP6_CEPKTS]);
+
+	nl_dump(p, "    ICMPv6:     InMsgs           InErrors        "
+		   "    OutMsgs          OutErrors       InCsumErrors\n");
+	nl_dump(p, "    %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
 		link->l_stats[RTNL_LINK_ICMP6_INMSGS],
 		link->l_stats[RTNL_LINK_ICMP6_INERRORS],
 		link->l_stats[RTNL_LINK_ICMP6_OUTMSGS],
-		link->l_stats[RTNL_LINK_ICMP6_OUTERRORS]);
+		link->l_stats[RTNL_LINK_ICMP6_OUTERRORS],
+		link->l_stats[RTNL_LINK_ICMP6_CSUMERRORS]);
 }
 
 static const struct nla_policy protinfo_policy = {
-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:18:45 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:45 +0100
Subject: [PATCH 4/5] route: rename internal copy of kernel header file
 'inetdevice.h' to 'ip.h'
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395339526-3510-5-git-send-email-thaller@redhat.com>

libnl used 'inetdevice.h' for the IPV4_DEVCONF_* names, which the kernel
in the meantime moved to public user space API and are now defined in 'ip.h'.

As a first step, rename the file 'inetdevice.h'.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 include/Makefile.am               |  2 +-
 include/linux/inetdevice.h        | 36 ------------------------------------
 include/linux/ip.h                | 36 ++++++++++++++++++++++++++++++++++++
 include/netlink-private/netlink.h |  2 +-
 4 files changed, 38 insertions(+), 38 deletions(-)
 delete mode 100644 include/linux/inetdevice.h
 create mode 100644 include/linux/ip.h

diff --git a/include/Makefile.am b/include/Makefile.am
index 32f872f..1b13f5a 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -117,7 +117,7 @@ noinst_HEADERS = \
 	linux/if_bridge.h \
 	linux/if_link.h \
 	linux/if_vlan.h \
-	linux/inetdevice.h \
+	linux/ip.h \
 	linux/ip_mp_alg.h \
 	linux/ipv6.h \
 	linux/can/netlink.h \
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
deleted file mode 100644
index fd4d2df..0000000
--- a/include/linux/inetdevice.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _LINUX_INETDEVICE_H
-#define _LINUX_INETDEVICE_H
-
-enum
-{
-	IPV4_DEVCONF_FORWARDING=1,
-	IPV4_DEVCONF_MC_FORWARDING,
-	IPV4_DEVCONF_PROXY_ARP,
-	IPV4_DEVCONF_ACCEPT_REDIRECTS,
-	IPV4_DEVCONF_SECURE_REDIRECTS,
-	IPV4_DEVCONF_SEND_REDIRECTS,
-	IPV4_DEVCONF_SHARED_MEDIA,
-	IPV4_DEVCONF_RP_FILTER,
-	IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE,
-	IPV4_DEVCONF_BOOTP_RELAY,
-	IPV4_DEVCONF_LOG_MARTIANS,
-	IPV4_DEVCONF_TAG,
-	IPV4_DEVCONF_ARPFILTER,
-	IPV4_DEVCONF_MEDIUM_ID,
-	IPV4_DEVCONF_NOXFRM,
-	IPV4_DEVCONF_NOPOLICY,
-	IPV4_DEVCONF_FORCE_IGMP_VERSION,
-	IPV4_DEVCONF_ARP_ANNOUNCE,
-	IPV4_DEVCONF_ARP_IGNORE,
-	IPV4_DEVCONF_PROMOTE_SECONDARIES,
-	IPV4_DEVCONF_ARP_ACCEPT,
-	IPV4_DEVCONF_ARP_NOTIFY,
-	IPV4_DEVCONF_ACCEPT_LOCAL,
-	IPV4_DEVCONF_SRC_VMARK,
-	IPV4_DEVCONF_PROXY_ARP_PVLAN,
-	__IPV4_DEVCONF_MAX
-};
-
-#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
-
-#endif /* _LINUX_INETDEVICE_H */
diff --git a/include/linux/ip.h b/include/linux/ip.h
new file mode 100644
index 0000000..fd4d2df
--- /dev/null
+++ b/include/linux/ip.h
@@ -0,0 +1,36 @@
+#ifndef _LINUX_INETDEVICE_H
+#define _LINUX_INETDEVICE_H
+
+enum
+{
+	IPV4_DEVCONF_FORWARDING=1,
+	IPV4_DEVCONF_MC_FORWARDING,
+	IPV4_DEVCONF_PROXY_ARP,
+	IPV4_DEVCONF_ACCEPT_REDIRECTS,
+	IPV4_DEVCONF_SECURE_REDIRECTS,
+	IPV4_DEVCONF_SEND_REDIRECTS,
+	IPV4_DEVCONF_SHARED_MEDIA,
+	IPV4_DEVCONF_RP_FILTER,
+	IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE,
+	IPV4_DEVCONF_BOOTP_RELAY,
+	IPV4_DEVCONF_LOG_MARTIANS,
+	IPV4_DEVCONF_TAG,
+	IPV4_DEVCONF_ARPFILTER,
+	IPV4_DEVCONF_MEDIUM_ID,
+	IPV4_DEVCONF_NOXFRM,
+	IPV4_DEVCONF_NOPOLICY,
+	IPV4_DEVCONF_FORCE_IGMP_VERSION,
+	IPV4_DEVCONF_ARP_ANNOUNCE,
+	IPV4_DEVCONF_ARP_IGNORE,
+	IPV4_DEVCONF_PROMOTE_SECONDARIES,
+	IPV4_DEVCONF_ARP_ACCEPT,
+	IPV4_DEVCONF_ARP_NOTIFY,
+	IPV4_DEVCONF_ACCEPT_LOCAL,
+	IPV4_DEVCONF_SRC_VMARK,
+	IPV4_DEVCONF_PROXY_ARP_PVLAN,
+	__IPV4_DEVCONF_MAX
+};
+
+#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
+
+#endif /* _LINUX_INETDEVICE_H */
diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
index 2b1a68e..ee2a8b1 100644
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -51,7 +51,7 @@
 #include <linux/gen_stats.h>
 #include <linux/ip_mp_alg.h>
 #include <linux/atm.h>
-#include <linux/inetdevice.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/snmp.h>
 
-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:18:46 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:18:46 +0100
Subject: [PATCH 5/5] route: update copy of kernel header 'ip.h'
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395339526-3510-6-git-send-email-thaller@redhat.com>

Take 'include/uapi/linux/ip.h' from current kernel v3.13
(commit d8ec26d7f8287f5788a494f56e8814210f0e64be).

Also add three new IPV4_DEVCONF_* names.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 include/linux/ip.h    | 142 ++++++++++++++++++++++++++++++++++++++++++++++++--
 lib/route/link/inet.c |   3 ++
 2 files changed, 142 insertions(+), 3 deletions(-)

diff --git a/include/linux/ip.h b/include/linux/ip.h
index fd4d2df..4119594 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -1,6 +1,139 @@
-#ifndef _LINUX_INETDEVICE_H
-#define _LINUX_INETDEVICE_H
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		Definitions for the IP protocol.
+ *
+ * Version:	@(#)ip.h	1.0.2	04/28/93
+ *
+ * Authors:	Fred N. van Kempen, <waltje at uWalt.NL.Mugnet.ORG>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_LINUX_IP_H
+#define _UAPI_LINUX_IP_H
+#include <linux/types.h>
+#include <asm/byteorder.h>
 
+#define IPTOS_TOS_MASK		0x1E
+#define IPTOS_TOS(tos)		((tos)&IPTOS_TOS_MASK)
+#define	IPTOS_LOWDELAY		0x10
+#define	IPTOS_THROUGHPUT	0x08
+#define	IPTOS_RELIABILITY	0x04
+#define	IPTOS_MINCOST		0x02
+
+#define IPTOS_PREC_MASK		0xE0
+#define IPTOS_PREC(tos)		((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL           0xe0
+#define IPTOS_PREC_INTERNETCONTROL      0xc0
+#define IPTOS_PREC_CRITIC_ECP           0xa0
+#define IPTOS_PREC_FLASHOVERRIDE        0x80
+#define IPTOS_PREC_FLASH                0x60
+#define IPTOS_PREC_IMMEDIATE            0x40
+#define IPTOS_PREC_PRIORITY             0x20
+#define IPTOS_PREC_ROUTINE              0x00
+
+
+/* IP options */
+#define IPOPT_COPY		0x80
+#define IPOPT_CLASS_MASK	0x60
+#define IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_COPIED(o)		((o)&IPOPT_COPY)
+#define	IPOPT_CLASS(o)		((o)&IPOPT_CLASS_MASK)
+#define	IPOPT_NUMBER(o)		((o)&IPOPT_NUMBER_MASK)
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_MEASUREMENT	0x40
+#define	IPOPT_RESERVED2		0x60
+
+#define IPOPT_END	(0 |IPOPT_CONTROL)
+#define IPOPT_NOOP	(1 |IPOPT_CONTROL)
+#define IPOPT_SEC	(2 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_LSRR	(3 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_TIMESTAMP	(4 |IPOPT_MEASUREMENT)
+#define IPOPT_CIPSO	(6 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RR	(7 |IPOPT_CONTROL)
+#define IPOPT_SID	(8 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_SSRR	(9 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RA	(20|IPOPT_CONTROL|IPOPT_COPY)
+
+#define IPVERSION	4
+#define MAXTTL		255
+#define IPDEFTTL	64
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN   1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+#define MAX_IPOPTLEN 40
+#define IPOPT_NOP IPOPT_NOOP
+#define IPOPT_EOL IPOPT_END
+#define IPOPT_TS  IPOPT_TIMESTAMP
+
+#define	IPOPT_TS_TSONLY		0		/* timestamps only */
+#define	IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
+#define	IPOPT_TS_PRESPEC	3		/* specified modules only */
+
+#define IPV4_BEET_PHMAXLEN 8
+
+struct iphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8	ihl:4,
+		version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+	__u8	version:4,
+  		ihl:4;
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+	__u8	tos;
+	__be16	tot_len;
+	__be16	id;
+	__be16	frag_off;
+	__u8	ttl;
+	__u8	protocol;
+	__sum16	check;
+	__be32	saddr;
+	__be32	daddr;
+	/*The options start here. */
+};
+
+
+struct ip_auth_hdr {
+	__u8  nexthdr;
+	__u8  hdrlen;		/* This one is measured in 32 bit units! */
+	__be16 reserved;
+	__be32 spi;
+	__be32 seq_no;		/* Sequence number */
+	__u8  auth_data[0];	/* Variable len but >=4. Mind the 64 bit alignment! */
+};
+
+struct ip_esp_hdr {
+	__be32 spi;
+	__be32 seq_no;		/* Sequence number */
+	__u8  enc_data[0];	/* Variable len but >=8. Mind the 64 bit alignment! */
+};
+
+struct ip_comp_hdr {
+	__u8 nexthdr;
+	__u8 flags;
+	__be16 cpi;
+};
+
+struct ip_beet_phdr {
+	__u8 nexthdr;
+	__u8 hdrlen;
+	__u8 padlen;
+	__u8 reserved;
+};
+
+/* index values for the variables in ipv4_devconf */
 enum
 {
 	IPV4_DEVCONF_FORWARDING=1,
@@ -28,9 +161,12 @@ enum
 	IPV4_DEVCONF_ACCEPT_LOCAL,
 	IPV4_DEVCONF_SRC_VMARK,
 	IPV4_DEVCONF_PROXY_ARP_PVLAN,
+	IPV4_DEVCONF_ROUTE_LOCALNET,
+	IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
+	IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
 	__IPV4_DEVCONF_MAX
 };
 
 #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
 
-#endif /* _LINUX_INETDEVICE_H */
+#endif /* _UAPI_LINUX_IP_H */
diff --git a/lib/route/link/inet.c b/lib/route/link/inet.c
index 2e61323..e94342f 100644
--- a/lib/route/link/inet.c
+++ b/lib/route/link/inet.c
@@ -166,6 +166,9 @@ static const struct trans_tbl inet_devconf[] = {
 	__ADD(IPV4_DEVCONF_ACCEPT_LOCAL, accept_local)
 	__ADD(IPV4_DEVCONF_SRC_VMARK, src_vmark)
 	__ADD(IPV4_DEVCONF_PROXY_ARP_PVLAN, proxy_arp_pvlan)
+	__ADD(IPV4_DEVCONF_ROUTE_LOCALNET, route_localnet)
+	__ADD(IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, igmpv2_unsolicited_report_interval)
+	__ADD(IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, igmpv3_unsolicited_report_interval)
 };
 
 const char *rtnl_link_inet_devconf2str(int type, char *buf, size_t len)
-- 
1.8.5.3



From thaller at redhat.com  Thu Mar 20 14:41:23 2014
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 20 Mar 2014 19:41:23 +0100
Subject: [Patch] document sk == NULL case for rtnl_link_alloc_cache()
In-Reply-To: <1395337545-27526-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395337545-27526-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1395340883.2830.6.camel@hal>

On Thu, 2014-03-20 at 10:45 -0700, Cong Wang wrote:
> When sk == NULL, rtnl_link_alloc_cache() returns 0 but the cache
> is still empty. We should document this behavior, otherwise it is confusing.


Hi Cong,


pushed to master as
https://github.com/thom311/libnl/commit/67a704676c9ccc153f87aa86cd0a444f42608162


Note that I added the prefix "link: " to your commit message.

I also modified your patch to fix a error that already existed before your patch:

- If the operation succeeds the resulting cache will a link object...
+ If the operation succeeds, the resulting cache will contain a link object...


Thanks,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140320/b0ba2005/attachment.sig>

From xiyou.wangcong at gmail.com  Thu Mar 20 16:22:52 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 20 Mar 2014 13:22:52 -0700
Subject: [Patch] document sk == NULL case for rtnl_link_alloc_cache()
In-Reply-To: <1395340883.2830.6.camel@hal>
References: <1395337545-27526-1-git-send-email-xiyou.wangcong@gmail.com>
 <1395340883.2830.6.camel@hal>
Message-ID: <CAM_iQpWcB+JJFjGv9p_G=ZKtuPihM_JtagTTuBp9_cdLUr5RnQ@mail.gmail.com>

On Thu, Mar 20, 2014 at 11:41 AM, Thomas Haller <thaller at redhat.com> wrote:
> Hi Cong,
>
>
> pushed to master as
> https://github.com/thom311/libnl/commit/67a704676c9ccc153f87aa86cd0a444f42608162
>

OK.

>
> Note that I added the prefix "link: " to your commit message.
>
> I also modified your patch to fix a error that already existed before your patch:
>
> - If the operation succeeds the resulting cache will a link object...
> + If the operation succeeds, the resulting cache will contain a link object...
>


That's awesome! Thanks for doing that.


From tgraf at suug.ch  Thu Mar 20 18:25:02 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:25:02 +0000
Subject: [Patch] u32: add const to rtnl_u32_add_key_in*_addr()
In-Reply-To: <1395336252-20893-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395336252-20893-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140320222502.GB9833@casper.infradead.org>

On 03/20/14 at 10:24am, Cong Wang wrote:
> Cc: Thomas Haller <thaller at redhat.com>
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

ABI safe

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:26:48 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:26:48 +0000
Subject: [PATCH 1/5] route: don't enforce minlen in
 inet6_parse_protinfo() (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC)
In-Reply-To: <1395339526-3510-2-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
 <1395339526-3510-2-git-send-email-thaller@redhat.com>
Message-ID: <20140320222648.GC9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> Older kernel version might have fewer values defined, so they would send
> netlink messages that got rejected. Only check that at least one value
> got sent.
> 
> This is especially grave as libnl uses an internal copy of the
> kernel header files. Thus not only it is bound to the installed kernel
> headers but to the libnl internal header copies that might easily be out
> of sync with the kernel.
> 
> This affects IFLA_PROTINFO, inet6_parse_protinfo():
>   - tb[IFLA_INET6_CONF], expecting DEVCONF_MAX
>   - tb[IFLA_INET6_STATS], expecting __IPSTATS_MIB_MAX
>   - tb[IFLA_INET6_ICMP6STATS], expecting __ICMP6_MIB_MAX
> and IFLA_AF_SPEC, inet_parse_af():
>   - tb[IFLA_INET_CONF], expecting IPV4_DEVCONF_MAX
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1062533
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:27:19 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:27:19 +0000
Subject: [PATCH 2/5] route: detect missing cfgid in
 rtnl_link_inet_get_conf()
In-Reply-To: <1395339526-3510-3-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
 <1395339526-3510-3-git-send-email-thaller@redhat.com>
Message-ID: <20140320222719.GD9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> If the netlink message for IFLA_INET_CONF contains less then
> IPV4_DEVCONF_MAX entires, the last entries in i_conf are unset.
> Modify rtnl_link_inet_get_conf() to return -EINVAL when accessing
> an unset cfgid.
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:28:32 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:28:32 +0000
Subject: [PATCH 3/5] route: update kernel header snmp.h and fix
 inet6_parse_protinfo() after kernel API breakage
In-Reply-To: <1395339526-3510-4-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
 <1395339526-3510-4-git-send-email-thaller@redhat.com>
Message-ID: <20140320222832.GE9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> Take 'include/uapi/linux/snmp.h' from current kernel v3.13
> (commit d8ec26d7f8287f5788a494f56e8814210f0e64be).
> 
> The header file added new values for IPSTATS_MIB_* and ICMP6_MIB_*, but
> more importantly, the kernel broke user space API by reordering enum values in
> IPSTATS_MIB_*. Add a workaround when parsing IFLA_PROTINFO trying to
> be compatible with both older and newer kernels.
> 
> Note that this workaround might fail for some specific kernel versions by
> assuming the old enum value mapping, although the kernel version already
> contains the API change. In this case rtnl_link_get_stat() mixes up
> values.
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:29:07 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:29:07 +0000
Subject: [PATCH 4/5] route: rename internal copy of kernel header file
 'inetdevice.h' to 'ip.h'
In-Reply-To: <1395339526-3510-5-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
 <1395339526-3510-5-git-send-email-thaller@redhat.com>
Message-ID: <20140320222907.GF9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> libnl used 'inetdevice.h' for the IPV4_DEVCONF_* names, which the kernel
> in the meantime moved to public user space API and are now defined in 'ip.h'.
> 
> As a first step, rename the file 'inetdevice.h'.
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:29:44 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:29:44 +0000
Subject: [PATCH 5/5] route: update copy of kernel header 'ip.h'
In-Reply-To: <1395339526-3510-6-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
 <1395339526-3510-6-git-send-email-thaller@redhat.com>
Message-ID: <20140320222944.GG9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> Take 'include/uapi/linux/ip.h' from current kernel v3.13
> (commit d8ec26d7f8287f5788a494f56e8814210f0e64be).
> 
> Also add three new IPV4_DEVCONF_* names.
> 
> Signed-off-by: Thomas Haller <thaller at redhat.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 20 18:29:56 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 20 Mar 2014 22:29:56 +0000
Subject: [PATCH 0/5 v2] make parsing in inet6_parse_protinfo() and
 inet_parse_af() more liberal
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <20140320222956.GH9833@casper.infradead.org>

On 03/20/14 at 07:18pm, Thomas Haller wrote:
> This obsoletes my two patches from yesterdays email
> '[PATCH 0/2] make parsing in inet6_parse_protinfo() and inet_parse_af() more liberal'
> 
> Thomas Haller (5):
>   route: don't enforce minlen in inet6_parse_protinfo() (IFLA_PROTINFO)
>     and inet_parse_af() (IFLA_AF_SPEC)
>   route: detect missing cfgid in rtnl_link_inet_get_conf()
>   route: update kernel header snmp.h and fix inet6_parse_protinfo()
>     after kernel API breakage
>   route: rename internal copy of kernel header file 'inetdevice.h' to
>     'ip.h'
>   route: update copy of kernel header 'ip.h'
> 
>  include/Makefile.am               |   2 +-
>  include/linux/inetdevice.h        |  36 --------
>  include/linux/ip.h                | 172 ++++++++++++++++++++++++++++++++++++++
>  include/linux/snmp.h              |  43 ++++++++--
>  include/netlink-private/netlink.h |   2 +-
>  include/netlink/route/link.h      |   6 ++
>  lib/route/link.c                  |   6 ++
>  lib/route/link/inet.c             |  21 ++++-
>  lib/route/link/inet6.c            | 133 ++++++++++++++++++++++++++---
>  9 files changed, 360 insertions(+), 61 deletions(-)
>  delete mode 100644 include/linux/inetdevice.h
>  create mode 100644 include/linux/ip.h

Awesome work!


From thaller at redhat.com  Fri Mar 21 07:46:20 2014
From: thaller at redhat.com (Thomas Haller)
Date: Fri, 21 Mar 2014 12:46:20 +0100
Subject: [PATCH 0/5 v2] make parsing in inet6_parse_protinfo() and
 inet_parse_af() more liberal
In-Reply-To: <1395339526-3510-1-git-send-email-thaller@redhat.com>
References: <1395339526-3510-1-git-send-email-thaller@redhat.com>
Message-ID: <1395402380.4895.5.camel@hal>

On Thu, 2014-03-20 at 19:18 +0100, Thomas Haller wrote:
> This obsoletes my two patches from yesterdays email
> '[PATCH 0/2] make parsing in inet6_parse_protinfo() and inet_parse_af() more liberal'
> 

Pushed all 5 commits to master as:

https://github.com/thom311/libnl/commit/dfd0a80ec845a800504fecb936c2b33d6918fc9c
https://github.com/thom311/libnl/commit/3584a7ab55cb93225a0216385b62fbe5331388cd
https://github.com/thom311/libnl/commit/5981a39583ab65dca230a8ee70625626d9ec9fc8
https://github.com/thom311/libnl/commit/1048a610fb03dd994285f55427f207fdcaf2b725
https://github.com/thom311/libnl/commit/a593803ad6de2cfa9d652a76e0cf71799f71bb3d



Note, I fixed a code comment in commit 
  "route: update kernel header snmp.h and fix inet6_parse_protinfo() after kernel API breakage"
compared to the patch sent to mailing list originally:

 	 * This version was valid since commit edf391ff17232f097d72441c9ad467bcb3b5db18, which
-	 * predates support for parsing IFLA_PROTINFO in libnl3. An even meaning of
+	 * predates support for parsing IFLA_PROTINFO in libnl3. Such an even older meaning of
 	 * the flags is not supported in libnl3. */


Ciao,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140321/9cb2bcdd/attachment.sig>

From thaller at redhat.com  Fri Mar 21 07:40:04 2014
From: thaller at redhat.com (Thomas Haller)
Date: Fri, 21 Mar 2014 12:40:04 +0100
Subject: [Patch] u32: add const to rtnl_u32_add_key_in*_addr()
In-Reply-To: <1395336252-20893-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395336252-20893-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1395402004.4895.0.camel@hal>

On Thu, 2014-03-20 at 10:24 -0700, Cong Wang wrote:
> Cc: Thomas Haller <thaller at redhat.com>
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>


Pushed to master as:
https://github.com/thom311/libnl/commit/c0a5b393086e052d45f0f43ae1ec3b65b6de0d97


Thank you, Cong!!
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140321/0912cef2/attachment.sig>

From xiyou.wangcong at gmail.com  Sun Mar 23 15:02:07 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Sun, 23 Mar 2014 12:02:07 -0700
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing netlink
 message
Message-ID: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 4ce1f10..0cac428 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -42,7 +42,6 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
 {
 	struct nlattr *tb[VETH_INFO_MAX+1];
 	struct nlattr *peer_tb[IFLA_MAX + 1];
-	struct rtnl_link *peer = link->l_info;
 	int err;
 
 	NL_DBG(3, "Parsing veth link info");
@@ -51,9 +50,12 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
 		goto errout;
 
 	if (tb[VETH_INFO_PEER]) {
+		struct rtnl_link *peer = rtnl_link_alloc();
 		struct nlattr *nla_peer;
 		struct ifinfomsg *ifi;
 
+		if (!peer)
+			return -NLE_NOMEM;
 		nla_peer = tb[VETH_INFO_PEER];
 		ifi = nla_data(nla_peer);
 
@@ -72,6 +74,7 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
 		err = rtnl_link_info_parse(peer, peer_tb);
 		if (err < 0)
 			goto errout;
+		link->l_info = peer;
 	}
 
 	err = 0;
-- 
1.8.1.4



From xiyou.wangcong at gmail.com  Sun Mar 23 15:02:10 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Sun, 23 Mar 2014 12:02:10 -0700
Subject: [PATCH 4/4] act: fix a pointer in rtnl_act_msg_parse()
In-Reply-To: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1395601330-20039-4-git-send-email-xiyou.wangcong@gmail.com>

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/act.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/route/act.c b/lib/route/act.c
index 0a181dd..b908b17 100644
--- a/lib/route/act.c
+++ b/lib/route/act.c
@@ -449,7 +449,7 @@ err_free:
 
 static int rtnl_act_msg_parse(struct nlmsghdr *n, struct rtnl_act **act)
 {
-	struct rtnl_tc *tc = TC_CAST(act);
+	struct rtnl_tc *tc = TC_CAST(*act);
 	struct nl_cache *link_cache;
 	struct nlattr *tb[TCAA_MAX + 1];
 	struct tcamsg *tm;
-- 
1.8.1.4



From xiyou.wangcong at gmail.com  Sun Mar 23 15:02:09 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Sun, 23 Mar 2014 12:02:09 -0700
Subject: [PATCH 3/4] veth: use nl_object_clone() to deep copy rtnl_link object
In-Reply-To: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1395601330-20039-3-git-send-email-xiyou.wangcong@gmail.com>

Currently we use memcpy() to copy the peer rtnl_link for veth device,
this is wrong, we should do deep copy by calling nl_object_clone()
recursively. We should be careful and need to make sure we only call
it once.

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 65e9a87..36315b5 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -101,19 +101,19 @@ static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
 
 static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src)
 {
-	struct rtnl_link *dst_peer , *src_peer = src->l_info;
-	int err;
-
-	dst_peer = dst->l_info = rtnl_link_alloc();
-	if (!dst_peer || !src_peer)
-		return -NLE_NOMEM;
-	if ((err = rtnl_link_set_type(dst, "veth")) < 0) {
-		rtnl_link_put(dst_peer);
-		return err;
+	struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info;
+
+	/* we are calling nl_object_clone() recursively, this should
+	 * happen only once */
+	if (src_peer) {
+		src_peer->l_info = NULL;
+		dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer));
+		if (!dst_peer)
+			return -NLE_NOMEM;
+		src_peer->l_info = src;
+		dst_peer->l_info = dst;
 	}
-
-	memcpy(dst_peer, src_peer, sizeof(struct rtnl_link));
-
+	dst->l_info = dst_peer;
 	return 0;
 }
 
-- 
1.8.1.4



From xiyou.wangcong at gmail.com  Sun Mar 23 15:02:08 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Sun, 23 Mar 2014 12:02:08 -0700
Subject: [PATCH 2/4] veth: implement ->io_free
In-Reply-To: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1395601330-20039-2-git-send-email-xiyou.wangcong@gmail.com>

So that veth link can be just put by rtnl_link_put()

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 0cac428..65e9a87 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -143,6 +143,16 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
 	return 0;
 }
 
+static void veth_free(struct rtnl_link *link)
+{
+	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
+	link->l_info = NULL;
+	if (peer) {
+		peer->l_info = NULL;
+		rtnl_link_put(peer);
+	}
+}
+
 static struct rtnl_link_info_ops veth_info_ops = {
 	.io_name		= "veth",
 	.io_parse		= veth_parse,
@@ -152,6 +162,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
 	},
 	.io_clone		= veth_clone,
 	.io_put_attrs		= veth_put_attrs,
+	.io_free		= veth_free,
 };
 
 /** @cond SKIP */
@@ -219,8 +230,12 @@ struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
 void rtnl_link_veth_release(struct rtnl_link *link)
 {
 	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
-	rtnl_link_put(peer);
+	link->l_info = NULL;
 	rtnl_link_put(link);
+	if (peer) {
+		peer->l_info = NULL;
+		rtnl_link_put(peer);
+	}
 }
 
 /**
@@ -266,9 +281,7 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
 	rtnl_link_set_ns_pid(peer, pid);
 	err = rtnl_link_add(sock, link, NLM_F_CREATE);
 
-	rtnl_link_put(peer);
 	rtnl_link_put(link);
-
         return err;
 }
 
-- 
1.8.1.4



From xiyou.wangcong at gmail.com  Thu Mar 27 01:43:16 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Wed, 26 Mar 2014 22:43:16 -0700
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
Message-ID: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/act.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/route/act.c b/lib/route/act.c
index b908b17..23f9393 100644
--- a/lib/route/act.c
+++ b/lib/route/act.c
@@ -390,7 +390,7 @@ int rtnl_act_parse(struct rtnl_act **head, struct nlattr *tb)
 	if (err < 0)
 		return err;
 
-	for (i = 1; i <= TCA_ACT_MAX_PRIO && nla[i]; i++) {
+	for (i = 0; i < TCA_ACT_MAX_PRIO && nla[i]; i++) {
 		struct rtnl_act *act;
 		struct rtnl_tc *tc;
 
-- 
1.7.11.7



From tgraf at suug.ch  Thu Mar 27 04:28:57 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 27 Mar 2014 08:28:57 +0000
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
In-Reply-To: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140327082857.GA8354@casper.infradead.org>

On 03/26/14 at 10:43pm, Cong Wang wrote:
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/act.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/route/act.c b/lib/route/act.c
> index b908b17..23f9393 100644

LGTM

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Thu Mar 27 05:13:11 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 27 Mar 2014 09:13:11 +0000
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing
 netlink message
In-Reply-To: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140327091311.GB8354@casper.infradead.org>

On 03/23/14 at 12:02pm, Cong Wang wrote:
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/link/veth.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> index 4ce1f10..0cac428 100644
> --- a/lib/route/link/veth.c
> +++ b/lib/route/link/veth.c
> @@ -42,7 +42,6 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
>  {
>  	struct nlattr *tb[VETH_INFO_MAX+1];
>  	struct nlattr *peer_tb[IFLA_MAX + 1];
> -	struct rtnl_link *peer = link->l_info;
>  	int err;
>  
>  	NL_DBG(3, "Parsing veth link info");
> @@ -51,9 +50,12 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
>  		goto errout;
>  
>  	if (tb[VETH_INFO_PEER]) {
> +		struct rtnl_link *peer = rtnl_link_alloc();
>  		struct nlattr *nla_peer;
>  		struct ifinfomsg *ifi;
>  
> +		if (!peer)
> +			return -NLE_NOMEM;
>  		nla_peer = tb[VETH_INFO_PEER];
>  		ifi = nla_data(nla_peer);
>  
> @@ -72,6 +74,7 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
>  		err = rtnl_link_info_parse(peer, peer_tb);
>  		if (err < 0)
>  			goto errout;

I think peer is leaked in the error cases above.

> +		link->l_info = peer;
>  	}


From tgraf at suug.ch  Thu Mar 27 05:25:14 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 27 Mar 2014 09:25:14 +0000
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing
 netlink message
In-Reply-To: <20140327091311.GB8354@casper.infradead.org>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327091311.GB8354@casper.infradead.org>
Message-ID: <20140327092514.GC8354@casper.infradead.org>

On 03/27/14 at 09:13am, Thomas Graf wrote:
> On 03/23/14 at 12:02pm, Cong Wang wrote:
> > Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> > ---
> >  lib/route/link/veth.c | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> > index 4ce1f10..0cac428 100644
> > --- a/lib/route/link/veth.c
> > +++ b/lib/route/link/veth.c
> > @@ -42,7 +42,6 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
> >  {
> >  	struct nlattr *tb[VETH_INFO_MAX+1];
> >  	struct nlattr *peer_tb[IFLA_MAX + 1];
> > -	struct rtnl_link *peer = link->l_info;
> >  	int err;
> >  
> >  	NL_DBG(3, "Parsing veth link info");
> > @@ -51,9 +50,12 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
> >  		goto errout;
> >  
> >  	if (tb[VETH_INFO_PEER]) {
> > +		struct rtnl_link *peer = rtnl_link_alloc();

Why don't you just use io_alloc()? That way the peer link is always
around and you never need to check whether you have created it or not.


> >  		struct nlattr *nla_peer;
> >  		struct ifinfomsg *ifi;
> >  
> > +		if (!peer)
> > +			return -NLE_NOMEM;
> >  		nla_peer = tb[VETH_INFO_PEER];
> >  		ifi = nla_data(nla_peer);
> >  
> > @@ -72,6 +74,7 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
> >  		err = rtnl_link_info_parse(peer, peer_tb);
> >  		if (err < 0)
> >  			goto errout;
> 
> I think peer is leaked in the error cases above.
> 
> > +		link->l_info = peer;
> >  	}


From tgraf at suug.ch  Thu Mar 27 05:26:49 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 27 Mar 2014 09:26:49 +0000
Subject: [PATCH 4/4] act: fix a pointer in rtnl_act_msg_parse()
In-Reply-To: <1395601330-20039-4-git-send-email-xiyou.wangcong@gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
 <1395601330-20039-4-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140327092649.GD8354@casper.infradead.org>

On 03/23/14 at 12:02pm, Cong Wang wrote:
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/act.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Thomas Graf <tgraf at suug.ch>


From xiyou.wangcong at gmail.com  Thu Mar 27 16:41:17 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 27 Mar 2014 13:41:17 -0700
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing netlink
 message
In-Reply-To: <20140327092514.GC8354@casper.infradead.org>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327091311.GB8354@casper.infradead.org>
 <20140327092514.GC8354@casper.infradead.org>
Message-ID: <CAM_iQpWr-wk39KHtE8BzZgOeYGy=G8EYmFtqhRjpAo4zeZ-jHA@mail.gmail.com>

On Thu, Mar 27, 2014 at 2:25 AM, Thomas Graf <tgraf at suug.ch> wrote:
> On 03/27/14 at 09:13am, Thomas Graf wrote:
>> On 03/23/14 at 12:02pm, Cong Wang wrote:
>> > Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
>> > ---
>> >  lib/route/link/veth.c | 5 ++++-
>> >  1 file changed, 4 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
>> > index 4ce1f10..0cac428 100644
>> > --- a/lib/route/link/veth.c
>> > +++ b/lib/route/link/veth.c
>> > @@ -42,7 +42,6 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
>> >  {
>> >     struct nlattr *tb[VETH_INFO_MAX+1];
>> >     struct nlattr *peer_tb[IFLA_MAX + 1];
>> > -   struct rtnl_link *peer = link->l_info;
>> >     int err;
>> >
>> >     NL_DBG(3, "Parsing veth link info");
>> > @@ -51,9 +50,12 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
>> >             goto errout;
>> >
>> >     if (tb[VETH_INFO_PEER]) {
>> > +           struct rtnl_link *peer = rtnl_link_alloc();
>
> Why don't you just use io_alloc()? That way the peer link is always
> around and you never need to check whether you have created it or not.
>

Good point! I thought each type of link should provide a rtnl_link_*_alloc()
API to allocate the correct struct, but it seems better to implement
->io_alloc() so that struct would be allocate when calling rtnl_link_set_type().

However, here for veth_parse() it seems rtnl_link_set_type() is not ever
called by its caller? I suppose rtnl_link_info_parse() should call it.


From tgraf at suug.ch  Thu Mar 27 19:46:31 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Thu, 27 Mar 2014 23:46:31 +0000
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing
 netlink message
In-Reply-To: <CAM_iQpWr-wk39KHtE8BzZgOeYGy=G8EYmFtqhRjpAo4zeZ-jHA@mail.gmail.com>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327091311.GB8354@casper.infradead.org>
 <20140327092514.GC8354@casper.infradead.org>
 <CAM_iQpWr-wk39KHtE8BzZgOeYGy=G8EYmFtqhRjpAo4zeZ-jHA@mail.gmail.com>
Message-ID: <20140327234631.GE13573@casper.infradead.org>

On 03/27/14 at 01:41pm, Cong Wang wrote:
> On Thu, Mar 27, 2014 at 2:25 AM, Thomas Graf <tgraf at suug.ch> wrote:
> > On 03/27/14 at 09:13am, Thomas Graf wrote:
> >> On 03/23/14 at 12:02pm, Cong Wang wrote:
> >> > Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> >> > ---
> >> >  lib/route/link/veth.c | 5 ++++-
> >> >  1 file changed, 4 insertions(+), 1 deletion(-)
> >> >
> >> > diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> >> > index 4ce1f10..0cac428 100644
> >> > --- a/lib/route/link/veth.c
> >> > +++ b/lib/route/link/veth.c
> >> > @@ -42,7 +42,6 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
> >> >  {
> >> >     struct nlattr *tb[VETH_INFO_MAX+1];
> >> >     struct nlattr *peer_tb[IFLA_MAX + 1];
> >> > -   struct rtnl_link *peer = link->l_info;
> >> >     int err;
> >> >
> >> >     NL_DBG(3, "Parsing veth link info");
> >> > @@ -51,9 +50,12 @@ static int veth_parse(struct rtnl_link *link, struct nlattr *data,
> >> >             goto errout;
> >> >
> >> >     if (tb[VETH_INFO_PEER]) {
> >> > +           struct rtnl_link *peer = rtnl_link_alloc();
> >
> > Why don't you just use io_alloc()? That way the peer link is always
> > around and you never need to check whether you have created it or not.
> >
> 
> Good point! I thought each type of link should provide a rtnl_link_*_alloc()
> API to allocate the correct struct, but it seems better to implement
> ->io_alloc() so that struct would be allocate when calling rtnl_link_set_type().
> 
> However, here for veth_parse() it seems rtnl_link_set_type() is not ever
> called by its caller? I suppose rtnl_link_info_parse() should call it.

link_msg_parser() should call it instead of setting l_info_kind
manually. It's a bug.


From xiyou.wangcong at gmail.com  Fri Mar 28 01:29:44 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Thu, 27 Mar 2014 22:29:44 -0700
Subject: [PATCH 1/4] veth: alloc link struct for peer when parsing netlink
 message
In-Reply-To: <20140327234631.GE13573@casper.infradead.org>
References: <1395601330-20039-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327091311.GB8354@casper.infradead.org>
 <20140327092514.GC8354@casper.infradead.org>
 <CAM_iQpWr-wk39KHtE8BzZgOeYGy=G8EYmFtqhRjpAo4zeZ-jHA@mail.gmail.com>
 <20140327234631.GE13573@casper.infradead.org>
Message-ID: <CAM_iQpXHCL_t4d+9WVYeEh8r+akjPERFrOagTvNK9wQiPuOytQ@mail.gmail.com>

On Thu, Mar 27, 2014 at 4:46 PM, Thomas Graf <tgraf at suug.ch> wrote:
>
> link_msg_parser() should call it instead of setting l_info_kind
> manually. It's a bug.

I cooked a patch and updated these 3 veth patches too,
I am testing them now.

Thanks!


From thaller at redhat.com  Fri Mar 28 09:17:48 2014
From: thaller at redhat.com (Thomas Haller)
Date: Fri, 28 Mar 2014 14:17:48 +0100
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
In-Reply-To: <20140327082857.GA8354@casper.infradead.org>
References: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327082857.GA8354@casper.infradead.org>
Message-ID: <1396012668.25452.16.camel@Host-001>

On Thu, 2014-03-27 at 08:28 +0000, Thomas Graf wrote:
> On 03/26/14 at 10:43pm, Cong Wang wrote:
> > Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> > ---
> >  lib/route/act.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/lib/route/act.c b/lib/route/act.c
> > index b908b17..23f9393 100644
> 
> LGTM
> 
> Acked-by: Thomas Graf <tgraf at suug.ch>
> 

Hi,

Cong, why do you think that libnl should shift the index "i" by one?
Sorry, I just don't see it :)


kernel also uses similar loops:

$ git grep -n for.*TCA_ACT_MAX_PRIO
net/sched/act_api.c:593: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
net/sched/act_api.c:871: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {


Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140328/5f89ad00/attachment.sig>

From tgraf at suug.ch  Fri Mar 28 09:52:03 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Fri, 28 Mar 2014 13:52:03 +0000
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
In-Reply-To: <1396012668.25452.16.camel@Host-001>
References: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327082857.GA8354@casper.infradead.org>
 <1396012668.25452.16.camel@Host-001>
Message-ID: <20140328135203.GF13573@casper.infradead.org>

On 03/28/14 at 02:17pm, Thomas Haller wrote:
> On Thu, 2014-03-27 at 08:28 +0000, Thomas Graf wrote:
> > On 03/26/14 at 10:43pm, Cong Wang wrote:
> > > Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> > > ---
> > >  lib/route/act.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/lib/route/act.c b/lib/route/act.c
> > > index b908b17..23f9393 100644
> > 
> > LGTM
> > 
> > Acked-by: Thomas Graf <tgraf at suug.ch>
> > 
> 
> Hi,
> 
> Cong, why do you think that libnl should shift the index "i" by one?
> Sorry, I just don't see it :)
> 
> 
> kernel also uses similar loops:
> 
> $ git grep -n for.*TCA_ACT_MAX_PRIO
> net/sched/act_api.c:593: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
> net/sched/act_api.c:871: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {

Looking at the dumper:

        int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
        struct nlattr *nest;

        spin_lock_bh(&hinfo->lock);

        s_i = cb->args[0];

        for (i = 0; i < (hinfo->hmask + 1); i++) {
                head = &hinfo->htab[tcf_hash(i, hinfo->hmask)];

                hlist_for_each_entry_rcu(p, head, tcfc_head) {
                        index++;
                        if (index < s_i)
                                continue;
                        a->priv = p;
                        a->order = n_i;

                        nest = nla_nest_start(skb, a->order);
                        if (nest == NULL)
                                goto nla_put_failure;
                        err = tcf_action_dump_1(skb, a, 0, 0);
                        if (err < 0) {
                                index--;
                                nlmsg_trim(skb, nest);
                                goto done;
                        }
                        nla_nest_end(skb, nest);
                        n_i++;
                        if (n_i >= TCA_ACT_MAX_PRIO)
                                goto done;
                }
        }


It does use 0..TCA_ACT_MAX_PRIO


From xiyou.wangcong at gmail.com  Fri Mar 28 20:28:24 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Fri, 28 Mar 2014 17:28:24 -0700
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
In-Reply-To: <1396012668.25452.16.camel@Host-001>
References: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327082857.GA8354@casper.infradead.org>
 <1396012668.25452.16.camel@Host-001>
Message-ID: <CAM_iQpW_V6uJTiMKwqh4hZKcJ3f+y-ip_2jKwx03_o-76t6fzQ@mail.gmail.com>

On Fri, Mar 28, 2014 at 6:17 AM, Thomas Haller <thaller at redhat.com> wrote:
> Hi,
>
> Cong, why do you think that libnl should shift the index "i" by one?
> Sorry, I just don't see it :)
>
>
> kernel also uses similar loops:
>
> $ git grep -n for.*TCA_ACT_MAX_PRIO
> net/sched/act_api.c:593: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
> net/sched/act_api.c:871: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {

I had the same conclusion until I saw a crash. ;)

For some reason I don't know,  the message dumped by kernel uses 0..MAX-1,
while the message to create new action uses 1..MAX. It is indeed weird for me
too.


From xiyou.wangcong at gmail.com  Fri Mar 28 21:08:17 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Fri, 28 Mar 2014 18:08:17 -0700
Subject: [Patch v2 3/4] veth: implement ->io_free
In-Reply-To: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1396055298-12548-3-git-send-email-xiyou.wangcong@gmail.com>

So that veth link can be just put by rtnl_link_put()

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index cf2e513..c6a4cc7 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -163,6 +163,16 @@ static int veth_alloc(struct rtnl_link *link)
 	return 0;
 }
 
+static void veth_free(struct rtnl_link *link)
+{
+	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
+	link->l_info = NULL;
+	if (peer) {
+		peer->l_info = NULL;
+		rtnl_link_put(peer);
+	}
+}
+
 static struct rtnl_link_info_ops veth_info_ops = {
 	.io_name		= "veth",
 	.io_parse		= veth_parse,
@@ -173,6 +183,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
 	.io_alloc		= veth_alloc,
 	.io_clone		= veth_clone,
 	.io_put_attrs		= veth_put_attrs,
+	.io_free		= veth_free,
 };
 
 /** @cond SKIP */
@@ -227,8 +238,12 @@ struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
 void rtnl_link_veth_release(struct rtnl_link *link)
 {
 	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
-	rtnl_link_put(peer);
+	link->l_info = NULL;
 	rtnl_link_put(link);
+	if (peer) {
+		peer->l_info = NULL;
+		rtnl_link_put(peer);
+	}
 }
 
 /**
@@ -274,9 +289,7 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
 	rtnl_link_set_ns_pid(peer, pid);
 	err = rtnl_link_add(sock, link, NLM_F_CREATE);
 
-	rtnl_link_put(peer);
 	rtnl_link_put(link);
-
         return err;
 }
 
-- 
1.7.11.7



From xiyou.wangcong at gmail.com  Fri Mar 28 21:08:18 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Fri, 28 Mar 2014 18:08:18 -0700
Subject: [Patch v2 4/4] veth: use nl_object_clone() to deep copy rtnl_link
 object
In-Reply-To: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1396055298-12548-4-git-send-email-xiyou.wangcong@gmail.com>

Currently we use memcpy() to copy the peer rtnl_link for veth device,
this is wrong, we should do deep copy by calling nl_object_clone()
recursively. We should be careful and need to make sure we only call
it once.

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index c6a4cc7..817a268 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -98,19 +98,19 @@ static void veth_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
 
 static int veth_clone(struct rtnl_link *dst, struct rtnl_link *src)
 {
-	struct rtnl_link *dst_peer , *src_peer = src->l_info;
-	int err;
-
-	dst_peer = dst->l_info = rtnl_link_alloc();
-	if (!dst_peer || !src_peer)
-		return -NLE_NOMEM;
-	if ((err = rtnl_link_set_type(dst, "veth")) < 0) {
-		rtnl_link_put(dst_peer);
-		return err;
+	struct rtnl_link *dst_peer = NULL, *src_peer = src->l_info;
+
+	/* we are calling nl_object_clone() recursively, this should
+	 * happen only once */
+	if (src_peer) {
+		src_peer->l_info = NULL;
+		dst_peer = (struct rtnl_link *)nl_object_clone(OBJ_CAST(src_peer));
+		if (!dst_peer)
+			return -NLE_NOMEM;
+		src_peer->l_info = src;
+		dst_peer->l_info = dst;
 	}
-
-	memcpy(dst_peer, src_peer, sizeof(struct rtnl_link));
-
+	dst->l_info = dst_peer;
 	return 0;
 }
 
-- 
1.7.11.7



From xiyou.wangcong at gmail.com  Fri Mar 28 21:08:16 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Fri, 28 Mar 2014 18:08:16 -0700
Subject: [Patch v2 2/4] veth: implement io_alloc()
In-Reply-To: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <1396055298-12548-2-git-send-email-xiyou.wangcong@gmail.com>

Users don't have to call rtnl_link_veth_alloc(), instead
use generic rtnl_link_set_type().

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link/veth.c | 39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
index 4ce1f10..cf2e513 100644
--- a/lib/route/link/veth.c
+++ b/lib/route/link/veth.c
@@ -140,6 +140,29 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
 	return 0;
 }
 
+static int veth_alloc(struct rtnl_link *link)
+{
+	struct rtnl_link *peer;
+	int err;
+
+	if (link->l_info)
+		return 0;
+
+	if (!(peer = rtnl_link_alloc())) {
+		rtnl_link_put(link);
+		return -NLE_NOMEM;
+	}
+
+	peer->l_info = link;
+	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
+		rtnl_link_put(peer);
+		return err;
+	}
+
+	link->l_info = peer;
+	return 0;
+}
+
 static struct rtnl_link_info_ops veth_info_ops = {
 	.io_name		= "veth",
 	.io_parse		= veth_parse,
@@ -147,6 +170,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
 	    [NL_DUMP_LINE]	= veth_dump_line,
 	    [NL_DUMP_DETAILS]	= veth_dump_details,
 	},
+	.io_alloc		= veth_alloc,
 	.io_clone		= veth_clone,
 	.io_put_attrs		= veth_put_attrs,
 };
@@ -172,29 +196,16 @@ static struct rtnl_link_info_ops veth_info_ops = {
  */
 struct rtnl_link *rtnl_link_veth_alloc(void)
 {
-	struct rtnl_link *link, *peer;
+	struct rtnl_link *link;
 	int err;
 
 	if (!(link = rtnl_link_alloc()))
 		return NULL;
-	if (!(peer = rtnl_link_alloc())) {
-		rtnl_link_put(link);
-		return NULL;
-	}
-
 	if ((err = rtnl_link_set_type(link, "veth")) < 0) {
-		rtnl_link_put(peer);
-		rtnl_link_put(link);
-		return NULL;
-	}
-	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
-		rtnl_link_put(peer);
 		rtnl_link_put(link);
 		return NULL;
 	}
 
-	link->l_info = peer;
-	peer->l_info = link;
 	return link;
 }
 
-- 
1.7.11.7



From xiyou.wangcong at gmail.com  Fri Mar 28 21:08:15 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Fri, 28 Mar 2014 18:08:15 -0700
Subject: [Patch v2 1/4] link: call rtnl_link_set_type() in link_msg_parser()
Message-ID: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>

We need to call link-specific ->io_alloc() to alloc
addtional structures.

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 lib/route/link.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/lib/route/link.c b/lib/route/link.c
index d609b17..7f7b1ce 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -537,16 +537,10 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
 
 		if (li[IFLA_INFO_KIND]) {
 			struct rtnl_link_info_ops *ops;
-			char *kind;
+			char *kind = nla_get_string(li[IFLA_INFO_KIND]);
 			int af;
 
-			kind = nla_strdup(li[IFLA_INFO_KIND]);
-			if (kind == NULL) {
-				err = -NLE_NOMEM;
-				goto errout;
-			}
-			link->l_info_kind = kind;
-			link->ce_mask |= LINK_ATTR_LINKINFO;
+			rtnl_link_set_type(link, kind);
 
 			if ((af = nl_str2af(kind)) >= 0 &&
 				!af_ops && (af_ops = af_lookup_and_alloc(link, af))) {
-- 
1.7.11.7



From thaller at redhat.com  Mon Mar 31 03:47:22 2014
From: thaller at redhat.com (Thomas Haller)
Date: Mon, 31 Mar 2014 09:47:22 +0200
Subject: [PATCH] fix off-by-one in rtnl_act_parse()
In-Reply-To: <CAM_iQpW_V6uJTiMKwqh4hZKcJ3f+y-ip_2jKwx03_o-76t6fzQ@mail.gmail.com>
References: <1395898996-29902-1-git-send-email-xiyou.wangcong@gmail.com>
 <20140327082857.GA8354@casper.infradead.org>
 <1396012668.25452.16.camel@Host-001>
 <CAM_iQpW_V6uJTiMKwqh4hZKcJ3f+y-ip_2jKwx03_o-76t6fzQ@mail.gmail.com>
Message-ID: <1396252042.5814.7.camel@Host-001>

On Fri, 2014-03-28 at 17:28 -0700, Cong Wang wrote:
> On Fri, Mar 28, 2014 at 6:17 AM, Thomas Haller <thaller at redhat.com> wrote:
> > Hi,
> >
> > Cong, why do you think that libnl should shift the index "i" by one?
> > Sorry, I just don't see it :)
> >
> >
> > kernel also uses similar loops:
> >
> > $ git grep -n for.*TCA_ACT_MAX_PRIO
> > net/sched/act_api.c:593: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
> > net/sched/act_api.c:871: for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
> 
> I had the same conclusion until I saw a crash. ;)
> 
> For some reason I don't know,  the message dumped by kernel uses 0..MAX-1,
> while the message to create new action uses 1..MAX. It is indeed weird for me
> too.

Ok then :)

Pushed to master as:
https://github.com/thom311/libnl/commit/baa2cadd02086a053eb140c91d7f0681112ac370


Thank you,
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140331/f51d3ef8/attachment.sig>

From tgraf at suug.ch  Mon Mar 31 06:56:48 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Mon, 31 Mar 2014 11:56:48 +0100
Subject: [Patch v2 1/4] link: call rtnl_link_set_type() in
 link_msg_parser()
In-Reply-To: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140331105648.GA22628@casper.infradead.org>

On 03/28/14 at 06:08pm, Cong Wang wrote:
> We need to call link-specific ->io_alloc() to alloc
> addtional structures.
> 
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Mon Mar 31 07:04:44 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Mon, 31 Mar 2014 12:04:44 +0100
Subject: [Patch v2 2/4] veth: implement io_alloc()
In-Reply-To: <1396055298-12548-2-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-2-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140331110444.GB22628@casper.infradead.org>

On 03/28/14 at 06:08pm, Cong Wang wrote:
> Users don't have to call rtnl_link_veth_alloc(), instead
> use generic rtnl_link_set_type().
> 
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/link/veth.c | 39 +++++++++++++++++++++++++--------------
>  1 file changed, 25 insertions(+), 14 deletions(-)
> 
> diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> index 4ce1f10..cf2e513 100644
> --- a/lib/route/link/veth.c
> +++ b/lib/route/link/veth.c
> @@ -140,6 +140,29 @@ static int veth_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
>  	return 0;
>  }
>  
> +static int veth_alloc(struct rtnl_link *link)
> +{
> +	struct rtnl_link *peer;
> +	int err;
> +
> +	if (link->l_info)
> +		return 0;

Can you put a comment above to explain that the return is needed
to break the recursion loop?

> +
> +	if (!(peer = rtnl_link_alloc())) {
> +		rtnl_link_put(link);

This put looks wrong. It could free the link object beneath
the caller.

> +		return -NLE_NOMEM;
> +	}
> +
> +	peer->l_info = link;

You need to acquire a refcnt to link to make sure link is
not freed while you hold that reference.

nl_object_get(OBJ_CAST(link));
peer->l_info = link;

And then release it again in io_free


> +	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
> +		rtnl_link_put(peer);
> +		return err;
> +	}
> +
> +	link->l_info = peer;
> +	return 0;
> +}
> +
>  static struct rtnl_link_info_ops veth_info_ops = {
>  	.io_name		= "veth",
>  	.io_parse		= veth_parse,
> @@ -147,6 +170,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
>  	    [NL_DUMP_LINE]	= veth_dump_line,
>  	    [NL_DUMP_DETAILS]	= veth_dump_details,
>  	},
> +	.io_alloc		= veth_alloc,
>  	.io_clone		= veth_clone,
>  	.io_put_attrs		= veth_put_attrs,
>  };
> @@ -172,29 +196,16 @@ static struct rtnl_link_info_ops veth_info_ops = {
>   */
>  struct rtnl_link *rtnl_link_veth_alloc(void)
>  {
> -	struct rtnl_link *link, *peer;
> +	struct rtnl_link *link;
>  	int err;
>  
>  	if (!(link = rtnl_link_alloc()))
>  		return NULL;
> -	if (!(peer = rtnl_link_alloc())) {
> -		rtnl_link_put(link);
> -		return NULL;
> -	}
> -
>  	if ((err = rtnl_link_set_type(link, "veth")) < 0) {
> -		rtnl_link_put(peer);
> -		rtnl_link_put(link);
> -		return NULL;
> -	}
> -	if ((err = rtnl_link_set_type(peer, "veth")) < 0) {
> -		rtnl_link_put(peer);
>  		rtnl_link_put(link);
>  		return NULL;
>  	}
>  
> -	link->l_info = peer;
> -	peer->l_info = link;
>  	return link;
>  }

This part looks good.


From tgraf at suug.ch  Mon Mar 31 07:07:04 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Mon, 31 Mar 2014 12:07:04 +0100
Subject: [Patch v2 3/4] veth: implement ->io_free
In-Reply-To: <1396055298-12548-3-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-3-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140331110704.GC22628@casper.infradead.org>

On 03/28/14 at 06:08pm, Cong Wang wrote:
> So that veth link can be just put by rtnl_link_put()
> 
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
> ---
>  lib/route/link/veth.c | 19 ++++++++++++++++---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/route/link/veth.c b/lib/route/link/veth.c
> index cf2e513..c6a4cc7 100644
> --- a/lib/route/link/veth.c
> +++ b/lib/route/link/veth.c
> @@ -163,6 +163,16 @@ static int veth_alloc(struct rtnl_link *link)
>  	return 0;
>  }
>  
> +static void veth_free(struct rtnl_link *link)
> +{
> +	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
> +	link->l_info = NULL;
> +	if (peer) {
> +		peer->l_info = NULL;
> +		rtnl_link_put(peer);
> +	}

I think this should call _release() to not dupliacte code.

> +}
> +
>  static struct rtnl_link_info_ops veth_info_ops = {
>  	.io_name		= "veth",
>  	.io_parse		= veth_parse,
> @@ -173,6 +183,7 @@ static struct rtnl_link_info_ops veth_info_ops = {
>  	.io_alloc		= veth_alloc,
>  	.io_clone		= veth_clone,
>  	.io_put_attrs		= veth_put_attrs,
> +	.io_free		= veth_free,
>  };
>  
>  /** @cond SKIP */
> @@ -227,8 +238,12 @@ struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
>  void rtnl_link_veth_release(struct rtnl_link *link)
>  {
>  	struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
> -	rtnl_link_put(peer);
> +	link->l_info = NULL;

Will need to release the reference as requested in patch 2.

>  	rtnl_link_put(link);
> +	if (peer) {
> +		peer->l_info = NULL;
> +		rtnl_link_put(peer);
> +	}
>  }
>  
>  /**
> @@ -274,9 +289,7 @@ int rtnl_link_veth_add(struct nl_sock *sock, const char *name,
>  	rtnl_link_set_ns_pid(peer, pid);
>  	err = rtnl_link_add(sock, link, NLM_F_CREATE);
>  
> -	rtnl_link_put(peer);
>  	rtnl_link_put(link);
> -
>          return err;
>  }
>  
> -- 
> 1.7.11.7
> 
> 
> _______________________________________________
> libnl mailing list
> libnl at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libnl
> 


From tgraf at suug.ch  Mon Mar 31 07:09:25 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Mon, 31 Mar 2014 12:09:25 +0100
Subject: [Patch v2 4/4] veth: use nl_object_clone() to deep copy
 rtnl_link object
In-Reply-To: <1396055298-12548-4-git-send-email-xiyou.wangcong@gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-4-git-send-email-xiyou.wangcong@gmail.com>
Message-ID: <20140331110925.GD22628@casper.infradead.org>

On 03/28/14 at 06:08pm, Cong Wang wrote:
> Currently we use memcpy() to copy the peer rtnl_link for veth device,
> this is wrong, we should do deep copy by calling nl_object_clone()
> recursively. We should be careful and need to make sure we only call
> it once.
> 
> Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>

Acked-by: Thomas Graf <tgraf at suug.ch>


From tgraf at suug.ch  Mon Mar 31 07:21:06 2014
From: tgraf at suug.ch (Thomas Graf)
Date: Mon, 31 Mar 2014 13:21:06 +0200
Subject: [PATCH] link: Catch missing io_free() implementations
Message-ID: <11fa976b0cc2afa353f9ff69684b1f823e56038b.1396264828.git.tgraf@suug.ch>

Signed-off-by: Thomas Graf <tgraf at suug.ch>
---
 include/netlink-private/netlink.h | 7 +++++++
 lib/route/link.c                  | 4 ++++
 2 files changed, 11 insertions(+)

diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
index ee2a8b1..e366d1e 100644
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -102,6 +102,13 @@ struct trans_list {
 		assert(0);						\
 	} while (0)
 
+#define BUG_ON(condition)						\
+	do {								\
+		if (condition)						\
+			BUG();						\
+	} while (0)
+
+
 #define APPBUG(msg)							\
 	do {								\
 		fprintf(stderr, "APPLICATION BUG: %s:%d:%s: %s\n",	\
diff --git a/lib/route/link.c b/lib/route/link.c
index d609b17..3263096 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -194,6 +194,10 @@ static void release_link_info(struct rtnl_link *link)
 	if (io != NULL) {
 		if (io->io_free)
 			io->io_free(link);
+		else {
+			/* Catch missing io_free() implementations */
+			BUG_ON(link->l_info);
+		}
 		rtnl_link_info_ops_put(io);
 		link->l_info_ops = NULL;
 	}
-- 
1.8.3.1



From thaller at redhat.com  Mon Mar 31 07:28:08 2014
From: thaller at redhat.com (Thomas Haller)
Date: Mon, 31 Mar 2014 13:28:08 +0200
Subject: [PATCH] link: Catch missing io_free() implementations
In-Reply-To: <11fa976b0cc2afa353f9ff69684b1f823e56038b.1396264828.git.tgraf@suug.ch>
References: <11fa976b0cc2afa353f9ff69684b1f823e56038b.1396264828.git.tgraf@suug.ch>
Message-ID: <1396265288.5814.27.camel@Host-001>

On Mon, 2014-03-31 at 13:21 +0200, Thomas Graf wrote:
> Signed-off-by: Thomas Graf <tgraf at suug.ch>
> ---
>  include/netlink-private/netlink.h | 7 +++++++
>  lib/route/link.c                  | 4 ++++
>  2 files changed, 11 insertions(+)


Pushed to master as:

https://github.com/thom311/libnl/commit/34bfce62150d07cf9894f2d9cbd0c989a203ea52



Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20140331/de0d80f4/attachment.sig>

From xiyou.wangcong at gmail.com  Mon Mar 31 15:11:57 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Mon, 31 Mar 2014 12:11:57 -0700
Subject: [Patch v2 2/4] veth: implement io_alloc()
In-Reply-To: <20140331110444.GB22628@casper.infradead.org>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-2-git-send-email-xiyou.wangcong@gmail.com>
 <20140331110444.GB22628@casper.infradead.org>
Message-ID: <CAM_iQpWcv28t0N1qxM3+YcSnYVKxdCQWh4d78-C_S2xbJOZ_1Q@mail.gmail.com>

On Mon, Mar 31, 2014 at 4:04 AM, Thomas Graf <tgraf at suug.ch> wrote:
> On 03/28/14 at 06:08pm, Cong Wang wrote:
>> +static int veth_alloc(struct rtnl_link *link)
>> +{
>> +     struct rtnl_link *peer;
>> +     int err;
>> +
>> +     if (link->l_info)
>> +             return 0;
>
> Can you put a comment above to explain that the return is needed
> to break the recursion loop?
>

Sure.

>> +
>> +     if (!(peer = rtnl_link_alloc())) {
>> +             rtnl_link_put(link);
>
> This put looks wrong. It could free the link object beneath
> the caller.
>

Good catch, I will fix it.

>> +             return -NLE_NOMEM;
>> +     }
>> +
>> +     peer->l_info = link;
>
> You need to acquire a refcnt to link to make sure link is
> not freed while you hold that reference.
>
> nl_object_get(OBJ_CAST(link));
> peer->l_info = link;
>
> And then release it again in io_free
>

Yeah, will do.

Thanks!


From xiyou.wangcong at gmail.com  Mon Mar 31 15:16:44 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Mon, 31 Mar 2014 12:16:44 -0700
Subject: [Patch v2 3/4] veth: implement ->io_free
In-Reply-To: <20140331110704.GC22628@casper.infradead.org>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-3-git-send-email-xiyou.wangcong@gmail.com>
 <20140331110704.GC22628@casper.infradead.org>
Message-ID: <CAM_iQpVdUJk==odRkihx=Ld4C7s9PHo2bqUKdUF7GmNhZ27iRA@mail.gmail.com>

On Mon, Mar 31, 2014 at 4:07 AM, Thomas Graf <tgraf at suug.ch> wrote:
> On 03/28/14 at 06:08pm, Cong Wang wrote:
>> +static void veth_free(struct rtnl_link *link)
>> +{
>> +     struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
>> +     link->l_info = NULL;
>> +     if (peer) {
>> +             peer->l_info = NULL;
>> +             rtnl_link_put(peer);
>> +     }
>
> I think this should call _release() to not dupliacte code.

The difference between veth_free() and veth_release() is
veth_free() is not supposed to call rtnl_link_put() on `link`,
its caller will do it. So, the code is not duplicated actually.


>> @@ -227,8 +238,12 @@ struct rtnl_link *rtnl_link_veth_get_peer(struct rtnl_link *link)
>>  void rtnl_link_veth_release(struct rtnl_link *link)
>>  {
>>       struct rtnl_link *peer = rtnl_link_veth_get_peer(link);
>> -     rtnl_link_put(peer);
>> +     link->l_info = NULL;
>
> Will need to release the reference as requested in patch 2.

Sure.

Thanks!


From xiyou.wangcong at gmail.com  Mon Mar 31 19:49:43 2014
From: xiyou.wangcong at gmail.com (Cong Wang)
Date: Mon, 31 Mar 2014 16:49:43 -0700
Subject: [Patch v2 2/4] veth: implement io_alloc()
In-Reply-To: <CAM_iQpWcv28t0N1qxM3+YcSnYVKxdCQWh4d78-C_S2xbJOZ_1Q@mail.gmail.com>
References: <1396055298-12548-1-git-send-email-xiyou.wangcong@gmail.com>
 <1396055298-12548-2-git-send-email-xiyou.wangcong@gmail.com>
 <20140331110444.GB22628@casper.infradead.org>
 <CAM_iQpWcv28t0N1qxM3+YcSnYVKxdCQWh4d78-C_S2xbJOZ_1Q@mail.gmail.com>
Message-ID: <CAM_iQpVXVsUO0x7WPF7p_oqZA3ka4Y5GHHOUqf0kVXqPWHKHgg@mail.gmail.com>

On Mon, Mar 31, 2014 at 12:11 PM, Cong Wang <xiyou.wangcong at gmail.com> wrote:
> On Mon, Mar 31, 2014 at 4:04 AM, Thomas Graf <tgraf at suug.ch> wrote:
>> On 03/28/14 at 06:08pm, Cong Wang wrote:
>>> +             return -NLE_NOMEM;
>>> +     }
>>> +
>>> +     peer->l_info = link;
>>
>> You need to acquire a refcnt to link to make sure link is
>> not freed while you hold that reference.
>>
>> nl_object_get(OBJ_CAST(link));
>> peer->l_info = link;
>>
>> And then release it again in io_free
>>
>
> Yeah, will do.


Hmm, thinking a bit more, I think we probably we don't need
a hold a reference here, because no matter we free link from
either link or its peer, it will free the ->l_info struct together.
IOW, they share the same life time thus their refcounts are
always same.

I tried to grab a reference here, but it's hard to make it working
correctly.

What do you think?


