From gilles.dejaegere at mail.polimi.it  Thu May  5 01:03:27 2016
From: gilles.dejaegere at mail.polimi.it (Gilles Dejaegere)
Date: Thu, 5 May 2016 08:03:27 +0000
Subject: cgroup classifier problem
Message-ID: <DB4PR06MB491F172D10D37C468D148E4BC7C0@DB4PR06MB491.eurprd06.prod.outlook.com>

Dear All,

I have some trouble making a "cgroup classifier". When trying to add  them, I always get an "Unable to add cls: Invalid input data or  parameter" answer. I am trying to do the same as these two commands :  "tc qdisc add dev eth10 root handle 10: htb default 1" and "tc filter add dev eth10 parent 10: protocol ip prio 10 handle 1  cgroup". I did not succeed to make my code work. I suspect that the  problem comes from the handle attribute for two reasons. First of all,  it is the only attribute that when removed changes the error in "Missing attribute". And secondly, when I try to make a  "u32" instead of "cgroup" classifier, I can simply remove this attribute  and everything will work fine. 
I have tried changing the values of both the classifier and the parent qdisc but nothing works.

Here is the code : 


#include <stdio.h>
#include <linux/if_ether.h>

#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/cache.h>
#include <netlink/route/link.h>
#include <netlink/route/addr.h>
#include <netlink/route/qdisc.h>
#include <netlink/route/qdisc/htb.h>
#include <netlink/route/class.h>
#include <netlink/route/classifier.h>
#include <netlink/route/cls/cgroup.h>

int main () {
??? struct nl_sock *sock;
??? struct rtnl_link *link; 
??? struct rtnl_qdisc *qdisc;
??? struct rtnl_cls *cls;
?? ?
??? int if_index;
??? int err;
?? ?
??? sock = nl_socket_alloc();
??? nl_connect(sock, NETLINK_ROUTE);
?? ?
??? if( rtnl_link_get_kernel(sock, 0, "eth10", &link) >= 0) {? ?
??????? if_index = rtnl_link_get_ifindex(link);
??? }

??? //creating Qdisc
??? if ((qdisc = rtnl_qdisc_alloc())) {
??????? printf("qdisc allocated \n");
??? }
?? ?
??? rtnl_tc_set_link(TC_CAST(qdisc), link);
??? rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
??? rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(10,0));
??? rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
??? rtnl_htb_set_defcls(qdisc, 0x1);????????? ?
??? rtnl_htb_set_rate2quantum(qdisc, 10);
??? err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE);

??? if (err < 0) {
??????????? fprintf(stderr, "Unable to add qdisc: %s\n", nl_geterror(err));
??? }?? ?
??? rtnl_qdisc_put(qdisc);

??? //creating classifier?? ?
??? uint32_t protocol = ETH_P_IP;??? ?
??? uint32_t prio = 10;
??? if ((cls = rtnl_cls_alloc())) {
??????? printf("cls allocated \n");
??? }
?? ?
??? rtnl_tc_set_link(TC_CAST(cls), link);
??? rtnl_tc_set_kind(TC_CAST(cls), "cgroup");
??? rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(10,0));
??? rtnl_tc_set_handle(TC_CAST(cls), TC_HANDLE(10,1));
??? rtnl_cls_set_prio(cls, prio);
??? rtnl_cls_set_protocol(cls, protocol);
?? ?
??? err = rtnl_cls_add(sock, cls, NLM_F_CREATE);

??? if (err < 0) {
??????????? fprintf(stderr, "Unable to add cls: %s\n", nl_geterror(err));
??????????? return err;
??? }?? ??? 
}

I am not used to mailing list so I hope it is the appropriate place to ask my question.

Thank you in advance for your help.

Gilles Dejaegere.



From joel.cunningham at me.com  Mon May  9 09:48:20 2016
From: joel.cunningham at me.com (Joel Cunningham)
Date: Mon, 09 May 2016 11:48:20 -0500
Subject: nlmsg_len and NLMSG_ALIGN
Message-ID: <F7C03890-CE47-4024-9AF0-06A063C5D9F6@me.com>

Hi,

I'm working on gaining an understanding of the libnl implementation and one thing I've found confusing is the usage of the nlmsg_len member of struct nlmsghdr.  It's my understanding that this member represents the currently reserved/used space in the struct nlmsgmdr, including padding.

Throughout the libnl code, various places use nlmsg_len with NLMSG_ALIGN wrapped around it and other places without.  If nlmsg_len is supposed to already include the padding, why use NLMSG_ALIGN?

Here are a couple of examples of each:

With NLMSG_ALIGN:
nlmsg_next
nlmsg_tail
nla_nest_end
nla_reserve

Without:
nlmsg_reserve (assignment of buf)
nl_send
genlmsg_len

Thanks,

Joel

From jef.oliver at intel.com  Wed May 11 15:01:27 2016
From: jef.oliver at intel.com (Jef Oliver)
Date: Wed, 11 May 2016 15:01:27 -0700
Subject: [PATCH] link: Support RTEXT_FILTER_VF
Message-ID: <1463004087-5757-1-git-send-email-jef.oliver@intel.com>

Extend rtnl_link_build_get_request() and link_request_update()
to provide IFLA_EXT_MASK with RTEXT_FILTER_VF.

Define RTEXT_FILTER_VF

This enables rtnl_link_get_num_vf to properly return the number
of VFs defined for a link.

Signed-off-by: Jef Oliver <jef.oliver at intel.com>
---
 include/linux-private/linux/rtnetlink.h |  3 +++
 lib/route/link.c                        | 26 ++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/include/linux-private/linux/rtnetlink.h b/include/linux-private/linux/rtnetlink.h
index 2363c18..1e0425e 100644
--- a/include/linux-private/linux/rtnetlink.h
+++ b/include/linux-private/linux/rtnetlink.h
@@ -600,6 +600,9 @@ struct tcamsg {
 #define TCA_ACT_TAB 1 /* attr type must be >=1 */	
 #define TCAA_MAX 1
 
+/* Extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF		(1 << 0)
+
 /* End of information exported to user level */
 
 #endif	/* __LINUX_RTNETLINK_H */
diff --git a/lib/route/link.c b/lib/route/link.c
index 0b3238f..6cce85e 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -640,9 +640,29 @@ errout:
 
 static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 {
-	int family = cache->c_iarg1;
+	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);
 
-	return nl_rtgen_request(sk, RTM_GETLINK, family, NLM_F_DUMP);
+nla_put_failure:
+	nlmsg_free(msg);
+	return err;
 }
 
 static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
@@ -1139,6 +1159,8 @@ int rtnl_link_build_get_request(int ifindex, const char *name,
 	if (name)
 		NLA_PUT_STRING(msg, IFLA_IFNAME, name);
 
+        NLA_PUT_U32(msg, IFLA_EXT_MASK, RTEXT_FILTER_VF);
+
 	*result = msg;
 	return 0;
 
-- 
2.8.2



From thaller at redhat.com  Thu May 12 09:02:30 2016
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 12 May 2016 18:02:30 +0200
Subject: [PATCH] link: Support RTEXT_FILTER_VF
In-Reply-To: <1463004087-5757-1-git-send-email-jef.oliver@intel.com>
References: <1463004087-5757-1-git-send-email-jef.oliver@intel.com>
Message-ID: <1463068950.6131.40.camel@redhat.com>

On Wed, 2016-05-11 at 15:01 -0700, Jef Oliver wrote:
> Extend rtnl_link_build_get_request() and link_request_update()
> to provide IFLA_EXT_MASK with RTEXT_FILTER_VF.
> 
> Define RTEXT_FILTER_VF
> 
> This enables rtnl_link_get_num_vf to properly return the number
> of VFs defined for a link.
> 
> Signed-off-by: Jef Oliver <jef.oliver at intel.com>

Hi,


this patch applies on?libnl3_2_27, but not on current master.


It conflicts with?
https://github.com/thom311/libnl/commit/1b2c247571c748a422864f9122bd16cb20e37f83
which adds?ao_get_af().

See also?
https://github.com/thom311/libnl/commit/05631628a57ce88fe1c884680eac6e00fcca810d


Any chance, to rebase your patch onto master?


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

From thaller at redhat.com  Thu May 12 09:51:27 2016
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 12 May 2016 18:51:27 +0200
Subject: nlmsg_len and NLMSG_ALIGN
In-Reply-To: <F7C03890-CE47-4024-9AF0-06A063C5D9F6@me.com>
References: <F7C03890-CE47-4024-9AF0-06A063C5D9F6@me.com>
Message-ID: <1463071887.6131.77.camel@redhat.com>

On Mon, 2016-05-09 at 11:48 -0500, Joel Cunningham wrote:
> Hi,
> 
> I'm working on gaining an understanding of the libnl implementation
> and one thing I've found confusing is the usage of the nlmsg_len
> member of struct nlmsghdr.??It's my understanding that this member
> represents the currently reserved/used space in the struct nlmsgmdr,
> including padding.

I think it represents the currently used space for that nlmsg
(including header).

nlmsg_len is the length of the message that is valid/reserved.
NLMSG_ALIGN(nlmsg_len) is where the next message start (when reading
from the socket).


I don't think this includes "padding".
There is padding ~inside a message between individual attributes~. Yes,
nlmsg_len entails that kind padding, but it doesn't really know
anything about what is inside the message, whether that is padding or
data.
But nlmsg_len does not entail ~padding between the current message and
the next~.



> Throughout the libnl code, various places use nlmsg_len with
> NLMSG_ALIGN wrapped around it and other places without.??If nlmsg_len
> is supposed to already include the padding, why use NLMSG_ALIGN?
> 
> Here are a couple of examples of each:
> 
> With NLMSG_ALIGN:
> nlmsg_next

This jumps over the current message and returns the next one. Messages
must be aligned between each other, thus it uses NLMSG_ALIGN.

> nlmsg_tail
> nla_nest_end
> nla_reserve

Attributes inside a message must also be aligned with NLMSG_ALIGN().


> Without:
> nlmsg_reserve (assignment of buf)

This only reserves "len" bytes (including optional padding).
Afterwards, nlmsg_len points to the end of ALIGN(len,pad).
But nlmsg_len is not necessarily aligned with NLMSG_ALIGN().

Also, it reserves data at the current end. This end, may not be
aligned, thus it reserves it after nlmsg_len, and not
NLMSG_ALIGN(nlmsg_len).


> nl_send

nl_send sends the part of the message that is reserved and initialized.
The length of one message may not be aligned.



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

From thaller at redhat.com  Thu May 12 10:07:41 2016
From: thaller at redhat.com (Thomas Haller)
Date: Thu, 12 May 2016 19:07:41 +0200
Subject: cgroup classifier problem
In-Reply-To: <DB4PR06MB491F172D10D37C468D148E4BC7C0@DB4PR06MB491.eurprd06.prod.outlook.com>
References: <DB4PR06MB491F172D10D37C468D148E4BC7C0@DB4PR06MB491.eurprd06.prod.outlook.com>
Message-ID: <1463072861.6131.81.camel@redhat.com>

On Thu, 2016-05-05 at 08:03 +0000, Gilles Dejaegere wrote:
> Dear All,
> 
> I have some trouble making a "cgroup classifier". When trying to
> add??them, I always get an "Unable to add cls: Invalid input data
> or??parameter" answer. I am trying to do the same as these two
> commands :??"tc qdisc add dev eth10 root handle 10: htb default 1"
> and "tc filter add dev eth10 parent 10: protocol ip prio 10 handle
> 1??cgroup". I did not succeed to make my code work. I suspect that
> the??problem comes from the handle attribute for two reasons. First
> of all,??it is the only attribute that when removed changes the error
> in "Missing attribute". And secondly, when I try to make a??"u32"
> instead of "cgroup" classifier, I can simply remove this
> attribute??and everything will work fine.?
> I have tried changing the values of both the classifier and the
> parent qdisc but nothing works.


Hi,

I don't know the answer to this (I never tried it).

But as you know how to do it with iproute2 (tc), I would look at
iproute2.

tc basically creates a netlink message, fills it according to the
command line options, and sends it. I would look which properties are
set, and set the same via libnl3.

sorry for not being of more help.


good luck,
Thomas


> 
> Here is the code :?
> 
> 
> #include <stdio.h>
> #include <linux/if_ether.h>
> 
> #include <netlink/netlink.h>
> #include <netlink/socket.h>
> #include <netlink/cache.h>
> #include <netlink/route/link.h>
> #include <netlink/route/addr.h>
> #include <netlink/route/qdisc.h>
> #include <netlink/route/qdisc/htb.h>
> #include <netlink/route/class.h>
> #include <netlink/route/classifier.h>
> #include <netlink/route/cls/cgroup.h>
> 
> int main () {
> ??? struct nl_sock *sock;
> ??? struct rtnl_link *link;?
> ??? struct rtnl_qdisc *qdisc;
> ??? struct rtnl_cls *cls;
> ?? ?
> ??? int if_index;
> ??? int err;
> ?? ?
> ??? sock = nl_socket_alloc();
> ??? nl_connect(sock, NETLINK_ROUTE);
> ?? ?
> ??? if( rtnl_link_get_kernel(sock, 0, "eth10", &link) >= 0) {? ?
> ??????? if_index = rtnl_link_get_ifindex(link);
> ??? }
> 
> ??? //creating Qdisc
> ??? if ((qdisc = rtnl_qdisc_alloc())) {
> ??????? printf("qdisc allocated \n");
> ??? }
> ?? ?
> ??? rtnl_tc_set_link(TC_CAST(qdisc), link);
> ??? rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
> ??? rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(10,0));
> ??? rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
> ??? rtnl_htb_set_defcls(qdisc, 0x1);????????? ?
> ??? rtnl_htb_set_rate2quantum(qdisc, 10);
> ??? err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE);
> 
> ??? if (err < 0) {
> ??????????? fprintf(stderr, "Unable to add qdisc: %s\n",
> nl_geterror(err));
> ??? }?? ?
> ??? rtnl_qdisc_put(qdisc);
> 
> ??? //creating classifier?? ?
> ??? uint32_t protocol = ETH_P_IP;??? ?
> ??? uint32_t prio = 10;
> ??? if ((cls = rtnl_cls_alloc())) {
> ??????? printf("cls allocated \n");
> ??? }
> ?? ?
> ??? rtnl_tc_set_link(TC_CAST(cls), link);
> ??? rtnl_tc_set_kind(TC_CAST(cls), "cgroup");
> ??? rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(10,0));
> ??? rtnl_tc_set_handle(TC_CAST(cls), TC_HANDLE(10,1));
> ??? rtnl_cls_set_prio(cls, prio);
> ??? rtnl_cls_set_protocol(cls, protocol);
> ?? ?
> ??? err = rtnl_cls_add(sock, cls, NLM_F_CREATE);
> 
> ??? if (err < 0) {
> ??????????? fprintf(stderr, "Unable to add cls: %s\n",
> nl_geterror(err));
> ??????????? return err;
> ??? }?? ????
> }
> 
> I am not used to mailing list so I hope it is the appropriate place
> to ask my question.
> 
> Thank you in advance for your help.
> 
> Gilles Dejaegere.
> 
> 
> _______________________________________________
> libnl mailing list
> libnl at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libnl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160512/37ebb97e/attachment.sig>

From jef.oliver at intel.com  Thu May 12 10:11:19 2016
From: jef.oliver at intel.com (Oliver, Jef)
Date: Thu, 12 May 2016 17:11:19 +0000
Subject: [PATCH] link: Support RTEXT_FILTER_VF
In-Reply-To: <1463068950.6131.40.camel@redhat.com>
References: <1463004087-5757-1-git-send-email-jef.oliver@intel.com>
 <1463068950.6131.40.camel@redhat.com>
Message-ID: <987D2CB872357542B41F1C2F08E20B015ECB8D00@ORSMSX111.amr.corp.intel.com>

Most certainly. I'll rebase.

-----Original Message-----
From: Thomas Haller [mailto:thaller at redhat.com] 
Sent: Thursday, May 12, 2016 9:03 AM
To: Oliver, Jef <jef.oliver at intel.com>; libnl at lists.infradead.org
Subject: Re: [PATCH] link: Support RTEXT_FILTER_VF

On Wed, 2016-05-11 at 15:01 -0700, Jef Oliver wrote:
> Extend rtnl_link_build_get_request() and link_request_update() to 
> provide IFLA_EXT_MASK with RTEXT_FILTER_VF.
> 
> Define RTEXT_FILTER_VF
> 
> This enables rtnl_link_get_num_vf to properly return the number of VFs 
> defined for a link.
> 
> Signed-off-by: Jef Oliver <jef.oliver at intel.com>

Hi,


this patch applies on?libnl3_2_27, but not on current master.


It conflicts with
https://github.com/thom311/libnl/commit/1b2c247571c748a422864f9122bd16cb20e37f83
which adds?ao_get_af().

See also
https://github.com/thom311/libnl/commit/05631628a57ce88fe1c884680eac6e00fcca810d


Any chance, to rebase your patch onto master?


Thanks,
Thomas

From jef.oliver at intel.com  Thu May 12 11:29:57 2016
From: jef.oliver at intel.com (Oliver, Jef)
Date: Thu, 12 May 2016 18:29:57 +0000
Subject: [PATCH] link: Support RTEXT_FILTER_VF
In-Reply-To: <1463068950.6131.40.camel@redhat.com>
References: <1463004087-5757-1-git-send-email-jef.oliver@intel.com>
 <1463068950.6131.40.camel@redhat.com>
Message-ID: <987D2CB872357542B41F1C2F08E20B015ECB8D6A@ORSMSX111.amr.corp.intel.com>

> > Extend rtnl_link_build_get_request() and link_request_update() to 
> > provide IFLA_EXT_MASK with RTEXT_FILTER_VF.
> > 
> > Define RTEXT_FILTER_VF
> > 
> > This enables rtnl_link_get_num_vf to properly return the number of VFs 
> > defined for a link.
> > 
> > Signed-off-by: Jef Oliver <jef.oliver at intel.com>
>
> Hi,
>
>
> this patch applies on?libnl3_2_27, but not on current master.
>
>
> It conflicts with
> https://github.com/thom311/libnl/commit/1b2c247571c748a422864f9122bd16cb20e37f83
> which adds?ao_get_af().
>
> See also
> https://github.com/thom311/libnl/commit/05631628a57ce88fe1c884680eac6e00fcca810d
>
>
> Any chance, to rebase your patch onto master?
>
>
> Thanks,
> Thomas
>

SRIOV VFs are an extension to the link they are on. They do not register as a separate device unless a VF driver is loaded. Even in that case, the VF exposed by the VF driver appears to be a standard link. Looking at ao_get_af(), it is looking for a rtnl_link_af_ops struct registered for a family. Would I be correct in thinking I need to create this struct for the default link and register it at link_init() ? (This would attach to AF_UNSPEC since SRIOV does not have its own address family?)

This could be expanded to a module (similar to bridge) later when VF info parsing is completed. As of now, the proper count of VFs needs to be returned.

Thanks,
Jef

From kadur.kiran at sawridgesystems.com  Sun May 15 22:54:01 2016
From: kadur.kiran at sawridgesystems.com (kadur.kiran at sawridgesystems.com)
Date: Sun, 15 May 2016 22:54:01 -0700
Subject: API's for iptable commands
Message-ID: <20160515225401.a13f6ae702cc964b23d22fb10a8bfc57.3efc4e513c.wbe@email19.asia.godaddy.com>

Hi All,

iptables -t mangle -I FORWARD 1 -o em1 -d 10.180.190.221 -p tcp --sport
22 -j MARK --set-mark 102

I want to reproduce above iptables command programatically using API's.
But unable to find suitable documentation.
please suggest is there any approach to achieve the same.



Thanks,


From thaller at redhat.com  Mon May 16 05:10:06 2016
From: thaller at redhat.com (Thomas Haller)
Date: Mon, 16 May 2016 14:10:06 +0200
Subject: API's for iptable commands
In-Reply-To: <20160515225401.a13f6ae702cc964b23d22fb10a8bfc57.3efc4e513c.wbe@email19.asia.godaddy.com>
References: <20160515225401.a13f6ae702cc964b23d22fb10a8bfc57.3efc4e513c.wbe@email19.asia.godaddy.com>
Message-ID: <1463400606.20516.6.camel@redhat.com>

On Sun, 2016-05-15 at 22:54 -0700, kadur.kiran at sawridgesystems.com
wrote:
> Hi All,
> 
> iptables -t mangle -I FORWARD 1 -o em1 -d 10.180.190.221 -p tcp --
> sport
> 22 -j MARK --set-mark 102
> 
> I want to reproduce above iptables command programatically using
> API's.
> But unable to find suitable documentation.
> please suggest is there any approach to achieve the same.
> 

Hi,

not netlink/libnl3.
https://stackoverflow.com/questions/109553/how-can-i-programmatically-manage-iptables-rules-on-the-fly

seems the ~best~ way is to run iptables binary.

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

From jef.oliver at intel.com  Mon May 16 16:23:23 2016
From: jef.oliver at intel.com (Jef Oliver)
Date: Mon, 16 May 2016 16:23:23 -0700
Subject: [PATCH] Support RTEXT_FILTER_VF
Message-ID: <1463441003-9720-1-git-send-email-jef.oliver@intel.com>

This patch adds RTEXT_FILTER_VF mask support for SRIOV VFs. Since
SRIOV VFs don't have a defined address family (ie bridge), there
are no new address family specific operations defined.

Exposing this mask makes rtnl_link_get_num_vfs() properly return
the number of loaded SRIOV VFs.

Signed-off-by: Jef Oliver <jef.oliver at intel.com>
---
 lib/route/link.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/lib/route/link.c b/lib/route/link.c
index 1fa2672..0ac7b78 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -677,6 +677,7 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 	struct rtnl_link_af_ops *ops;
 	struct nl_msg *msg;
 	int err;
+	__u32 vf_mask = RTEXT_FILTER_VF;
 
 	msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP);
 	if (!msg)
@@ -686,12 +687,17 @@ static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 	if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
 		goto nla_put_failure;
 
+	err = nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask);
+	if (err)
+		goto nla_put_failure;
+
 	ops = rtnl_link_af_ops_lookup(family);
 	if (ops && ops->ao_get_af) {
 		err = ops->ao_get_af(msg);
 		if (err)
 			goto nla_put_failure;
 	}
+
 	err = nl_send_auto(sk, msg);
 	if (err > 0)
 		err = 0;
@@ -1218,6 +1224,8 @@ int rtnl_link_build_get_request(int ifindex, const char *name,
 {
 	struct ifinfomsg ifi;
 	struct nl_msg *msg;
+	__u32 vf_mask = RTEXT_FILTER_VF;
+	int err;
 
 	if (ifindex <= 0 && !name) {
 		APPBUG("ifindex or name must be specified");
@@ -1232,18 +1240,24 @@ int rtnl_link_build_get_request(int ifindex, const char *name,
 	if (ifindex > 0)
 		ifi.ifi_index = ifindex;
 
-	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
+	if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) {
+		err = -NLE_MSGSIZE;
 		goto nla_put_failure;
+	}
 
 	if (name)
 		NLA_PUT_STRING(msg, IFLA_IFNAME, name);
 
+	err = nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask);
+	if (err)
+		goto nla_put_failure;
+
 	*result = msg;
 	return 0;
 
 nla_put_failure:
 	nlmsg_free(msg);
-	return -NLE_MSGSIZE;
+	return err;
 }
 
 /**
-- 
2.8.2



From jonasj76 at gmail.com  Mon May 16 23:28:04 2016
From: jonasj76 at gmail.com (Jonas Johansson)
Date: Tue, 17 May 2016 08:28:04 +0200
Subject: [PATCH] neigh: add function to look up neighbour (fdb) by ifindex,
 mac and vlan
Message-ID: <1463466484-19641-1-git-send-email-jonas.johansson@westermo.se>

The rtnl_neigh_get() function can not be used to look up a fdb entry in the
neigh cache. This is due to that the function searches among destination
addresses (NDA_DST) and not among link layer addresses (NDA_LLADDR), which is
used by fdb entries. A fdb entry can also exist in several vlans, so a vlan id
parameter is also needed to find a unique entry.
This commit adds a function, rtnl_neigh_get_by_vlan() which searches the neigh
cache for a specific neighbour (fdb) entry by interface index, link layer
address and vlan id.

Signed-off-by: Jonas Johansson <jonas.johansson at westermo.se>
---
 include/netlink/route/neighbour.h |  2 ++
 lib/route/neigh.c                 | 26 ++++++++++++++++++++++++++
 libnl-route-3.sym                 |  1 +
 3 files changed, 29 insertions(+)

diff --git a/include/netlink/route/neighbour.h b/include/netlink/route/neighbour.h
index fb98113..6ea4753 100644
--- a/include/netlink/route/neighbour.h
+++ b/include/netlink/route/neighbour.h
@@ -31,6 +31,8 @@ extern int	rtnl_neigh_alloc_cache_flags(struct nl_sock *,
 					     unsigned int);
 extern struct rtnl_neigh *rtnl_neigh_get(struct nl_cache *, int,
 					       struct nl_addr *);
+extern struct rtnl_neigh *rtnl_neigh_get_by_vlan(struct nl_cache *, int,
+						 struct nl_addr *, int);
 
 extern int      rtnl_neigh_parse(struct nlmsghdr *, struct rtnl_neigh **);
 
diff --git a/lib/route/neigh.c b/lib/route/neigh.c
index 260e8b4..c8979ab 100644
--- a/lib/route/neigh.c
+++ b/lib/route/neigh.c
@@ -607,6 +607,32 @@ struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
 	return NULL;
 }
 
+/**
+ * Look up a neighbour by interface index, link layer address and vlan id
+ * @arg cache		neighbour cache
+ * @arg ifindex 	interface index the neighbour is on
+ * @arg lladdr		link layer address of the neighbour
+ * @arg vlan		vlan id of the neighbour
+ *
+ * @return neighbour handle or NULL if no match was found.
+ */
+struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex,
+					   struct nl_addr *lladdr, int vlan)
+{
+	struct rtnl_neigh *neigh;
+
+	nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
+		if (neigh->n_ifindex == ifindex &&
+		    neigh->n_vlan == vlan &&
+		    neigh->n_lladdr && !nl_addr_cmp(neigh->n_lladdr, lladdr)) {
+			nl_object_get((struct nl_object *) neigh);
+			return neigh;
+		}
+	}
+
+	return NULL;
+}
+
 /** @} */
 
 /**
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 2c72498..ee1677b 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -917,5 +917,6 @@ global:
 	rtnl_link_vrf_get_tableid;
 	rtnl_link_vrf_set_tableid;
 	rtnl_neigh_alloc_cache_flags;
+	rtnl_neigh_ll_get;
 } libnl_3_2_27;
 
-- 
2.5.0



From ville.vaittinen at ge.com  Tue May 24 04:30:51 2016
From: ville.vaittinen at ge.com (Vaittinen, Ville (GE Healthcare))
Date: Tue, 24 May 2016 11:30:51 +0000
Subject: wlan signal via libnl
Message-ID: <6474A6BE7A7AEB46A4DDDCA063EA8CAA2445D7@ALPURAPA22.e2k.ad.ge.com>

Hi,

we are trying to use libnl for querying wlan signal strength
and have got it basically working. 

Our basic calling pattern is
    nl_send_auto_complete(m_socket, msg);

    nl_cb* callback = nl_socket_get_cb(m_socket);

    int ret = nl_recvmsgs(m_socket, callback);

And in the callback function we parse the message / signal strength.

Due to the lacking knowledge of lower level implementation details we are wondering,
if it actually can happen that due to some internals nl_recvmsgs() might actually block
and never return? And if so, what would be the counter-measure (configuring a timeout possible?, non-blocking socket).

Furthermore is it sufficient in this case to call nl_recvmsgs() once or should it be called
in while loop along the lines iw tool does it that sets additional callbacks of types NL_CB_FINISH, NL_CB_ACK and
checks the output in them to stop the while loop.

Ville Vaittinen

From thaller at redhat.com  Tue May 24 07:14:28 2016
From: thaller at redhat.com (Thomas Haller)
Date: Tue, 24 May 2016 16:14:28 +0200
Subject: wlan signal via libnl
In-Reply-To: <6474A6BE7A7AEB46A4DDDCA063EA8CAA2445D7@ALPURAPA22.e2k.ad.ge.com>
References: <6474A6BE7A7AEB46A4DDDCA063EA8CAA2445D7@ALPURAPA22.e2k.ad.ge.com>
Message-ID: <1464099268.3737.16.camel@redhat.com>

On Tue, 2016-05-24 at 11:30 +0000, Vaittinen, Ville (GE Healthcare)
wrote:
> Hi,

Hi,




> we are trying to use libnl for querying wlan signal strength
> and have got it basically working.?
> 
> Our basic calling pattern is
> ????nl_send_auto_complete(m_socket, msg);
> 
> ????nl_cb* callback = nl_socket_get_cb(m_socket);
> 
> ????int ret = nl_recvmsgs(m_socket, callback);
> 
> And in the callback function we parse the message / signal strength.
> 
> Due to the lacking knowledge of lower level implementation details we
> are wondering,
> if it actually can happen that due to some internals nl_recvmsgs()
> might actually block
> and never return? And if so, what would be the counter-measure
> (configuring a timeout possible?, non-blocking socket).

If the file descriptor is set to blocking, it blocks until there is
something to read. That is fine, if you don't have any other event you
are waiting for (e.g. timeout, UI interaction, etc).
Note, that a blocking read might always be interrupted by a signal, so
usually you would do something like:

again:
? ? ?i = nl_recvmsgs(fd);
? ? ?if (i == -NLE_EAGAIN)
? ? ? ? ?goto again;


Otherwise:

(1) either, make the socket non-blocking and react on NLE_EAGAIN,
? ? which in this case means, there is nothing to read currently
? ? (nl_socket_set_nonblocking()).

(2) or, select/poll on the filedescribtor so that you know something
? ? is available to read.


Actually, (1) and (2) is not either-or, because even if you make the
socket non-blocking, it is not clear when there is something available
to read. So, usually also when using non-blocking IO, you still must
select/poll to know when something is read.



> Furthermore is it sufficient in this case to call nl_recvmsgs() once
> or should it be called
> in while loop along the lines iw tool does it that sets additional
> callbacks of types NL_CB_FINISH, NL_CB_ACK and
> checks the output in them to stop the while loop.

nl_recvmsgs() documentation says:

Stops reading if one of the callbacks returns NL_STOP or nl_recv
returns either 0 or a negative error code.

So, it will return a bunch of messages, but stop on the first error (or
NL_STOP).



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

From thaller at redhat.com  Sun May 29 05:38:09 2016
From: thaller at redhat.com (Thomas Haller)
Date: Sun, 29 May 2016 14:38:09 +0200
Subject: [Fwd: [PATCH 0/6] route cache: support for non-exclusive and append
 routes]
References: <1446501929-32003-3-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-6-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-1-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-2-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-5-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-7-git-send-email-roopa@cumulusnetworks.com>
 <1446501929-32003-4-git-send-email-roopa@cumulusnetworks.com>
Message-ID: <1464525489.5788.14.camel@redhat.com>

Hi,


already in November 2016, Roopa Prabhu kindly sent the attached
patchset to the mailing list.

For some inexplicable?reason, they never reached the mailing list.
With her permission, I'm forwarding the patches to the list.


It's about how the libnl cache handles routes.


This is also related to the email thread
http://lists.infradead.org/pipermail/libnl/2013-March/000965.html


and recently, I opened two kernel bugs against RHEL, which are related
as well:
??https://bugzilla.redhat.com/show_bug.cgi?id=1337860
??https://bugzilla.redhat.com/show_bug.cgi?id=1337855



Thomas
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 2/6] hashtable: convert hashtable bucket list to a circular doubly linked list
Date: Mon,  2 Nov 2015 14:05:25 -0800
Size: 8810
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0007.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 5/6] cache: add new NL_OBJ_DUMP cache flag (ce_flags)
Date: Mon,  2 Nov 2015 14:05:28 -0800
Size: 5789
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0008.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 0/6] route cache: support for non-exclusive and append routes
Date: Mon,  2 Nov 2015 14:05:23 -0800
Size: 7517
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0009.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 1/6] nl_object: add new ce_msgflags field to nl_object
Date: Mon,  2 Nov 2015 14:05:24 -0800
Size: 4643
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0010.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 4/6] obj_ops: add new oo_hash_attrs_get to get hash key attributes of any object
Date: Mon,  2 Nov 2015 14:05:27 -0800
Size: 4246
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0011.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 6/6] route: cache and object changes to support non-exclusive and append routes
Date: Mon,  2 Nov 2015 14:05:29 -0800
Size: 10184
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0012.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Roopa Prabhu <roopa at cumulusnetworks.com>
Subject: [PATCH 3/6] cache: modify nl_cache_search to look at cache provided attributes for search
Date: Mon,  2 Nov 2015 14:05:26 -0800
Size: 11179
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0013.mht>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/libnl/attachments/20160529/fdb6af46/attachment-0001.sig>

From thaller at redhat.com  Sun May 29 06:23:35 2016
From: thaller at redhat.com (Thomas Haller)
Date: Sun, 29 May 2016 15:23:35 +0200
Subject: [PATCH] neigh: add function to look up neighbour (fdb) by
 ifindex, mac and vlan
In-Reply-To: <1463466484-19641-1-git-send-email-jonas.johansson@westermo.se>
References: <1463466484-19641-1-git-send-email-jonas.johansson@westermo.se>
Message-ID: <1464528215.5788.21.camel@redhat.com>

On Tue, 2016-05-17 at 08:28 +0200, Jonas Johansson wrote:
> The rtnl_neigh_get() function can not be used to look up a fdb entry
> in the
> neigh cache. This is due to that the function searches among
> destination
> addresses (NDA_DST) and not among link layer addresses (NDA_LLADDR),
> which is
> used by fdb entries. A fdb entry can also exist in several vlans, so
> a vlan id
> parameter is also needed to find a unique entry.
> This commit adds a function, rtnl_neigh_get_by_vlan() which searches
> the neigh
> cache for a specific neighbour (fdb) entry by interface index, link
> layer
> address and vlan id.
> 
> Signed-off-by: Jonas Johansson <jonas.johansson at westermo.se>
> 

Hi Jonas,

sorry for the late response.

Patch merged to master:
https://github.com/thom311/libnl/commit/3bf503d30c271822158414f63eed620afc9b10cd


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

From thaller at redhat.com  Sun May 29 07:33:30 2016
From: thaller at redhat.com (Thomas Haller)
Date: Sun, 29 May 2016 16:33:30 +0200
Subject: [PATCH] Support RTEXT_FILTER_VF
In-Reply-To: <1463441003-9720-1-git-send-email-jef.oliver@intel.com>
References: <1463441003-9720-1-git-send-email-jef.oliver@intel.com>
Message-ID: <1464532410.5788.33.camel@redhat.com>

On Mon, 2016-05-16 at 16:23 -0700, Jef Oliver wrote:
> This patch adds RTEXT_FILTER_VF mask support for SRIOV VFs. Since
> SRIOV VFs don't have a defined address family (ie bridge), there
> are no new address family specific operations defined.
> 
> Exposing this mask makes rtnl_link_get_num_vfs() properly return
> the number of loaded SRIOV VFs.
> 
> Signed-off-by: Jef Oliver <jef.oliver at intel.com>
> ---


Hi Jef,


your patch looks right to me (except a minor fixup, see link below).

currently libnl doesn't seem to handle information about SRIOV except
get_num_vf(). Is the *only* purpose of this patch to fix
rtnl_link_get_num_vf(), or do you have a more complex use-case?

For bridge types,?link_request_update() would set
both?IFLA_EXT_MASK=RTEXT_FILTER_VF and later it is overwriten with
IFLA_EXT_MASK=RTEXT_FILTER_BRVLAN.
That seems wrong. How about the follow-up patch:
https://github.com/thom311/libnl/commits/ext_filter_mask



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

From jef.oliver at intel.com  Sun May 29 21:16:04 2016
From: jef.oliver at intel.com (Oliver, Jef)
Date: Mon, 30 May 2016 04:16:04 +0000
Subject: [PATCH] Support RTEXT_FILTER_VF
In-Reply-To: <1464532410.5788.33.camel@redhat.com>
References: <1463441003-9720-1-git-send-email-jef.oliver@intel.com>
 <1464532410.5788.33.camel@redhat.com>
Message-ID: <987D2CB872357542B41F1C2F08E20B015ECC5AF2@ORSMSX111.amr.corp.intel.com>

> -----Original Message-----
> From: Thomas Haller [mailto:thaller at redhat.com]
> Sent: Sunday, May 29, 2016 7:34 AM
> To: Oliver, Jef <jef.oliver at intel.com>; libnl at lists.infradead.org
> Subject: Re: [PATCH] Support RTEXT_FILTER_VF
> 
> On Mon, 2016-05-16 at 16:23 -0700, Jef Oliver wrote:
> > This patch adds RTEXT_FILTER_VF mask support for SRIOV VFs. Since
> > SRIOV VFs don't have a defined address family (ie bridge), there are
> > no new address family specific operations defined.
> >
> > Exposing this mask makes rtnl_link_get_num_vfs() properly return the
> > number of loaded SRIOV VFs.
> >
> > Signed-off-by: Jef Oliver <jef.oliver at intel.com>
> > ---
> 
> 
> Hi Jef,
> 
> 
> your patch looks right to me (except a minor fixup, see link below).
> 
> currently libnl doesn't seem to handle information about SRIOV except
> get_num_vf(). Is the *only* purpose of this patch to fix
> rtnl_link_get_num_vf(), or do you have a more complex use-case?
> 
> For bridge types,?link_request_update() would set
> both?IFLA_EXT_MASK=RTEXT_FILTER_VF and later it is overwriten with
> IFLA_EXT_MASK=RTEXT_FILTER_BRVLAN.
> That seems wrong. How about the follow-up patch:
> https://github.com/thom311/libnl/commits/ext_filter_mask
> 
> 
> 
> Thomas

Thomas,

The fixup looks good. I neglected thinking of link_updates only needing the requested update. This patches purpose is to fix the get_num_vf for AF_UNSPEC requests. Bridge links, tunnel links, etc..., will not have this information present. So it is ok if bridge types overwrite IFLA_EXT_MASK. With this patch being present, I am planning on expanding out SRIOV support in libnl. I hope to add functions to expose the LLADDR, VLAN, QoS, etc.. of a VF. (Baring objection.)

Jef


From przemekszczerbik at gmail.com  Mon May 30 14:26:00 2016
From: przemekszczerbik at gmail.com (Przemyslaw Szczerbik)
Date: Mon, 30 May 2016 23:26:00 +0200
Subject: [PATCH] lib: Return error on Netlink attribute length overflow
Message-ID: <1464643560-31038-1-git-send-email-przemek.szczerbik@gmail.com>

Netlink attribute length is defined as u16. It's possible to exceed nla_len when
creating nested attributes. Storing incorrect length due to overflow will cause
a reader to read only a part of nested attribute or skip it entirely.

As a solution cancel the addition of a nested attribute when nla_len size is
exceeded.

Signed-off-by: Przemyslaw Szczerbik <przemek.szczerbik at gmail.com>
---
 include/netlink/errno.h | 3 ++-
 lib/attr.c              | 9 +++++----
 lib/error.c             | 1 +
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/netlink/errno.h b/include/netlink/errno.h
index f8b5130..35710cf 100644
--- a/include/netlink/errno.h
+++ b/include/netlink/errno.h
@@ -50,8 +50,9 @@ extern "C" {
 #define NLE_NODEV		31
 #define NLE_IMMUTABLE		32
 #define NLE_DUMP_INTR		33
+#define NLE_ATTRSIZE		34
 
-#define NLE_MAX			NLE_DUMP_INTR
+#define NLE_MAX		NLE_ATTRSIZE
 
 extern const char *	nl_geterror(int);
 extern void		nl_perror(int, const char *);
diff --git a/lib/attr.c b/lib/attr.c
index 9d8bb26..a3d1b16 100644
--- a/lib/attr.c
+++ b/lib/attr.c
@@ -912,7 +912,7 @@ struct nlattr *nla_nest_start(struct nl_msg *msg, int attrtype)
  *
  * Corrects the container attribute header to include the appeneded attributes.
  *
- * @return 0
+ * @return 0 on success or a negative error code.
  */
 int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
 {
@@ -920,14 +920,15 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
 
 	len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) start;
 
-	if (len == NLA_HDRLEN) {
+	if (len == NLA_HDRLEN || len > USHRT_MAX) {
 		/*
-		 * Kernel can't handle empty nested attributes, trim the
+		 * Max nlattr size exceeded or empty nested attribute, trim the
 		 * attribute header again
 		 */
 		nla_nest_cancel(msg, start);
 
-		return 0;
+		/* Return error only if nlattr size was exceeded */
+		return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE;
 	}
 
 	start->nla_len = len;
diff --git a/lib/error.c b/lib/error.c
index f30b9a5..7fbd389 100644
--- a/lib/error.c
+++ b/lib/error.c
@@ -47,6 +47,7 @@ static const char *errmsg[NLE_MAX+1] = {
 [NLE_NODEV]		= "No such device",
 [NLE_IMMUTABLE]		= "Immutable attribute",
 [NLE_DUMP_INTR]		= "Dump inconsistency detected, interrupted",
+[NLE_ATTRSIZE]		= "Attribute max length exceeded",
 };
 
 /**
-- 
2.7.4



From thomas.egerer at secunet.com  Tue May 31 08:29:58 2016
From: thomas.egerer at secunet.com (Thomas Egerer)
Date: Tue, 31 May 2016 17:29:58 +0200
Subject: [PATCH 1/2] xfrm: fix buffer overflow when copying keys
Message-ID: <574DADF6.5040509@secunet.com>

A colleague of mine came to notice that -- when adding keys to the
xfrm-part of libnl -- memcpy is given newlen, which copies sizeof(struct
xfrmnl_...) plus keysize instead of only the keysize.
This patch uses a keysize parameter to only copy the required number of
bytes.

Signed-off-by: Thomas Egerer <thomas.egerer at secunet.com>
---
 lib/xfrm/sa.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 31c22ba..69bcfd6 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -1629,7 +1629,8 @@ int xfrmnl_sa_get_aead_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 
 int xfrmnl_sa_set_aead_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int key_len, unsigned int icv_len, char* key)
 {
-	uint32_t    newlen = sizeof (struct xfrmnl_algo_aead) + (sizeof (uint8_t) * ((key_len + 7)/8));
+	size_t      keysize = sizeof (uint8_t) * ((key_len + 7)/8);
+	uint32_t    newlen = sizeof (struct xfrmnl_algo_aead) + keysize;
 
 	/* Free up the old key and allocate memory to hold new key */
 	if (sa->aead)
@@ -1641,7 +1642,7 @@ int xfrmnl_sa_set_aead_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	strcpy (sa->aead->alg_name, alg_name);
 	sa->aead->alg_key_len   = key_len;
 	sa->aead->alg_icv_len   = icv_len;
-	memcpy ((void *)sa->aead->alg_key, (void *)key, newlen);
+	memcpy ((void *)sa->aead->alg_key, (void *)key, keysize);
 
 	sa->ce_mask |= XFRM_SA_ATTR_ALG_AEAD;
 
@@ -1665,7 +1666,8 @@ int xfrmnl_sa_get_auth_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 
 int xfrmnl_sa_set_auth_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int key_len, unsigned int trunc_len, char* key)
 {
-	uint32_t    newlen = sizeof (struct xfrmnl_algo_auth) + (sizeof (uint8_t) * ((key_len + 7)/8));
+	size_t      keysize = sizeof (uint8_t) * ((key_len + 7)/8);
+	uint32_t    newlen = sizeof (struct xfrmnl_algo_auth) + keysize;
 
 	/* Free up the old auth data and allocate new one */
 	if (sa->auth)
@@ -1677,7 +1679,7 @@ int xfrmnl_sa_set_auth_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	strcpy (sa->auth->alg_name, alg_name);
 	sa->auth->alg_key_len   = key_len;
 	sa->auth->alg_trunc_len = trunc_len;
-	memcpy ((void *)sa->auth->alg_key, (void *)key, newlen);
+	memcpy ((void *)sa->auth->alg_key, (void *)key, keysize);
 
 	sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH;
 
@@ -1700,7 +1702,8 @@ int xfrmnl_sa_get_crypto_params (struct xfrmnl_sa* sa, char* alg_name, unsigned
 
 int xfrmnl_sa_set_crypto_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int key_len, char* key)
 {
-	uint32_t    newlen = sizeof (struct xfrmnl_algo) + (sizeof (uint8_t) * ((key_len + 7)/8));
+	size_t      keysize = sizeof (uint8_t) * ((key_len + 7)/8);
+	uint32_t    newlen = sizeof (struct xfrmnl_algo) + keysize;
 
 	/* Free up the old crypto and allocate new one */
 	if (sa->crypt)
@@ -1711,7 +1714,7 @@ int xfrmnl_sa_set_crypto_params (struct xfrmnl_sa* sa, char* alg_name, unsigned
 	/* Save the new info */
 	strcpy (sa->crypt->alg_name, alg_name);
 	sa->crypt->alg_key_len  = key_len;
-	memcpy ((void *)sa->crypt->alg_key, (void *)key, newlen);
+	memcpy ((void *)sa->crypt->alg_key, (void *)key, keysize);
 
 	sa->ce_mask |= XFRM_SA_ATTR_ALG_CRYPT;
 
@@ -1734,7 +1737,8 @@ int xfrmnl_sa_get_comp_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 
 int xfrmnl_sa_set_comp_params (struct xfrmnl_sa* sa, char* alg_name, unsigned int key_len, char* key)
 {
-	uint32_t    newlen = sizeof (struct xfrmnl_algo) + (sizeof (uint8_t) * ((key_len + 7)/8));
+	size_t      keysize = sizeof (uint8_t) * ((key_len + 7)/8);
+	uint32_t    newlen = sizeof (struct xfrmnl_algo) + keysize;
 
 	/* Free up the old compression algo params and allocate new one */
 	if (sa->comp)
@@ -1745,7 +1749,7 @@ int xfrmnl_sa_set_comp_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	/* Save the new info */
 	strcpy (sa->comp->alg_name, alg_name);
 	sa->comp->alg_key_len  = key_len;
-	memcpy ((void *)sa->comp->alg_key, (void *)key, newlen);
+	memcpy ((void *)sa->comp->alg_key, (void *)key, keysize);
 
 	sa->ce_mask |= XFRM_SA_ATTR_ALG_COMP;
 
-- 
2.6.4




From thomas.egerer at secunet.com  Tue May 31 08:30:03 2016
From: thomas.egerer at secunet.com (Thomas Egerer)
Date: Tue, 31 May 2016 17:30:03 +0200
Subject: [PATCH 2/2] xfrm: check length of alg_name before strcpying it
Message-ID: <574DADFB.5060404@secunet.com>

If the parameter alg_name points to a string longer then what libnl
accepts as alg_name, the call to strcpy may write far beyond the
particular data structure.
Instead of truncating the string (using strncpy) this patch adds a check
and returns -1 for strings being longer than 63 bytes.

Signed-off-by: Thomas Egerer <thomas.egerer at secunet.com>
---
 lib/xfrm/sa.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 69bcfd6..1cd6edd 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -1635,7 +1635,7 @@ int xfrmnl_sa_set_aead_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	/* Free up the old key and allocate memory to hold new key */
 	if (sa->aead)
 		free (sa->aead);
-	if ((sa->aead = calloc (1, newlen)) == NULL)
+	if (strlen (alg_name) >= sizeof (sa->aead->alg_name) || (sa->aead = calloc (1, newlen)) == NULL)
 		return -1;
 
 	/* Save the new info */
@@ -1672,7 +1672,7 @@ int xfrmnl_sa_set_auth_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	/* Free up the old auth data and allocate new one */
 	if (sa->auth)
 		free (sa->auth);
-	if ((sa->auth = calloc (1, newlen)) == NULL)
+	if (strlen (alg_name) >= sizeof (sa->auth->alg_name) || (sa->auth = calloc (1, newlen)) == NULL)
 		return -1;
 
 	/* Save the new info */
@@ -1708,7 +1708,7 @@ int xfrmnl_sa_set_crypto_params (struct xfrmnl_sa* sa, char* alg_name, unsigned
 	/* Free up the old crypto and allocate new one */
 	if (sa->crypt)
 		free (sa->crypt);
-	if ((sa->crypt = calloc (1, newlen)) == NULL)
+	if (strlen (alg_name) >= sizeof (sa->crypt->alg_name) || (sa->crypt = calloc (1, newlen)) == NULL)
 		return -1;
 
 	/* Save the new info */
@@ -1743,7 +1743,7 @@ int xfrmnl_sa_set_comp_params (struct xfrmnl_sa* sa, char* alg_name, unsigned in
 	/* Free up the old compression algo params and allocate new one */
 	if (sa->comp)
 		free (sa->comp);
-	if ((sa->comp = calloc (1, newlen)) == NULL)
+	if (strlen (alg_name) >= sizeof (sa->comp->alg_name) || (sa->comp = calloc (1, newlen)) == NULL)
 		return -1;
 
 	/* Save the new info */
-- 
2.6.4



From thomas.egerer at secunet.com  Tue May 31 08:29:53 2016
From: thomas.egerer at secunet.com (Thomas Egerer)
Date: Tue, 31 May 2016 17:29:53 +0200
Subject: [PATCH 0/2] xfrm: fix buffer overflows
Message-ID: <574DADF1.6070309@secunet.com>

Hi *,

we have found one definite and one potential buffer overflow
in libnl when adding xfrm states.
The definite one is triggered whenever an aead/auth (etc) key
is added to an xfrmnl_sa structure. The potential one is only
triggered if the same functions are called with alg_names
longer than 72/68 bytes + keysize. Then a strcpy call writes
beyond the appropriate data structures in struct xfrmnl_sa.

Cheers,
Thomas

Thomas Egerer (2):
  xfrm: fix buffer overflow when copying keys
  xfrm: check length of alg_name before strcpying it

 lib/xfrm/sa.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

-- 
2.6.4



