Skip to contentSkip to conversation

: Add nested compat attribute

RTNETLINK Applied Patrick McHardy 3 participants 15 messages Jun 22, 2007 – Jun 26, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

This patch adds a new attribute type that can be used to replace non-nested attributes that contain structures by nested ones in a compatible way.

This can be used in cases like Peter's who is trying to extend sch_prio, which currently uses a fixed structure without any holes.

Switching to nested attributes makes sure that the next person won't run into the same problem.

[RTNETLINK]: Add nested compat attribute

Add a nested compat attribute type that can be used to convert attributes that contain a structure to nested attributes in a backwards compatible way.

The attribute looks like this:

struct {
[ compat contents ]
struct rtattr {
.rta_len = total size,
.rta_type = type,
} rta;
struct old_structure struct;

[ nested top-level attribute ]
struct rtattr {
.rta_len = nest size,
.rta_type = type,
} nest_attr;

[ optional 0 .. n nested attributes ]
struct rtattr {
.rta_len = private attribute len,
.rta_type = private attribute typ,
} nested_attr;
struct nested_data data;
};

Since both userspace and kernel deal correctly with attributes that are larger than expected old versions will just parse the compat part and ignore the rest.

---
commit dece87e23c7cfa1159d3be0ea5b0db89a0fc5872
tree c14be602de94b258e0343816b6c1809233a2ff5f
parent c4edf5d552b1450d903a7e7e2d846f2169087e10
author Patrick McHardy <[email protected]> Fri, 22 Jun 2007 17:52:21 +0200 committer Patrick McHardy <[email protected]> Fri, 22 Jun 2007 17:52:21 +0200

 include/linux/rtnetlink.h |   14 ++++++++++++++
 net/core/rtnetlink.c      |   16 ++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
include/linux/rtnetlink.h +14 -0
index 6127858..6731e7f 100644
@@ -570,6 +570,8 @@ static __inline__ int rtattr_strcmp(cons
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				      struct rtattr *rta, void **data, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
@@ -638,6 +640,18 @@ #define RTA_NEST_END(skb, start) \
 ({	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
 	(skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({	struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+	RTA_PUT(skb, type, attrlen, data); \
+	RTA_NEST(skb, type); \
+	__start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({	struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+	RTA_NEST_END(skb, __nest); \
+	(skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({	if (start) \
 		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
net/core/rtnetlink.c +16 -0
index 06c0c5a..c25d23b 100644
@@ -97,6 +97,21 @@ int rtattr_parse(struct rtattr *tb[], in
 	return 0;
 }
 
+int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			       struct rtattr *rta, void **data, int len)
+{
+	if (RTA_PAYLOAD(rta) < len)
+		return -1;
+	*data = RTA_DATA(rta);
+
+	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+		rta = RTA_DATA(rta) + RTA_ALIGN(len);
+		return rtattr_parse_nested(tb, maxattr, rta);
+	}
+	memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+	return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -1297,6 +1312,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
#1 lore raw

Review

Quoted 4 lines · Patrick McHardy

extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);

(quoted diff) +2 -0
+extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				      struct rtattr *rta, void **data, int len);

This version is a bit nicer because it avoids a cast in the caller and makes the signature match the existing functions better.

In the previous version it the call would have looked like this:

if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, (void *)&qopt,

                               sizeof(*qopt)))
	return -EINVAL;

now its:

if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt,

                               qopt, sizeof(*qopt)))
	return -EINVAL;

[RTNETLINK]: Add nested compat attribute

Add a nested compat attribute type that can be used to convert attributes that contain a structure to nested attributes in a backwards compatible way.

The attribute looks like this:

struct {
[ compat contents ]
struct rtattr {
.rta_len = total size,
.rta_type = type,
} rta;
struct old_structure struct;

[ nested top-level attribute ]
struct rtattr {
.rta_len = nest size,
.rta_type = type,
} nest_attr;

[ optional 0 .. n nested attributes ]
struct rtattr {
.rta_len = private attribute len,
.rta_type = private attribute typ,
} nested_attr;
struct nested_data data;
};

Since both userspace and kernel deal correctly with attributes that are larger than expected old versions will just parse the compat part and ignore the rest.

---
commit 1e16b5e521172515c53ce96a0bc3cf0e2d77c001
tree c9880c58391e2df77ecab3d9b6a6849947714eb3
parent c4edf5d552b1450d903a7e7e2d846f2169087e10
author Patrick McHardy <[email protected]> Fri, 22 Jun 2007 19:06:54 +0200 committer Patrick McHardy <[email protected]> Fri, 22 Jun 2007 19:06:54 +0200

 include/linux/rtnetlink.h |   18 ++++++++++++++++++
 net/core/rtnetlink.c      |   14 ++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)
include/linux/rtnetlink.h +18 -0
index 6127858..d40b0c9 100644
@@ -570,10 +570,16 @@ static __inline__ int rtattr_strcmp(cons
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				        struct rtattr *rta, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
 
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__rtattr_parse_nested_compat(tb, max, rta, len); })
+
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
 extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
@@ -638,6 +644,18 @@ #define RTA_NEST_END(skb, start) \
 ({	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
 	(skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({	struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+	RTA_PUT(skb, type, attrlen, data); \
+	RTA_NEST(skb, type); \
+	__start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({	struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+	RTA_NEST_END(skb, __nest); \
+	(skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({	if (start) \
 		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
net/core/rtnetlink.c +14 -0
index 06c0c5a..54c17e4 100644
@@ -97,6 +97,19 @@ int rtattr_parse(struct rtattr *tb[], in
 	return 0;
 }
 
+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			         struct rtattr *rta, int len)
+{
+	if (RTA_PAYLOAD(rta) < len)
+		return -1;
+	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+		rta = RTA_DATA(rta) + RTA_ALIGN(len);
+		return rtattr_parse_nested(tb, maxattr, rta);
+	}
+	memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+	return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -1297,6 +1310,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(__rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
#2 lore raw
In reply to Patrick McHardy
Quoted 10 lines

This patch adds a new attribute type that can be used to replace non-nested attributes that contain structures by nested ones in a compatible way.

This can be used in cases like Peter's who is trying to extend sch_prio, which currently uses a fixed structure without any holes.

Switching to nested attributes makes sure that the next person won't run into the same problem.

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these patches when they have time? I'd be interested in seeing them make it into 2.6.23.

Thanks!!

-PJ Waskiewicz

maintainer
#3 lore raw

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 10:14:37 -0700

Quoted 8 lines
Quoted 8 lines

This patch adds a new attribute type that can be used to replace non-nested attributes that contain structures by nested ones in a compatible way.

This can be used in cases like Peter's who is trying to extend sch_prio, which currently uses a fixed structure without any holes.

Quoted 6 lines
Quoted 2 lines

Switching to nested attributes makes sure that the next person won't run into the same problem.

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these patches when they have time? I'd be interested in seeing them make it into 2.6.23.

I've just put Patrick's patch into the net-2.6.23 tree.

#4 lore raw
Quoted 15 lines

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 10:14:37 -0700

Quoted 6 lines
Quoted 6 lines

This patch adds a new attribute type that can be used to replace non-nested attributes that contain structures by nested ones in a compatible way.

This can be used in cases like Peter's who is trying to extend sch_prio, which currently uses a fixed structure without

any holes.

Quoted 2 lines
Quoted 2 lines

Switching to nested attributes makes sure that the next

person won't

Quoted 2 lines
Quoted 1 line

run into the same problem.

Quoted 7 lines
Quoted 2 lines

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these

patches when

Quoted 1 line

they have time? I'd be interested in seeing them make it

into 2.6.23.

I've just put Patrick's patch into the net-2.6.23 tree.

Awesome Dave!! Thank you very much. :)

-PJ Waskiewicz

maintainer
#5 lore raw

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 14:01:31 -0700

Quoted 1 line

Awesome Dave!! Thank you very much. :)

Please get your next round of patches ready, Patrick and I can review them and barring any serious issues we can finally put this stuff in to net-2.6.23.

#6 lore raw
Quoted 8 lines

-----Original Message-----
From: David Miller [mailto:[email protected]]
Sent: Monday, June 25, 2007 2:30 PM
To: Waskiewicz Jr, Peter P
Cc: [email protected]; [email protected]; [email protected]
Subject: Re: [RTNETLINK]: Add nested compat attribute

Quoted 8 lines

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 14:01:31 -0700

Quoted 1 line

Awesome Dave!! Thank you very much. :)

Please get your next round of patches ready, Patrick and I can review them and barring any serious issues we can finally put this stuff in to net-2.6.23.

I'm putting them into the latest 2.6.23 tree right now - I'll have them tested and sent upstream later today.

Thanks Dave,

-PJ Waskiewicz

maintainer
#7 lore raw

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 14:33:12 -0700

Quoted 2 lines

I'm putting them into the latest 2.6.23 tree right now - I'll have them tested and sent upstream later today.

Please repull as I just put Patrick's RTNETLINK patch in "for real this time" :-)

#8 lore raw
In reply to David Miller
Quoted 8 lines · David Miller
Quoted 5 lines

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these patches when they have time? I'd be interested in seeing them make it into 2.6.23.

I've just put Patrick's patch into the net-2.6.23 tree.

You seem to have added the netlink patch for the generic netlink attributes. Peter needs the rtnetlink attribute patch since qdiscs still use the old stuff.

Attached again to this mail.

[RTNETLINK]: Add nested compat attribute

Add a nested compat attribute type that can be used to convert attributes that contain a structure to nested attributes in a backwards compatible way.

The attribute looks like this:

struct {
[ compat contents ]
struct rtattr {
.rta_len = total size,
.rta_type = type,
} rta;
struct old_structure struct;

[ nested top-level attribute ]
struct rtattr {
.rta_len = nest size,
.rta_type = type,
} nest_attr;

[ optional 0 .. n nested attributes ]
struct rtattr {
.rta_len = private attribute len,
.rta_type = private attribute typ,
} nested_attr;
struct nested_data data;
};

Since both userspace and kernel deal correctly with attributes that are larger than expected old versions will just parse the compat part and ignore the rest.

---
commit dece87e23c7cfa1159d3be0ea5b0db89a0fc5872
tree c14be602de94b258e0343816b6c1809233a2ff5f
parent c4edf5d552b1450d903a7e7e2d846f2169087e10
author Patrick McHardy <[email protected]> Fri, 22 Jun 2007 17:52:21 +0200 committer Patrick McHardy <[email protected]> Fri, 22 Jun 2007 17:52:21 +0200

 include/linux/rtnetlink.h |   14 ++++++++++++++
 net/core/rtnetlink.c      |   16 ++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
include/linux/rtnetlink.h +14 -0
index 6127858..6731e7f 100644
@@ -570,6 +570,8 @@ static __inline__ int rtattr_strcmp(cons
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				      struct rtattr *rta, void **data, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
@@ -638,6 +640,18 @@ #define RTA_NEST_END(skb, start) \
 ({	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
 	(skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({	struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+	RTA_PUT(skb, type, attrlen, data); \
+	RTA_NEST(skb, type); \
+	__start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({	struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+	RTA_NEST_END(skb, __nest); \
+	(skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({	if (start) \
 		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
net/core/rtnetlink.c +16 -0
index 06c0c5a..c25d23b 100644
@@ -97,6 +97,21 @@ int rtattr_parse(struct rtattr *tb[], in
 	return 0;
 }
 
+int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			       struct rtattr *rta, void **data, int len)
+{
+	if (RTA_PAYLOAD(rta) < len)
+		return -1;
+	*data = RTA_DATA(rta);
+
+	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+		rta = RTA_DATA(rta) + RTA_ALIGN(len);
+		return rtattr_parse_nested(tb, maxattr, rta);
+	}
+	memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+	return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -1297,6 +1312,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
maintainer Applied
#9 lore raw

From: Patrick McHardy <[email protected]>
Date: Mon, 25 Jun 2007 23:08:09 +0200

Quoted 7 lines
Quoted 6 lines · David Miller
Quoted 5 lines

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these patches when they have time? I'd be interested in seeing them make it into 2.6.23.

Quoted 8 lines
Quoted 2 lines

I've just put Patrick's patch into the net-2.6.23 tree.

You seem to have added the netlink patch for the generic netlink attributes. Peter needs the rtnetlink attribute patch since qdiscs still use the old stuff.

Attached again to this mail.

Thanks for the clarification, I thought they were both the same patch, resent for the sake of tgraf seeing it.

I've applied this one too, thanks Patrick.

#10 lore raw
Quoted 18 lines

From: Patrick McHardy <[email protected]>
Date: Mon, 25 Jun 2007 23:08:09 +0200

Quoted 5 lines
Quoted 4 lines · David Miller
Quoted 4 lines

I've been using this patch and the IPROUTE2 patches Patrick has proposed with no issues. Can someone else look at these patches when they have time? I'd be interested in seeing them

make it into 2.6.23.

Quoted 9 lines
Quoted 4 lines
Quoted 1 line

I've just put Patrick's patch into the net-2.6.23 tree.

You seem to have added the netlink patch for the generic netlink attributes. Peter needs the rtnetlink attribute patch since qdiscs still use the old stuff.

Quoted 6 lines
Quoted 1 line

Attached again to this mail.

Thanks for the clarification, I thought they were both the same patch, resent for the sake of tgraf seeing it.

I've applied this one too, thanks Patrick.

It looks like the one Patrick resent was the older version that requires a typecast. This is the function prototype currently in the kernel:

+extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+ struct rtattr *rta, void **data,
int len);

This is the newer version:

+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+ struct rtattr *rta, int len);
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+ __rtattr_parse_nested_compat(tb, max, rta, len); })
+

I can send the update to what's in 2.6.23 as the first patch of my series, or I can write my function calls using the older callback (which isn't a problem). Which would you prefer?

Thanks,
-PJ Waskiewicz

maintainer
#11 lore raw

From: "Waskiewicz Jr, Peter P" <[email protected]>
Date: Mon, 25 Jun 2007 16:23:02 -0700

Quoted 17 lines

It looks like the one Patrick resent was the older version that requires a typecast. This is the function prototype currently in the kernel:

(quoted diff) +2 -0
+extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				      struct rtattr *rta, void **data,

int len);

This is the newer version:

+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,

(quoted diff) +5 -0
+				        struct rtattr *rta, int len);
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__rtattr_parse_nested_compat(tb, max, rta, len); })
+
Quoted 3 lines

I can send the update to what's in 2.6.23 as the first patch of my series, or I can write my function calls using the older callback (which isn't a problem). Which would you prefer?

Either way is fine with me, just use the interface in the tree for now and we can fix it up if we add the prototype change.

Meanwhile, Patrick please clear up the situation :-)

#12 lore raw
Quoted 1 line · David Miller

Meanwhile, Patrick please clear up the situation :-)

Attached is both an incremental patch and a complete replacement, please take whichever you like better :)

[RTNETLINK]: Add nested compat attribute

Add a nested compat attribute type that can be used to convert attributes that contain a structure to nested attributes in a backwards compatible way.

The attribute looks like this:

struct {
[ compat contents ]
struct rtattr {
.rta_len = total size,
.rta_type = type,
} rta;
struct old_structure struct;

[ nested top-level attribute ]
struct rtattr {
.rta_len = nest size,
.rta_type = type,
} nest_attr;

[ optional 0 .. n nested attributes ]
struct rtattr {
.rta_len = private attribute len,
.rta_type = private attribute typ,
} nested_attr;
struct nested_data data;
};

Since both userspace and kernel deal correctly with attributes that are larger than expected old versions will just parse the compat part and ignore the rest.

---
commit 1e16b5e521172515c53ce96a0bc3cf0e2d77c001
tree c9880c58391e2df77ecab3d9b6a6849947714eb3
parent c4edf5d552b1450d903a7e7e2d846f2169087e10
author Patrick McHardy <[email protected]> Fri, 22 Jun 2007 19:06:54 +0200 committer Patrick McHardy <[email protected]> Fri, 22 Jun 2007 19:06:54 +0200

 include/linux/rtnetlink.h |   18 ++++++++++++++++++
 net/core/rtnetlink.c      |   14 ++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)
include/linux/rtnetlink.h +18 -0
index 6127858..d40b0c9 100644
@@ -570,10 +570,16 @@ static __inline__ int rtattr_strcmp(cons
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				        struct rtattr *rta, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
 
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__rtattr_parse_nested_compat(tb, max, rta, len); })
+
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
 extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
@@ -638,6 +644,18 @@ #define RTA_NEST_END(skb, start) \
 ({	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
 	(skb)->len; })
 
+#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
+({	struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
+	RTA_PUT(skb, type, attrlen, data); \
+	RTA_NEST(skb, type); \
+	__start; })
+
+#define RTA_NEST_COMPAT_END(skb, start) \
+({	struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
+	(start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
+	RTA_NEST_END(skb, __nest); \
+	(skb)->len; })
+
 #define RTA_NEST_CANCEL(skb, start) \
 ({	if (start) \
 		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
net/core/rtnetlink.c +14 -0
index 06c0c5a..54c17e4 100644
@@ -97,6 +97,19 @@ int rtattr_parse(struct rtattr *tb[], in
 	return 0;
 }
 
+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			         struct rtattr *rta, int len)
+{
+	if (RTA_PAYLOAD(rta) < len)
+		return -1;
+	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+		rta = RTA_DATA(rta) + RTA_ALIGN(len);
+		return rtattr_parse_nested(tb, maxattr, rta);
+	}
+	memset(tb, 0, sizeof(struct rtattr *) * maxattr);
+	return 0;
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -1297,6 +1310,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
+EXPORT_SYMBOL(__rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);

[RTNETLINK]: Fix rtnetlink compat attribute patch

Sent the wrong patch previously.

include/linux/rtnetlink.h +6 -2
index 5852921..a37be6a 100644
@@ -570,12 +570,16 @@ static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 }
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
-extern int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
-				      struct rtattr *rta, void **data, int len);
+extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+				        struct rtattr *rta, int len);
 
 #define rtattr_parse_nested(tb, max, rta) \
 	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
 
+#define rtattr_parse_nested_compat(tb, max, rta, data, len) \
+({	data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+	__rtattr_parse_nested_compat(tb, max, rta, len); })
+
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
 extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
net/core/rtnetlink.c +3 -5
index 012363b..0c4be06 100644
@@ -97,13 +97,11 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
 	return 0;
 }
 
-int rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
-			       struct rtattr *rta, void **data, int len)
+int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
+			         struct rtattr *rta, int len)
 {
 	if (RTA_PAYLOAD(rta) < len)
 		return -1;
-	*data = RTA_DATA(rta);
-
 	if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
 		rta = RTA_DATA(rta) + RTA_ALIGN(len);
 		return rtattr_parse_nested(tb, maxattr, rta);
@@ -975,7 +973,7 @@ void __init rtnetlink_init(void)
 EXPORT_SYMBOL(__rta_fill);
 EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
-EXPORT_SYMBOL(rtattr_parse_nested_compat);
+EXPORT_SYMBOL(__rtattr_parse_nested_compat);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
maintainer Applied
#13 lore raw

From: Patrick McHardy <[email protected]>
Date: Tue, 26 Jun 2007 12:04:21 +0200

Quoted 6 lines
Quoted 1 line · David Miller

Meanwhile, Patrick please clear up the situation :-)

Attached is both an incremental patch and a complete replacement, please take whichever you like better :)

I applied the incremental, thanks.

I'll combine them next time I rebase.

#14 lore raw
In reply to Waskiewicz Jr, Peter P
Quoted 2 lines · Peter P

It looks like the one Patrick resent was the older version that requires a typecast. This is the function prototype currently in the kernel:

Oops, sorry, I messed that up. Will fix immediately.