Netdev List
 help / color / mirror / Atom feed
* Re: [2.6.20.17 review 35/58] forcedeth bug fix: realtek phy
From: Willy Tarreau @ 2007-08-22 16:10 UTC (permalink / raw)
  To: Chuck Ebbert
  Cc: linux-kernel, stable, Ayaz Abdulla, Greg Kroah-Hartman, netdev
In-Reply-To: <46CC5CBA.2050901@redhat.com>

On Wed, Aug 22, 2007 at 11:56:42AM -0400, Chuck Ebbert wrote:
> On 08/22/2007 05:39 AM, Willy Tarreau wrote:
> > This patch contains errata fixes for the realtek phy. It only renamed the
> > defines to be phy specific.
> > 
> > Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
> > Signed-off-by: Willy Tarreau <w@1wt.eu>
> > ---
> >  drivers/net/forcedeth.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 54 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
> > index c383dc3..dbfdbed 100644
> > --- a/drivers/net/forcedeth.c
> > +++ b/drivers/net/forcedeth.c
> > @@ -554,6 +554,7 @@ union ring_type {
> >  #define PHY_OUI_MARVELL	0x5043
> >  #define PHY_OUI_CICADA	0x03f1
> >  #define PHY_OUI_VITESSE	0x01c1
> > +#define PHY_OUI_REALTEK	0x01c1
> >  #define PHYID1_OUI_MASK	0x03ff
> >  #define PHYID1_OUI_SHFT	6
> >  #define PHYID2_OUI_MASK	0xfc00
> 
> Realtek is 0x0732
> 
> This is still wrong upstream -- what happened to the patch to fix it?

Good catch, thanks Chuck! I've already seen the fix somewhere, I believe it
was on netdev, though I'm not sure. I'm fixing the patch in place right now.
I can add your signoff if you want.

Cheers,
Willy


^ permalink raw reply

* [ofa-general] Re: [PATCH 1/10 Rev4] [Doc] HOWTO Documentation for batching
From: Randy Dunlap @ 2007-08-22 15:50 UTC (permalink / raw)
  To: Krishna Kumar
  Cc: johnpol, jagana, herbert, gaagaan, Robert.Olsson, kumarkr,
	rdreier, peter.p.waskiewicz.jr, hadi, kaber, jeff, general,
	netdev, tgraf, mcarlson, sri, shemminger, davem, mchan
In-Reply-To: <20070822082858.11964.87377.sendpatchset@localhost.localdomain>

On Wed, 22 Aug 2007 13:58:58 +0530 Krishna Kumar wrote:

> Add Documentation describing batching skb xmit capability.
> 
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
>  batching_skb_xmit.txt |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 78 insertions(+)
> 
> diff -ruNp org/Documentation/networking/batching_skb_xmit.txt new/Documentation/networking/batching_skb_xmit.txt
> --- org/Documentation/networking/batching_skb_xmit.txt	1970-01-01 05:30:00.000000000 +0530
> +++ new/Documentation/networking/batching_skb_xmit.txt	2007-08-22 10:21:19.000000000 +0530
> @@ -0,0 +1,78 @@
> +		 HOWTO for batching skb xmit support
> +		 -----------------------------------
> +
> +Section 1: What is batching skb xmit
> +Section 2: How batching xmit works vs the regular xmit
> +Section 3: How drivers can support batching
> +Section 4: How users can work with batching
> +
> +
> +Introduction: Kernel support for batching skb
> +----------------------------------------------
> +
> +A new capability to support xmit of multiple skbs is provided in the netdevice
> +layer. Drivers which enable this capability should be able to process multiple
> +skbs in a single call to their xmit handler.
> +
> +
> +Section 1: What is batching skb xmit
> +-------------------------------------
> +
> +	This capability is optionally enabled by a driver by setting the
> +	NETIF_F_BATCH_SKBS bit in dev->features. The pre-requisite for a

                                                     prerequisite

> +	driver to use this capability is that it should have a reasonably

	I would say "reasonably-sized".

> +	sized hardware queue that can process multiple skbs.
> +
> +
> +Section 2: How batching xmit works vs the regular xmit
> +-------------------------------------------------------
> +
> +	The network stack gets called from upper layer protocols with a single
> +	skb to transmit. This skb is first enqueue'd and an attempt is made to

                                           enqueued

> +	transmit it immediately (via qdisc_run). However, events like tx lock
> +	contention, tx queue stopped, etc, can result in the skb not getting

                                      etc.,

> +	sent out and it remains in the queue. When the next xmit is called or
> +	when the queue is re-enabled, qdisc_run could potentially find
> +	multiple packets in the queue, and iteratively send them all out
> +	one-by-one.
> +
> +	Batching skb xmit is a mechanism to exploit this situation where all
> +	skbs can be passed in one shot to the device. This reduces driver
> +	processing, locking at the driver (or in stack for ~LLTX drivers)
> +	gets amortized over multiple skbs, and in case of specific drivers
> +	where every xmit results in a completion processing (like IPoIB) -
> +	optimizations can be made in the driver to request a completion for
> +	only the last skb that was sent which results in saving interrupts
> +	for every (but the last) skb that was sent in the same batch.
> +
> +	Batching can result in significant performance gains for systems that
> +	have multiple data stream paths over the same network interface card.
> +
> +
> +Section 3: How drivers can support batching
> +---------------------------------------------
> +
> +	Batching requires the driver to set the NETIF_F_BATCH_SKBS bit in
> +	dev->features.
> +
> +	The driver's xmit handler should be modified to process multiple skbs
> +	instead of one skb. The driver's xmit handler is called either with a

                                                                           an

> +	skb to transmit or NULL skb, where the latter case should be handled
> +	as a call to xmit multiple skbs. This is done by sending out all skbs
> +	in the dev->skb_blist list (where it was added by the core stack).
> +
> +
> +Section 4: How users can work with batching
> +---------------------------------------------
> +
> +	Batching can be disabled for a particular device, e.g. on desktop
> +	systems if only one stream of network activity for that device is
> +	taking place, since performance could be slightly affected due to
> +	extra processing that batching adds (unless packets are getting
> +	sent fast resulting in stopped queue's). Batching can be enabled if

                                       queues).

> +	more than one stream of network activity per device is being done,
> +	e.g. on servers; or even desktop usage with multiple browser, chat,
> +	file transfer sessions, etc.
> +
> +	Per device batching can be enabled/disabled by passing 'on' or 'off'
> +	respectively to ethtool.

	with what other parameter(s), e.g.,

	ethtool <dev> batching on/off ?

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply

* Re: net/ipv4/fib_trie.c - compile error (Re: 2.6.23-rc3-mm1)
From: Adrian Bunk @ 2007-08-22 15:41 UTC (permalink / raw)
  To: Gabriel C; +Cc: Andrew Morton, linux-kernel, netdev
In-Reply-To: <46CC5685.7090500@googlemail.com>

On Wed, Aug 22, 2007 at 05:30:13PM +0200, Gabriel C wrote:
> Got it with a randconfig ( http://194.231.229.228/kernel/mm/2.6.23-rc3-mm1/r/randconfig-8 )
> 
> ...
> 
> net/ipv4/fib_trie.c: In function 'trie_rebalance':
> net/ipv4/fib_trie.c:969: error: lvalue required as unary '&' operand
> net/ipv4/fib_trie.c:971: error: lvalue required as unary '&' operand
> net/ipv4/fib_trie.c:977: error: lvalue required as unary '&' operand
> net/ipv4/fib_trie.c:980: error: lvalue required as unary '&' operand
>...

Side effect of the git-net removal, temporarily removing 
immunize-rcu_dereference-against-crazy-compiler-writers.patch should 
work around it.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply

* net/ipv4/fib_trie.c - compile error (Re: 2.6.23-rc3-mm1)
From: Gabriel C @ 2007-08-22 15:30 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, netdev
In-Reply-To: <20070822020648.5ea3a612.akpm@linux-foundation.org>

Got it with a randconfig ( http://194.231.229.228/kernel/mm/2.6.23-rc3-mm1/r/randconfig-8 )

...

net/ipv4/fib_trie.c: In function 'trie_rebalance':
net/ipv4/fib_trie.c:969: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:971: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:977: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:980: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'fib_insert_node':
net/ipv4/fib_trie.c:1034: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1034: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1034: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'fn_trie_lookup':
net/ipv4/fib_trie.c:1498: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1502: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1502: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1503: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'trie_leaf_remove':
net/ipv4/fib_trie.c:1539: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1539: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1539: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1554: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'nextleaf':
net/ipv4/fib_trie.c:1706: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c:1743: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'fib_trie_get_next':
net/ipv4/fib_trie.c:2046: error: lvalue required as unary '&' operand
net/ipv4/fib_trie.c: In function 'fib_trie_seq_show':
net/ipv4/fib_trie.c:2320: error: lvalue required as unary '&' operand
make[2]: *** [net/ipv4/fib_trie.o] Error 1
make[1]: *** [net/ipv4] Error 2
make: *** [net] Error 2
make: *** Waiting for unfinished jobs....

...

^ permalink raw reply

* [PATCH 07/16] [XFRM] netlink: Clear up some of the CONFIG_XFRM_SUB_POLICY ifdef mess
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_userpolicy_type_size --]
[-- Type: text/plain, Size: 2703 bytes --]

Moves all of the SUB_POLICY ifdefs related to the attribute size
calculation into a function.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:03:43.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:04:46.000000000 +0200
@@ -1224,6 +1224,14 @@ static inline int copy_to_user_sec_ctx(s
 	}
 	return 0;
 }
+static inline size_t userpolicy_type_attrsize(void)
+{
+#ifdef CONFIG_XFRM_SUB_POLICY
+	return nla_total_size(sizeof(struct xfrm_userpolicy_type));
+#else
+	return 0;
+#endif
+}
 
 #ifdef CONFIG_XFRM_SUB_POLICY
 static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
@@ -1857,9 +1865,7 @@ static int xfrm_send_migrate(struct xfrm
 
 	len = RTA_SPACE(sizeof(struct xfrm_user_migrate) * num_migrate);
 	len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_id));
-#ifdef CONFIG_XFRM_SUB_POLICY
-	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
-#endif
+	len += userpolicy_type_attrsize();
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -2214,9 +2220,7 @@ static int xfrm_send_acquire(struct xfrm
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
 	len += RTA_SPACE(xfrm_user_sec_ctx_size(x->security));
-#ifdef CONFIG_XFRM_SUB_POLICY
-	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
-#endif
+	len += userpolicy_type_attrsize();
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -2322,9 +2326,7 @@ static int xfrm_exp_policy_notify(struct
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
 	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp->security));
-#ifdef CONFIG_XFRM_SUB_POLICY
-	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
-#endif
+	len += userpolicy_type_attrsize();
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -2349,9 +2351,7 @@ static int xfrm_notify_policy(struct xfr
 		len += RTA_SPACE(headlen);
 		headlen = sizeof(*id);
 	}
-#ifdef CONFIG_XFRM_SUB_POLICY
-	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
-#endif
+	len += userpolicy_type_attrsize();
 	len += NLMSG_SPACE(headlen);
 
 	skb = alloc_skb(len, GFP_ATOMIC);
@@ -2401,9 +2401,7 @@ static int xfrm_notify_policy_flush(stru
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 	int len = 0;
-#ifdef CONFIG_XFRM_SUB_POLICY
-	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
-#endif
+	len += userpolicy_type_attrsize();
 	len += NLMSG_LENGTH(0);
 
 	skb = alloc_skb(len, GFP_ATOMIC);

-- 


^ permalink raw reply

* [PATCH 13/16] [XFRM] netlink: Use nlattr instead of rtattr
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nlattr --]
[-- Type: text/plain, Size: 15760 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:34:29.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:35:13.000000000 +0200
@@ -38,16 +38,16 @@ static inline int alg_len(struct xfrm_al
 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
 }
 
-static int verify_one_alg(struct rtattr **attrs, enum xfrm_attr_type_t type)
+static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
 {
-	struct rtattr *rt = attrs[type];
+	struct nlattr *rt = attrs[type];
 	struct xfrm_algo *algp;
 
 	if (!rt)
 		return 0;
 
-	algp = RTA_DATA(rt);
-	if (RTA_PAYLOAD(rt) < alg_len(algp))
+	algp = nla_data(rt);
+	if (nla_len(rt) < alg_len(algp))
 		return -EINVAL;
 
 	switch (type) {
@@ -75,24 +75,24 @@ static int verify_one_alg(struct rtattr 
 	return 0;
 }
 
-static void verify_one_addr(struct rtattr **attrs, enum xfrm_attr_type_t type,
+static void verify_one_addr(struct nlattr **attrs, enum xfrm_attr_type_t type,
 			   xfrm_address_t **addrp)
 {
-	struct rtattr *rt = attrs[type];
+	struct nlattr *rt = attrs[type];
 
 	if (rt && addrp)
-		*addrp = RTA_DATA(rt);
+		*addrp = nla_data(rt);
 }
 
-static inline int verify_sec_ctx_len(struct rtattr **attrs)
+static inline int verify_sec_ctx_len(struct nlattr **attrs)
 {
-	struct rtattr *rt = attrs[XFRMA_SEC_CTX];
+	struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
 		return 0;
 
-	uctx = RTA_DATA(rt);
+	uctx = nla_data(rt);
 	if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
 		return -EINVAL;
 
@@ -101,7 +101,7 @@ static inline int verify_sec_ctx_len(str
 
 
 static int verify_newsa_info(struct xfrm_usersa_info *p,
-			     struct rtattr **attrs)
+			     struct nlattr **attrs)
 {
 	int err;
 
@@ -191,16 +191,15 @@ out:
 
 static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
 			   struct xfrm_algo_desc *(*get_byname)(char *, int),
-			   struct rtattr *u_arg)
+			   struct nlattr *rta)
 {
-	struct rtattr *rta = u_arg;
 	struct xfrm_algo *p, *ualg;
 	struct xfrm_algo_desc *algo;
 
 	if (!rta)
 		return 0;
 
-	ualg = RTA_DATA(rta);
+	ualg = nla_data(rta);
 
 	algo = get_byname(ualg->alg_name, 1);
 	if (!algo)
@@ -216,15 +215,14 @@ static int attach_one_algo(struct xfrm_a
 	return 0;
 }
 
-static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_arg)
+static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct nlattr *rta)
 {
-	struct rtattr *rta = u_arg;
 	struct xfrm_encap_tmpl *p, *uencap;
 
 	if (!rta)
 		return 0;
 
-	uencap = RTA_DATA(rta);
+	uencap = nla_data(rta);
 	p = kmemdup(uencap, sizeof(*p), GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
@@ -245,26 +243,25 @@ static inline int xfrm_user_sec_ctx_size
 	return len;
 }
 
-static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
+static int attach_sec_ctx(struct xfrm_state *x, struct nlattr *u_arg)
 {
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!u_arg)
 		return 0;
 
-	uctx = RTA_DATA(u_arg);
+	uctx = nla_data(u_arg);
 	return security_xfrm_state_alloc(x, uctx);
 }
 
-static int attach_one_addr(xfrm_address_t **addrpp, struct rtattr *u_arg)
+static int attach_one_addr(xfrm_address_t **addrpp, struct nlattr *rta)
 {
-	struct rtattr *rta = u_arg;
 	xfrm_address_t *p, *uaddrp;
 
 	if (!rta)
 		return 0;
 
-	uaddrp = RTA_DATA(rta);
+	uaddrp = nla_data(rta);
 	p = kmemdup(uaddrp, sizeof(*p), GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
@@ -298,23 +295,23 @@ static void copy_from_user_state(struct 
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **attrs)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs)
 {
-	struct rtattr *rp = attrs[XFRMA_REPLAY_VAL];
-	struct rtattr *lt = attrs[XFRMA_LTIME_VAL];
-	struct rtattr *et = attrs[XFRMA_ETIMER_THRESH];
-	struct rtattr *rt = attrs[XFRMA_REPLAY_THRESH];
+	struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
+	struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
+	struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
+	struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
 	if (rp) {
 		struct xfrm_replay_state *replay;
-		replay = RTA_DATA(rp);
+		replay = nla_data(rp);
 		memcpy(&x->replay, replay, sizeof(*replay));
 		memcpy(&x->preplay, replay, sizeof(*replay));
 	}
 
 	if (lt) {
 		struct xfrm_lifetime_cur *ltime;
-		ltime = RTA_DATA(lt);
+		ltime = nla_data(lt);
 		x->curlft.bytes = ltime->bytes;
 		x->curlft.packets = ltime->packets;
 		x->curlft.add_time = ltime->add_time;
@@ -322,14 +319,14 @@ static void xfrm_update_ae_params(struct
 	}
 
 	if (et)
-		x->replay_maxage = *(u32*)RTA_DATA(et);
+		x->replay_maxage = nla_get_u32(et);
 
 	if (rt)
-		x->replay_maxdiff = *(u32*)RTA_DATA(rt);
+		x->replay_maxdiff = nla_get_u32(rt);
 }
 
 static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
-					       struct rtattr **attrs,
+					       struct nlattr **attrs,
 					       int *errp)
 {
 	struct xfrm_state *x = xfrm_state_alloc();
@@ -373,7 +370,7 @@ static struct xfrm_state *xfrm_state_con
 
 	/* override default values from above */
 
-	xfrm_update_ae_params(x, (struct rtattr **)attrs);
+	xfrm_update_ae_params(x, attrs);
 
 	return x;
 
@@ -386,7 +383,7 @@ error_no_put:
 }
 
 static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_usersa_info *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
@@ -427,7 +424,7 @@ out:
 }
 
 static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
-						 struct rtattr **attrs,
+						 struct nlattr **attrs,
 						 int *errp)
 {
 	struct xfrm_state *x = NULL;
@@ -457,7 +454,7 @@ static struct xfrm_state *xfrm_user_stat
 }
 
 static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_state *x;
 	int err = -ESRCH;
@@ -669,7 +666,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
@@ -722,7 +719,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
@@ -740,7 +737,7 @@ static int xfrm_get_sadinfo(struct sk_bu
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
@@ -786,7 +783,7 @@ static int verify_userspi_info(struct xf
 }
 
 static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
@@ -915,15 +912,15 @@ static int verify_newpolicy_info(struct 
 	return verify_policy_dir(p->dir);
 }
 
-static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **attrs)
+static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs)
 {
-	struct rtattr *rt = attrs[XFRMA_SEC_CTX];
+	struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
 		return 0;
 
-	uctx = RTA_DATA(rt);
+	uctx = nla_data(rt);
 	return security_xfrm_policy_alloc(pol, uctx);
 }
 
@@ -983,35 +980,35 @@ static int validate_tmpl(int nr, struct 
 	return 0;
 }
 
-static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **attrs)
+static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
 {
-	struct rtattr *rt = attrs[XFRMA_TMPL];
+	struct nlattr *rt = attrs[XFRMA_TMPL];
 
 	if (!rt) {
 		pol->xfrm_nr = 0;
 	} else {
-		struct xfrm_user_tmpl *utmpl = RTA_DATA(rt);
-		int nr = (rt->rta_len - sizeof(*rt)) / sizeof(*utmpl);
+		struct xfrm_user_tmpl *utmpl = nla_data(rt);
+		int nr = nla_len(rt) / sizeof(*utmpl);
 		int err;
 
 		err = validate_tmpl(nr, utmpl, pol->family);
 		if (err)
 			return err;
 
-		copy_templates(pol, RTA_DATA(rt), nr);
+		copy_templates(pol, utmpl, nr);
 	}
 	return 0;
 }
 
-static int copy_from_user_policy_type(u8 *tp, struct rtattr **attrs)
+static int copy_from_user_policy_type(u8 *tp, struct nlattr **attrs)
 {
-	struct rtattr *rt = attrs[XFRMA_POLICY_TYPE];
+	struct nlattr *rt = attrs[XFRMA_POLICY_TYPE];
 	struct xfrm_userpolicy_type *upt;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
 
 	if (rt) {
-		upt = RTA_DATA(rt);
+		upt = nla_data(rt);
 		type = upt->type;
 	}
 
@@ -1049,7 +1046,7 @@ static void copy_to_user_policy(struct x
 	p->share = XFRM_SHARE_ANY; /* XXX xp->share */
 }
 
-static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct rtattr **attrs, int *errp)
+static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
 {
 	struct xfrm_policy *xp = xfrm_policy_alloc(GFP_KERNEL);
 	int err;
@@ -1078,7 +1075,7 @@ static struct xfrm_policy *xfrm_policy_c
 }
 
 static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
 	struct xfrm_policy *xp;
@@ -1271,7 +1268,7 @@ static struct sk_buff *xfrm_policy_netli
 }
 
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
@@ -1294,7 +1291,7 @@ static int xfrm_get_policy(struct sk_buf
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
 	else {
-		struct rtattr *rt = attrs[XFRMA_SEC_CTX];
+		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
 		err = verify_sec_ctx_len(attrs);
@@ -1303,7 +1300,7 @@ static int xfrm_get_policy(struct sk_buf
 
 		memset(&tmp, 0, sizeof(struct xfrm_policy));
 		if (rt) {
-			struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+			struct xfrm_user_sec_ctx *uctx = nla_data(rt);
 
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
@@ -1345,7 +1342,7 @@ out:
 }
 
 static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct km_event c;
 	struct xfrm_usersa_flush *p = nlmsg_data(nlh);
@@ -1411,7 +1408,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_state *x;
 	struct sk_buff *r_skb;
@@ -1449,14 +1446,14 @@ static int xfrm_get_ae(struct sk_buff *s
 }
 
 static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_state *x;
 	struct km_event c;
 	int err = - EINVAL;
 	struct xfrm_aevent_id *p = nlmsg_data(nlh);
-	struct rtattr *rp = attrs[XFRMA_REPLAY_VAL];
-	struct rtattr *lt = attrs[XFRMA_LTIME_VAL];
+	struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
+	struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
 
 	if (!lt && !rp)
 		return err;
@@ -1488,7 +1485,7 @@ out:
 }
 
 static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct km_event c;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
@@ -1513,7 +1510,7 @@ static int xfrm_flush_policy(struct sk_b
 }
 
 static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_user_polexpire *up = nlmsg_data(nlh);
@@ -1528,7 +1525,7 @@ static int xfrm_add_pol_expire(struct sk
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
 	else {
-		struct rtattr *rt = attrs[XFRMA_SEC_CTX];
+		struct nlattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
 		err = verify_sec_ctx_len(attrs);
@@ -1537,7 +1534,7 @@ static int xfrm_add_pol_expire(struct sk
 
 		memset(&tmp, 0, sizeof(struct xfrm_policy));
 		if (rt) {
-			struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+			struct xfrm_user_sec_ctx *uctx = nla_data(rt);
 
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
@@ -1574,7 +1571,7 @@ out:
 }
 
 static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_state *x;
 	int err;
@@ -1606,12 +1603,12 @@ out:
 }
 
 static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **attrs)
+		struct nlattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_user_tmpl *ut;
 	int i;
-	struct rtattr *rt = attrs[XFRMA_TMPL];
+	struct nlattr *rt = attrs[XFRMA_TMPL];
 
 	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
 	struct xfrm_state *x = xfrm_state_alloc();
@@ -1628,7 +1625,7 @@ static int xfrm_add_acquire(struct sk_bu
 	}
 
 	/*   build an XP */
-	xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) attrs, &err);
+	xp = xfrm_policy_construct(&ua->policy, attrs, &err);
 	if (!xp) {
 		kfree(x);
 		return err;
@@ -1638,7 +1635,7 @@ static int xfrm_add_acquire(struct sk_bu
 	memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr));
 	memcpy(&x->sel, &ua->sel, sizeof(ua->sel));
 
-	ut = RTA_DATA(rt);
+	ut = nla_data(rt);
 	/* extract the templates and for each call km_key */
 	for (i = 0; i < xp->xfrm_nr; i++, ut++) {
 		struct xfrm_tmpl *t = &xp->xfrm_vec[i];
@@ -1661,14 +1658,14 @@ static int xfrm_add_acquire(struct sk_bu
 
 #ifdef CONFIG_XFRM_MIGRATE
 static int copy_from_user_migrate(struct xfrm_migrate *ma,
-				  struct rtattr **attrs, int *num)
+				  struct nlattr **attrs, int *num)
 {
-	struct rtattr *rt = attrs[XFRMA_MIGRATE];
+	struct nlattr *rt = attrs[XFRMA_MIGRATE];
 	struct xfrm_user_migrate *um;
 	int i, num_migrate;
 
-	um = RTA_DATA(rt);
-	num_migrate = (rt->rta_len - sizeof(*rt)) / sizeof(*um);
+	um = nla_data(rt);
+	num_migrate = nla_len(rt) / sizeof(*um);
 
 	if (num_migrate <= 0 || num_migrate > XFRM_MAX_DEPTH)
 		return -EINVAL;
@@ -1692,7 +1689,7 @@ static int copy_from_user_migrate(struct
 }
 
 static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
-			   struct rtattr **attrs)
+			   struct nlattr **attrs)
 {
 	struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
 	struct xfrm_migrate m[XFRM_MAX_DEPTH];
@@ -1703,12 +1700,12 @@ static int xfrm_do_migrate(struct sk_buf
 	if (attrs[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
 
-	err = copy_from_user_policy_type(&type, (struct rtattr **)attrs);
+	err = copy_from_user_policy_type(&type, attrs);
 	if (err)
 		return err;
 
 	err = copy_from_user_migrate((struct xfrm_migrate *)m,
-				     (struct rtattr **)attrs, &n);
+				     attrs, &n);
 	if (err)
 		return err;
 
@@ -1721,7 +1718,7 @@ static int xfrm_do_migrate(struct sk_buf
 }
 #else
 static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
-			   struct rtattr **attrs)
+			   struct nlattr **attrs)
 {
 	return -ENOPROTOOPT;
 }
@@ -1854,7 +1851,7 @@ static const struct nla_policy xfrma_pol
 };
 
 static struct xfrm_link {
-	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **);
+	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
 	int (*dump)(struct sk_buff *, struct netlink_callback *);
 } xfrm_dispatch[XFRM_NR_MSGTYPES] = {
 	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = { .doit = xfrm_add_sa        },
@@ -1914,7 +1911,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 	if (link->doit == NULL)
 		return -EINVAL;
 
-	return link->doit(skb, nlh, (struct rtattr **) attrs);
+	return link->doit(skb, nlh, attrs);
 }
 
 static void xfrm_netlink_rcv(struct sock *sk, int len)

-- 


^ permalink raw reply

* [PATCH 04/16] [XFRM] netlink: Use nlmsg_broadcast() and nlmsg_unicast()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_netlink_broadcast --]
[-- Type: text/plain, Size: 5279 bytes --]

This simplifies successful return codes from >0 to 0.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 16:13:57.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 16:15:03.000000000 +0200
@@ -800,8 +800,7 @@ static int xfrm_get_sa(struct sk_buff *s
 	if (IS_ERR(resp_skb)) {
 		err = PTR_ERR(resp_skb);
 	} else {
-		err = netlink_unicast(xfrm_nl, resp_skb,
-				      NETLINK_CB(skb).pid, MSG_DONTWAIT);
+		err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid);
 	}
 	xfrm_state_put(x);
 out_noput:
@@ -882,8 +881,7 @@ static int xfrm_alloc_userspi(struct sk_
 		goto out;
 	}
 
-	err = netlink_unicast(xfrm_nl, resp_skb,
-			      NETLINK_CB(skb).pid, MSG_DONTWAIT);
+	err = nlmsg_unicast(xfrm_nl, resp_skb, NETLINK_CB(skb).pid);
 
 out:
 	xfrm_state_put(x);
@@ -1393,9 +1391,8 @@ static int xfrm_get_policy(struct sk_buf
 		if (IS_ERR(resp_skb)) {
 			err = PTR_ERR(resp_skb);
 		} else {
-			err = netlink_unicast(xfrm_nl, resp_skb,
-					      NETLINK_CB(skb).pid,
-					      MSG_DONTWAIT);
+			err = nlmsg_unicast(xfrm_nl, resp_skb,
+					    NETLINK_CB(skb).pid);
 		}
 	} else {
 		xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
@@ -1525,8 +1522,7 @@ static int xfrm_get_ae(struct sk_buff *s
 
 	if (build_aevent(r_skb, x, &c) < 0)
 		BUG();
-	err = netlink_unicast(xfrm_nl, r_skb,
-			      NETLINK_CB(skb).pid, MSG_DONTWAIT);
+	err = nlmsg_unicast(xfrm_nl, r_skb, NETLINK_CB(skb).pid);
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
 	return err;
@@ -1903,9 +1899,7 @@ static int xfrm_send_migrate(struct xfrm
 	if (build_migrate(skb, m, num_migrate, sel, dir, type) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_MIGRATE;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE,
-				 GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);
 }
 #else
 static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -2061,8 +2055,7 @@ static int xfrm_exp_state_notify(struct 
 	if (build_expire(skb, x, c) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
 }
 
 static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
@@ -2079,8 +2072,7 @@ static int xfrm_aevent_state_notify(stru
 	if (build_aevent(skb, x, c) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_AEVENTS;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_AEVENTS, GFP_ATOMIC);
 }
 
 static int xfrm_notify_sa_flush(struct km_event *c)
@@ -2105,8 +2097,7 @@ static int xfrm_notify_sa_flush(struct k
 
 	nlmsg_end(skb, nlh);
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_SA;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 }
 
 static inline int xfrm_sa_len(struct xfrm_state *x)
@@ -2175,8 +2166,7 @@ static int xfrm_notify_sa(struct xfrm_st
 
 	nlmsg_end(skb, nlh);
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_SA;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 
 nlmsg_failure:
 rtattr_failure:
@@ -2262,8 +2252,7 @@ static int xfrm_send_acquire(struct xfrm
 	if (build_acquire(skb, x, xt, xp, dir) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_ACQUIRE;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_ACQUIRE, GFP_ATOMIC);
 }
 
 /* User gives us xfrm_user_policy_info followed by an array of 0
@@ -2371,8 +2360,7 @@ static int xfrm_exp_policy_notify(struct
 	if (build_polexpire(skb, xp, dir, c) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_EXPIRE;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_EXPIRE, GFP_ATOMIC);
 }
 
 static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
@@ -2423,8 +2411,7 @@ static int xfrm_notify_policy(struct xfr
 
 	nlmsg_end(skb, nlh);
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_POLICY;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
 
 nlmsg_failure:
 rtattr_failure:
@@ -2454,8 +2441,7 @@ static int xfrm_notify_policy_flush(stru
 
 	nlmsg_end(skb, nlh);
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_POLICY;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
 
 nlmsg_failure:
 	kfree_skb(skb);
@@ -2520,8 +2506,7 @@ static int xfrm_send_report(u8 proto, st
 	if (build_report(skb, proto, sel, addr) < 0)
 		BUG();
 
-	NETLINK_CB(skb).dst_group = XFRMNLGRP_REPORT;
-	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
+	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
 }
 
 static struct xfrm_mgr netlink_mgr = {

-- 


^ permalink raw reply

* [PATCH 05/16] [XFRM] netlink: Use nla_put()/NLA_PUT() variantes
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nla_put --]
[-- Type: text/plain, Size: 8431 bytes --]

Also makes use of copy_sec_ctx() in another place and removes
duplicated code.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 16:15:03.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 16:16:03.000000000 +0200
@@ -576,6 +576,27 @@ struct xfrm_dump_info {
 	int this_idx;
 };
 
+static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
+{
+	int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
+	struct xfrm_user_sec_ctx *uctx;
+	struct nlattr *attr;
+
+	attr = nla_reserve(skb, XFRMA_SEC_CTX, ctx_size);
+	if (attr == NULL)
+		return -EMSGSIZE;
+
+	uctx = nla_data(attr);
+	uctx->exttype = XFRMA_SEC_CTX;
+	uctx->len = ctx_size;
+	uctx->ctx_doi = s->ctx_doi;
+	uctx->ctx_alg = s->ctx_alg;
+	uctx->ctx_len = s->ctx_len;
+	memcpy(uctx + 1, s->ctx_str, s->ctx_len);
+
+	return 0;
+}
+
 static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
 {
 	struct xfrm_dump_info *sp = ptr;
@@ -596,43 +617,32 @@ static int dump_one_state(struct xfrm_st
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
-		RTA_PUT(skb, XFRMA_ALG_AUTH,
+		NLA_PUT(skb, XFRMA_ALG_AUTH,
 			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
 	if (x->ealg)
-		RTA_PUT(skb, XFRMA_ALG_CRYPT,
+		NLA_PUT(skb, XFRMA_ALG_CRYPT,
 			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
 	if (x->calg)
-		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
+		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
 
 	if (x->encap)
-		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+		NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
-	if (x->security) {
-		int ctx_size = sizeof(struct xfrm_sec_ctx) +
-				x->security->ctx_len;
-		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
-		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
-
-		uctx->exttype = XFRMA_SEC_CTX;
-		uctx->len = ctx_size;
-		uctx->ctx_doi = x->security->ctx_doi;
-		uctx->ctx_alg = x->security->ctx_alg;
-		uctx->ctx_len = x->security->ctx_len;
-		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
-	}
+	if (x->security && copy_sec_ctx(x->security, skb) < 0)
+		goto nla_put_failure;
 
 	if (x->coaddr)
-		RTA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
+		NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
 
 	if (x->lastused)
-		RTA_PUT(skb, XFRMA_LASTUSED, sizeof(x->lastused), &x->lastused);
+		NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
 
 	nlmsg_end(skb, nlh);
 out:
 	sp->this_idx++;
 	return 0;
 
-rtattr_failure:
+nla_put_failure:
 	nlmsg_cancel(skb, nlh);
 	return -EMSGSIZE;
 }
@@ -1193,32 +1203,9 @@ static int copy_to_user_tmpl(struct xfrm
 		up->ealgos = kp->ealgos;
 		up->calgos = kp->calgos;
 	}
-	RTA_PUT(skb, XFRMA_TMPL,
-		(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr),
-		vec);
-
-	return 0;
-
-rtattr_failure:
-	return -1;
-}
-
-static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb)
-{
-	int ctx_size = sizeof(struct xfrm_sec_ctx) + s->ctx_len;
-	struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
-	struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
-
-	uctx->exttype = XFRMA_SEC_CTX;
-	uctx->len = ctx_size;
-	uctx->ctx_doi = s->ctx_doi;
-	uctx->ctx_alg = s->ctx_alg;
-	uctx->ctx_len = s->ctx_len;
-	memcpy(uctx + 1, s->ctx_str, s->ctx_len);
-	return 0;
 
- rtattr_failure:
-	return -1;
+	return nla_put(skb, XFRMA_TMPL,
+		       sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr, vec);
 }
 
 static inline int copy_to_user_state_sec_ctx(struct xfrm_state *x, struct sk_buff *skb)
@@ -1240,17 +1227,11 @@ static inline int copy_to_user_sec_ctx(s
 #ifdef CONFIG_XFRM_SUB_POLICY
 static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
 {
-	struct xfrm_userpolicy_type upt;
+	struct xfrm_userpolicy_type upt = {
+		.type = type,
+	};
 
-	memset(&upt, 0, sizeof(upt));
-	upt.type = type;
-
-	RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
-
-	return 0;
-
-rtattr_failure:
-	return -1;
+	return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
 }
 
 #else
@@ -1440,7 +1421,6 @@ static int build_aevent(struct sk_buff *
 {
 	struct xfrm_aevent_id *id;
 	struct nlmsghdr *nlh;
-	struct xfrm_lifetime_cur ltime;
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
 	if (nlh == NULL)
@@ -1455,27 +1435,19 @@ static int build_aevent(struct sk_buff *
 	id->reqid = x->props.reqid;
 	id->flags = c->data.aevent;
 
-	RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
-
-	ltime.bytes = x->curlft.bytes;
-	ltime.packets = x->curlft.packets;
-	ltime.add_time = x->curlft.add_time;
-	ltime.use_time = x->curlft.use_time;
-
-	RTA_PUT(skb, XFRMA_LTIME_VAL, sizeof(struct xfrm_lifetime_cur), &ltime);
+	NLA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
+	NLA_PUT(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft);
 
-	if (id->flags&XFRM_AE_RTHR) {
-		RTA_PUT(skb,XFRMA_REPLAY_THRESH,sizeof(u32),&x->replay_maxdiff);
-	}
+	if (id->flags & XFRM_AE_RTHR)
+		NLA_PUT_U32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff);
 
-	if (id->flags&XFRM_AE_ETHR) {
-		u32 etimer = x->replay_maxage*10/HZ;
-		RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer);
-	}
+	if (id->flags & XFRM_AE_ETHR)
+		NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH,
+			    x->replay_maxage * 10 / HZ);
 
 	return nlmsg_end(skb, nlh);
 
-rtattr_failure:
+nla_put_failure:
 	nlmsg_cancel(skb, nlh);
 	return -EMSGSIZE;
 }
@@ -1840,11 +1812,7 @@ static int copy_to_user_migrate(struct x
 	memcpy(&um.new_daddr, &m->new_daddr, sizeof(um.new_daddr));
 	memcpy(&um.new_saddr, &m->new_saddr, sizeof(um.new_saddr));
 
-	RTA_PUT(skb, XFRMA_MIGRATE, sizeof(um), &um);
-	return 0;
-
-rtattr_failure:
-	return -1;
+	return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
 }
 
 static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
@@ -2137,39 +2105,44 @@ static int xfrm_notify_sa(struct xfrm_st
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
 	if (nlh == NULL)
-		goto nlmsg_failure;
+		goto nla_put_failure;
 
 	p = nlmsg_data(nlh);
 	if (c->event == XFRM_MSG_DELSA) {
+		struct nlattr *attr;
+
 		id = nlmsg_data(nlh);
 		memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
 		id->spi = x->id.spi;
 		id->family = x->props.family;
 		id->proto = x->id.proto;
 
-		p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p)));
+		attr = nla_reserve(skb, XFRMA_SA, sizeof(*p));
+		if (attr == NULL)
+			goto nla_put_failure;
+
+		p = nla_data(attr);
 	}
 
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
-		RTA_PUT(skb, XFRMA_ALG_AUTH,
+		NLA_PUT(skb, XFRMA_ALG_AUTH,
 			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
 	if (x->ealg)
-		RTA_PUT(skb, XFRMA_ALG_CRYPT,
+		NLA_PUT(skb, XFRMA_ALG_CRYPT,
 			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
 	if (x->calg)
-		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
+		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
 
 	if (x->encap)
-		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+		NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
 	nlmsg_end(skb, nlh);
 
 	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 
-nlmsg_failure:
-rtattr_failure:
+nla_put_failure:
 	kfree_skb(skb);
 	return -1;
 }
@@ -2392,6 +2365,8 @@ static int xfrm_notify_policy(struct xfr
 
 	p = nlmsg_data(nlh);
 	if (c->event == XFRM_MSG_DELPOLICY) {
+		struct nlattr *attr;
+
 		id = nlmsg_data(nlh);
 		memset(id, 0, sizeof(*id));
 		id->dir = dir;
@@ -2400,7 +2375,11 @@ static int xfrm_notify_policy(struct xfr
 		else
 			memcpy(&id->sel, &xp->selector, sizeof(id->sel));
 
-		p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p)));
+		attr = nla_reserve(skb, XFRMA_POLICY, sizeof(*p));
+		if (attr == NULL)
+			goto nlmsg_failure;
+
+		p = nla_data(attr);
 	}
 
 	copy_to_user_policy(xp, p, dir);
@@ -2414,7 +2393,6 @@ static int xfrm_notify_policy(struct xfr
 	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
 
 nlmsg_failure:
-rtattr_failure:
 	kfree_skb(skb);
 	return -1;
 }
@@ -2483,11 +2461,11 @@ static int build_report(struct sk_buff *
 	memcpy(&ur->sel, sel, sizeof(ur->sel));
 
 	if (addr)
-		RTA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
+		NLA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
 
 	return nlmsg_end(skb, nlh);
 
-rtattr_failure:
+nla_put_failure:
 	nlmsg_cancel(skb, nlh);
 	return -EMSGSIZE;
 }

-- 


^ permalink raw reply

* [PATCH 14/16] [XFRM] netlink: Use nla_memcpy() in xfrm_update_ae_params()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nla_memcpy --]
[-- Type: text/plain, Size: 1045 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:35:13.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:36:59.000000000 +0200
@@ -303,20 +303,12 @@ static void xfrm_update_ae_params(struct
 	struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
 	if (rp) {
-		struct xfrm_replay_state *replay;
-		replay = nla_data(rp);
-		memcpy(&x->replay, replay, sizeof(*replay));
-		memcpy(&x->preplay, replay, sizeof(*replay));
+		nla_memcpy(&x->replay, rp, sizeof(x->replay));
+		nla_memcpy(&x->preplay, rp, sizeof(x->preplay));
 	}
 
-	if (lt) {
-		struct xfrm_lifetime_cur *ltime;
-		ltime = nla_data(lt);
-		x->curlft.bytes = ltime->bytes;
-		x->curlft.packets = ltime->packets;
-		x->curlft.add_time = ltime->add_time;
-		x->curlft.use_time = ltime->use_time;
-	}
+	if (lt)
+		nla_memcpy(&x->curlft, lt, sizeof(x->curlft));
 
 	if (et)
 		x->replay_maxage = nla_get_u32(et);

-- 


^ permalink raw reply

* [PATCH 03/16] [XFRM] netlink: Use nlmsg_data() instead of NLMSG_DATA()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nlmsg_data --]
[-- Type: text/plain, Size: 8027 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 16:12:20.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 16:13:57.000000000 +0200
@@ -443,7 +443,7 @@ error_no_put:
 static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct rtattr **xfrma)
 {
-	struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
+	struct xfrm_usersa_info *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	int err;
 	struct km_event c;
@@ -520,7 +520,7 @@ static int xfrm_del_sa(struct sk_buff *s
 	struct xfrm_state *x;
 	int err = -ESRCH;
 	struct km_event c;
-	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
+	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 
 	x = xfrm_user_state_lookup(p, xfrma, &err);
 	if (x == NULL)
@@ -592,7 +592,7 @@ static int dump_one_state(struct xfrm_st
 	if (nlh == NULL)
 		return -EMSGSIZE;
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
@@ -715,7 +715,7 @@ static int xfrm_get_spdinfo(struct sk_bu
 		struct rtattr **xfrma)
 {
 	struct sk_buff *r_skb;
-	u32 *flags = NLMSG_DATA(nlh);
+	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
 	u32 seq = nlh->nlmsg_seq;
 	int len = NLMSG_LENGTH(sizeof(u32));
@@ -765,7 +765,7 @@ static int xfrm_get_sadinfo(struct sk_bu
 		struct rtattr **xfrma)
 {
 	struct sk_buff *r_skb;
-	u32 *flags = NLMSG_DATA(nlh);
+	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
 	u32 seq = nlh->nlmsg_seq;
 	int len = NLMSG_LENGTH(sizeof(u32));
@@ -787,7 +787,7 @@ static int xfrm_get_sadinfo(struct sk_bu
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct rtattr **xfrma)
 {
-	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
+	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	struct sk_buff *resp_skb;
 	int err = -ESRCH;
@@ -841,7 +841,7 @@ static int xfrm_alloc_userspi(struct sk_
 	int family;
 	int err;
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	err = verify_userspi_info(p);
 	if (err)
 		goto out_noput;
@@ -1130,7 +1130,7 @@ static struct xfrm_policy *xfrm_policy_c
 static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		struct rtattr **xfrma)
 {
-	struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh);
+	struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
 	struct xfrm_policy *xp;
 	struct km_event c;
 	int err;
@@ -1277,8 +1277,8 @@ static int dump_one_policy(struct xfrm_p
 			XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	p = NLMSG_DATA(nlh);
 
+	p = nlmsg_data(nlh);
 	copy_to_user_policy(xp, p, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
@@ -1351,7 +1351,7 @@ static int xfrm_get_policy(struct sk_buf
 	struct km_event c;
 	int delete;
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
 
 	err = copy_from_user_policy_type(&type, xfrma);
@@ -1420,7 +1420,7 @@ static int xfrm_flush_sa(struct sk_buff 
 		struct rtattr **xfrma)
 {
 	struct km_event c;
-	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
+	struct xfrm_usersa_flush *p = nlmsg_data(nlh);
 	struct xfrm_audit audit_info;
 	int err;
 
@@ -1448,8 +1448,8 @@ static int build_aevent(struct sk_buff *
 	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	id = NLMSG_DATA(nlh);
 
+	id = nlmsg_data(nlh);
 	memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr));
 	id->sa_id.spi = x->id.spi;
 	id->sa_id.family = x->props.family;
@@ -1490,7 +1490,7 @@ static int xfrm_get_ae(struct sk_buff *s
 	struct sk_buff *r_skb;
 	int err;
 	struct km_event c;
-	struct xfrm_aevent_id *p = NLMSG_DATA(nlh);
+	struct xfrm_aevent_id *p = nlmsg_data(nlh);
 	int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
 	struct xfrm_usersa_id *id = &p->sa_id;
 
@@ -1538,7 +1538,7 @@ static int xfrm_new_ae(struct sk_buff *s
 	struct xfrm_state *x;
 	struct km_event c;
 	int err = - EINVAL;
-	struct xfrm_aevent_id *p = NLMSG_DATA(nlh);
+	struct xfrm_aevent_id *p = nlmsg_data(nlh);
 	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
 	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
 
@@ -1602,7 +1602,7 @@ static int xfrm_add_pol_expire(struct sk
 		struct rtattr **xfrma)
 {
 	struct xfrm_policy *xp;
-	struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
+	struct xfrm_user_polexpire *up = nlmsg_data(nlh);
 	struct xfrm_userpolicy_info *p = &up->pol;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err = -ENOENT;
@@ -1664,7 +1664,7 @@ static int xfrm_add_sa_expire(struct sk_
 {
 	struct xfrm_state *x;
 	int err;
-	struct xfrm_user_expire *ue = NLMSG_DATA(nlh);
+	struct xfrm_user_expire *ue = nlmsg_data(nlh);
 	struct xfrm_usersa_info *p = &ue->state;
 
 	x = xfrm_state_lookup(&p->id.daddr, p->id.spi, p->id.proto, p->family);
@@ -1699,7 +1699,7 @@ static int xfrm_add_acquire(struct sk_bu
 	int i;
 	struct rtattr *rt = xfrma[XFRMA_TMPL-1];
 
-	struct xfrm_user_acquire *ua = NLMSG_DATA(nlh);
+	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
 	struct xfrm_state *x = xfrm_state_alloc();
 	int err = -ENOMEM;
 
@@ -1794,7 +1794,7 @@ static int copy_from_user_migrate(struct
 static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 			   struct rtattr **xfrma)
 {
-	struct xfrm_userpolicy_id *pi = NLMSG_DATA(nlh);
+	struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
 	struct xfrm_migrate m[XFRM_MAX_DEPTH];
 	u8 type;
 	int err;
@@ -1863,8 +1863,8 @@ static int build_migrate(struct sk_buff 
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	pol_id = NLMSG_DATA(nlh);
 
+	pol_id = nlmsg_data(nlh);
 	/* copy data from selector, dir, and type to the pol_id */
 	memset(pol_id, 0, sizeof(*pol_id));
 	memcpy(&pol_id->sel, sel, sizeof(pol_id->sel));
@@ -2041,8 +2041,8 @@ static int build_expire(struct sk_buff *
 	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	ue = NLMSG_DATA(nlh);
 
+	ue = nlmsg_data(nlh);
 	copy_to_user_state(x, &ue->state);
 	ue->hard = (c->data.hard != 0) ? 1 : 0;
 
@@ -2100,7 +2100,7 @@ static int xfrm_notify_sa_flush(struct k
 		return -EMSGSIZE;
 	}
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	p->proto = c->data.proto;
 
 	nlmsg_end(skb, nlh);
@@ -2148,9 +2148,9 @@ static int xfrm_notify_sa(struct xfrm_st
 	if (nlh == NULL)
 		goto nlmsg_failure;
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	if (c->event == XFRM_MSG_DELSA) {
-		id = NLMSG_DATA(nlh);
+		id = nlmsg_data(nlh);
 		memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
 		id->spi = x->id.spi;
 		id->family = x->props.family;
@@ -2218,8 +2218,8 @@ static int build_acquire(struct sk_buff 
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_ACQUIRE, sizeof(*ua), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	ua = NLMSG_DATA(nlh);
 
+	ua = nlmsg_data(nlh);
 	memcpy(&ua->id, &x->id, sizeof(ua->id));
 	memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr));
 	memcpy(&ua->sel, &x->sel, sizeof(ua->sel));
@@ -2335,8 +2335,8 @@ static int build_polexpire(struct sk_buf
 	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	upe = NLMSG_DATA(nlh);
 
+	upe = nlmsg_data(nlh);
 	copy_to_user_policy(xp, &upe->pol, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
@@ -2402,9 +2402,9 @@ static int xfrm_notify_policy(struct xfr
 	if (nlh == NULL)
 		goto nlmsg_failure;
 
-	p = NLMSG_DATA(nlh);
+	p = nlmsg_data(nlh);
 	if (c->event == XFRM_MSG_DELPOLICY) {
-		id = NLMSG_DATA(nlh);
+		id = nlmsg_data(nlh);
 		memset(id, 0, sizeof(*id));
 		id->dir = dir;
 		if (c->data.byid)
@@ -2491,8 +2491,8 @@ static int build_report(struct sk_buff *
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_REPORT, sizeof(*ur), 0);
 	if (nlh == NULL)
 		return -EMSGSIZE;
-	ur = NLMSG_DATA(nlh);
 
+	ur = nlmsg_data(nlh);
 	ur->proto = proto;
 	memcpy(&ur->sel, sel, sizeof(ur->sel));
 

-- 


^ permalink raw reply

* [PATCH 15/16] [XFRM] netlink: Remove dependency on rtnetlink
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_remove_rtnetlink_include --]
[-- Type: text/plain, Size: 511 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:36:59.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:37:18.000000000 +0200
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/net.h>
 #include <linux/skbuff.h>
-#include <linux/rtnetlink.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 #include <linux/init.h>

-- 


^ permalink raw reply

* [PATCH 11/16] [XFRM] netlink: Enhance indexing of the attribute array
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_attr_index --]
[-- Type: text/plain, Size: 7434 bytes --]

nlmsg_parse() puts attributes at array[type] so the indexing
method can be simpilfied by removing the obscuring "- 1".

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:31:56.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:34:10.000000000 +0200
@@ -40,7 +40,7 @@ static inline int alg_len(struct xfrm_al
 
 static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
 {
-	struct rtattr *rt = xfrma[type - 1];
+	struct rtattr *rt = xfrma[type];
 	struct xfrm_algo *algp;
 
 	if (!rt)
@@ -78,7 +78,7 @@ static int verify_one_alg(struct rtattr 
 static void verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
 			   xfrm_address_t **addrp)
 {
-	struct rtattr *rt = xfrma[type - 1];
+	struct rtattr *rt = xfrma[type];
 
 	if (rt && addrp)
 		*addrp = RTA_DATA(rt);
@@ -86,7 +86,7 @@ static void verify_one_addr(struct rtatt
 
 static inline int verify_sec_ctx_len(struct rtattr **xfrma)
 {
-	struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
@@ -125,35 +125,35 @@ static int verify_newsa_info(struct xfrm
 	err = -EINVAL;
 	switch (p->id.proto) {
 	case IPPROTO_AH:
-		if (!xfrma[XFRMA_ALG_AUTH-1]	||
-		    xfrma[XFRMA_ALG_CRYPT-1]	||
-		    xfrma[XFRMA_ALG_COMP-1])
+		if (!xfrma[XFRMA_ALG_AUTH]	||
+		    xfrma[XFRMA_ALG_CRYPT]	||
+		    xfrma[XFRMA_ALG_COMP])
 			goto out;
 		break;
 
 	case IPPROTO_ESP:
-		if ((!xfrma[XFRMA_ALG_AUTH-1] &&
-		     !xfrma[XFRMA_ALG_CRYPT-1])	||
-		    xfrma[XFRMA_ALG_COMP-1])
+		if ((!xfrma[XFRMA_ALG_AUTH] &&
+		     !xfrma[XFRMA_ALG_CRYPT])	||
+		    xfrma[XFRMA_ALG_COMP])
 			goto out;
 		break;
 
 	case IPPROTO_COMP:
-		if (!xfrma[XFRMA_ALG_COMP-1]	||
-		    xfrma[XFRMA_ALG_AUTH-1]	||
-		    xfrma[XFRMA_ALG_CRYPT-1])
+		if (!xfrma[XFRMA_ALG_COMP]	||
+		    xfrma[XFRMA_ALG_AUTH]	||
+		    xfrma[XFRMA_ALG_CRYPT])
 			goto out;
 		break;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case IPPROTO_DSTOPTS:
 	case IPPROTO_ROUTING:
-		if (xfrma[XFRMA_ALG_COMP-1]	||
-		    xfrma[XFRMA_ALG_AUTH-1]	||
-		    xfrma[XFRMA_ALG_CRYPT-1]	||
-		    xfrma[XFRMA_ENCAP-1]	||
-		    xfrma[XFRMA_SEC_CTX-1]	||
-		    !xfrma[XFRMA_COADDR-1])
+		if (xfrma[XFRMA_ALG_COMP]	||
+		    xfrma[XFRMA_ALG_AUTH]	||
+		    xfrma[XFRMA_ALG_CRYPT]	||
+		    xfrma[XFRMA_ENCAP]		||
+		    xfrma[XFRMA_SEC_CTX]	||
+		    !xfrma[XFRMA_COADDR])
 			goto out;
 		break;
 #endif
@@ -300,10 +300,10 @@ static void copy_from_user_state(struct 
 */
 static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
 {
-	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
-	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
-	struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1];
-	struct rtattr *rt = xfrma[XFRMA_REPLAY_THRESH-1];
+	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL];
+	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL];
+	struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH];
+	struct rtattr *rt = xfrma[XFRMA_REPLAY_THRESH];
 
 	if (rp) {
 		struct xfrm_replay_state *replay;
@@ -342,25 +342,25 @@ static struct xfrm_state *xfrm_state_con
 
 	if ((err = attach_one_algo(&x->aalg, &x->props.aalgo,
 				   xfrm_aalg_get_byname,
-				   xfrma[XFRMA_ALG_AUTH-1])))
+				   xfrma[XFRMA_ALG_AUTH])))
 		goto error;
 	if ((err = attach_one_algo(&x->ealg, &x->props.ealgo,
 				   xfrm_ealg_get_byname,
-				   xfrma[XFRMA_ALG_CRYPT-1])))
+				   xfrma[XFRMA_ALG_CRYPT])))
 		goto error;
 	if ((err = attach_one_algo(&x->calg, &x->props.calgo,
 				   xfrm_calg_get_byname,
-				   xfrma[XFRMA_ALG_COMP-1])))
+				   xfrma[XFRMA_ALG_COMP])))
 		goto error;
-	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
+	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP])))
 		goto error;
-	if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_COADDR-1])))
+	if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_COADDR])))
 		goto error;
 	err = xfrm_init_state(x);
 	if (err)
 		goto error;
 
-	if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
+	if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX])))
 		goto error;
 
 	x->km.seq = p->seq;
@@ -917,7 +917,7 @@ static int verify_newpolicy_info(struct 
 
 static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
 {
-	struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
@@ -985,7 +985,7 @@ static int validate_tmpl(int nr, struct 
 
 static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
 {
-	struct rtattr *rt = xfrma[XFRMA_TMPL-1];
+	struct rtattr *rt = xfrma[XFRMA_TMPL];
 
 	if (!rt) {
 		pol->xfrm_nr = 0;
@@ -1005,7 +1005,7 @@ static int copy_from_user_tmpl(struct xf
 
 static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma)
 {
-	struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE-1];
+	struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE];
 	struct xfrm_userpolicy_type *upt;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
@@ -1294,7 +1294,7 @@ static int xfrm_get_policy(struct sk_buf
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
 	else {
-		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+		struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
 		err = verify_sec_ctx_len(xfrma);
@@ -1455,8 +1455,8 @@ static int xfrm_new_ae(struct sk_buff *s
 	struct km_event c;
 	int err = - EINVAL;
 	struct xfrm_aevent_id *p = nlmsg_data(nlh);
-	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
-	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
+	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL];
+	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL];
 
 	if (!lt && !rp)
 		return err;
@@ -1528,7 +1528,7 @@ static int xfrm_add_pol_expire(struct sk
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
 	else {
-		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+		struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
 		err = verify_sec_ctx_len(xfrma);
@@ -1611,7 +1611,7 @@ static int xfrm_add_acquire(struct sk_bu
 	struct xfrm_policy *xp;
 	struct xfrm_user_tmpl *ut;
 	int i;
-	struct rtattr *rt = xfrma[XFRMA_TMPL-1];
+	struct rtattr *rt = xfrma[XFRMA_TMPL];
 
 	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
 	struct xfrm_state *x = xfrm_state_alloc();
@@ -1663,7 +1663,7 @@ static int xfrm_add_acquire(struct sk_bu
 static int copy_from_user_migrate(struct xfrm_migrate *ma,
 				  struct rtattr **xfrma, int *num)
 {
-	struct rtattr *rt = xfrma[XFRMA_MIGRATE-1];
+	struct rtattr *rt = xfrma[XFRMA_MIGRATE];
 	struct xfrm_user_migrate *um;
 	int i, num_migrate;
 
@@ -1700,7 +1700,7 @@ static int xfrm_do_migrate(struct sk_buf
 	int err;
 	int n = 0;
 
-	if (xfrma[XFRMA_MIGRATE-1] == NULL)
+	if (xfrma[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
 
 	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
@@ -1906,9 +1906,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL);
 	}
 
-	/* FIXME: Temporary hack, nlmsg_parse() starts at xfrma[1], old code
-	 * expects first attribute at xfrma[0] */
-	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX,
+	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma, XFRMA_MAX,
 			  xfrma_policy);
 	if (err < 0)
 		return err;

-- 


^ permalink raw reply

* [PATCH 12/16] [XFRM] netlink: Rename attribyte array from xfrma[] to attrs[]
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrma_rename --]
[-- Type: text/plain, Size: 17424 bytes --]

Increases readability a lot.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:34:10.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:34:29.000000000 +0200
@@ -38,9 +38,9 @@ static inline int alg_len(struct xfrm_al
 	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
 }
 
-static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
+static int verify_one_alg(struct rtattr **attrs, enum xfrm_attr_type_t type)
 {
-	struct rtattr *rt = xfrma[type];
+	struct rtattr *rt = attrs[type];
 	struct xfrm_algo *algp;
 
 	if (!rt)
@@ -75,18 +75,18 @@ static int verify_one_alg(struct rtattr 
 	return 0;
 }
 
-static void verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
+static void verify_one_addr(struct rtattr **attrs, enum xfrm_attr_type_t type,
 			   xfrm_address_t **addrp)
 {
-	struct rtattr *rt = xfrma[type];
+	struct rtattr *rt = attrs[type];
 
 	if (rt && addrp)
 		*addrp = RTA_DATA(rt);
 }
 
-static inline int verify_sec_ctx_len(struct rtattr **xfrma)
+static inline int verify_sec_ctx_len(struct rtattr **attrs)
 {
-	struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
+	struct rtattr *rt = attrs[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
@@ -101,7 +101,7 @@ static inline int verify_sec_ctx_len(str
 
 
 static int verify_newsa_info(struct xfrm_usersa_info *p,
-			     struct rtattr **xfrma)
+			     struct rtattr **attrs)
 {
 	int err;
 
@@ -125,35 +125,35 @@ static int verify_newsa_info(struct xfrm
 	err = -EINVAL;
 	switch (p->id.proto) {
 	case IPPROTO_AH:
-		if (!xfrma[XFRMA_ALG_AUTH]	||
-		    xfrma[XFRMA_ALG_CRYPT]	||
-		    xfrma[XFRMA_ALG_COMP])
+		if (!attrs[XFRMA_ALG_AUTH]	||
+		    attrs[XFRMA_ALG_CRYPT]	||
+		    attrs[XFRMA_ALG_COMP])
 			goto out;
 		break;
 
 	case IPPROTO_ESP:
-		if ((!xfrma[XFRMA_ALG_AUTH] &&
-		     !xfrma[XFRMA_ALG_CRYPT])	||
-		    xfrma[XFRMA_ALG_COMP])
+		if ((!attrs[XFRMA_ALG_AUTH] &&
+		     !attrs[XFRMA_ALG_CRYPT])	||
+		    attrs[XFRMA_ALG_COMP])
 			goto out;
 		break;
 
 	case IPPROTO_COMP:
-		if (!xfrma[XFRMA_ALG_COMP]	||
-		    xfrma[XFRMA_ALG_AUTH]	||
-		    xfrma[XFRMA_ALG_CRYPT])
+		if (!attrs[XFRMA_ALG_COMP]	||
+		    attrs[XFRMA_ALG_AUTH]	||
+		    attrs[XFRMA_ALG_CRYPT])
 			goto out;
 		break;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case IPPROTO_DSTOPTS:
 	case IPPROTO_ROUTING:
-		if (xfrma[XFRMA_ALG_COMP]	||
-		    xfrma[XFRMA_ALG_AUTH]	||
-		    xfrma[XFRMA_ALG_CRYPT]	||
-		    xfrma[XFRMA_ENCAP]		||
-		    xfrma[XFRMA_SEC_CTX]	||
-		    !xfrma[XFRMA_COADDR])
+		if (attrs[XFRMA_ALG_COMP]	||
+		    attrs[XFRMA_ALG_AUTH]	||
+		    attrs[XFRMA_ALG_CRYPT]	||
+		    attrs[XFRMA_ENCAP]		||
+		    attrs[XFRMA_SEC_CTX]	||
+		    !attrs[XFRMA_COADDR])
 			goto out;
 		break;
 #endif
@@ -162,13 +162,13 @@ static int verify_newsa_info(struct xfrm
 		goto out;
 	}
 
-	if ((err = verify_one_alg(xfrma, XFRMA_ALG_AUTH)))
+	if ((err = verify_one_alg(attrs, XFRMA_ALG_AUTH)))
 		goto out;
-	if ((err = verify_one_alg(xfrma, XFRMA_ALG_CRYPT)))
+	if ((err = verify_one_alg(attrs, XFRMA_ALG_CRYPT)))
 		goto out;
-	if ((err = verify_one_alg(xfrma, XFRMA_ALG_COMP)))
+	if ((err = verify_one_alg(attrs, XFRMA_ALG_COMP)))
 		goto out;
-	if ((err = verify_sec_ctx_len(xfrma)))
+	if ((err = verify_sec_ctx_len(attrs)))
 		goto out;
 
 	err = -EINVAL;
@@ -298,12 +298,12 @@ static void copy_from_user_state(struct 
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **attrs)
 {
-	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL];
-	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL];
-	struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH];
-	struct rtattr *rt = xfrma[XFRMA_REPLAY_THRESH];
+	struct rtattr *rp = attrs[XFRMA_REPLAY_VAL];
+	struct rtattr *lt = attrs[XFRMA_LTIME_VAL];
+	struct rtattr *et = attrs[XFRMA_ETIMER_THRESH];
+	struct rtattr *rt = attrs[XFRMA_REPLAY_THRESH];
 
 	if (rp) {
 		struct xfrm_replay_state *replay;
@@ -329,7 +329,7 @@ static void xfrm_update_ae_params(struct
 }
 
 static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
-					       struct rtattr **xfrma,
+					       struct rtattr **attrs,
 					       int *errp)
 {
 	struct xfrm_state *x = xfrm_state_alloc();
@@ -342,25 +342,25 @@ static struct xfrm_state *xfrm_state_con
 
 	if ((err = attach_one_algo(&x->aalg, &x->props.aalgo,
 				   xfrm_aalg_get_byname,
-				   xfrma[XFRMA_ALG_AUTH])))
+				   attrs[XFRMA_ALG_AUTH])))
 		goto error;
 	if ((err = attach_one_algo(&x->ealg, &x->props.ealgo,
 				   xfrm_ealg_get_byname,
-				   xfrma[XFRMA_ALG_CRYPT])))
+				   attrs[XFRMA_ALG_CRYPT])))
 		goto error;
 	if ((err = attach_one_algo(&x->calg, &x->props.calgo,
 				   xfrm_calg_get_byname,
-				   xfrma[XFRMA_ALG_COMP])))
+				   attrs[XFRMA_ALG_COMP])))
 		goto error;
-	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP])))
+	if ((err = attach_encap_tmpl(&x->encap, attrs[XFRMA_ENCAP])))
 		goto error;
-	if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_COADDR])))
+	if ((err = attach_one_addr(&x->coaddr, attrs[XFRMA_COADDR])))
 		goto error;
 	err = xfrm_init_state(x);
 	if (err)
 		goto error;
 
-	if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX])))
+	if ((err = attach_sec_ctx(x, attrs[XFRMA_SEC_CTX])))
 		goto error;
 
 	x->km.seq = p->seq;
@@ -373,7 +373,7 @@ static struct xfrm_state *xfrm_state_con
 
 	/* override default values from above */
 
-	xfrm_update_ae_params(x, (struct rtattr **)xfrma);
+	xfrm_update_ae_params(x, (struct rtattr **)attrs);
 
 	return x;
 
@@ -386,18 +386,18 @@ error_no_put:
 }
 
 static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_usersa_info *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	int err;
 	struct km_event c;
 
-	err = verify_newsa_info(p, xfrma);
+	err = verify_newsa_info(p, attrs);
 	if (err)
 		return err;
 
-	x = xfrm_state_construct(p, xfrma, &err);
+	x = xfrm_state_construct(p, attrs, &err);
 	if (!x)
 		return err;
 
@@ -427,7 +427,7 @@ out:
 }
 
 static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
-						 struct rtattr **xfrma,
+						 struct rtattr **attrs,
 						 int *errp)
 {
 	struct xfrm_state *x = NULL;
@@ -439,7 +439,7 @@ static struct xfrm_state *xfrm_user_stat
 	} else {
 		xfrm_address_t *saddr = NULL;
 
-		verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr);
+		verify_one_addr(attrs, XFRMA_SRCADDR, &saddr);
 		if (!saddr) {
 			err = -EINVAL;
 			goto out;
@@ -457,14 +457,14 @@ static struct xfrm_state *xfrm_user_stat
 }
 
 static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_state *x;
 	int err = -ESRCH;
 	struct km_event c;
 	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 
-	x = xfrm_user_state_lookup(p, xfrma, &err);
+	x = xfrm_user_state_lookup(p, attrs, &err);
 	if (x == NULL)
 		return err;
 
@@ -669,7 +669,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
@@ -722,7 +722,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct sk_buff *r_skb;
 	u32 *flags = nlmsg_data(nlh);
@@ -740,14 +740,14 @@ static int xfrm_get_sadinfo(struct sk_bu
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_usersa_id *p = nlmsg_data(nlh);
 	struct xfrm_state *x;
 	struct sk_buff *resp_skb;
 	int err = -ESRCH;
 
-	x = xfrm_user_state_lookup(p, xfrma, &err);
+	x = xfrm_user_state_lookup(p, attrs, &err);
 	if (x == NULL)
 		goto out_noput;
 
@@ -786,7 +786,7 @@ static int verify_userspi_info(struct xf
 }
 
 static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
@@ -915,9 +915,9 @@ static int verify_newpolicy_info(struct 
 	return verify_policy_dir(p->dir);
 }
 
-static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
+static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **attrs)
 {
-	struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
+	struct rtattr *rt = attrs[XFRMA_SEC_CTX];
 	struct xfrm_user_sec_ctx *uctx;
 
 	if (!rt)
@@ -983,9 +983,9 @@ static int validate_tmpl(int nr, struct 
 	return 0;
 }
 
-static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
+static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **attrs)
 {
-	struct rtattr *rt = xfrma[XFRMA_TMPL];
+	struct rtattr *rt = attrs[XFRMA_TMPL];
 
 	if (!rt) {
 		pol->xfrm_nr = 0;
@@ -1003,9 +1003,9 @@ static int copy_from_user_tmpl(struct xf
 	return 0;
 }
 
-static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma)
+static int copy_from_user_policy_type(u8 *tp, struct rtattr **attrs)
 {
-	struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE];
+	struct rtattr *rt = attrs[XFRMA_POLICY_TYPE];
 	struct xfrm_userpolicy_type *upt;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
@@ -1049,7 +1049,7 @@ static void copy_to_user_policy(struct x
 	p->share = XFRM_SHARE_ANY; /* XXX xp->share */
 }
 
-static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct rtattr **xfrma, int *errp)
+static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, struct rtattr **attrs, int *errp)
 {
 	struct xfrm_policy *xp = xfrm_policy_alloc(GFP_KERNEL);
 	int err;
@@ -1061,12 +1061,12 @@ static struct xfrm_policy *xfrm_policy_c
 
 	copy_from_user_policy(xp, p);
 
-	err = copy_from_user_policy_type(&xp->type, xfrma);
+	err = copy_from_user_policy_type(&xp->type, attrs);
 	if (err)
 		goto error;
 
-	if (!(err = copy_from_user_tmpl(xp, xfrma)))
-		err = copy_from_user_sec_ctx(xp, xfrma);
+	if (!(err = copy_from_user_tmpl(xp, attrs)))
+		err = copy_from_user_sec_ctx(xp, attrs);
 	if (err)
 		goto error;
 
@@ -1078,7 +1078,7 @@ static struct xfrm_policy *xfrm_policy_c
 }
 
 static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
 	struct xfrm_policy *xp;
@@ -1089,11 +1089,11 @@ static int xfrm_add_policy(struct sk_buf
 	err = verify_newpolicy_info(p);
 	if (err)
 		return err;
-	err = verify_sec_ctx_len(xfrma);
+	err = verify_sec_ctx_len(attrs);
 	if (err)
 		return err;
 
-	xp = xfrm_policy_construct(p, xfrma, &err);
+	xp = xfrm_policy_construct(p, attrs, &err);
 	if (!xp)
 		return err;
 
@@ -1271,7 +1271,7 @@ static struct sk_buff *xfrm_policy_netli
 }
 
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
@@ -1283,7 +1283,7 @@ static int xfrm_get_policy(struct sk_buf
 	p = nlmsg_data(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
 
-	err = copy_from_user_policy_type(&type, xfrma);
+	err = copy_from_user_policy_type(&type, attrs);
 	if (err)
 		return err;
 
@@ -1294,10 +1294,10 @@ static int xfrm_get_policy(struct sk_buf
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
 	else {
-		struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
+		struct rtattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
-		err = verify_sec_ctx_len(xfrma);
+		err = verify_sec_ctx_len(attrs);
 		if (err)
 			return err;
 
@@ -1345,7 +1345,7 @@ out:
 }
 
 static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct km_event c;
 	struct xfrm_usersa_flush *p = nlmsg_data(nlh);
@@ -1411,7 +1411,7 @@ nla_put_failure:
 }
 
 static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_state *x;
 	struct sk_buff *r_skb;
@@ -1449,14 +1449,14 @@ static int xfrm_get_ae(struct sk_buff *s
 }
 
 static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_state *x;
 	struct km_event c;
 	int err = - EINVAL;
 	struct xfrm_aevent_id *p = nlmsg_data(nlh);
-	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL];
-	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL];
+	struct rtattr *rp = attrs[XFRMA_REPLAY_VAL];
+	struct rtattr *lt = attrs[XFRMA_LTIME_VAL];
 
 	if (!lt && !rp)
 		return err;
@@ -1473,7 +1473,7 @@ static int xfrm_new_ae(struct sk_buff *s
 		goto out;
 
 	spin_lock_bh(&x->lock);
-	xfrm_update_ae_params(x, xfrma);
+	xfrm_update_ae_params(x, attrs);
 	spin_unlock_bh(&x->lock);
 
 	c.event = nlh->nlmsg_type;
@@ -1488,14 +1488,14 @@ out:
 }
 
 static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct km_event c;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
 	struct xfrm_audit audit_info;
 
-	err = copy_from_user_policy_type(&type, xfrma);
+	err = copy_from_user_policy_type(&type, attrs);
 	if (err)
 		return err;
 
@@ -1513,7 +1513,7 @@ static int xfrm_flush_policy(struct sk_b
 }
 
 static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_user_polexpire *up = nlmsg_data(nlh);
@@ -1521,17 +1521,17 @@ static int xfrm_add_pol_expire(struct sk
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err = -ENOENT;
 
-	err = copy_from_user_policy_type(&type, xfrma);
+	err = copy_from_user_policy_type(&type, attrs);
 	if (err)
 		return err;
 
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
 	else {
-		struct rtattr *rt = xfrma[XFRMA_SEC_CTX];
+		struct rtattr *rt = attrs[XFRMA_SEC_CTX];
 		struct xfrm_policy tmp;
 
-		err = verify_sec_ctx_len(xfrma);
+		err = verify_sec_ctx_len(attrs);
 		if (err)
 			return err;
 
@@ -1574,7 +1574,7 @@ out:
 }
 
 static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_state *x;
 	int err;
@@ -1606,12 +1606,12 @@ out:
 }
 
 static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
-		struct rtattr **xfrma)
+		struct rtattr **attrs)
 {
 	struct xfrm_policy *xp;
 	struct xfrm_user_tmpl *ut;
 	int i;
-	struct rtattr *rt = xfrma[XFRMA_TMPL];
+	struct rtattr *rt = attrs[XFRMA_TMPL];
 
 	struct xfrm_user_acquire *ua = nlmsg_data(nlh);
 	struct xfrm_state *x = xfrm_state_alloc();
@@ -1628,7 +1628,7 @@ static int xfrm_add_acquire(struct sk_bu
 	}
 
 	/*   build an XP */
-	xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err);
+	xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) attrs, &err);
 	if (!xp) {
 		kfree(x);
 		return err;
@@ -1661,9 +1661,9 @@ static int xfrm_add_acquire(struct sk_bu
 
 #ifdef CONFIG_XFRM_MIGRATE
 static int copy_from_user_migrate(struct xfrm_migrate *ma,
-				  struct rtattr **xfrma, int *num)
+				  struct rtattr **attrs, int *num)
 {
-	struct rtattr *rt = xfrma[XFRMA_MIGRATE];
+	struct rtattr *rt = attrs[XFRMA_MIGRATE];
 	struct xfrm_user_migrate *um;
 	int i, num_migrate;
 
@@ -1692,7 +1692,7 @@ static int copy_from_user_migrate(struct
 }
 
 static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
-			   struct rtattr **xfrma)
+			   struct rtattr **attrs)
 {
 	struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
 	struct xfrm_migrate m[XFRM_MAX_DEPTH];
@@ -1700,15 +1700,15 @@ static int xfrm_do_migrate(struct sk_buf
 	int err;
 	int n = 0;
 
-	if (xfrma[XFRMA_MIGRATE] == NULL)
+	if (attrs[XFRMA_MIGRATE] == NULL)
 		return -EINVAL;
 
-	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
+	err = copy_from_user_policy_type(&type, (struct rtattr **)attrs);
 	if (err)
 		return err;
 
 	err = copy_from_user_migrate((struct xfrm_migrate *)m,
-				     (struct rtattr **)xfrma, &n);
+				     (struct rtattr **)attrs, &n);
 	if (err)
 		return err;
 
@@ -1721,7 +1721,7 @@ static int xfrm_do_migrate(struct sk_buf
 }
 #else
 static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
-			   struct rtattr **xfrma)
+			   struct rtattr **attrs)
 {
 	return -ENOPROTOOPT;
 }
@@ -1882,7 +1882,7 @@ static struct xfrm_link {
 
 static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
-	struct nlattr *xfrma[XFRMA_MAX+1];
+	struct nlattr *attrs[XFRMA_MAX+1];
 	struct xfrm_link *link;
 	int type, err;
 
@@ -1906,7 +1906,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL);
 	}
 
-	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma, XFRMA_MAX,
+	err = nlmsg_parse(nlh, xfrm_msg_min[type], attrs, XFRMA_MAX,
 			  xfrma_policy);
 	if (err < 0)
 		return err;
@@ -1914,7 +1914,7 @@ static int xfrm_user_rcv_msg(struct sk_b
 	if (link->doit == NULL)
 		return -EINVAL;
 
-	return link->doit(skb, nlh, (struct rtattr **) xfrma);
+	return link->doit(skb, nlh, (struct rtattr **) attrs);
 }
 
 static void xfrm_netlink_rcv(struct sock *sk, int len)

-- 


^ permalink raw reply

* [PATCH 16/16] [XFRM] netlink: Inline attach_encap_tmpl(), attach_sec_ctx(), and attach_one_addr()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_inline_attach_one_addr --]
[-- Type: text/plain, Size: 2459 bytes --]

These functions are only used once and are a lot easier to understand if
inlined directly into the function.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 23:05:30.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-22 16:45:31.000000000 +0200
@@ -214,23 +214,6 @@ static int attach_one_algo(struct xfrm_a
 	return 0;
 }
 
-static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct nlattr *rta)
-{
-	struct xfrm_encap_tmpl *p, *uencap;
-
-	if (!rta)
-		return 0;
-
-	uencap = nla_data(rta);
-	p = kmemdup(uencap, sizeof(*p), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
-
-	*encapp = p;
-	return 0;
-}
-
-
 static inline int xfrm_user_sec_ctx_size(struct xfrm_sec_ctx *xfrm_ctx)
 {
 	int len = 0;
@@ -242,33 +225,6 @@ static inline int xfrm_user_sec_ctx_size
 	return len;
 }
 
-static int attach_sec_ctx(struct xfrm_state *x, struct nlattr *u_arg)
-{
-	struct xfrm_user_sec_ctx *uctx;
-
-	if (!u_arg)
-		return 0;
-
-	uctx = nla_data(u_arg);
-	return security_xfrm_state_alloc(x, uctx);
-}
-
-static int attach_one_addr(xfrm_address_t **addrpp, struct nlattr *rta)
-{
-	xfrm_address_t *p, *uaddrp;
-
-	if (!rta)
-		return 0;
-
-	uaddrp = nla_data(rta);
-	p = kmemdup(uaddrp, sizeof(*p), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
-
-	*addrpp = p;
-	return 0;
-}
-
 static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
 	memcpy(&x->id, &p->id, sizeof(x->id));
@@ -340,15 +296,27 @@ static struct xfrm_state *xfrm_state_con
 				   xfrm_calg_get_byname,
 				   attrs[XFRMA_ALG_COMP])))
 		goto error;
-	if ((err = attach_encap_tmpl(&x->encap, attrs[XFRMA_ENCAP])))
-		goto error;
-	if ((err = attach_one_addr(&x->coaddr, attrs[XFRMA_COADDR])))
-		goto error;
+
+	if (attrs[XFRMA_ENCAP]) {
+		x->encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]),
+				   sizeof(x->encap), GFP_KERNEL);
+		if (x->encap == NULL)
+			goto error;
+	}
+
+	if (attrs[XFRMA_COADDR]) {
+		x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
+				    sizeof(x->coaddr), GFP_KERNEL);
+		if (x->coaddr == NULL)
+			goto error;
+	}
+
 	err = xfrm_init_state(x);
 	if (err)
 		goto error;
 
-	if ((err = attach_sec_ctx(x, attrs[XFRMA_SEC_CTX])))
+	if (attrs[XFRMA_SEC_CTX] &&
+	    security_xfrm_state_alloc(x, nla_data(attrs[XFRMA_SEC_CTX])))
 		goto error;
 
 	x->km.seq = p->seq;

-- 


^ permalink raw reply

* [PATCH 10/16] [XFRM] netlink: Establish an attribute policy
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_attr_policy --]
[-- Type: text/plain, Size: 7399 bytes --]

Adds a policy defining the minimal payload lengths for all the attributes
allowing for most attribute validation checks to be removed from in
the middle of the code path. Makes updates more consistent as many format
errors are recognised earlier, before any changes have been attempted.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:31:04.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:31:56.000000000 +0200
@@ -42,19 +42,12 @@ static int verify_one_alg(struct rtattr 
 {
 	struct rtattr *rt = xfrma[type - 1];
 	struct xfrm_algo *algp;
-	int len;
 
 	if (!rt)
 		return 0;
 
-	len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp);
-	if (len < 0)
-		return -EINVAL;
-
 	algp = RTA_DATA(rt);
-
-	len -= (algp->alg_key_len + 7U) / 8;
-	if (len < 0)
+	if (RTA_PAYLOAD(rt) < alg_len(algp))
 		return -EINVAL;
 
 	switch (type) {
@@ -82,55 +75,25 @@ static int verify_one_alg(struct rtattr 
 	return 0;
 }
 
-static int verify_encap_tmpl(struct rtattr **xfrma)
-{
-	struct rtattr *rt = xfrma[XFRMA_ENCAP - 1];
-	struct xfrm_encap_tmpl *encap;
-
-	if (!rt)
-		return 0;
-
-	if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap))
-		return -EINVAL;
-
-	return 0;
-}
-
-static int verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
+static void verify_one_addr(struct rtattr **xfrma, enum xfrm_attr_type_t type,
 			   xfrm_address_t **addrp)
 {
 	struct rtattr *rt = xfrma[type - 1];
 
-	if (!rt)
-		return 0;
-
-	if ((rt->rta_len - sizeof(*rt)) < sizeof(**addrp))
-		return -EINVAL;
-
-	if (addrp)
+	if (rt && addrp)
 		*addrp = RTA_DATA(rt);
-
-	return 0;
 }
 
 static inline int verify_sec_ctx_len(struct rtattr **xfrma)
 {
 	struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
 	struct xfrm_user_sec_ctx *uctx;
-	int len = 0;
 
 	if (!rt)
 		return 0;
 
-	if (rt->rta_len < sizeof(*uctx))
-		return -EINVAL;
-
 	uctx = RTA_DATA(rt);
-
-	len += sizeof(struct xfrm_user_sec_ctx);
-	len += uctx->ctx_len;
-
-	if (uctx->len != len)
+	if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
 		return -EINVAL;
 
 	return 0;
@@ -205,12 +168,8 @@ static int verify_newsa_info(struct xfrm
 		goto out;
 	if ((err = verify_one_alg(xfrma, XFRMA_ALG_COMP)))
 		goto out;
-	if ((err = verify_encap_tmpl(xfrma)))
-		goto out;
 	if ((err = verify_sec_ctx_len(xfrma)))
 		goto out;
-	if ((err = verify_one_addr(xfrma, XFRMA_COADDR, NULL)))
-		goto out;
 
 	err = -EINVAL;
 	switch (p->mode) {
@@ -339,9 +298,8 @@ static void copy_from_user_state(struct 
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static int xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct rtattr **xfrma)
 {
-	int err = - EINVAL;
 	struct rtattr *rp = xfrma[XFRMA_REPLAY_VAL-1];
 	struct rtattr *lt = xfrma[XFRMA_LTIME_VAL-1];
 	struct rtattr *et = xfrma[XFRMA_ETIMER_THRESH-1];
@@ -349,8 +307,6 @@ static int xfrm_update_ae_params(struct 
 
 	if (rp) {
 		struct xfrm_replay_state *replay;
-		if (RTA_PAYLOAD(rp) < sizeof(*replay))
-			goto error;
 		replay = RTA_DATA(rp);
 		memcpy(&x->replay, replay, sizeof(*replay));
 		memcpy(&x->preplay, replay, sizeof(*replay));
@@ -358,8 +314,6 @@ static int xfrm_update_ae_params(struct 
 
 	if (lt) {
 		struct xfrm_lifetime_cur *ltime;
-		if (RTA_PAYLOAD(lt) < sizeof(*ltime))
-			goto error;
 		ltime = RTA_DATA(lt);
 		x->curlft.bytes = ltime->bytes;
 		x->curlft.packets = ltime->packets;
@@ -367,21 +321,11 @@ static int xfrm_update_ae_params(struct 
 		x->curlft.use_time = ltime->use_time;
 	}
 
-	if (et) {
-		if (RTA_PAYLOAD(et) < sizeof(u32))
-			goto error;
+	if (et)
 		x->replay_maxage = *(u32*)RTA_DATA(et);
-	}
 
-	if (rt) {
-		if (RTA_PAYLOAD(rt) < sizeof(u32))
-			goto error;
+	if (rt)
 		x->replay_maxdiff = *(u32*)RTA_DATA(rt);
-	}
-
-	return 0;
-error:
-	return err;
 }
 
 static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
@@ -429,9 +373,7 @@ static struct xfrm_state *xfrm_state_con
 
 	/* override default values from above */
 
-	err = xfrm_update_ae_params(x, (struct rtattr **)xfrma);
-	if (err	< 0)
-		goto error;
+	xfrm_update_ae_params(x, (struct rtattr **)xfrma);
 
 	return x;
 
@@ -497,10 +439,7 @@ static struct xfrm_state *xfrm_user_stat
 	} else {
 		xfrm_address_t *saddr = NULL;
 
-		err = verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr);
-		if (err)
-			goto out;
-
+		verify_one_addr(xfrma, XFRMA_SRCADDR, &saddr);
 		if (!saddr) {
 			err = -EINVAL;
 			goto out;
@@ -1072,9 +1011,6 @@ static int copy_from_user_policy_type(u8
 	int err;
 
 	if (rt) {
-		if (rt->rta_len < sizeof(*upt))
-			return -EINVAL;
-
 		upt = RTA_DATA(rt);
 		type = upt->type;
 	}
@@ -1537,10 +1473,8 @@ static int xfrm_new_ae(struct sk_buff *s
 		goto out;
 
 	spin_lock_bh(&x->lock);
-	err = xfrm_update_ae_params(x, xfrma);
+	xfrm_update_ae_params(x, xfrma);
 	spin_unlock_bh(&x->lock);
-	if (err	< 0)
-		goto out;
 
 	c.event = nlh->nlmsg_type;
 	c.seq = nlh->nlmsg_seq;
@@ -1726,20 +1660,6 @@ static int xfrm_add_acquire(struct sk_bu
 }
 
 #ifdef CONFIG_XFRM_MIGRATE
-static int verify_user_migrate(struct rtattr **xfrma)
-{
-	struct rtattr *rt = xfrma[XFRMA_MIGRATE-1];
-	struct xfrm_user_migrate *um;
-
-	if (!rt)
-		return -EINVAL;
-
-	if ((rt->rta_len - sizeof(*rt)) < sizeof(*um))
-		return -EINVAL;
-
-	return 0;
-}
-
 static int copy_from_user_migrate(struct xfrm_migrate *ma,
 				  struct rtattr **xfrma, int *num)
 {
@@ -1780,9 +1700,8 @@ static int xfrm_do_migrate(struct sk_buf
 	int err;
 	int n = 0;
 
-	err = verify_user_migrate((struct rtattr **)xfrma);
-	if (err)
-		return err;
+	if (xfrma[XFRMA_MIGRATE-1] == NULL)
+		return -EINVAL;
 
 	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
 	if (err)
@@ -1917,6 +1836,23 @@ static const int xfrm_msg_min[XFRM_NR_MS
 
 #undef XMSGSIZE
 
+static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
+	[XFRMA_ALG_AUTH]	= { .len = sizeof(struct xfrm_algo) },
+	[XFRMA_ALG_CRYPT]	= { .len = sizeof(struct xfrm_algo) },
+	[XFRMA_ALG_COMP]	= { .len = sizeof(struct xfrm_algo) },
+	[XFRMA_ENCAP]		= { .len = sizeof(struct xfrm_encap_tmpl) },
+	[XFRMA_TMPL]		= { .len = sizeof(struct xfrm_user_tmpl) },
+	[XFRMA_SEC_CTX]		= { .len = sizeof(struct xfrm_sec_ctx) },
+	[XFRMA_LTIME_VAL]	= { .len = sizeof(struct xfrm_lifetime_cur) },
+	[XFRMA_REPLAY_VAL]	= { .len = sizeof(struct xfrm_replay_state) },
+	[XFRMA_REPLAY_THRESH]	= { .type = NLA_U32 },
+	[XFRMA_ETIMER_THRESH]	= { .type = NLA_U32 },
+	[XFRMA_SRCADDR]		= { .len = sizeof(xfrm_address_t) },
+	[XFRMA_COADDR]		= { .len = sizeof(xfrm_address_t) },
+	[XFRMA_POLICY_TYPE]	= { .len = sizeof(struct xfrm_userpolicy_type)},
+	[XFRMA_MIGRATE]		= { .len = sizeof(struct xfrm_user_migrate) },
+};
+
 static struct xfrm_link {
 	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **);
 	int (*dump)(struct sk_buff *, struct netlink_callback *);
@@ -1972,7 +1908,8 @@ static int xfrm_user_rcv_msg(struct sk_b
 
 	/* FIXME: Temporary hack, nlmsg_parse() starts at xfrma[1], old code
 	 * expects first attribute at xfrma[0] */
-	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX, NULL);
+	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX,
+			  xfrma_policy);
 	if (err < 0)
 		return err;
 

-- 


^ permalink raw reply

* [PATCH 06/16] [XFRM] netlink: Move algorithm length calculation to its own function
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_alg_key_len --]
[-- Type: text/plain, Size: 2578 bytes --]

Adds alg_len() to calculate the properly padded length of an
algorithm attribute to simplify the code.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 16:16:03.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:03:43.000000000 +0200
@@ -33,6 +33,11 @@
 #endif
 #include <linux/audit.h>
 
+static inline int alg_len(struct xfrm_algo *alg)
+{
+	return sizeof(*alg) + ((alg->alg_key_len + 7) / 8);
+}
+
 static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
 {
 	struct rtattr *rt = xfrma[type - 1];
@@ -232,7 +237,6 @@ static int attach_one_algo(struct xfrm_a
 	struct rtattr *rta = u_arg;
 	struct xfrm_algo *p, *ualg;
 	struct xfrm_algo_desc *algo;
-	int len;
 
 	if (!rta)
 		return 0;
@@ -244,8 +248,7 @@ static int attach_one_algo(struct xfrm_a
 		return -ENOSYS;
 	*props = algo->desc.sadb_alg_id;
 
-	len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8;
-	p = kmemdup(ualg, len, GFP_KERNEL);
+	p = kmemdup(ualg, alg_len(ualg), GFP_KERNEL);
 	if (!p)
 		return -ENOMEM;
 
@@ -617,11 +620,9 @@ static int dump_one_state(struct xfrm_st
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
-		NLA_PUT(skb, XFRMA_ALG_AUTH,
-			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
+		NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg);
 	if (x->ealg)
-		NLA_PUT(skb, XFRMA_ALG_CRYPT,
-			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
+		NLA_PUT(skb, XFRMA_ALG_CRYPT, alg_len(x->ealg), x->ealg);
 	if (x->calg)
 		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
 
@@ -2072,9 +2073,9 @@ static inline int xfrm_sa_len(struct xfr
 {
 	int l = 0;
 	if (x->aalg)
-		l += RTA_SPACE(sizeof(*x->aalg) + (x->aalg->alg_key_len+7)/8);
+		l += RTA_SPACE(alg_len(x->aalg));
 	if (x->ealg)
-		l += RTA_SPACE(sizeof(*x->ealg) + (x->ealg->alg_key_len+7)/8);
+		l += RTA_SPACE(alg_len(x->ealg));
 	if (x->calg)
 		l += RTA_SPACE(sizeof(*x->calg));
 	if (x->encap)
@@ -2127,11 +2128,9 @@ static int xfrm_notify_sa(struct xfrm_st
 	copy_to_user_state(x, p);
 
 	if (x->aalg)
-		NLA_PUT(skb, XFRMA_ALG_AUTH,
-			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
+		NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg);
 	if (x->ealg)
-		NLA_PUT(skb, XFRMA_ALG_CRYPT,
-			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
+		NLA_PUT(skb, XFRMA_ALG_CRYPT, alg_len(x->ealg), x->ealg);
 	if (x->calg)
 		NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
 

-- 


^ permalink raw reply

* [PATCH 08/16] [XFRM] netlink: Use nlmsg_new() and type-safe size calculation helpers
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: nlmsg_new --]
[-- Type: text/plain, Size: 11059 bytes --]

Moves all complex message size calculation into own inlined helper
functions and makes use of the type-safe netlink interface.

Using nlmsg_new() simplifies the calculation itself as it takes care
of the netlink header length by itself.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:04:46.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:07:38.000000000 +0200
@@ -670,7 +670,7 @@ static struct sk_buff *xfrm_state_netlin
 	struct xfrm_dump_info info;
 	struct sk_buff *skb;
 
-	skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
 	if (!skb)
 		return ERR_PTR(-ENOMEM);
 
@@ -688,6 +688,13 @@ static struct sk_buff *xfrm_state_netlin
 	return skb;
 }
 
+static inline size_t xfrm_spdinfo_msgsize(void)
+{
+	return NLMSG_ALIGN(4)
+	       + nla_total_size(sizeof(struct xfrmu_spdinfo))
+	       + nla_total_size(sizeof(struct xfrmu_spdhinfo));
+}
+
 static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags)
 {
 	struct xfrmk_spdinfo si;
@@ -729,12 +736,8 @@ static int xfrm_get_spdinfo(struct sk_bu
 	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
 	u32 seq = nlh->nlmsg_seq;
-	int len = NLMSG_LENGTH(sizeof(u32));
 
-	len += RTA_SPACE(sizeof(struct xfrmu_spdinfo));
-	len += RTA_SPACE(sizeof(struct xfrmu_spdhinfo));
-
-	r_skb = alloc_skb(len, GFP_ATOMIC);
+	r_skb = nlmsg_new(xfrm_spdinfo_msgsize(), GFP_ATOMIC);
 	if (r_skb == NULL)
 		return -ENOMEM;
 
@@ -744,6 +747,13 @@ static int xfrm_get_spdinfo(struct sk_bu
 	return nlmsg_unicast(xfrm_nl, r_skb, spid);
 }
 
+static inline size_t xfrm_sadinfo_msgsize(void)
+{
+	return NLMSG_ALIGN(4)
+	       + nla_total_size(sizeof(struct xfrmu_sadhinfo))
+	       + nla_total_size(4); /* XFRMA_SAD_CNT */
+}
+
 static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags)
 {
 	struct xfrmk_sadinfo si;
@@ -779,13 +789,8 @@ static int xfrm_get_sadinfo(struct sk_bu
 	u32 *flags = nlmsg_data(nlh);
 	u32 spid = NETLINK_CB(skb).pid;
 	u32 seq = nlh->nlmsg_seq;
-	int len = NLMSG_LENGTH(sizeof(u32));
-
-	len += RTA_SPACE(sizeof(struct xfrmu_sadhinfo));
-	len += RTA_SPACE(sizeof(u32));
-
-	r_skb = alloc_skb(len, GFP_ATOMIC);
 
+	r_skb = nlmsg_new(xfrm_sadinfo_msgsize(), GFP_ATOMIC);
 	if (r_skb == NULL)
 		return -ENOMEM;
 
@@ -1311,7 +1316,7 @@ static struct sk_buff *xfrm_policy_netli
 	struct xfrm_dump_info info;
 	struct sk_buff *skb;
 
-	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!skb)
 		return ERR_PTR(-ENOMEM);
 
@@ -1425,6 +1430,14 @@ static int xfrm_flush_sa(struct sk_buff 
 	return 0;
 }
 
+static inline size_t xfrm_aevent_msgsize(void)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_aevent_id))
+	       + nla_total_size(sizeof(struct xfrm_replay_state))
+	       + nla_total_size(sizeof(struct xfrm_lifetime_cur))
+	       + nla_total_size(4) /* XFRM_AE_RTHR */
+	       + nla_total_size(4); /* XFRM_AE_ETHR */
+}
 
 static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
 {
@@ -1469,19 +1482,9 @@ static int xfrm_get_ae(struct sk_buff *s
 	int err;
 	struct km_event c;
 	struct xfrm_aevent_id *p = nlmsg_data(nlh);
-	int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
 	struct xfrm_usersa_id *id = &p->sa_id;
 
-	len += RTA_SPACE(sizeof(struct xfrm_replay_state));
-	len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
-
-	if (p->flags&XFRM_AE_RTHR)
-		len+=RTA_SPACE(sizeof(u32));
-
-	if (p->flags&XFRM_AE_ETHR)
-		len+=RTA_SPACE(sizeof(u32));
-
-	r_skb = alloc_skb(len, GFP_ATOMIC);
+	r_skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
 	if (r_skb == NULL)
 		return -ENOMEM;
 
@@ -1824,6 +1827,13 @@ static int copy_to_user_migrate(struct x
 	return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
 }
 
+static inline size_t xfrm_migrate_msgsize(int num_migrate)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
+	       + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
+	       + userpolicy_type_attrsize();
+}
+
 static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
 			 int num_migrate, struct xfrm_selector *sel,
 			 u8 dir, u8 type)
@@ -1861,12 +1871,8 @@ static int xfrm_send_migrate(struct xfrm
 			     struct xfrm_migrate *m, int num_migrate)
 {
 	struct sk_buff *skb;
-	size_t len;
 
-	len = RTA_SPACE(sizeof(struct xfrm_user_migrate) * num_migrate);
-	len += NLMSG_SPACE(sizeof(struct xfrm_userpolicy_id));
-	len += userpolicy_type_attrsize();
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2002,6 +2008,11 @@ static void xfrm_netlink_rcv(struct sock
 	} while (qlen);
 }
 
+static inline size_t xfrm_expire_msgsize(void)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_user_expire));
+}
+
 static int build_expire(struct sk_buff *skb, struct xfrm_state *x, struct km_event *c)
 {
 	struct xfrm_user_expire *ue;
@@ -2021,9 +2032,8 @@ static int build_expire(struct sk_buff *
 static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 {
 	struct sk_buff *skb;
-	int len = NLMSG_LENGTH(sizeof(struct xfrm_user_expire));
 
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_expire_msgsize(), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2036,11 +2046,8 @@ static int xfrm_exp_state_notify(struct 
 static int xfrm_aevent_state_notify(struct xfrm_state *x, struct km_event *c)
 {
 	struct sk_buff *skb;
-	int len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
 
-	len += RTA_SPACE(sizeof(struct xfrm_replay_state));
-	len += RTA_SPACE(sizeof(struct xfrm_lifetime_cur));
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_aevent_msgsize(), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2055,9 +2062,9 @@ static int xfrm_notify_sa_flush(struct k
 	struct xfrm_usersa_flush *p;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	int len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush));
+	int len = NLMSG_ALIGN(sizeof(struct xfrm_usersa_flush));
 
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2075,17 +2082,17 @@ static int xfrm_notify_sa_flush(struct k
 	return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
 }
 
-static inline int xfrm_sa_len(struct xfrm_state *x)
+static inline size_t xfrm_sa_len(struct xfrm_state *x)
 {
-	int l = 0;
+	size_t l = 0;
 	if (x->aalg)
-		l += RTA_SPACE(alg_len(x->aalg));
+		l += nla_total_size(alg_len(x->aalg));
 	if (x->ealg)
-		l += RTA_SPACE(alg_len(x->ealg));
+		l += nla_total_size(alg_len(x->ealg));
 	if (x->calg)
-		l += RTA_SPACE(sizeof(*x->calg));
+		l += nla_total_size(sizeof(*x->calg));
 	if (x->encap)
-		l += RTA_SPACE(sizeof(*x->encap));
+		l += nla_total_size(sizeof(*x->encap));
 
 	return l;
 }
@@ -2101,12 +2108,12 @@ static int xfrm_notify_sa(struct xfrm_st
 
 	headlen = sizeof(*p);
 	if (c->event == XFRM_MSG_DELSA) {
-		len += RTA_SPACE(headlen);
+		len += nla_total_size(headlen);
 		headlen = sizeof(*id);
 	}
-	len += NLMSG_SPACE(headlen);
+	len += NLMSG_ALIGN(headlen);
 
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2175,6 +2182,15 @@ static int xfrm_send_state_notify(struct
 
 }
 
+static inline size_t xfrm_acquire_msgsize(struct xfrm_state *x,
+					  struct xfrm_policy *xp)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_user_acquire))
+	       + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
+	       + nla_total_size(xfrm_user_sec_ctx_size(x->security))
+	       + userpolicy_type_attrsize();
+}
+
 static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
 			 struct xfrm_tmpl *xt, struct xfrm_policy *xp,
 			 int dir)
@@ -2215,13 +2231,8 @@ static int xfrm_send_acquire(struct xfrm
 			     struct xfrm_policy *xp, int dir)
 {
 	struct sk_buff *skb;
-	size_t len;
 
-	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
-	len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
-	len += RTA_SPACE(xfrm_user_sec_ctx_size(x->security));
-	len += userpolicy_type_attrsize();
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_acquire_msgsize(x, xp), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2290,6 +2301,14 @@ static struct xfrm_policy *xfrm_compile_
 	return xp;
 }
 
+static inline size_t xfrm_polexpire_msgsize(struct xfrm_policy *xp)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_user_polexpire))
+	       + nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr)
+	       + nla_total_size(xfrm_user_sec_ctx_size(xp->security))
+	       + userpolicy_type_attrsize();
+}
+
 static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
 			   int dir, struct km_event *c)
 {
@@ -2321,13 +2340,8 @@ nlmsg_failure:
 static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
 	struct sk_buff *skb;
-	size_t len;
 
-	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
-	len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
-	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp->security));
-	len += userpolicy_type_attrsize();
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_polexpire_msgsize(xp), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2343,18 +2357,18 @@ static int xfrm_notify_policy(struct xfr
 	struct xfrm_userpolicy_id *id;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
+	int len = nla_total_size(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	int headlen;
 
 	headlen = sizeof(*p);
 	if (c->event == XFRM_MSG_DELPOLICY) {
-		len += RTA_SPACE(headlen);
+		len += nla_total_size(headlen);
 		headlen = sizeof(*id);
 	}
 	len += userpolicy_type_attrsize();
-	len += NLMSG_SPACE(headlen);
+	len += NLMSG_ALIGN(headlen);
 
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2400,11 +2414,8 @@ static int xfrm_notify_policy_flush(stru
 {
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	int len = 0;
-	len += userpolicy_type_attrsize();
-	len += NLMSG_LENGTH(0);
 
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(userpolicy_type_attrsize(), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
@@ -2443,6 +2454,11 @@ static int xfrm_send_policy_notify(struc
 
 }
 
+static inline size_t xfrm_report_msgsize(void)
+{
+	return NLMSG_ALIGN(sizeof(struct xfrm_user_report));
+}
+
 static int build_report(struct sk_buff *skb, u8 proto,
 			struct xfrm_selector *sel, xfrm_address_t *addr)
 {
@@ -2471,10 +2487,8 @@ static int xfrm_send_report(u8 proto, st
 			    xfrm_address_t *addr)
 {
 	struct sk_buff *skb;
-	size_t len;
 
-	len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_user_report)));
-	skb = alloc_skb(len, GFP_ATOMIC);
+	skb = nlmsg_new(xfrm_report_msgsize(), GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 

-- 


^ permalink raw reply

* [PATCH 09/16] [XFRM] netlink: Use nlmsg_parse() to parse attributes
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_parse_attr --]
[-- Type: text/plain, Size: 3192 bytes --]

Uses nlmsg_parse() to parse the attributes. This actually changes
behaviour as unknown attributes (type > MAXTYPE) no longer cause
an error. Instead unknown attributes will be ignored henceforth
to keep older kernels compatible with more recent userspace tools.

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 17:07:38.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 17:31:04.000000000 +0200
@@ -1890,7 +1890,7 @@ static int xfrm_send_migrate(struct xfrm
 }
 #endif
 
-#define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type))
+#define XMSGSIZE(type) sizeof(struct type)
 
 static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
 	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
@@ -1906,13 +1906,13 @@ static const int xfrm_msg_min[XFRM_NR_MS
 	[XFRM_MSG_UPDSA       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info),
 	[XFRM_MSG_POLEXPIRE   - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_polexpire),
 	[XFRM_MSG_FLUSHSA     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush),
-	[XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0),
+	[XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = 0,
 	[XFRM_MSG_NEWAE       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
 	[XFRM_MSG_GETAE       - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id),
 	[XFRM_MSG_REPORT      - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report),
 	[XFRM_MSG_MIGRATE     - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id),
-	[XFRM_MSG_GETSADINFO  - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)),
-	[XFRM_MSG_GETSPDINFO  - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)),
+	[XFRM_MSG_GETSADINFO  - XFRM_MSG_BASE] = sizeof(u32),
+	[XFRM_MSG_GETSPDINFO  - XFRM_MSG_BASE] = sizeof(u32),
 };
 
 #undef XMSGSIZE
@@ -1946,9 +1946,9 @@ static struct xfrm_link {
 
 static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
-	struct rtattr *xfrma[XFRMA_MAX];
+	struct nlattr *xfrma[XFRMA_MAX+1];
 	struct xfrm_link *link;
-	int type, min_len;
+	int type, err;
 
 	type = nlh->nlmsg_type;
 	if (type > XFRM_MSG_MAX)
@@ -1970,30 +1970,16 @@ static int xfrm_user_rcv_msg(struct sk_b
 		return netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL);
 	}
 
-	memset(xfrma, 0, sizeof(xfrma));
-
-	if (nlh->nlmsg_len < (min_len = xfrm_msg_min[type]))
-		return -EINVAL;
-
-	if (nlh->nlmsg_len > min_len) {
-		int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
-		struct rtattr *attr = (void *) nlh + NLMSG_ALIGN(min_len);
-
-		while (RTA_OK(attr, attrlen)) {
-			unsigned short flavor = attr->rta_type;
-			if (flavor) {
-				if (flavor > XFRMA_MAX)
-					return -EINVAL;
-				xfrma[flavor - 1] = attr;
-			}
-			attr = RTA_NEXT(attr, attrlen);
-		}
-	}
+	/* FIXME: Temporary hack, nlmsg_parse() starts at xfrma[1], old code
+	 * expects first attribute at xfrma[0] */
+	err = nlmsg_parse(nlh, xfrm_msg_min[type], xfrma-1, XFRMA_MAX, NULL);
+	if (err < 0)
+		return err;
 
 	if (link->doit == NULL)
 		return -EINVAL;
 
-	return link->doit(skb, nlh, xfrma);
+	return link->doit(skb, nlh, (struct rtattr **) xfrma);
 }
 
 static void xfrm_netlink_rcv(struct sock *sk, int len)

-- 


^ permalink raw reply

* [PATCH 02/16] [XFRM] netlink: Use nlmsg_end() and nlmsg_cancel()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nlmsg_end --]
[-- Type: text/plain, Size: 8652 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-21 16:10:34.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 16:12:20.000000000 +0200
@@ -583,7 +583,6 @@ static int dump_one_state(struct xfrm_st
 	struct sk_buff *skb = sp->out_skb;
 	struct xfrm_usersa_info *p;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	if (sp->this_idx < sp->start_idx)
 		goto out;
@@ -628,14 +627,14 @@ static int dump_one_state(struct xfrm_st
 	if (x->lastused)
 		RTA_PUT(skb, XFRMA_LASTUSED, sizeof(x->lastused), &x->lastused);
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
+	nlmsg_end(skb, nlh);
 out:
 	sp->this_idx++;
 	return 0;
 
 rtattr_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
@@ -1270,7 +1269,6 @@ static int dump_one_policy(struct xfrm_p
 	struct sk_buff *in_skb = sp->in_skb;
 	struct sk_buff *skb = sp->out_skb;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	if (sp->this_idx < sp->start_idx)
 		goto out;
@@ -1289,14 +1287,14 @@ static int dump_one_policy(struct xfrm_p
 	if (copy_to_user_policy_type(xp->type, skb) < 0)
 		goto nlmsg_failure;
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
+	nlmsg_end(skb, nlh);
 out:
 	sp->this_idx++;
 	return 0;
 
 nlmsg_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
@@ -1446,7 +1444,6 @@ static int build_aevent(struct sk_buff *
 	struct xfrm_aevent_id *id;
 	struct nlmsghdr *nlh;
 	struct xfrm_lifetime_cur ltime;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
 	if (nlh == NULL)
@@ -1479,12 +1476,11 @@ static int build_aevent(struct sk_buff *
 		RTA_PUT(skb,XFRMA_ETIMER_THRESH,sizeof(u32),&etimer);
 	}
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 
 rtattr_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1862,7 +1858,6 @@ static int build_migrate(struct sk_buff 
 	struct xfrm_migrate *mp;
 	struct xfrm_userpolicy_id *pol_id;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 	int i;
 
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id), 0);
@@ -1883,11 +1878,10 @@ static int build_migrate(struct sk_buff 
 			goto nlmsg_failure;
 	}
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 nlmsg_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -2043,7 +2037,6 @@ static int build_expire(struct sk_buff *
 {
 	struct xfrm_user_expire *ue;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);
 	if (nlh == NULL)
@@ -2053,8 +2046,7 @@ static int build_expire(struct sk_buff *
 	copy_to_user_state(x, &ue->state);
 	ue->hard = (c->data.hard != 0) ? 1 : 0;
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 }
 
 static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
@@ -2096,13 +2088,11 @@ static int xfrm_notify_sa_flush(struct k
 	struct xfrm_usersa_flush *p;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	sk_buff_data_t b;
 	int len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush));
 
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
-	b = skb->tail;
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0);
 	if (nlh == NULL) {
@@ -2113,7 +2103,7 @@ static int xfrm_notify_sa_flush(struct k
 	p = NLMSG_DATA(nlh);
 	p->proto = c->data.proto;
 
-	nlh->nlmsg_len = skb->tail - b;
+	nlmsg_end(skb, nlh);
 
 	NETLINK_CB(skb).dst_group = XFRMNLGRP_SA;
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
@@ -2140,7 +2130,6 @@ static int xfrm_notify_sa(struct xfrm_st
 	struct xfrm_usersa_id *id;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	sk_buff_data_t b;
 	int len = xfrm_sa_len(x);
 	int headlen;
 
@@ -2154,7 +2143,6 @@ static int xfrm_notify_sa(struct xfrm_st
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
-	b = skb->tail;
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
 	if (nlh == NULL)
@@ -2185,7 +2173,7 @@ static int xfrm_notify_sa(struct xfrm_st
 	if (x->encap)
 		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
-	nlh->nlmsg_len = skb->tail - b;
+	nlmsg_end(skb, nlh);
 
 	NETLINK_CB(skb).dst_group = XFRMNLGRP_SA;
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
@@ -2225,7 +2213,6 @@ static int build_acquire(struct sk_buff 
 {
 	struct xfrm_user_acquire *ua;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 	__u32 seq = xfrm_get_acqseq();
 
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_ACQUIRE, sizeof(*ua), 0);
@@ -2249,12 +2236,11 @@ static int build_acquire(struct sk_buff 
 	if (copy_to_user_policy_type(xp->type, skb) < 0)
 		goto nlmsg_failure;
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 
 nlmsg_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
@@ -2345,7 +2331,6 @@ static int build_polexpire(struct sk_buf
 	struct xfrm_user_polexpire *upe;
 	struct nlmsghdr *nlh;
 	int hard = c->data.hard;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
 	if (nlh == NULL)
@@ -2361,12 +2346,11 @@ static int build_polexpire(struct sk_buf
 		goto nlmsg_failure;
 	upe->hard = !!hard;
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 
 nlmsg_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
@@ -2397,7 +2381,6 @@ static int xfrm_notify_policy(struct xfr
 	struct xfrm_userpolicy_id *id;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	sk_buff_data_t b;
 	int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	int headlen;
 
@@ -2414,7 +2397,6 @@ static int xfrm_notify_policy(struct xfr
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
-	b = skb->tail;
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
 	if (nlh == NULL)
@@ -2439,7 +2421,7 @@ static int xfrm_notify_policy(struct xfr
 	if (copy_to_user_policy_type(xp->type, skb) < 0)
 		goto nlmsg_failure;
 
-	nlh->nlmsg_len = skb->tail - b;
+	nlmsg_end(skb, nlh);
 
 	NETLINK_CB(skb).dst_group = XFRMNLGRP_POLICY;
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
@@ -2454,7 +2436,6 @@ static int xfrm_notify_policy_flush(stru
 {
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	sk_buff_data_t b;
 	int len = 0;
 #ifdef CONFIG_XFRM_SUB_POLICY
 	len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
@@ -2464,8 +2445,6 @@ static int xfrm_notify_policy_flush(stru
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
-	b = skb->tail;
-
 
 	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0);
 	if (nlh == NULL)
@@ -2473,7 +2452,7 @@ static int xfrm_notify_policy_flush(stru
 	if (copy_to_user_policy_type(c->data.type, skb) < 0)
 		goto nlmsg_failure;
 
-	nlh->nlmsg_len = skb->tail - b;
+	nlmsg_end(skb, nlh);
 
 	NETLINK_CB(skb).dst_group = XFRMNLGRP_POLICY;
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
@@ -2508,7 +2487,6 @@ static int build_report(struct sk_buff *
 {
 	struct xfrm_user_report *ur;
 	struct nlmsghdr *nlh;
-	unsigned char *b = skb_tail_pointer(skb);
 
 	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_REPORT, sizeof(*ur), 0);
 	if (nlh == NULL)
@@ -2521,12 +2499,11 @@ static int build_report(struct sk_buff *
 	if (addr)
 		RTA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
 
-	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
-	return skb->len;
+	return nlmsg_end(skb, nlh);
 
 rtattr_failure:
-	nlmsg_trim(skb, b);
-	return -1;
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
 }
 
 static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,

-- 


^ permalink raw reply

* [PATCH 00/16] xfrm netlink interface cleanups
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev

This patchset converts the xfrm netlink bits over to the type
safe netlink interface and does some cleanups.

 xfrm_user.c | 1041 ++++++++++++++++++++++++------------------------------------
 1 file changed, 433 insertions(+), 608 deletions(-)


^ permalink raw reply

* [PATCH 01/16] [XFRM] netlink: Use nlmsg_put() instead of NLMSG_PUT()
From: Thomas Graf @ 2007-08-22 14:55 UTC (permalink / raw)
  To: davem; +Cc: netdev, Thomas Graf
In-Reply-To: <20070822145538.861270927@lsx.localdomain>

[-- Attachment #1: xfrm_nlmsg_put --]
[-- Type: text/plain, Size: 6598 bytes --]

Signed-off-by: Thomas Graf <tgraf@suug.ch>

Index: net-2.6.24/net/xfrm/xfrm_user.c
===================================================================
--- net-2.6.24.orig/net/xfrm/xfrm_user.c	2007-08-20 17:09:48.000000000 +0200
+++ net-2.6.24/net/xfrm/xfrm_user.c	2007-08-21 16:10:34.000000000 +0200
@@ -588,10 +588,10 @@ static int dump_one_state(struct xfrm_st
 	if (sp->this_idx < sp->start_idx)
 		goto out;
 
-	nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid,
-			sp->nlmsg_seq,
-			XFRM_MSG_NEWSA, sizeof(*p));
-	nlh->nlmsg_flags = sp->nlmsg_flags;
+	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
+			XFRM_MSG_NEWSA, sizeof(*p), sp->nlmsg_flags);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 
 	p = NLMSG_DATA(nlh);
 	copy_to_user_state(x, p);
@@ -633,7 +633,6 @@ out:
 	sp->this_idx++;
 	return 0;
 
-nlmsg_failure:
 rtattr_failure:
 	nlmsg_trim(skb, b);
 	return -1;
@@ -1276,11 +1275,11 @@ static int dump_one_policy(struct xfrm_p
 	if (sp->this_idx < sp->start_idx)
 		goto out;
 
-	nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid,
-			sp->nlmsg_seq,
-			XFRM_MSG_NEWPOLICY, sizeof(*p));
+	nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, sp->nlmsg_seq,
+			XFRM_MSG_NEWPOLICY, sizeof(*p), sp->nlmsg_flags);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	p = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = sp->nlmsg_flags;
 
 	copy_to_user_policy(xp, p, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
@@ -1449,9 +1448,10 @@ static int build_aevent(struct sk_buff *
 	struct xfrm_lifetime_cur ltime;
 	unsigned char *b = skb_tail_pointer(skb);
 
-	nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id));
+	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_NEWAE, sizeof(*id), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	id = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr));
 	id->sa_id.spi = x->id.spi;
@@ -1483,7 +1483,6 @@ static int build_aevent(struct sk_buff *
 	return skb->len;
 
 rtattr_failure:
-nlmsg_failure:
 	nlmsg_trim(skb, b);
 	return -1;
 }
@@ -1866,9 +1865,10 @@ static int build_migrate(struct sk_buff 
 	unsigned char *b = skb_tail_pointer(skb);
 	int i;
 
-	nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id));
+	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MIGRATE, sizeof(*pol_id), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	pol_id = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	/* copy data from selector, dir, and type to the pol_id */
 	memset(pol_id, 0, sizeof(*pol_id));
@@ -2045,20 +2045,16 @@ static int build_expire(struct sk_buff *
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb_tail_pointer(skb);
 
-	nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_EXPIRE,
-			sizeof(*ue));
+	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_EXPIRE, sizeof(*ue), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	ue = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	copy_to_user_state(x, &ue->state);
 	ue->hard = (c->data.hard != 0) ? 1 : 0;
 
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	return skb->len;
-
-nlmsg_failure:
-	nlmsg_trim(skb, b);
-	return -1;
 }
 
 static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
@@ -2108,9 +2104,11 @@ static int xfrm_notify_sa_flush(struct k
 		return -ENOMEM;
 	b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, c->pid, c->seq,
-			XFRM_MSG_FLUSHSA, sizeof(*p));
-	nlh->nlmsg_flags = 0;
+	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHSA, sizeof(*p), 0);
+	if (nlh == NULL) {
+		kfree_skb(skb);
+		return -EMSGSIZE;
+	}
 
 	p = NLMSG_DATA(nlh);
 	p->proto = c->data.proto;
@@ -2119,10 +2117,6 @@ static int xfrm_notify_sa_flush(struct k
 
 	NETLINK_CB(skb).dst_group = XFRMNLGRP_SA;
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_SA, GFP_ATOMIC);
-
-nlmsg_failure:
-	kfree_skb(skb);
-	return -1;
 }
 
 static inline int xfrm_sa_len(struct xfrm_state *x)
@@ -2162,8 +2156,9 @@ static int xfrm_notify_sa(struct xfrm_st
 		return -ENOMEM;
 	b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen);
-	nlh->nlmsg_flags = 0;
+	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
+	if (nlh == NULL)
+		goto nlmsg_failure;
 
 	p = NLMSG_DATA(nlh);
 	if (c->event == XFRM_MSG_DELSA) {
@@ -2233,10 +2228,10 @@ static int build_acquire(struct sk_buff 
 	unsigned char *b = skb_tail_pointer(skb);
 	__u32 seq = xfrm_get_acqseq();
 
-	nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_ACQUIRE,
-			sizeof(*ua));
+	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_ACQUIRE, sizeof(*ua), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	ua = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	memcpy(&ua->id, &x->id, sizeof(ua->id));
 	memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr));
@@ -2352,9 +2347,10 @@ static int build_polexpire(struct sk_buf
 	int hard = c->data.hard;
 	unsigned char *b = skb_tail_pointer(skb);
 
-	nlh = NLMSG_PUT(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe));
+	nlh = nlmsg_put(skb, c->pid, 0, XFRM_MSG_POLEXPIRE, sizeof(*upe), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	upe = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	copy_to_user_policy(xp, &upe->pol, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
@@ -2420,7 +2416,9 @@ static int xfrm_notify_policy(struct xfr
 		return -ENOMEM;
 	b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen);
+	nlh = nlmsg_put(skb, c->pid, c->seq, c->event, headlen, 0);
+	if (nlh == NULL)
+		goto nlmsg_failure;
 
 	p = NLMSG_DATA(nlh);
 	if (c->event == XFRM_MSG_DELPOLICY) {
@@ -2435,8 +2433,6 @@ static int xfrm_notify_policy(struct xfr
 		p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p)));
 	}
 
-	nlh->nlmsg_flags = 0;
-
 	copy_to_user_policy(xp, p, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
@@ -2471,8 +2467,9 @@ static int xfrm_notify_policy_flush(stru
 	b = skb->tail;
 
 
-	nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0);
-	nlh->nlmsg_flags = 0;
+	nlh = nlmsg_put(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0, 0);
+	if (nlh == NULL)
+		goto nlmsg_failure;
 	if (copy_to_user_policy_type(c->data.type, skb) < 0)
 		goto nlmsg_failure;
 
@@ -2513,9 +2510,10 @@ static int build_report(struct sk_buff *
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb_tail_pointer(skb);
 
-	nlh = NLMSG_PUT(skb, 0, 0, XFRM_MSG_REPORT, sizeof(*ur));
+	nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_REPORT, sizeof(*ur), 0);
+	if (nlh == NULL)
+		return -EMSGSIZE;
 	ur = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = 0;
 
 	ur->proto = proto;
 	memcpy(&ur->sel, sel, sizeof(ur->sel));
@@ -2526,7 +2524,6 @@ static int build_report(struct sk_buff *
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	return skb->len;
 
-nlmsg_failure:
 rtattr_failure:
 	nlmsg_trim(skb, b);
 	return -1;

-- 


^ permalink raw reply

* [PATCH] [06/10] pasemi_mac: Batch up TX buffer frees
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-tx-lock-reduction --]
[-- Type: text/plain, Size: 2158 bytes --]

Postpone pci unmap and skb free of the transmitted buffers to outside of
the tx ring lock, batching them up 32 at a time.

Also increase the count threshold to 128.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -561,37 +561,56 @@ static int pasemi_mac_clean_tx(struct pa
 	int i;
 	struct pasemi_mac_buffer *info;
 	struct pas_dma_xct_descr *dp;
-	int start, count;
+	unsigned int start, count, limit;
+	unsigned int total_count;
 	int flags;
+	struct sk_buff *skbs[32];
+	dma_addr_t dmas[32];
 
+	total_count = 0;
+restart:
 	spin_lock_irqsave(&mac->tx->lock, flags);
 
 	start = mac->tx->next_to_clean;
+	limit = min(mac->tx->next_to_use, start+32);
+
 	count = 0;
 
-	for (i = start; i < mac->tx->next_to_use; i++) {
+	for (i = start; i < limit; i++) {
 		dp = &TX_DESC(mac, i);
+
 		if (unlikely(dp->mactx & XCT_MACTX_O))
+			/* Not yet transmitted */
 			break;
 
-		count++;
-
 		info = &TX_DESC_INFO(mac, i);
-
-		pci_unmap_single(mac->dma_pdev, info->dma,
-				 info->skb->len, PCI_DMA_TODEVICE);
-		dev_kfree_skb_irq(info->skb);
+		skbs[count] = info->skb;
+		dmas[count] = info->dma;
 
 		info->skb = NULL;
 		info->dma = 0;
 		dp->mactx = 0;
 		dp->ptr = 0;
+
+		count++;
 	}
 	mac->tx->next_to_clean += count;
 	spin_unlock_irqrestore(&mac->tx->lock, flags);
 	netif_wake_queue(mac->netdev);
 
-	return count;
+	for (i = 0; i < count; i++) {
+		pci_unmap_single(mac->dma_pdev, dmas[i],
+				 skbs[i]->len, PCI_DMA_TODEVICE);
+		dev_kfree_skb_irq(skbs[i]);
+	}
+
+	total_count += count;
+
+	/* If the batch was full, try to clean more */
+	if (count == 32)
+		goto restart;
+
+	return total_count;
 }
 
 
@@ -787,7 +806,7 @@ static int pasemi_mac_open(struct net_de
 			   PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
 
 	write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
-			   PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+			   PAS_IOB_DMA_TXCH_CFG_CNTTH(128));
 
 	/* Clear out any residual packet count state from firmware */
 	pasemi_mac_restart_rx_intr(mac);

--

^ permalink raw reply

* [PATCH] [09/10] pasemi_mac: Fix RX checksum flags
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-rx-checksum-fix --]
[-- Type: text/plain, Size: 631 bytes --]

RX side flag to use is CHECKSUM_UNNECESSARY, not CHECKSUM_COMPLETE.

Signed-off-by: Olof Johansson <olof@lixom.net>

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -534,7 +534,7 @@ static int pasemi_mac_clean_rx(struct pa
 		skb_put(skb, len);
 
 		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
-			skb->ip_summed = CHECKSUM_COMPLETE;
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
 					   XCT_MACRX_CSUM_S;
 		} else

--

^ permalink raw reply

* [PATCH] [10/10] pasemi_mac: Clean TX ring in poll
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-clean-tx-in-poll --]
[-- Type: text/plain, Size: 1130 bytes --]

Unfortunately there's no timeout for how long a packet can sit on
the TX ring after completion before an interrupt is generated, and
we want to have a threshold that's larger than one packet per interrupt.

So we have to have a timer that occasionally cleans the TX ring even
though there hasn't been an interrupt. Instead of setting up a dedicated
timer for this, just clean it in the NAPI poll routine instead.


Signed-off-by: Olof Johansson <olof@lixom.net>

---

I know I got this rejected last time it was submitted, but no answers with
suggestions on how to handle it better. I'm all ears if there's a better
way.  (I noticed that Intel's new ixgbe driver does the same thing).

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -1086,6 +1086,7 @@ static int pasemi_mac_poll(struct net_de
 	int pkts, limit = min(*budget, dev->quota);
 	struct pasemi_mac *mac = netdev_priv(dev);
 
+	pasemi_mac_clean_tx(mac);
 	pkts = pasemi_mac_clean_rx(mac, limit);
 
 	dev->quota -= pkts;

--

^ permalink raw reply

* [PATCH] [08/10] pasemi_mac: Fix TX ring wrap checking
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070817205413.548020000@lixom.net>

[-- Attachment #1: pasemi_mac-ringwrap-bugfix --]
[-- Type: text/plain, Size: 3771 bytes --]

The old logic didn't detect full (tx) ring cases properly, causing
overruns and general badness. Clean it up a bit and abstract out the
ring size checks, always making sure to leave 1 slot open.


Signed-off-by: Olof Johansson <olof@lixom.net>

Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -69,6 +69,10 @@
 #define RX_DESC_INFO(mac, num)	((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(mac, num)	((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
 
+#define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
+				 & ((ring)->size - 1))
+#define RING_AVAIL(ring)	((ring->size) - RING_USED(ring))
+
 #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 
 MODULE_LICENSE("GPL");
@@ -184,6 +188,7 @@ static int pasemi_mac_setup_rx_resources
 
 	spin_lock_init(&ring->lock);
 
+	ring->size = RX_RING_SIZE;
 	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  RX_RING_SIZE, GFP_KERNEL);
 
@@ -263,6 +268,7 @@ static int pasemi_mac_setup_tx_resources
 
 	spin_lock_init(&ring->lock);
 
+	ring->size = TX_RING_SIZE;
 	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  TX_RING_SIZE, GFP_KERNEL);
 	if (!ring->desc_info)
@@ -291,7 +297,7 @@ static int pasemi_mac_setup_tx_resources
 			   PAS_DMA_TXCHAN_CFG_UP |
 			   PAS_DMA_TXCHAN_CFG_WT(2));
 
-	ring->next_to_use = 0;
+	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
 
 	snprintf(ring->irq_name, sizeof(ring->irq_name),
@@ -386,9 +392,7 @@ static void pasemi_mac_replenish_rx_ring
 	int start = mac->rx->next_to_fill;
 	unsigned int limit, count;
 
-	limit = (mac->rx->next_to_clean + RX_RING_SIZE -
-		 mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
-
+	limit = RING_AVAIL(mac->rx);
 	/* Check to see if we're doing first-time setup */
 	if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
 		limit = RX_RING_SIZE;
@@ -572,7 +576,7 @@ restart:
 	spin_lock_irqsave(&mac->tx->lock, flags);
 
 	start = mac->tx->next_to_clean;
-	limit = min(mac->tx->next_to_use, start+32);
+	limit = min(mac->tx->next_to_fill, start+32);
 
 	count = 0;
 
@@ -1013,14 +1017,13 @@ static int pasemi_mac_start_tx(struct sk
 
 	spin_lock_irqsave(&txring->lock, flags);
 
-	if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) {
+	if (RING_AVAIL(txring) <= 1) {
 		spin_unlock_irqrestore(&txring->lock, flags);
 		pasemi_mac_clean_tx(mac);
 		pasemi_mac_restart_tx_intr(mac);
 		spin_lock_irqsave(&txring->lock, flags);
 
-		if (txring->next_to_clean - txring->next_to_use ==
-		    TX_RING_SIZE) {
+		if (RING_AVAIL(txring) <= 1) {
 			/* Still no room -- stop the queue and wait for tx
 			 * intr when there's room.
 			 */
@@ -1029,15 +1032,15 @@ static int pasemi_mac_start_tx(struct sk
 		}
 	}
 
-	dp = &TX_DESC(mac, txring->next_to_use);
-	info = &TX_DESC_INFO(mac, txring->next_to_use);
+	dp = &TX_DESC(mac, txring->next_to_fill);
+	info = &TX_DESC_INFO(mac, txring->next_to_fill);
 
 	dp->mactx = mactx;
 	dp->ptr   = ptr;
 	info->dma = map;
 	info->skb = skb;
 
-	txring->next_to_use++;
+	txring->next_to_fill++;
 	mac->stats.tx_packets++;
 	mac->stats.tx_bytes += skb->len;
 
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -31,7 +31,7 @@ struct pasemi_mac_txring {
 	struct pas_dma_xct_descr	*desc;
 	dma_addr_t	 dma;
 	unsigned int	 size;
-	unsigned int	 next_to_use;
+	unsigned int	 next_to_fill;
 	unsigned int	 next_to_clean;
 	struct pasemi_mac_buffer *desc_info;
 	char		 irq_name[10];  /* "eth%d tx" */

--

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox