Netdev List
 help / color / mirror / Atom feed
* Re: [Cbe-oss-dev] [PATCH 1/5] spidernet: add missing initialization
From: Jens Osterkamp @ 2008-01-23 13:53 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Ishizaki Kou, netdev
In-Reply-To: <20080111.153859.-1300526764.kouish@swc.toshiba.co.jp>

On Friday 11 January 2008, Ishizaki Kou wrote:
> This patch fixes initialization of "aneg_count" and "medium" fields in
> spider_net_card to make spidernet driver correctly sets "link status".
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>

Acked-by: Jens Osterkamp <jens@de.ibm.com>

> ---
> 
> Index: linux-powerpc-git/drivers/net/spider_net.c
> ===================================================================
> --- linux-powerpc-git.orig/drivers/net/spider_net.c
> +++ linux-powerpc-git/drivers/net/spider_net.c
> @@ -1399,6 +1399,8 @@ spider_net_link_reset(struct net_device 
>  	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
> 
>  	/* reset phy and setup aneg */
> +	card->aneg_count = 0;
> +	card->medium = BCM54XX_COPPER;
>  	spider_net_setup_aneg(card);
>  	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
> 
> @@ -1982,6 +1984,8 @@ spider_net_open(struct net_device *netde
>  		goto init_firmware_failed;
> 
>  	/* start probing with copper */
> +	card->aneg_count = 0;
> +	card->medium = BCM54XX_COPPER;
>  	spider_net_setup_aneg(card);
>  	if (card->phy.def->phy_id)
>  		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev
>
-- 

Gruß,

Jens

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 2/5] spidernet: increase auto-negotiation timeout to 5 seconds
From: Jens Osterkamp @ 2008-01-23 13:54 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Ishizaki Kou, netdev
In-Reply-To: <20080111.154125.-1350516935.kouish@swc.toshiba.co.jp>

On Friday 11 January 2008, Ishizaki Kou wrote:
> This patch extends the timeout for spidernet auto-negotiation.
> Auto-negotiation often fails to finish in 2 seconds.
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>

Acked-by: Jens Osterkamp <jens@de.ibm.com>

> ---
> 
> Index: linux-powerpc-git/drivers/net/spider_net.h
> ===================================================================
> --- linux-powerpc-git.orig/drivers/net/spider_net.h
> +++ linux-powerpc-git/drivers/net/spider_net.h
> @@ -52,7 +52,7 @@ extern char spider_net_driver_name[];
> 
>  #define SPIDER_NET_TX_TIMER			(HZ/5)
>  #define SPIDER_NET_ANEG_TIMER			(HZ)
> -#define SPIDER_NET_ANEG_TIMEOUT			2
> +#define SPIDER_NET_ANEG_TIMEOUT			5
> 
>  #define SPIDER_NET_RX_CSUM_DEFAULT		1
> 
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev
> 



-- 

Gruß,

Jens

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 3/5] spidernet: change interrupt masks
From: Jens Osterkamp @ 2008-01-23 13:55 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Ishizaki Kou, netdev
In-Reply-To: <20080111.154343.-1625861724.kouish@swc.toshiba.co.jp>

On Friday 11 January 2008, Ishizaki Kou wrote:
> This patch changes spidernet interrupt masks.
> 
>  - unmask GDAINVAINT. There is an operation to do by spidernet
>    interrupt handler.
>  - mask some interrupts. There are no operations in the interrupt handler.
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>

Acked-by: Jens Osterkamp <jens@de.ibm.com>

> ---
> 
> Index: linux-powerpc-git/drivers/net/spider_net.h
> ===================================================================
> --- linux-powerpc-git.orig/drivers/net/spider_net.h
> +++ linux-powerpc-git/drivers/net/spider_net.h
> @@ -159,9 +159,8 @@ extern char spider_net_driver_name[];
> 
>  /** interrupt mask registers */
>  #define SPIDER_NET_INT0_MASK_VALUE	0x3f7fe2c7
> -#define SPIDER_NET_INT1_MASK_VALUE	0xffff7ff7
> -/* no MAC aborts -> auto retransmission */
> -#define SPIDER_NET_INT2_MASK_VALUE	0xffef7ff1
> +#define SPIDER_NET_INT1_MASK_VALUE	0x0000fff2
> +#define SPIDER_NET_INT2_MASK_VALUE	0x000003f1
> 
>  /* we rely on flagged descriptor interrupts */
>  #define SPIDER_NET_FRAMENUM_VALUE	0x00000000
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev
> 



-- 

Gruß,

Jens

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 4/5] spidernet: fix error interrupt handling
From: Jens Osterkamp @ 2008-01-23 13:55 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Ishizaki Kou, linas, netdev
In-Reply-To: <20080111.154614.-345477188.kouish@swc.toshiba.co.jp>

On Friday 11 January 2008, Ishizaki Kou wrote:
> In addition to the value of GHIINT0STS, spidernet interrupt handler
> should check the values of GHIINT1STS/GHIINT2STS registers at the
> beginning of spider_net_interrupt() so as not to drop error
> interrupts.
> 
> GHIINT1STS/GHIINT2STS registers indicates some of erroneous conditions
> in spidernet, and a few bits of GHIINT0STS register reflects these
> conditions. But GHIINT0MSK masks these bits, so you should check these
> conditions by reading GHIINT1STS/GHIINT2STS registers directly.
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>

Acked-by: Jens Osterkamp <jens@de.ibm.com>

> 
> Index: linux-powerpc-git/drivers/net/spider_net.c
> ===================================================================
> --- linux-powerpc-git.orig/drivers/net/spider_net.c
> +++ linux-powerpc-git/drivers/net/spider_net.c
> @@ -1415,18 +1415,12 @@ spider_net_link_reset(struct net_device 
>   * found when an interrupt is presented
>   */
>  static void
> -spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
> +spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
> +			    u32 error_reg1, u32 error_reg2)
>  {
> -	u32 error_reg1, error_reg2;
>  	u32 i;
>  	int show_error = 1;
> 
> -	error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
> -	error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
> -
> -	error_reg1 &= SPIDER_NET_INT1_MASK_VALUE;
> -	error_reg2 &= SPIDER_NET_INT2_MASK_VALUE;
> -
>  	/* check GHIINT0STS ************************************/
>  	if (status_reg)
>  		for (i = 0; i < 32; i++)
> @@ -1656,12 +1650,15 @@ spider_net_interrupt(int irq, void *ptr)
>  {
>  	struct net_device *netdev = ptr;
>  	struct spider_net_card *card = netdev_priv(netdev);
> -	u32 status_reg;
> +	u32 status_reg, error_reg1, error_reg2;
> 
>  	status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
> -	status_reg &= SPIDER_NET_INT0_MASK_VALUE;
> +	error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
> +	error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
> 
> -	if (!status_reg)
> +	if (!(status_reg & SPIDER_NET_INT0_MASK_VALUE) &&
> +	    !(error_reg1 & SPIDER_NET_INT1_MASK_VALUE) &&
> +	    !(error_reg2 & SPIDER_NET_INT2_MASK_VALUE))
>  		return IRQ_NONE;
> 
>  	if (status_reg & SPIDER_NET_RXINT ) {
> @@ -1676,7 +1673,8 @@ spider_net_interrupt(int irq, void *ptr)
>  		spider_net_link_reset(netdev);
> 
>  	if (status_reg & SPIDER_NET_ERRINT )
> -		spider_net_handle_error_irq(card, status_reg);
> +		spider_net_handle_error_irq(card, status_reg,
> +					    error_reg1, error_reg2);
> 
>  	/* clear interrupt sources */
>  	spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg);
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev
> 



-- 

Gruß,

Jens

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 5/5] spidernet: revise link status logging
From: Jens Osterkamp @ 2008-01-23 13:55 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Ishizaki Kou, netdev
In-Reply-To: <20080111.154847.-494080281.kouish@swc.toshiba.co.jp>

On Friday 11 January 2008, Ishizaki Kou wrote:
> This patch revises the logging for link informations of spidernet.
> 
>   - The link down message is too verbose because auto-negotiation timeout
>     occurs periodically while an ethernet cable is not connected. 
>   - We want to see the link result, and we think it should be displayed. 
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>

Acked-by: Jens Osterkamp <jens@de.ibm.com>

> ---
> 
> Index: linux-powerpc-git/drivers/net/spider_net.c
> ===================================================================
> --- linux-powerpc-git.orig/drivers/net/spider_net.c
> +++ linux-powerpc-git/drivers/net/spider_net.c
> @@ -2045,7 +2045,8 @@ static void spider_net_link_phy(unsigned
>  	/* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy again */
>  	if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
> 
> -		pr_info("%s: link is down trying to bring it up\n", card->netdev->name);
> +		pr_debug("%s: link is down trying to bring it up\n",
> +			 card->netdev->name);
> 
>  		switch (card->medium) {
>  		case BCM54XX_COPPER:
> @@ -2096,9 +2097,10 @@ static void spider_net_link_phy(unsigned
> 
>  	card->aneg_count = 0;
> 
> -	pr_debug("Found %s with %i Mbps, %s-duplex %sautoneg.\n",
> -		phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half",
> -		phy->autoneg==1 ? "" : "no ");
> +	pr_info("%s: link up, %i Mbps, %s-duplex %sautoneg.\n",
> +		card->netdev->name, phy->speed,
> +		phy->duplex == 1 ? "Full" : "Half",
> +		phy->autoneg == 1 ? "" : "no ");
> 
>  	return;
>  }
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev
> 



-- 

Gruß,

Jens

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply

* [IPV4 0/9] TRIE performance patches
From: Robert Olsson @ 2008-01-23 14:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, netdev
In-Reply-To: <20080122233733.404145234@linux-foundation.org>


Stephen Hemminger writes:

 > Time to handle a full BGP load (163K of routes).
 > 
 > Before:		Load		Dump		Flush
 >
 > kmem_cache	3.8		13.0		7.2
 > iter		3.9		12.3		6.9
 > unordered	3.1		11.9		4.9
 > find_node	3.1		 0.3		1.2

 I certainly like the speed but what will we brake when
 we don't return in longest prefix order?

labb:/# ip r
default via 10.10.10.1 dev eth0 
5.0.0.0/8 via 192.168.2.2 dev eth3 
10.10.10.0/24 dev eth0  proto kernel  scope link  src 10.10.10.2 
10.10.11.0/24 dev eth1  proto kernel  scope link  src 10.10.11.1 
11.0.0.0/8 via 10.10.11.2 dev eth1 
192.168.1.0/24 dev eth2  proto kernel  scope link  src 192.168.1.2 
192.168.2.0/24 dev eth3  proto kernel  scope link  src 192.168.2.1 

labb:/# ip route list match 10.10.10.1
default via 10.10.10.1 dev eth0 
10.10.10.0/24 dev eth0  proto kernel  scope link  src 10.10.10.2 
labb:/# 

Maybe the unordered dump can be ordered cheaply...

Cheers.
				--ro


^ permalink raw reply

* Re: [PATCH] Introducing socket mark socket option
From: Patrick McHardy @ 2008-01-23 14:19 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: Netfilter Developer Mailing List, netdev, linux-arch
In-Reply-To: <12010920051270-git-send-email-panther@balabit.hu>

Laszlo Attila Toth wrote:
> A userspace program may wish to set the mark for each packets its send
> without using the netfilter MARK target. Changing the mark can be used
> mark based routing without netfilter or for packet filtering.
> 
> It requires CAP_NET_ADMIN capability.
> 

> @@ -403,6 +403,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
>  					      { .daddr = daddr,
>  						.saddr = rt->rt_spec_dst,
>  						.tos = RT_TOS(ip_hdr(skb)->tos) } },
> +				    .mark = sk->sk_mark,

This is useless, the icmp socket is not visible to userspace.

> --- a/net/ipv4/ip_output.c
> +++ b/net/ipv4/ip_output.c
 > ...

What about IPv6?

^ permalink raw reply

* [PATCH 1/3] Cleanup and simplify virtnet header
From: Rusty Russell @ 2008-01-23 14:07 UTC (permalink / raw)
  To: netdev; +Cc: Herbert Xu, virtualization

1) Turn GSO on virtio net into an all-or-nothing (keep checksumming
   separate).  Having multiple bits is a pain: if you can't support something
   you should handle it in software, which is still a performance win.

2) Make VIRTIO_NET_HDR_GSO_ECN a flag in the header, so it can apply to
   IPv6 or v4.

3) Rename VIRTIO_NET_F_NO_CSUM to VIRTIO_NET_F_CSUM (ie. means we do
   checksumming).

4) Add csum and gso params to virtio_net to allow more testing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/net/virtio_net.c   |   32 ++++++++++++++++----------------
 include/linux/virtio_net.h |   12 ++++--------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff -r 4fb788b18cf8 drivers/net/virtio_net.c
--- a/drivers/net/virtio_net.c	Wed Jan 23 13:07:59 2008 +1100
+++ b/drivers/net/virtio_net.c	Wed Jan 23 18:46:05 2008 +1100
@@ -26,6 +26,10 @@
 
 static int napi_weight = 128;
 module_param(napi_weight, int, 0444);
+
+static int csum = 1, gso = 1;
+module_param(csum, int, 0444);
+module_param(gso, int, 0444);
 
 MODULE_LICENSE("GPL");
 
@@ -95,12 +99,9 @@ static void receive_skb(struct net_devic
 
 	if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
 		pr_debug("GSO!\n");
-		switch (hdr->gso_type) {
+		switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
 		case VIRTIO_NET_HDR_GSO_TCPV4:
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
-			break;
-		case VIRTIO_NET_HDR_GSO_TCPV4_ECN:
-			skb_shinfo(skb)->gso_type = SKB_GSO_TCP_ECN;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
@@ -114,6 +115,9 @@ static void receive_skb(struct net_devic
 				       dev->name, hdr->gso_type);
 			goto frame_err;
 		}
+
+		if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
+			skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
 
 		skb_shinfo(skb)->gso_size = hdr->gso_size;
 		if (skb_shinfo(skb)->gso_size == 0) {
@@ -249,9 +253,7 @@ static int start_xmit(struct sk_buff *sk
 	if (skb_is_gso(skb)) {
 		hdr->hdr_len = skb_transport_header(skb) - skb->data;
 		hdr->gso_size = skb_shinfo(skb)->gso_size;
-		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
-			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4_ECN;
-		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
 			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
 			hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
@@ -259,6 +261,8 @@ static int start_xmit(struct sk_buff *sk
 			hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
+			hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
 	} else {
 		hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
 		hdr->gso_size = hdr->hdr_len = 0;
@@ -354,17 +358,13 @@ static int virtnet_probe(struct virtio_d
 	SET_NETDEV_DEV(dev, &vdev->dev);
 
 	/* Do we support "hardware" checksums? */
-	if (vdev->config->feature(vdev, VIRTIO_NET_F_NO_CSUM)) {
+	if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) {
 		/* This opens up the world of extra features. */
 		dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
-		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4))
-			dev->features |= NETIF_F_TSO;
-		if (vdev->config->feature(vdev, VIRTIO_NET_F_UFO))
-			dev->features |= NETIF_F_UFO;
-		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO4_ECN))
-			dev->features |= NETIF_F_TSO_ECN;
-		if (vdev->config->feature(vdev, VIRTIO_NET_F_TSO6))
-			dev->features |= NETIF_F_TSO6;
+		if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) {
+			dev->features |= NETIF_F_TSO | NETIF_F_UFO
+				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
+		}
 	}
 
 	/* Configuration may specify what MAC to use.  Otherwise random. */
diff -r 4fb788b18cf8 include/linux/virtio_net.h
--- a/include/linux/virtio_net.h	Wed Jan 23 13:07:59 2008 +1100
+++ b/include/linux/virtio_net.h	Wed Jan 23 18:46:05 2008 +1100
@@ -6,12 +6,9 @@
 #define VIRTIO_ID_NET	1
 
 /* The feature bitmap for virtio net */
-#define VIRTIO_NET_F_NO_CSUM	0
-#define VIRTIO_NET_F_TSO4	1
-#define VIRTIO_NET_F_UFO	2
-#define VIRTIO_NET_F_TSO4_ECN	3
-#define VIRTIO_NET_F_TSO6	4
-#define VIRTIO_NET_F_MAC	5
+#define VIRTIO_NET_F_CSUM	0	/* Can handle pkts w/ partial csum */
+#define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
+#define VIRTIO_NET_F_GSO	6	/* Can handle pkts w/ any GSO type */
 
 struct virtio_net_config
 {
@@ -27,10 +24,9 @@ struct virtio_net_hdr
 	__u8 flags;
 #define VIRTIO_NET_HDR_GSO_NONE		0	// Not a GSO frame
 #define VIRTIO_NET_HDR_GSO_TCPV4	1	// GSO frame, IPv4 TCP (TSO)
-/* FIXME: Do we need this?  If they said they can handle ECN, do they care? */
-#define VIRTIO_NET_HDR_GSO_TCPV4_ECN	2	// GSO frame, IPv4 TCP w/ ECN
 #define VIRTIO_NET_HDR_GSO_UDP		3	// GSO frame, IPv4 UDP (UFO)
 #define VIRTIO_NET_HDR_GSO_TCPV6	4	// GSO frame, IPv6 TCP
+#define VIRTIO_NET_HDR_GSO_ECN		0x80	// TCP has ECN set
 	__u8 gso_type;
 	__u16 hdr_len;		/* Ethernet + IP + tcp/udp hdrs */
 	__u16 gso_size;		/* Bytes to append to gso_hdr_len per frame */

^ permalink raw reply

* [PATCH 2/3] partial checksum and GSO support for tun/tap.
From: Rusty Russell @ 2008-01-23 14:10 UTC (permalink / raw)
  To: netdev; +Cc: Herbert Xu, virtualization
In-Reply-To: <200801240107.38929.rusty@rustcorp.com.au>

(Changes since last time: we how have explicit IFF_RECV_CSUM and 
IFF_RECV_GSO bits, and some renaming of virtio_net hdr)

We use the virtio_net_hdr: it is an ABI already and designed to
encapsulate such metadata as GSO and partial checksums.

IFF_VIRTIO_HDR means you will write and read a 'struct virtio_net_hdr'
at the start of each packet.  You can always write packets with
partial checksum and gso to the tap device using this header.

IFF_RECV_CSUM means you can handle reading packets with partial
checksums.  If IFF_RECV_GSO is also set, it means you can handle
reading (all types of) GSO packets.

Note that there is no easy way to detect if these flags are supported:
see next patch.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/net/tun.c      |  259 +++++++++++++++++++++++++++++++++++++++++++------
 include/linux/if_tun.h |    6 +
 2 files changed, 238 insertions(+), 27 deletions(-)

diff -r cb85fb035378 drivers/net/tun.c
--- a/drivers/net/tun.c	Wed Jan 23 20:06:56 2008 +1100
+++ b/drivers/net/tun.c	Wed Jan 23 20:12:51 2008 +1100
@@ -62,6 +62,7 @@
 #include <linux/if_ether.h>
 #include <linux/if_tun.h>
 #include <linux/crc32.h>
+#include <linux/virtio_net.h>
 #include <net/net_namespace.h>
 
 #include <asm/system.h>
@@ -238,35 +239,188 @@ static unsigned int tun_chr_poll(struct 
 	return mask;
 }
 
+static struct sk_buff *copy_user_skb(size_t align, struct iovec *iv, size_t len)
+{
+	struct sk_buff *skb;
+
+	if (!(skb = alloc_skb(len + align, GFP_KERNEL)))
+		return ERR_PTR(-ENOMEM);
+
+	if (align)
+		skb_reserve(skb, align);
+
+	if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
+		kfree_skb(skb);
+		return ERR_PTR(-EFAULT);
+	}
+	return skb;
+}
+
+/* This will fail if they give us a crazy iovec, but that's their own fault. */
+static int get_user_skb_frags(const struct iovec *iv, size_t count,
+			      struct skb_frag_struct *f)
+{
+	unsigned int i, j, num_pg = 0;
+	int err;
+	struct page *pages[MAX_SKB_FRAGS];
+
+	down_read(&current->mm->mmap_sem);
+	for (i = 0; i < count; i++) {
+		int n, npages;
+		unsigned long base, len;
+		base = (unsigned long)iv[i].iov_base;
+		len = (unsigned long)iv[i].iov_len;
+
+		if (len == 0)
+			continue;
+
+		/* How many pages will this take? */
+		npages = 1 + (base + len - 1)/PAGE_SIZE - base/PAGE_SIZE;
+		if (unlikely(num_pg + npages > MAX_SKB_FRAGS)) {
+			err = -ENOSPC;
+			goto fail;
+		}
+		n = get_user_pages(current, current->mm, base, npages,
+				   0, 0, pages, NULL);
+		if (unlikely(n < 0)) {
+			err = n;
+			goto fail;
+		}
+
+		/* Transfer pages to the frag array */
+		for (j = 0; j < n; j++) {
+			f[num_pg].page = pages[j];
+			if (j == 0) {
+				f[num_pg].page_offset = offset_in_page(base);
+				f[num_pg].size = min(len, PAGE_SIZE -
+						     f[num_pg].page_offset);
+			} else {
+				f[num_pg].page_offset = 0;
+				f[num_pg].size = min(len, PAGE_SIZE);
+			}
+			len -= f[num_pg].size;
+			base += f[num_pg].size;
+			num_pg++;
+		}
+
+		if (unlikely(n != npages)) {
+			err = -EFAULT;
+			goto fail;
+		}
+	}
+	up_read(&current->mm->mmap_sem);
+	return num_pg;
+
+fail:
+	for (i = 0; i < num_pg; i++)
+		put_page(f[i].page);
+	up_read(&current->mm->mmap_sem);
+	return err;
+}
+
+
+static struct sk_buff *map_user_skb(const struct virtio_net_hdr *gso,
+				    size_t align, struct iovec *iv,
+				    size_t count, size_t len)
+{
+	struct sk_buff *skb;
+	struct skb_shared_info *sinfo;
+	int err;
+
+	if (!(skb = alloc_skb(gso->hdr_len + align, GFP_KERNEL)))
+		return ERR_PTR(-ENOMEM);
+
+	if (align)
+		skb_reserve(skb, align);
+
+	sinfo = skb_shinfo(skb);
+	sinfo->gso_size = gso->gso_size;
+	sinfo->gso_type = SKB_GSO_DODGY;
+	switch (gso->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+	case VIRTIO_NET_HDR_GSO_TCPV4:
+		sinfo->gso_type |= SKB_GSO_TCPV4;
+		break;
+	case VIRTIO_NET_HDR_GSO_TCPV6:
+		sinfo->gso_type |= SKB_GSO_TCPV6;
+		break;
+	case VIRTIO_NET_HDR_GSO_UDP:
+		sinfo->gso_type |= SKB_GSO_UDP;
+		break;
+	default:
+		err = -EINVAL;
+		goto fail;
+	}
+
+	if (gso->gso_type & VIRTIO_NET_HDR_GSO_ECN)
+		skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
+
+	/* Copy in the header. */
+	if (memcpy_fromiovec(skb_put(skb, gso->hdr_len), iv, gso->hdr_len)) {
+		err = -EFAULT;
+		goto fail;
+	}
+
+	err = get_user_skb_frags(iv, count, sinfo->frags);
+	if (err < 0)
+		goto fail;
+
+	sinfo->nr_frags = err;
+	skb->len += len;
+	skb->data_len += len;
+	
+	return skb;
+
+fail:
+	kfree_skb(skb);
+	return ERR_PTR(err);
+}
+
+static inline size_t iov_total(const struct iovec *iv, unsigned long count)
+{
+	unsigned long i;
+	size_t len;
+
+	for (i = 0, len = 0; i < count; i++)
+		len += iv[i].iov_len;
+
+	return len;
+}
+
 /* Get packet from user space buffer */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t num)
 {
 	struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
+	struct virtio_net_hdr gso = { 0, VIRTIO_NET_HDR_GSO_NONE };
 	struct sk_buff *skb;
-	size_t len = count, align = 0;
+	size_t tot_len = iov_total(iv, num);
+	size_t len = tot_len, align = 0;
 
 	if (!(tun->flags & TUN_NO_PI)) {
-		if ((len -= sizeof(pi)) > count)
+		if ((len -= sizeof(pi)) > tot_len)
 			return -EINVAL;
 
 		if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
+			return -EFAULT;
+	}
+	if (tun->flags & TUN_VIRTIO_HDR) {
+		if ((len -= sizeof(gso)) > tot_len)
+			return -EINVAL;
+
+		if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso)))
 			return -EFAULT;
 	}
 
 	if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV)
 		align = NET_IP_ALIGN;
 
-	if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
+	if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE)
+		skb = map_user_skb(&gso, align, iv, num, len);
+	else
+		skb = copy_user_skb(align, iv, len);
+
+	if (IS_ERR(skb)) {
 		tun->dev->stats.rx_dropped++;
-		return -ENOMEM;
-	}
-
-	if (align)
-		skb_reserve(skb, align);
-	if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
-		tun->dev->stats.rx_dropped++;
-		kfree_skb(skb);
-		return -EFAULT;
+		return PTR_ERR(skb);
 	}
 
 	switch (tun->flags & TUN_TYPE_MASK) {
@@ -280,7 +434,13 @@ static __inline__ ssize_t tun_get_user(s
 		break;
 	};
 
-	if (tun->flags & TUN_NOCHECKSUM)
+	if (gso.flags & (1 << VIRTIO_NET_F_CSUM)) {
+		if (!skb_partial_csum_set(skb,gso.csum_start,gso.csum_offset)) {
+			tun->dev->stats.rx_dropped++;
+			kfree_skb(skb);
+			return -EINVAL;
+		}
+	} else if (tun->flags & TUN_NOCHECKSUM)
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	netif_rx_ni(skb);
@@ -289,18 +449,7 @@ static __inline__ ssize_t tun_get_user(s
 	tun->dev->stats.rx_packets++;
 	tun->dev->stats.rx_bytes += len;
 
-	return count;
-}
-
-static inline size_t iov_total(const struct iovec *iv, unsigned long count)
-{
-	unsigned long i;
-	size_t len;
-
-	for (i = 0, len = 0; i < count; i++)
-		len += iv[i].iov_len;
-
-	return len;
+	return tot_len;
 }
 
 static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
@@ -313,7 +462,7 @@ static ssize_t tun_chr_aio_write(struct 
 
 	DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
 
-	return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
+	return tun_get_user(tun, (struct iovec *) iv, count);
 }
 
 /* Put packet to the user space buffer */
@@ -336,6 +485,42 @@ static __inline__ ssize_t tun_put_user(s
 		if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
 			return -EFAULT;
 		total += sizeof(pi);
+	}
+	if (tun->flags & TUN_VIRTIO_HDR) {
+		struct virtio_net_hdr gso;
+		struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+		if (skb_is_gso(skb)) {
+			gso.hdr_len = skb_transport_header(skb) - skb->data;
+			gso.gso_size = sinfo->gso_size;
+			if (sinfo->gso_type & SKB_GSO_TCPV4)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+			else if (sinfo->gso_type & SKB_GSO_TCPV6)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+			else if (sinfo->gso_type & SKB_GSO_UDP)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
+			else
+				BUG();
+			if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+				gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN;
+		} else
+			gso.gso_type = VIRTIO_NET_HDR_GSO_NONE;
+		
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+			gso.csum_start = skb->csum_start - skb_headroom(skb);
+			gso.csum_offset = skb->csum_offset;
+		} else {
+			gso.flags = 0;
+			gso.csum_offset = gso.csum_start = 0;
+		}
+
+		if ((len -= sizeof(gso)) < 0)
+			return -EINVAL;
+
+		if (memcpy_toiovec(iv, (void *)&gso, sizeof(gso)))
+			return -EFAULT;
+		total += sizeof(gso);
 	}
 
 	len = min_t(int, skb->len, len);
@@ -523,6 +708,17 @@ static int tun_set_iff(struct file *file
 
 		tun_net_init(dev);
 
+		/* Virtio header means we can handle csum & gso. */
+		if ((ifr->ifr_flags & (IFF_VIRTIO_HDR|IFF_RECV_CSUM)) ==
+		    (IFF_VIRTIO_HDR|IFF_RECV_CSUM)) {
+			dev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
+					NETIF_F_HIGHDMA | NETIF_F_FRAGLIST;
+
+			if (ifr->ifr_flags & IFF_RECV_GSO)
+				dev->features |= NETIF_F_TSO | NETIF_F_UFO |
+						 NETIF_F_TSO_ECN | NETIF_F_TSO6;
+		}
+
 		if (strchr(dev->name, '%')) {
 			err = dev_alloc_name(dev, dev->name);
 			if (err < 0)
@@ -543,6 +739,15 @@ static int tun_set_iff(struct file *file
 
 	if (ifr->ifr_flags & IFF_ONE_QUEUE)
 		tun->flags |= TUN_ONE_QUEUE;
+
+	if (ifr->ifr_flags & IFF_VIRTIO_HDR)
+		tun->flags |= TUN_VIRTIO_HDR;
+
+	if (ifr->ifr_flags & IFF_RECV_CSUM)
+		tun->flags |= TUN_RECV_CSUM;
+
+	if (ifr->ifr_flags & IFF_RECV_GSO)
+		tun->flags |= TUN_RECV_GSO;
 
 	file->private_data = tun;
 	tun->attached = 1;
diff -r cb85fb035378 include/linux/if_tun.h
--- a/include/linux/if_tun.h	Wed Jan 23 20:06:56 2008 +1100
+++ b/include/linux/if_tun.h	Wed Jan 23 20:12:51 2008 +1100
@@ -70,6 +70,9 @@ struct tun_struct {
 #define TUN_NO_PI	0x0040
 #define TUN_ONE_QUEUE	0x0080
 #define TUN_PERSIST 	0x0100	
+#define TUN_VIRTIO_HDR	0x0200
+#define TUN_RECV_CSUM	0x0400
+#define TUN_RECV_GSO	0x0400
 
 /* Ioctl defines */
 #define TUNSETNOCSUM  _IOW('T', 200, int) 
@@ -85,6 +88,9 @@ struct tun_struct {
 #define IFF_TAP		0x0002
 #define IFF_NO_PI	0x1000
 #define IFF_ONE_QUEUE	0x2000
+#define IFF_VIRTIO_HDR	0x4000
+#define IFF_RECV_CSUM	0x8000
+#define IFF_RECV_GSO	0x0800
 
 struct tun_pi {
 	unsigned short flags;

^ permalink raw reply

* [PATCH 3/3] Interface to query tun/tap features.
From: Rusty Russell @ 2008-01-23 14:14 UTC (permalink / raw)
  To: netdev; +Cc: Herbert Xu, virtualization
In-Reply-To: <200801240110.45178.rusty@rustcorp.com.au>

(No real change, just updated with new bits)

The problem with introducing IFF_RECV_CSUM and IFF_RECV_GSO is that
they need to set dev->features to enable GSO and/or checksumming,
which is supposed to be done before register_netdevice(), ie. as part
of TUNSETIFF.

Unfortunately, TUNSETIFF has always just ignored flags it doesn't understand,
so there's no good way of detecting whether the kernel supports IFF_GSO_HDR.

This patch implements a TUNGETFEATURES ioctl which returns all the valid IFF
flags.  It could be extended later to include other features.

Here's an example program which uses it:

#include <linux/if_tun.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <err.h>
#include <stdio.h>

static struct {
	unsigned int flag;
	const char *name;
} known_flags[] = {
	{ IFF_TUN, "TUN" },
	{ IFF_TAP, "TAP" },
	{ IFF_NO_PI, "NO_PI" },
	{ IFF_ONE_QUEUE, "ONE_QUEUE" },
	{ IFF_VIRTIO_HDR, "VIRTIO_HDR" },
	{ IFF_RECV_CSUM, "RECV_CSUM" },
	{ IFF_RECV_GSO, "RECV_GSO" },
};

int main()
{
	unsigned int features, i;

	int netfd = open("/dev/net/tun", O_RDWR);
	if (netfd < 0)
		err(1, "Opening /dev/net/tun");

	if (ioctl(netfd, TUNGETFEATURES, &features) != 0) {
		printf("Kernel does not support TUNGETFEATURES, guessing\n");
		features = (IFF_TUN|IFF_TAP|IFF_NO_PI|IFF_ONE_QUEUE);
	}
	printf("Available features are: ");
	for (i = 0; i < sizeof(known_flags)/sizeof(known_flags[0]); i++) {
		if (features & known_flags[i].flag) {
			features &= ~known_flags[i].flag;
			printf("%s ", known_flags[i].name);
		}
	}
	if (features)
		printf("(UNKNOWN %#x)", features);
	printf("\n");
	return 0;
}

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/net/tun.c      |    9 +++++++++
 include/linux/if_tun.h |    3 +++
 2 files changed, 12 insertions(+)

diff -r c0e7a8b99325 drivers/net/tun.c
--- a/drivers/net/tun.c	Wed Jan 23 20:12:51 2008 +1100
+++ b/drivers/net/tun.c	Wed Jan 23 20:17:28 2008 +1100
@@ -790,6 +790,15 @@ static int tun_chr_ioctl(struct inode *i
 		return 0;
 	}
 
+	if (cmd == TUNGETFEATURES) {
+		/* Currently this just means: "what IFF flags are valid?".
+		 * This is needed because we never checked for invalid flags on
+		 * TUNSETIFF.  This was introduced with IFF_GSO_HDR, so if a
+		 * kernel doesn't have this ioctl, it doesn't have GSO header
+		 * support. */
+		return put_user(IFF_ALL_FLAGS, (unsigned int __user*)argp);
+	}
+
 	if (!tun)
 		return -EBADFD;
 
diff -r c0e7a8b99325 include/linux/if_tun.h
--- a/include/linux/if_tun.h	Wed Jan 23 20:12:51 2008 +1100
+++ b/include/linux/if_tun.h	Wed Jan 23 20:17:28 2008 +1100
@@ -82,6 +82,7 @@ struct tun_struct {
 #define TUNSETOWNER   _IOW('T', 204, int)
 #define TUNSETLINK    _IOW('T', 205, int)
 #define TUNSETGROUP   _IOW('T', 206, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
@@ -91,6 +92,8 @@ struct tun_struct {
 #define IFF_VIRTIO_HDR	0x4000
 #define IFF_RECV_CSUM	0x8000
 #define IFF_RECV_GSO	0x0800
+#define IFF_ALL_FLAGS (IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE | \
+		       IFF_VIRTIO_HDR | IFF_RECV_CSUM | IFF_RECV_GSO)
 
 struct tun_pi {
 	unsigned short flags;

^ permalink raw reply

* [PATCH net-2.6.25] [PKTGEN] Remove an unused definition in pktgen.c.
From: Rami Rosen @ 2008-01-23 14:38 UTC (permalink / raw)
  To: David Miller, netdev

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

Hi,
- Remove an unused definition (LAT_BUCKETS_MAX) in net/core/pktgen.c.
- Remove the corresponding comment.
- The LAT_BUCKETS_MAX seems to have to do with a patch from a long
time ago which was not applied (Ben Greear), which dealt with latency
counters.

See, for example : http://oss.sgi.com/archives/netdev/2002-09/msg00184.html

Regards,
Rami Rosen


Signed-off-by: Rami Rosen <ramirose@gmail.com>

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 448 bytes --]

diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index eebccdb..b7f2de1 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -170,8 +170,6 @@
 
 #define VERSION  "pktgen v2.69: Packet Generator for packet performance testing.\n"
 
-/* The buckets are exponential in 'width' */
-#define LAT_BUCKETS_MAX 32
 #define IP_NAME_SZ 32
 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
 #define MPLS_STACK_BOTTOM htonl(0x00000100)

^ permalink raw reply related

* My 802.3ad is my bond
From: Steven Whitehouse @ 2008-01-23 15:45 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: netdev

Hi,

This commit: ece95f7fefe3afae19e641e1b3f5e64b00d5b948 seems to have
caused a problem with parsing bond arguments as now only the numeric
arguments seem to work (in modprobe.conf) and specifying 802.3ad fails.
When I revert that patch in my local tree all seems ok.

Also I notice that one of my two NICs now reports this:

bonding: bond0: link status definitely down for interface eth0,
disabling it
bonding: bond0: Interface eth0 is already enslaved!
bond0.5: no IPv6 routers present

which I think is also new with this set of bonding updates, before it
used to use both interfaces ok. I've not worked out which of the other
patches causes this so far, but I can if its helpful,

Steve.



^ permalink raw reply

* Re: [IPV4 0/9] TRIE performance patches
From: Stephen Hemminger @ 2008-01-23 16:31 UTC (permalink / raw)
  To: Robert Olsson; +Cc: David Miller, netdev
In-Reply-To: <18327.18935.137799.285515@robur.slu.se>

Robert Olsson wrote:
> Stephen Hemminger writes:
>
>  > Time to handle a full BGP load (163K of routes).
>  > 
>  > Before:		Load		Dump		Flush
>  >
>  > kmem_cache	3.8		13.0		7.2
>  > iter		3.9		12.3		6.9
>  > unordered	3.1		11.9		4.9
>  > find_node	3.1		 0.3		1.2
>
>  I certainly like the speed but what will we brake when
>  we don't return in longest prefix order?
>
> labb:/# ip r
> default via 10.10.10.1 dev eth0 
> 5.0.0.0/8 via 192.168.2.2 dev eth3 
> 10.10.10.0/24 dev eth0  proto kernel  scope link  src 10.10.10.2 
> 10.10.11.0/24 dev eth1  proto kernel  scope link  src 10.10.11.1 
> 11.0.0.0/8 via 10.10.11.2 dev eth1 
> 192.168.1.0/24 dev eth2  proto kernel  scope link  src 192.168.1.2 
> 192.168.2.0/24 dev eth3  proto kernel  scope link  src 192.168.2.1 
>
> labb:/# ip route list match 10.10.10.1
> default via 10.10.10.1 dev eth0 
> 10.10.10.0/24 dev eth0  proto kernel  scope link  src 10.10.10.2 
> labb:/# 
>
> Maybe the unordered dump can be ordered cheaply...
>
> Cheers.
> 				--ro
>
>   
Hash returned the routes in prefix order (then random).  Returning the 
routes in numerical order
seems just as logical. I'm going to test on quagga.


^ permalink raw reply

* [NET_SCHED 00/15]: Make use of new netlink API features
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy

Hi Dave,

these patches change the packet schedulers/classifers/actions to make use
of the features of the new netlink API, like typeful attribute dumping and
parsing, automatic basic attribute validation etc. The also fix a bug and
a warning introduced by my last set of patches.

Please apply, thanks.


 include/linux/pkt_sched.h |    2 +
 include/net/act_api.h     |    4 +-
 net/sched/act_api.c       |  197 +++++++++++++++++++++++++--------------------
 net/sched/act_gact.c      |   20 +++--
 net/sched/act_ipt.c       |   33 +++++---
 net/sched/act_mirred.c    |   15 +++-
 net/sched/act_nat.c       |   15 +++-
 net/sched/act_pedit.c     |   15 +++-
 net/sched/act_police.c    |   43 +++++-----
 net/sched/act_simple.c    |   15 +++-
 net/sched/cls_api.c       |   30 ++++---
 net/sched/cls_basic.c     |   33 ++++----
 net/sched/cls_fw.c        |   41 +++++-----
 net/sched/cls_route.c     |   47 +++++------
 net/sched/cls_rsvp.h      |   45 +++++------
 net/sched/cls_tcindex.c   |   70 ++++++++--------
 net/sched/cls_u32.c       |   56 +++++++------
 net/sched/em_meta.c       |   18 +++--
 net/sched/ematch.c        |   31 +++++---
 net/sched/sch_api.c       |    7 +-
 net/sched/sch_atm.c       |   45 ++++++----
 net/sched/sch_cbq.c       |   75 +++++++----------
 net/sched/sch_dsmark.c    |   37 +++++----
 net/sched/sch_gred.c      |   28 +++++--
 net/sched/sch_hfsc.c      |   30 ++++---
 net/sched/sch_htb.c       |   64 ++++++++++-----
 net/sched/sch_ingress.c   |   12 ++--
 net/sched/sch_netem.c     |   73 +++++++---------
 net/sched/sch_prio.c      |    9 ++-
 net/sched/sch_red.c       |   16 +++-
 net/sched/sch_tbf.c       |   29 +++++---
 31 files changed, 650 insertions(+), 505 deletions(-)

Patrick McHardy (15):
      [NET_SCHED]: sch_atm: fix format string warning
      [NET_SCHED]: sch_netem: use nla_parse_nested_compat
      [NET_SCHED]: act_api: fix netlink API conversion bug
      [NET_SCHED]: act_api: use nlmsg_parse
      [NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get
      [NET_SCHED]: Propagate nla_parse return value
      [NET_SCHED]: Use nla_nest_start/nla_nest_end
      [NET_SCHED]: Use NLA_PUT_STRING for string dumping
      [NET_SCHED]: Use typeful attribute construction helpers
      [NET_SCHED]: Use typeful attribute parsing helpers
      [NET_SCHED]: sch_api: introduce constant for rate table size
      [NET_SCHED]: Use nla_policy for attribute validation in packet schedulers
      [NET_SCHED]: Use nla_policy for attribute validation in classifiers
      [NET_SCHED]: Use nla_policy for attribute validation in actions
      [NET_SCHED]: Use nla_policy for attribute validation in ematches

^ permalink raw reply

* [NET_SCHED 01/15]: sch_atm: fix format string warning
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: sch_atm: fix format string warning

Fix format string warning introduces by the netlink API conversion:

net/sched/sch_atm.c:250: warning: format '%lu' expects type 'long unsigned int', but argument 3 has type 'int'.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 3bab4166cf0350552419d7871b4df463c5aed2ea
tree c08015e39f6f1da0255f1325cc21dfda0c738bc2
parent a7f92e3b13a5e3db64383c503f2249dc74b41bd6
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 16:48:28 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 16:48:28 +0100

 net/sched/sch_atm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index eb01aae..e587391 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -246,7 +246,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 		if (!excess)
 			return -ENOENT;
 	}
-	pr_debug("atm_tc_change: type %d, payload %lu, hdr_len %d\n",
+	pr_debug("atm_tc_change: type %d, payload %d, hdr_len %d\n",
 		 opt->nla_type, nla_len(opt), hdr_len);
 	sock = sockfd_lookup(fd, &error);
 	if (!sock)

^ permalink raw reply related

* [NET_SCHED 02/15]: sch_netem: use nla_parse_nested_compat
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: sch_netem: use nla_parse_nested_compat

Replace open coded equivalent of nla_parse_nested_compat().

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 1af28b79f4f0a67db344938ef6739ad2af1a72a7
tree 52294414fad2e6cd11aa719113f160a47bbe5bd5
parent 3bab4166cf0350552419d7871b4df463c5aed2ea
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 16:48:46 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 16:48:46 +0100

 net/sched/sch_netem.c |   58 ++++++++++++++++++++++---------------------------
 1 files changed, 26 insertions(+), 32 deletions(-)

diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index a7b58df..1a75579 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -407,13 +407,18 @@ static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
 static int netem_change(struct Qdisc *sch, struct nlattr *opt)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
+	struct nlattr *tb[TCA_NETEM_MAX + 1];
 	struct tc_netem_qopt *qopt;
 	int ret;
 
-	if (opt == NULL || nla_len(opt) < sizeof(*qopt))
+	if (opt == NULL)
 		return -EINVAL;
 
-	qopt = nla_data(opt);
+	ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, NULL, qopt,
+				      sizeof(*qopt));
+	if (ret < 0)
+		return ret;
+
 	ret = set_fifo_limit(q->qdisc, qopt->limit);
 	if (ret) {
 		pr_debug("netem: can't set fifo limit\n");
@@ -434,39 +439,28 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
 	if (q->gap)
 		q->reorder = ~0;
 
-	/* Handle nested options after initial queue options.
-	 * Should have put all options in nested format but too late now.
-	 */
-	if (nla_len(opt) > sizeof(*qopt)) {
-		struct nlattr *tb[TCA_NETEM_MAX + 1];
-		if (nla_parse(tb, TCA_NETEM_MAX,
-			      nla_data(opt) + sizeof(*qopt),
-			      nla_len(opt) - sizeof(*qopt), NULL))
-			return -EINVAL;
-
-		if (tb[TCA_NETEM_CORR]) {
-			ret = get_correlation(sch, tb[TCA_NETEM_CORR]);
-			if (ret)
-				return ret;
-		}
+	if (tb[TCA_NETEM_CORR]) {
+		ret = get_correlation(sch, tb[TCA_NETEM_CORR]);
+		if (ret)
+			return ret;
+	}
 
-		if (tb[TCA_NETEM_DELAY_DIST]) {
-			ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
-			if (ret)
-				return ret;
-		}
+	if (tb[TCA_NETEM_DELAY_DIST]) {
+		ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
+		if (ret)
+			return ret;
+	}
 
-		if (tb[TCA_NETEM_REORDER]) {
-			ret = get_reorder(sch, tb[TCA_NETEM_REORDER]);
-			if (ret)
-				return ret;
-		}
+	if (tb[TCA_NETEM_REORDER]) {
+		ret = get_reorder(sch, tb[TCA_NETEM_REORDER]);
+		if (ret)
+			return ret;
+	}
 
-		if (tb[TCA_NETEM_CORRUPT]) {
-			ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
-			if (ret)
-				return ret;
-		}
+	if (tb[TCA_NETEM_CORRUPT]) {
+		ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
+		if (ret)
+			return ret;
 	}
 
 	return 0;

^ permalink raw reply related

* [NET_SCHED 03/15]: act_api: fix netlink API conversion bug
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: act_api: fix netlink API conversion bug

Fix two invalid attribute accesses, indices start at 1 with the new
netlink API.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 512b2ab20730e1d24e36fb94eab4a2731e90e315
tree e3583125570ee0c7a57feac7aa6fcabe2541112a
parent 1af28b79f4f0a67db344938ef6739ad2af1a72a7
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:10:00 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:10:00 +0100

 net/sched/act_api.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index ebd21d2..ae077ed 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -997,11 +997,11 @@ find_dump_kind(struct nlmsghdr *n)
 	if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1),
 		      NLMSG_ALIGN(nla_len(tb1)), NULL) < 0)
 		return NULL;
-	if (tb[0] == NULL)
-		return NULL;
 
-	if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[0]),
-		      nla_len(tb[0]), NULL) < 0)
+	if (tb[1] == NULL)
+		return NULL;
+	if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]),
+		      nla_len(tb[1]), NULL) < 0)
 		return NULL;
 	kind = tb2[TCA_ACT_KIND];
 

^ permalink raw reply related

* [NET_SCHED 05/15]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 0919ac24aa4bd6978806f35f8daefe32aa997823
tree 95e2c04521d6a09c080eac8735ab0598c3b3ff5b
parent f9f9cbaccb1a58ea02318250192effe1e2e1e715
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:41 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:41 +0100

 include/net/act_api.h |    4 +--
 net/sched/act_api.c   |   71 +++++++++++++++++++++++++++----------------------
 net/sched/cls_api.c   |   14 +++++-----
 3 files changed, 48 insertions(+), 41 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index c5ac61a..565eed8 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -114,8 +114,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
 extern int tcf_unregister_action(struct tc_action_ops *a);
 extern void tcf_action_destroy(struct tc_action *a, int bind);
 extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
-extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind, int *err);
-extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind, int *err);
+extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
+extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
 extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2fe0345..ea80f82 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
+#include <linux/err.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/sch_generic.h>
@@ -463,15 +464,16 @@ errout:
 }
 
 struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
-				    char *name, int ovr, int bind, int *err)
+				    char *name, int ovr, int bind)
 {
 	struct tc_action *a;
 	struct tc_action_ops *a_o;
 	char act_name[IFNAMSIZ];
 	struct nlattr *tb[TCA_ACT_MAX+1];
 	struct nlattr *kind;
+	int err;
 
-	*err = -EINVAL;
+	err = -EINVAL;
 
 	if (name == NULL) {
 		if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
@@ -502,36 +504,35 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
 		 * indicate this using -EAGAIN.
 		 */
 		if (a_o != NULL) {
-			*err = -EAGAIN;
+			err = -EAGAIN;
 			goto err_mod;
 		}
 #endif
-		*err = -ENOENT;
+		err = -ENOENT;
 		goto err_out;
 	}
 
-	*err = -ENOMEM;
+	err = -ENOMEM;
 	a = kzalloc(sizeof(*a), GFP_KERNEL);
 	if (a == NULL)
 		goto err_mod;
 
 	/* backward compatibility for policer */
 	if (name == NULL)
-		*err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
+		err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
 	else
-		*err = a_o->init(nla, est, a, ovr, bind);
-	if (*err < 0)
+		err = a_o->init(nla, est, a, ovr, bind);
+	if (err < 0)
 		goto err_free;
 
 	/* module count goes up only when brand new policy is created
 	   if it exists and is only bound to in a_o->init() then
 	   ACT_P_CREATED is not returned (a zero is).
 	*/
-	if (*err != ACT_P_CREATED)
+	if (err != ACT_P_CREATED)
 		module_put(a_o->owner);
 	a->ops = a_o;
 
-	*err = 0;
 	return a;
 
 err_free:
@@ -539,24 +540,22 @@ err_free:
 err_mod:
 	module_put(a_o->owner);
 err_out:
-	return NULL;
+	return ERR_PTR(err);
 }
 
 struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
-				  char *name, int ovr, int bind, int *err)
+				  char *name, int ovr, int bind)
 {
 	struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
 	struct tc_action *head = NULL, *act, *act_prev = NULL;
 	int i;
 
-	if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0) {
-		*err = -EINVAL;
-		return head;
-	}
+	if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0)
+		return ERR_PTR(-EINVAL);
 
 	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
-		act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
-		if (act == NULL)
+		act = tcf_action_init_1(tb[i], est, name, ovr, bind);
+		if (IS_ERR(act))
 			goto err;
 		act->order = i;
 
@@ -571,7 +570,7 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
 err:
 	if (head != NULL)
 		tcf_action_destroy(head, bind);
-	return NULL;
+	return act;
 }
 
 int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
@@ -668,44 +667,46 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
 }
 
 static struct tc_action *
-tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int *err)
+tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 {
 	struct nlattr *tb[TCA_ACT_MAX+1];
 	struct tc_action *a;
 	int index;
+	int err;
 
-	*err = -EINVAL;
+	err = -EINVAL;
 	if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
-		return NULL;
+		goto err_out;
 
 	if (tb[TCA_ACT_INDEX] == NULL ||
 	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
-		return NULL;
+		goto err_out;
 	index = *(int *)nla_data(tb[TCA_ACT_INDEX]);
 
-	*err = -ENOMEM;
+	err = -ENOMEM;
 	a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
 	if (a == NULL)
-		return NULL;
+		goto err_out;
 
-	*err = -EINVAL;
+	err = -EINVAL;
 	a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
 	if (a->ops == NULL)
 		goto err_free;
 	if (a->ops->lookup == NULL)
 		goto err_mod;
-	*err = -ENOENT;
+	err = -ENOENT;
 	if (a->ops->lookup(a, index) == 0)
 		goto err_mod;
 
 	module_put(a->ops->owner);
-	*err = 0;
 	return a;
+
 err_mod:
 	module_put(a->ops->owner);
 err_free:
 	kfree(a);
-	return NULL;
+err_out:
+	return ERR_PTR(err);
 }
 
 static void cleanup_a(struct tc_action *act)
@@ -816,9 +817,11 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
 	}
 
 	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
-		act = tcf_action_get_1(tb[i], n, pid, &ret);
-		if (act == NULL)
+		act = tcf_action_get_1(tb[i], n, pid);
+		if (IS_ERR(act)) {
+			ret = PTR_ERR(act);
 			goto err;
+		}
 		act->order = i;
 
 		if (head == NULL)
@@ -912,9 +915,13 @@ tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
 	struct tc_action *a;
 	u32 seq = n->nlmsg_seq;
 
-	act = tcf_action_init(nla, NULL, NULL, ovr, 0, &ret);
+	act = tcf_action_init(nla, NULL, NULL, ovr, 0);
 	if (act == NULL)
 		goto done;
+	if (IS_ERR(act)) {
+		ret = PTR_ERR(act);
+		goto done;
+	}
 
 	/* dump then free all the actions after update; inserted policy
 	 * stays intact
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d870478..92fa155 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/netlink.h>
+#include <linux/err.h>
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/netlink.h>
@@ -487,23 +488,22 @@ int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
 
 #ifdef CONFIG_NET_CLS_ACT
 	{
-		int err;
 		struct tc_action *act;
 
 		if (map->police && tb[map->police]) {
 			act = tcf_action_init_1(tb[map->police], rate_tlv,
 						"police", TCA_ACT_NOREPLACE,
-						TCA_ACT_BIND, &err);
-			if (act == NULL)
-				return err;
+						TCA_ACT_BIND);
+			if (IS_ERR(act))
+				return PTR_ERR(act);
 
 			act->type = TCA_OLD_COMPAT;
 			exts->action = act;
 		} else if (map->action && tb[map->action]) {
 			act = tcf_action_init(tb[map->action], rate_tlv, NULL,
-				TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
-			if (act == NULL)
-				return err;
+					      TCA_ACT_NOREPLACE, TCA_ACT_BIND);
+			if (IS_ERR(act))
+				return PTR_ERR(act);
 
 			exts->action = act;
 		}

^ permalink raw reply related

* [NET_SCHED 04/15]: act_api: use nlmsg_parse
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: act_api: use nlmsg_parse

Convert open-coded nlmsg_parse to use the real function.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit f9f9cbaccb1a58ea02318250192effe1e2e1e715
tree 7ea770493ca465a7aac1a7779b2aa4c593de3a97
parent 512b2ab20730e1d24e36fb94eab4a2731e90e315
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:10:31 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:10:31 +0100

 net/sched/act_api.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index ae077ed..2fe0345 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -984,11 +984,8 @@ find_dump_kind(struct nlmsghdr *n)
 	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
 	struct nlattr *nla[TCAA_MAX + 1];
 	struct nlattr *kind;
-	int min_len = NLMSG_LENGTH(sizeof(struct tcamsg));
-	int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len);
-	struct nlattr *attr = (void *) n + NLMSG_ALIGN(min_len);
 
-	if (nla_parse(nla, TCAA_MAX, attr, attrlen, NULL) < 0)
+	if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0)
 		return NULL;
 	tb1 = nla[TCA_ACT_TAB];
 	if (tb1 == NULL)

^ permalink raw reply related

* [NET_SCHED 06/15]: Propagate nla_parse return value
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: Propagate nla_parse return value

nla_parse() returns more detailed errno codes, propagate them back on error.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit f9b5ab497909e836983bc31e5e7ad5065ccba6bc
tree 3b2ca0f7dcf925d113fce3e376cf7f2e995f0b7a
parent 0919ac24aa4bd6978806f35f8daefe32aa997823
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:54 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:54 +0100

 net/sched/act_api.c     |   29 ++++++++++++++++++-----------
 net/sched/act_gact.c    |    7 ++++++-
 net/sched/act_ipt.c     |    6 +++++-
 net/sched/act_mirred.c  |    8 ++++++--
 net/sched/act_nat.c     |    8 ++++++--
 net/sched/act_pedit.c   |    8 ++++++--
 net/sched/act_police.c  |    6 +++++-
 net/sched/act_simple.c  |    8 ++++++--
 net/sched/cls_basic.c   |    7 ++++---
 net/sched/cls_fw.c      |    5 +++--
 net/sched/cls_route.c   |    5 +++--
 net/sched/cls_rsvp.h    |    5 +++--
 net/sched/cls_tcindex.c |    6 ++++--
 net/sched/cls_u32.c     |    5 +++--
 net/sched/em_meta.c     |    6 ++++--
 net/sched/ematch.c      |    6 ++++--
 net/sched/sch_atm.c     |    6 +++++-
 net/sched/sch_cbq.c     |   14 +++++++++++---
 net/sched/sch_dsmark.c  |   14 ++++++++++++--
 net/sched/sch_gred.c    |   16 +++++++++++++---
 net/sched/sch_hfsc.c    |    7 ++++++-
 net/sched/sch_htb.c     |   23 +++++++++++++++++++----
 net/sched/sch_prio.c    |    9 ++++++---
 net/sched/sch_red.c     |    7 ++++++-
 net/sched/sch_tbf.c     |   10 +++++++---
 25 files changed, 171 insertions(+), 60 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index ea80f82..87818d7 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -473,17 +473,18 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
 	struct nlattr *kind;
 	int err;
 
-	err = -EINVAL;
-
 	if (name == NULL) {
-		if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
+		err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+		if (err < 0)
 			goto err_out;
+		err = -EINVAL;
 		kind = tb[TCA_ACT_KIND];
 		if (kind == NULL)
 			goto err_out;
 		if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
 			goto err_out;
 	} else {
+		err = -EINVAL;
 		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
 			goto err_out;
 	}
@@ -548,10 +549,12 @@ struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
 {
 	struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
 	struct tc_action *head = NULL, *act, *act_prev = NULL;
+	int err;
 	int i;
 
-	if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0)
-		return ERR_PTR(-EINVAL);
+	err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
+	if (err < 0)
+		return ERR_PTR(err);
 
 	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
 		act = tcf_action_init_1(tb[i], est, name, ovr, bind);
@@ -674,10 +677,11 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 	int index;
 	int err;
 
-	err = -EINVAL;
-	if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
+	err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+	if (err < 0)
 		goto err_out;
 
+	err = -EINVAL;
 	if (tb[TCA_ACT_INDEX] == NULL ||
 	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
 		goto err_out;
@@ -759,9 +763,11 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 
 	b = skb_tail_pointer(skb);
 
-	if (nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL) < 0)
+	err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+	if (err < 0)
 		goto err_out;
 
+	err = -EINVAL;
 	kind = tb[TCA_ACT_KIND];
 	a->ops = tc_lookup_action(kind);
 	if (a->ops == NULL)
@@ -804,12 +810,13 @@ err_out:
 static int
 tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
 {
-	int i, ret = 0;
+	int i, ret;
 	struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
 	struct tc_action *head = NULL, *act, *act_prev = NULL;
 
-	if (nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL) < 0)
-		return -EINVAL;
+	ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
+	if (ret < 0)
+		return ret;
 
 	if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
 		if (tb[0] != NULL && tb[1] == NULL)
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 5402cf8..df214d4 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -61,10 +61,15 @@ static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
 	struct tcf_gact *gact;
 	struct tcf_common *pc;
 	int ret = 0;
+	int err;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_GACT_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_GACT_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_GACT_PARMS] == NULL ||
 	    nla_len(tb[TCA_GACT_PARMS]) < sizeof(*parm))
 		return -EINVAL;
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index fee5282..1269334 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -104,9 +104,13 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
 	u32 hook = 0;
 	u32 index = 0;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_IPT_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_IPT_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_IPT_HOOK] == NULL ||
 	    nla_len(tb[TCA_IPT_HOOK]) < sizeof(u32))
 		return -EINVAL;
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index db943a8..6cb5e30 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -62,12 +62,16 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
 	struct tcf_mirred *m;
 	struct tcf_common *pc;
 	struct net_device *dev = NULL;
-	int ret = 0;
+	int ret = 0, err;
 	int ok_push = 0;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_MIRRED_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_MIRRED_PARMS] == NULL ||
 	    nla_len(tb[TCA_MIRRED_PARMS]) < sizeof(*parm))
 		return -EINVAL;
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index be007bb..5a512d4 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -45,13 +45,17 @@ static int tcf_nat_init(struct nlattr *nla, struct nlattr *est,
 {
 	struct nlattr *tb[TCA_NAT_MAX + 1];
 	struct tc_nat *parm;
-	int ret = 0;
+	int ret = 0, err;
 	struct tcf_nat *p;
 	struct tcf_common *pc;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_NAT_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_NAT_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_NAT_PARMS] == NULL ||
 	    nla_len(tb[TCA_NAT_PARMS]) < sizeof(*parm))
 		return -EINVAL;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 88d8a15..1b9ca45 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -38,15 +38,19 @@ static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
 {
 	struct nlattr *tb[TCA_PEDIT_MAX + 1];
 	struct tc_pedit *parm;
-	int ret = 0;
+	int ret = 0, err;
 	struct tcf_pedit *p;
 	struct tcf_common *pc;
 	struct tc_pedit_key *keys = NULL;
 	int ksize;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_PEDIT_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_PEDIT_PARMS] == NULL ||
 	    nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm))
 		return -EINVAL;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 3af5759..c0fce9b 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -129,9 +129,13 @@ static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
 	struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
 	int size;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_POLICE_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_POLICE_TBF] == NULL)
 		return -EINVAL;
 	size = nla_len(tb[TCA_POLICE_TBF]);
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index d3226e2..cedaadf 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -93,11 +93,15 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
 	struct tcf_common *pc;
 	void *defdata;
 	u32 datalen = 0;
-	int ret = 0;
+	int ret = 0, err;
 
-	if (nla == NULL || nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL) < 0)
+	if (nla == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_DEF_PARMS] == NULL ||
 	    nla_len(tb[TCA_DEF_PARMS]) < sizeof(*parm))
 		return -EINVAL;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 3953da3..524b788 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -166,7 +166,7 @@ errout:
 static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 			struct nlattr **tca, unsigned long *arg)
 {
-	int err = -EINVAL;
+	int err;
 	struct basic_head *head = (struct basic_head *) tp->root;
 	struct nlattr *tb[TCA_BASIC_MAX + 1];
 	struct basic_filter *f = (struct basic_filter *) *arg;
@@ -174,8 +174,9 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	if (tca[TCA_OPTIONS] == NULL)
 		return -EINVAL;
 
-	if (nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL);
+	if (err < 0)
+		return err;
 
 	if (f != NULL) {
 		if (handle && f->handle != handle)
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index db6e90a..a1a9f4d 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -246,8 +246,9 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
 	if (!opt)
 		return handle ? -EINVAL : 0;
 
-	if (nla_parse_nested(tb, TCA_FW_MAX, opt, NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_FW_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
 	if (f != NULL) {
 		if (f->id != handle && handle)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index b1aae84..3aa8109 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -440,8 +440,9 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
 	if ((f = (struct route4_filter*)*arg) != NULL) {
 		if (f->handle != handle && handle)
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 2364c79..5747408 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -416,8 +416,9 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
 	err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map);
 	if (err < 0)
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index ed80239..6b84d27 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -350,6 +350,7 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	struct nlattr *tb[TCA_TCINDEX_MAX + 1];
 	struct tcindex_data *p = PRIV(tp);
 	struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
+	int err;
 
 	pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
 	    "p %p,r %p,*arg 0x%lx\n",
@@ -358,8 +359,9 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	if (!opt)
 		return 0;
 
-	if (nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
 	return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE]);
 }
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index aaf5049..3228cc4 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -531,8 +531,9 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (nla_parse_nested(tb, TCA_U32_MAX, opt, NULL) < 0)
-		return -EINVAL;
+	err = nla_parse_nested(tb, TCA_U32_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
 	if ((n = (struct tc_u_knode*)*arg) != NULL) {
 		if (TC_U32_KEY(n->handle) == 0)
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 92b6863..dd57236 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -749,14 +749,16 @@ static inline int meta_is_supported(struct meta_value *val)
 static int em_meta_change(struct tcf_proto *tp, void *data, int len,
 			  struct tcf_ematch *m)
 {
-	int err = -EINVAL;
+	int err;
 	struct nlattr *tb[TCA_EM_META_MAX + 1];
 	struct tcf_meta_hdr *hdr;
 	struct meta_match *meta = NULL;
 
-	if (nla_parse(tb, TCA_EM_META_MAX, data, len, NULL) < 0)
+	err = nla_parse(tb, TCA_EM_META_MAX, data, len, NULL);
+	if (err < 0)
 		goto errout;
 
+	err = -EINVAL;
 	if (tb[TCA_EM_META_HDR] == NULL ||
 	    nla_len(tb[TCA_EM_META_HDR]) < sizeof(*hdr))
 		goto errout;
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 72d9b27..d2b480f 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -301,7 +301,7 @@ errout:
 int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
 			 struct tcf_ematch_tree *tree)
 {
-	int idx, list_len, matches_len, err = -EINVAL;
+	int idx, list_len, matches_len, err;
 	struct nlattr *tb[TCA_EMATCH_TREE_MAX + 1];
 	struct nlattr *rt_match, *rt_hdr, *rt_list;
 	struct tcf_ematch_tree_hdr *tree_hdr;
@@ -312,9 +312,11 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
 		return 0;
 	}
 
-	if (nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL) < 0)
+	err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL);
+	if (err < 0)
 		goto errout;
 
+	err = -EINVAL;
 	rt_hdr = tb[TCA_EMATCH_TREE_HDR];
 	rt_list = tb[TCA_EMATCH_TREE_LIST];
 
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index e587391..aaa32a2 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -223,8 +223,12 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 	 */
 	if (flow)
 		return -EBUSY;
-	if (opt == NULL || nla_parse_nested(tb, TCA_ATM_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
+	error = nla_parse_nested(tb, TCA_ATM_MAX, opt, NULL);
+	if (error < 0)
+		return error;
+
 	if (!tb[TCA_ATM_FD] || nla_len(tb[TCA_ATM_FD]) < sizeof(fd))
 		return -EINVAL;
 	fd = *(int *)nla_data(tb[TCA_ATM_FD]);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 5c8667e..585f8a6 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1382,9 +1382,13 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_CBQ_MAX + 1];
 	struct tc_ratespec *r;
+	int err;
+
+	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL);
+	if (err < 0)
+		return err;
 
-	if (nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL) < 0 ||
-	    tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL ||
+	if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL ||
 	    nla_len(tb[TCA_CBQ_RATE]) < sizeof(struct tc_ratespec))
 		return -EINVAL;
 
@@ -1764,9 +1768,13 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	struct cbq_class *parent;
 	struct qdisc_rate_table *rtab = NULL;
 
-	if (opt==NULL || nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_CBQ_OVL_STRATEGY] &&
 	    nla_len(tb[TCA_CBQ_OVL_STRATEGY]) < sizeof(struct tc_cbq_ovl))
 		return -EINVAL;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index f183ab7..f1d0a08 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -116,9 +116,14 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
 		goto errout;
 	}
 
-	if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL))
+	if (!opt)
 		goto errout;
 
+	err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
 	if (tb[TCA_DSMARK_MASK]) {
 		if (nla_len(tb[TCA_DSMARK_MASK]) < sizeof(u8))
 			goto errout;
@@ -351,9 +356,14 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
 
 	pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
 
-	if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL) < 0)
+	if (!opt)
+		goto errout;
+
+	err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL);
+	if (err < 0)
 		goto errout;
 
+	err = -EINVAL;
 	if (nla_len(tb[TCA_DSMARK_INDICES]) < sizeof(u16))
 		goto errout;
 	indices = nla_get_u16(tb[TCA_DSMARK_INDICES]);
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 6b78483..365c7d8 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -430,12 +430,16 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
 	struct gred_sched *table = qdisc_priv(sch);
 	struct tc_gred_qopt *ctl;
 	struct nlattr *tb[TCA_GRED_MAX + 1];
-	int err = -EINVAL, prio = GRED_DEF_PRIO;
+	int err, prio = GRED_DEF_PRIO;
 	u8 *stab;
 
-	if (opt == NULL || nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL)
 		return gred_change_table_def(sch, opt);
 
@@ -445,6 +449,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
 	    nla_len(tb[TCA_GRED_STAB]) < 256)
 		return -EINVAL;
 
+	err = -EINVAL;
 	ctl = nla_data(tb[TCA_GRED_PARMS]);
 	stab = nla_data(tb[TCA_GRED_STAB]);
 
@@ -489,10 +494,15 @@ errout:
 static int gred_init(struct Qdisc *sch, struct nlattr *opt)
 {
 	struct nlattr *tb[TCA_GRED_MAX + 1];
+	int err;
 
-	if (opt == NULL || nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_GRED_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_GRED_PARMS] || tb[TCA_GRED_STAB])
 		return -EINVAL;
 
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 4e6a164..fcb4826 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -997,10 +997,15 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	struct nlattr *tb[TCA_HFSC_MAX + 1];
 	struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
 	u64 cur_time;
+	int err;
 
-	if (opt == NULL || nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_HFSC_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_HFSC_RSC]) {
 		if (nla_len(tb[TCA_HFSC_RSC]) < sizeof(*rsc))
 			return -EINVAL;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 3b3ff64..512df9a 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -997,9 +997,17 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
 	struct htb_sched *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_HTB_INIT + 1];
 	struct tc_htb_glob *gopt;
+	int err;
 	int i;
-	if (!opt || nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL) ||
-	    tb[TCA_HTB_INIT] == NULL ||
+
+	if (!opt)
+		return -EINVAL;
+
+	err = nla_parse_nested(tb, TCA_HTB_INIT, opt, NULL);
+	if (err < 0)
+		return err;
+
+	if (tb[TCA_HTB_INIT] == NULL ||
 	    nla_len(tb[TCA_HTB_INIT]) < sizeof(*gopt)) {
 		printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
 		return -EINVAL;
@@ -1302,8 +1310,15 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 	struct tc_htb_opt *hopt;
 
 	/* extract all subattrs from opt attr */
-	if (!opt || nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL) ||
-	    tb[TCA_HTB_PARMS] == NULL ||
+	if (!opt)
+		goto failure;
+
+	err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, NULL);
+	if (err < 0)
+		goto failure;
+
+	err = -EINVAL;
+	if (tb[TCA_HTB_PARMS] == NULL ||
 	    nla_len(tb[TCA_HTB_PARMS]) < sizeof(*hopt))
 		goto failure;
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index a4f932d..4aa2b45 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -229,11 +229,14 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
 	struct prio_sched_data *q = qdisc_priv(sch);
 	struct tc_prio_qopt *qopt;
 	struct nlattr *tb[TCA_PRIO_MAX + 1];
+	int err;
 	int i;
 
-	if (nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt,
-				    sizeof(*qopt)))
-		return -EINVAL;
+	err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt,
+				      sizeof(*qopt));
+	if (err < 0)
+		return err;
+
 	q->bands = qopt->bands;
 	/* If we're multiqueue, make sure the number of incoming bands
 	 * matches the number of queues on the device we're associating with.
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 6ce8da5..dcf6afc 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -207,10 +207,15 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
 	struct nlattr *tb[TCA_RED_MAX + 1];
 	struct tc_red_qopt *ctl;
 	struct Qdisc *child = NULL;
+	int err;
 
-	if (opt == NULL || nla_parse_nested(tb, TCA_RED_MAX, opt, NULL))
+	if (opt == NULL)
 		return -EINVAL;
 
+	err = nla_parse_nested(tb, TCA_RED_MAX, opt, NULL);
+	if (err < 0)
+		return err;
+
 	if (tb[TCA_RED_PARMS] == NULL ||
 	    nla_len(tb[TCA_RED_PARMS]) < sizeof(*ctl) ||
 	    tb[TCA_RED_STAB] == NULL ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 6c4ad7e..f9b1543 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -272,7 +272,7 @@ static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
 
 static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
 {
-	int err = -EINVAL;
+	int err;
 	struct tbf_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_TBF_PTAB + 1];
 	struct tc_tbf_qopt *qopt;
@@ -281,8 +281,12 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
 	struct Qdisc *child = NULL;
 	int max_size,n;
 
-	if (nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL) ||
-	    tb[TCA_TBF_PARMS] == NULL ||
+	err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
+	if (tb[TCA_TBF_PARMS] == NULL ||
 	    nla_len(tb[TCA_TBF_PARMS]) < sizeof(*qopt))
 		goto done;
 

^ permalink raw reply related

* [NET_SCHED 07/15]: Use nla_nest_start/nla_nest_end
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: Use nla_nest_start/nla_nest_end

Use nla_nest_start/nla_nest_end for dumping nested attributes.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit bdd38a3b14cfa340da580f6e825d7f1142925926
tree 36dc82b63837c96b0f5e1b5c508f789abe7414e8
parent f9b5ab497909e836983bc31e5e7ad5065ccba6bc
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:54 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:54 +0100

 net/sched/act_api.c     |   84 ++++++++++++++++++++++++++---------------------
 net/sched/act_police.c  |   13 ++++---
 net/sched/cls_api.c     |   14 +++++---
 net/sched/cls_basic.c   |   12 +++----
 net/sched/cls_fw.c      |    9 +++--
 net/sched/cls_route.c   |    9 +++--
 net/sched/cls_rsvp.h    |   10 +++---
 net/sched/cls_tcindex.c |   13 ++++---
 net/sched/cls_u32.c     |   13 ++++---
 net/sched/ematch.c      |   16 ++++++---
 net/sched/sch_atm.c     |   15 +++++---
 net/sched/sch_cbq.c     |   24 +++++++------
 net/sched/sch_hfsc.c    |   11 +++---
 net/sched/sch_htb.c     |   32 +++++++++++-------
 net/sched/sch_ingress.c |   12 +++----
 net/sched/sch_tbf.c     |   12 +++----
 16 files changed, 166 insertions(+), 133 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 87818d7..3602260 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -69,7 +69,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
 {
 	struct tcf_common *p;
 	int err = 0, index = -1,i = 0, s_i = 0, n_i = 0;
-	struct nlattr *r ;
+	struct nlattr *nest;
 
 	read_lock_bh(hinfo->lock);
 
@@ -84,15 +84,17 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
 				continue;
 			a->priv = p;
 			a->order = n_i;
-			r = (struct nlattr *)skb_tail_pointer(skb);
-			NLA_PUT(skb, a->order, 0, NULL);
+
+			nest = nla_nest_start(skb, a->order);
+			if (nest == NULL)
+				goto nla_put_failure;
 			err = tcf_action_dump_1(skb, a, 0, 0);
 			if (err < 0) {
 				index--;
-				nlmsg_trim(skb, r);
+				nlmsg_trim(skb, nest);
 				goto done;
 			}
-			r->nla_len = skb_tail_pointer(skb) - (u8 *)r;
+			nla_nest_end(skb, nest);
 			n_i++;
 			if (n_i >= TCA_ACT_MAX_PRIO)
 				goto done;
@@ -105,7 +107,7 @@ done:
 	return n_i;
 
 nla_put_failure:
-	nlmsg_trim(skb, r);
+	nla_nest_cancel(skb, nest);
 	goto done;
 }
 
@@ -113,11 +115,12 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
 			  struct tcf_hashinfo *hinfo)
 {
 	struct tcf_common *p, *s_p;
-	struct nlattr *r ;
+	struct nlattr *nest;
 	int i= 0, n_i = 0;
 
-	r = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, a->order, 0, NULL);
+	nest = nla_nest_start(skb, a->order);
+	if (nest == NULL)
+		goto nla_put_failure;
 	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
 	for (i = 0; i < (hinfo->hmask + 1); i++) {
 		p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
@@ -131,11 +134,11 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
 		}
 	}
 	NLA_PUT(skb, TCA_FCNT, 4, &n_i);
-	r->nla_len = skb_tail_pointer(skb) - (u8 *)r;
+	nla_nest_end(skb, nest);
 
 	return n_i;
 nla_put_failure:
-	nlmsg_trim(skb, r);
+	nla_nest_cancel(skb, nest);
 	return -EINVAL;
 }
 
@@ -415,7 +418,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	int err = -EINVAL;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *r;
+	struct nlattr *nest;
 
 	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
@@ -423,10 +426,11 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
 	if (tcf_action_copy_stats(skb, a, 0))
 		goto nla_put_failure;
-	r = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 	if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
-		r->nla_len = skb_tail_pointer(skb) - (u8 *)r;
+		nla_nest_end(skb, nest);
 		return err;
 	}
 
@@ -441,17 +445,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 {
 	struct tc_action *a;
 	int err = -EINVAL;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *r ;
+	struct nlattr *nest;
 
 	while ((a = act) != NULL) {
-		r = (struct nlattr *)skb_tail_pointer(skb);
 		act = a->next;
-		NLA_PUT(skb, a->order, 0, NULL);
+		nest = nla_nest_start(skb, a->order);
+		if (nest == NULL)
+			goto nla_put_failure;
 		err = tcf_action_dump_1(skb, a, bind, ref);
 		if (err < 0)
 			goto errout;
-		r->nla_len = skb_tail_pointer(skb) - (u8 *)r;
+		nla_nest_end(skb, nest);
 	}
 
 	return 0;
@@ -459,7 +463,7 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 nla_put_failure:
 	err = -EINVAL;
 errout:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return err;
 }
 
@@ -627,7 +631,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
 	struct tcamsg *t;
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *x;
+	struct nlattr *nest;
 
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 
@@ -636,13 +640,14 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
 	t->tca__pad1 = 0;
 	t->tca__pad2 = 0;
 
-	x = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+	nest = nla_nest_start(skb, TCA_ACT_TAB);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (tcf_action_dump(skb, a, bind, ref) < 0)
 		goto nla_put_failure;
 
-	x->nla_len = skb_tail_pointer(skb) - (u8 *)x;
+	nla_nest_end(skb, nest);
 
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	return skb->len;
@@ -743,7 +748,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 	struct nlmsghdr *nlh;
 	struct tcamsg *t;
 	struct netlink_callback dcb;
-	struct nlattr *x;
+	struct nlattr *nest;
 	struct nlattr *tb[TCA_ACT_MAX+1];
 	struct nlattr *kind;
 	struct tc_action *a = create_a(0);
@@ -779,14 +784,15 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 	t->tca__pad1 = 0;
 	t->tca__pad2 = 0;
 
-	x = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+	nest = nla_nest_start(skb, TCA_ACT_TAB);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
 	if (err < 0)
 		goto nla_put_failure;
 
-	x->nla_len = skb_tail_pointer(skb) - (u8 *)x;
+	nla_nest_end(skb, nest);
 
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	nlh->nlmsg_flags |= NLM_F_ROOT;
@@ -875,7 +881,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
 	struct tcamsg *t;
 	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
-	struct nlattr *x;
+	struct nlattr *nest;
 	unsigned char *b;
 	int err = 0;
 
@@ -891,13 +897,14 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
 	t->tca__pad1 = 0;
 	t->tca__pad2 = 0;
 
-	x = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+	nest = nla_nest_start(skb, TCA_ACT_TAB);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (tcf_action_dump(skb, a, 0, 0) < 0)
 		goto nla_put_failure;
 
-	x->nla_len = skb_tail_pointer(skb) - (u8 *)x;
+	nla_nest_end(skb, nest);
 
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	NETLINK_CB(skb).dst_group = RTNLGRP_TC;
@@ -1025,7 +1032,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
 	struct net *net = skb->sk->sk_net;
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *x;
+	struct nlattr *nest;
 	struct tc_action_ops *a_o;
 	struct tc_action a;
 	int ret = 0;
@@ -1060,18 +1067,19 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
 	t->tca__pad1 = 0;
 	t->tca__pad2 = 0;
 
-	x = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+	nest = nla_nest_start(skb, TCA_ACT_TAB);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
 	if (ret < 0)
 		goto nla_put_failure;
 
 	if (ret > 0) {
-		x->nla_len = skb_tail_pointer(skb) - (u8 *)x;
+		nla_nest_end(skb, nest);
 		ret = skb->len;
 	} else
-		nlmsg_trim(skb, x);
+		nla_nest_cancel(skb, nest);
 
 	nlh->nlmsg_len = skb_tail_pointer(skb) - b;
 	if (NETLINK_CB(cb->skb).pid && ret)
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index c0fce9b..ee2f1b6 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -54,7 +54,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
 {
 	struct tcf_common *p;
 	int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
-	struct nlattr *r;
+	struct nlattr *nest;
 
 	read_lock_bh(&police_lock);
 
@@ -69,18 +69,19 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
 				continue;
 			a->priv = p;
 			a->order = index;
-			r = (struct nlattr *)skb_tail_pointer(skb);
-			NLA_PUT(skb, a->order, 0, NULL);
+			nest = nla_nest_start(skb, a->order);
+			if (nest == NULL)
+				goto nla_put_failure;
 			if (type == RTM_DELACTION)
 				err = tcf_action_dump_1(skb, a, 0, 1);
 			else
 				err = tcf_action_dump_1(skb, a, 0, 0);
 			if (err < 0) {
 				index--;
-				nlmsg_trim(skb, r);
+				nla_nest_cancel(skb, nest);
 				goto done;
 			}
-			r->nla_len = skb_tail_pointer(skb) - (u8 *)r;
+			nla_nest_end(skb, nest);
 			n_i++;
 		}
 	}
@@ -91,7 +92,7 @@ done:
 	return n_i;
 
 nla_put_failure:
-	nlmsg_trim(skb, r);
+	nla_nest_cancel(skb, nest);
 	goto done;
 }
 
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 92fa155..5584e7c 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -544,18 +544,22 @@ int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
 		 * to work with both old and new modes of entering
 		 * tc data even if iproute2  was newer - jhs
 		 */
-		struct nlattr *p_rta = (struct nlattr *)skb_tail_pointer(skb);
+		struct nlattr *nest;
 
 		if (exts->action->type != TCA_OLD_COMPAT) {
-			NLA_PUT(skb, map->action, 0, NULL);
+			nest = nla_nest_start(skb, map->action);
+			if (nest == NULL)
+				goto nla_put_failure;
 			if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
 				goto nla_put_failure;
-			p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta;
+			nla_nest_end(skb, nest);
 		} else if (map->police) {
-			NLA_PUT(skb, map->police, 0, NULL);
+			nest = nla_nest_start(skb, map->police);
+			if (nest == NULL)
+				goto nla_put_failure;
 			if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
 				goto nla_put_failure;
-			p_rta->nla_len = skb_tail_pointer(skb) - (u8 *)p_rta;
+			nla_nest_end(skb, nest);
 		}
 	}
 #endif
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 524b788..6d08b42 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -246,16 +246,16 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
 		      struct sk_buff *skb, struct tcmsg *t)
 {
 	struct basic_filter *f = (struct basic_filter *) fh;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	if (f == NULL)
 		return skb->len;
 
 	t->tcm_handle = f->handle;
 
-	nla = (struct nlattr *) b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (f->res.classid)
 		NLA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
@@ -264,11 +264,11 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
 	    tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
 		goto nla_put_failure;
 
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index a1a9f4d..e3dfbb3 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -334,7 +334,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
 	struct fw_head *head = (struct fw_head *)tp->root;
 	struct fw_filter *f = (struct fw_filter*)fh;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	if (f == NULL)
 		return skb->len;
@@ -344,8 +344,9 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
 	if (!f->res.classid && !tcf_exts_is_available(&f->exts))
 		return skb->len;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (f->res.classid)
 		NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid);
@@ -359,7 +360,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
 	if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
 		goto nla_put_failure;
 
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 
 	if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0)
 		goto nla_put_failure;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 3aa8109..1ce1f36 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -551,7 +551,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 {
 	struct route4_filter *f = (struct route4_filter*)fh;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 	u32 id;
 
 	if (f == NULL)
@@ -559,8 +559,9 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 
 	t->tcm_handle = f->handle;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (!(f->handle&0x8000)) {
 		id = f->id&0xFF;
@@ -579,7 +580,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 	if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
 		goto nla_put_failure;
 
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 
 	if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0)
 		goto nla_put_failure;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 5747408..77097e0 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -595,7 +595,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
 	struct rsvp_filter *f = (struct rsvp_filter*)fh;
 	struct rsvp_session *s;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 	struct tc_rsvp_pinfo pinfo;
 
 	if (f == NULL)
@@ -604,9 +604,9 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
 
 	t->tcm_handle = f->handle;
 
-
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	NLA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst);
 	pinfo.dpi = s->dpi;
@@ -624,7 +624,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
 	if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
 		goto nla_put_failure;
 
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 
 	if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
 		goto nla_put_failure;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 6b84d27..cd350d3 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -437,13 +437,16 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
 	struct tcindex_data *p = PRIV(tp);
 	struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh;
 	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
 		 tp, fh, skb, t, p, r, b);
 	pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h);
-	nla = (struct nlattr *) b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
+
 	if (!fh) {
 		t->tcm_handle = ~0; /* whatever ... */
 		NLA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash);
@@ -451,7 +454,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
 		NLA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift);
 		NLA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through),
 		    &p->fall_through);
-		nla->nla_len = skb_tail_pointer(skb) - b;
+		nla_nest_end(skb, nest);
 	} else {
 		if (p->perfect) {
 			t->tcm_handle = r-p->perfect;
@@ -474,7 +477,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
 
 		if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
 			goto nla_put_failure;
-		nla->nla_len = skb_tail_pointer(skb) - b;
+		nla_nest_end(skb, nest);
 
 		if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0)
 			goto nla_put_failure;
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 3228cc4..b51c2c3 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -694,16 +694,16 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
 		     struct sk_buff *skb, struct tcmsg *t)
 {
 	struct tc_u_knode *n = (struct tc_u_knode*)fh;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	if (n == NULL)
 		return skb->len;
 
 	t->tcm_handle = n->handle;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	if (TC_U32_KEY(n->handle) == 0) {
 		struct tc_u_hnode *ht = (struct tc_u_hnode*)fh;
@@ -741,14 +741,15 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
 #endif
 	}
 
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
+
 	if (TC_U32_KEY(n->handle))
 		if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0)
 			goto nla_put_failure;
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index d2b480f..daa9c4e 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -436,14 +436,18 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
 {
 	int i;
 	u8 *tail;
-	struct nlattr *top_start = (struct nlattr *)skb_tail_pointer(skb);
+	struct nlattr *top_start;
 	struct nlattr *list_start;
 
-	NLA_PUT(skb, tlv, 0, NULL);
+	top_start = nla_nest_start(skb, tlv);
+	if (top_start == NULL)
+		goto nla_put_failure;
+
 	NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
 
-	list_start = (struct nlattr *)skb_tail_pointer(skb);
-	NLA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL);
+	list_start = nla_nest_start(skb, TCA_EMATCH_TREE_LIST);
+	if (list_start == NULL)
+		goto nla_put_failure;
 
 	tail = skb_tail_pointer(skb);
 	for (i = 0; i < tree->hdr.nmatches; i++) {
@@ -470,8 +474,8 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
 		match_start->nla_len = tail - (u8 *)match_start;
 	}
 
-	list_start->nla_len = tail - (u8 *)list_start;
-	top_start->nla_len = tail - (u8 *)top_start;
+	nla_nest_end(skb, list_start);
+	nla_nest_end(skb, top_start);
 
 	return 0;
 
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index aaa32a2..19c0007 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -605,8 +605,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 {
 	struct atm_qdisc_data *p = qdisc_priv(sch);
 	struct atm_flow_data *flow = (struct atm_flow_data *)cl;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
 		sch, p, flow, skb, tcm);
@@ -614,8 +613,11 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 		return -EINVAL;
 	tcm->tcm_handle = flow->classid;
 	tcm->tcm_info = flow->q->handle;
-	nla = (struct nlattr *)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
+
 	NLA_PUT(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr);
 	if (flow->vcc) {
 		struct sockaddr_atmpvc pvc;
@@ -636,11 +638,12 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 
 		NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(zero), &zero);
 	}
-	nla->nla_len = skb_tail_pointer(skb) - b;
+
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 static int
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 585f8a6..da0f6c0 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1565,18 +1565,18 @@ static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
 static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 	if (cbq_dump_attr(skb, &q->link) < 0)
 		goto nla_put_failure;
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
@@ -1594,8 +1594,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
 	       struct sk_buff *skb, struct tcmsg *tcm)
 {
 	struct cbq_class *cl = (struct cbq_class*)arg;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
 	if (cl->tparent)
 		tcm->tcm_parent = cl->tparent->classid;
@@ -1604,15 +1603,16 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
 	tcm->tcm_handle = cl->classid;
 	tcm->tcm_info = cl->q->handle;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 	if (cbq_dump_attr(skb, cl) < 0)
 		goto nla_put_failure;
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index fcb4826..54c3e90 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1343,22 +1343,23 @@ hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
 		struct tcmsg *tcm)
 {
 	struct hfsc_class *cl = (struct hfsc_class *)arg;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla = (struct nlattr *)b;
+	struct nlattr *nest;
 
 	tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT;
 	tcm->tcm_handle = cl->classid;
 	if (cl->level == 0)
 		tcm->tcm_info = cl->qdisc->handle;
 
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 	if (hfsc_dump_curves(skb, cl) < 0)
 		goto nla_put_failure;
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
 	return skb->len;
 
  nla_put_failure:
-	nlmsg_trim(skb, b);
+ 	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 512df9a..69fac32 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1043,25 +1043,29 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
 static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct htb_sched *q = qdisc_priv(sch);
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 	struct tc_htb_glob gopt;
+
 	spin_lock_bh(&sch->dev->queue_lock);
-	gopt.direct_pkts = q->direct_pkts;
 
+	gopt.direct_pkts = q->direct_pkts;
 	gopt.version = HTB_VER;
 	gopt.rate2quantum = q->rate2quantum;
 	gopt.defcls = q->defcls;
 	gopt.debug = 0;
-	nla = (struct nlattr *)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 	NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nla_nest_end(skb, nest);
+
 	spin_unlock_bh(&sch->dev->queue_lock);
 	return skb->len;
+
 nla_put_failure:
 	spin_unlock_bh(&sch->dev->queue_lock);
-	nlmsg_trim(skb, skb_tail_pointer(skb));
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
@@ -1069,8 +1073,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
 			  struct sk_buff *skb, struct tcmsg *tcm)
 {
 	struct htb_class *cl = (struct htb_class *)arg;
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 	struct tc_htb_opt opt;
 
 	spin_lock_bh(&sch->dev->queue_lock);
@@ -1079,8 +1082,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
 	if (!cl->level && cl->un.leaf.q)
 		tcm->tcm_info = cl->un.leaf.q->handle;
 
-	nla = (struct nlattr *)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	memset(&opt, 0, sizeof(opt));
 
@@ -1092,12 +1096,14 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
 	opt.prio = cl->un.leaf.prio;
 	opt.level = cl->level;
 	NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
-	nla->nla_len = skb_tail_pointer(skb) - b;
+
+	nla_nest_end(skb, nest);
 	spin_unlock_bh(&sch->dev->queue_lock);
 	return skb->len;
+
 nla_put_failure:
 	spin_unlock_bh(&sch->dev->queue_lock);
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index f6decbb..3f72d52 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -183,16 +183,16 @@ static void ingress_destroy(struct Qdisc *sch)
 
 static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 
-	nla = (struct nlattr *)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
-	nla->nla_len = skb_tail_pointer(skb) - b;
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index f9b1543..b7a185d 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -375,12 +375,12 @@ static void tbf_destroy(struct Qdisc *sch)
 static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct tbf_sched_data *q = qdisc_priv(sch);
-	unsigned char *b = skb_tail_pointer(skb);
-	struct nlattr *nla;
+	struct nlattr *nest;
 	struct tc_tbf_qopt opt;
 
-	nla = (struct nlattr*)b;
-	NLA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	nest = nla_nest_start(skb, TCA_OPTIONS);
+	if (nest == NULL)
+		goto nla_put_failure;
 
 	opt.limit = q->limit;
 	opt.rate = q->R_tab->rate;
@@ -391,12 +391,12 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
 	opt.mtu = q->mtu;
 	opt.buffer = q->buffer;
 	NLA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt);
-	nla->nla_len = skb_tail_pointer(skb) - b;
 
+	nla_nest_end(skb, nest);
 	return skb->len;
 
 nla_put_failure:
-	nlmsg_trim(skb, b);
+	nla_nest_cancel(skb, nest);
 	return -1;
 }
 

^ permalink raw reply related

* [NET_SCHED 08/15]: Use NLA_PUT_STRING for string dumping
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: Use NLA_PUT_STRING for string dumping

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit ad688fbdf7dd0ebeb1b2fba0d7d2105bdf3c6de9
tree 68bb3e1dc3484d6ca0e7ddc55ad4e25864aaac84
parent bdd38a3b14cfa340da580f6e825d7f1142925926
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:55 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:55 +0100

 net/sched/act_api.c |    4 ++--
 net/sched/act_ipt.c |    2 +-
 net/sched/cls_api.c |    2 +-
 net/sched/cls_fw.c  |    2 +-
 net/sched/cls_u32.c |    2 +-
 net/sched/sch_api.c |    4 ++--
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 3602260..e33e43a 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -121,7 +121,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
 	nest = nla_nest_start(skb, a->order);
 	if (nest == NULL)
 		goto nla_put_failure;
-	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
+	NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
 	for (i = 0; i < (hinfo->hmask + 1); i++) {
 		p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
 
@@ -423,7 +423,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
 
-	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
+	NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
 	if (tcf_action_copy_stats(skb, a, 0))
 		goto nla_put_failure;
 	nest = nla_nest_start(skb, TCA_OPTIONS);
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 1269334..ecda51d 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -257,7 +257,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
 	NLA_PUT(skb, TCA_IPT_INDEX, 4, &ipt->tcf_index);
 	NLA_PUT(skb, TCA_IPT_HOOK, 4, &ipt->tcfi_hook);
 	NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
-	NLA_PUT(skb, TCA_IPT_TABLE, IFNAMSIZ, ipt->tcfi_tname);
+	NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname);
 	tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install);
 	tm.lastuse = jiffies_to_clock_t(jiffies - ipt->tcf_tm.lastuse);
 	tm.expires = jiffies_to_clock_t(ipt->tcf_tm.expires);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5584e7c..3377ca0 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -337,7 +337,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
 	tcm->tcm_ifindex = tp->q->dev->ifindex;
 	tcm->tcm_parent = tp->classid;
 	tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
-	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind);
+	NLA_PUT_STRING(skb, TCA_KIND, tp->ops->kind);
 	tcm->tcm_handle = fh;
 	if (RTM_DELTFILTER != event) {
 		tcm->tcm_handle = 0;
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index e3dfbb3..3107473 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -352,7 +352,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
 		NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid);
 #ifdef CONFIG_NET_CLS_IND
 	if (strlen(f->indev))
-		NLA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev);
+		NLA_PUT_STRING(skb, TCA_FW_INDEV, f->indev);
 #endif /* CONFIG_NET_CLS_IND */
 	if (head->mask != 0xFFFFFFFF)
 		NLA_PUT(skb, TCA_FW_MASK, 4, &head->mask);
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index b51c2c3..7a15025 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -732,7 +732,7 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
 
 #ifdef CONFIG_NET_CLS_IND
 		if(strlen(n->indev))
-			NLA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev);
+			NLA_PUT_STRING(skb, TCA_U32_INDEV, n->indev);
 #endif
 #ifdef CONFIG_CLS_U32_PERF
 		NLA_PUT(skb, TCA_U32_PCNT,
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 7abb028..8db554d 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -834,7 +834,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
 	tcm->tcm_parent = clid;
 	tcm->tcm_handle = q->handle;
 	tcm->tcm_info = atomic_read(&q->refcnt);
-	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id);
+	NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
 	if (q->ops->dump && q->ops->dump(q, skb) < 0)
 		goto nla_put_failure;
 	q->qstats.qlen = q->q.qlen;
@@ -1080,7 +1080,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
 	tcm->tcm_parent = q->handle;
 	tcm->tcm_handle = q->handle;
 	tcm->tcm_info = 0;
-	NLA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id);
+	NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
 	if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
 		goto nla_put_failure;
 

^ permalink raw reply related

* [NET_SCHED 10/15]: Use typeful attribute parsing helpers
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: Use typeful attribute parsing helpers

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 3e73383f7c353af51e8cc475f1c217a6b81fcecf
tree 53d369ca2ffca26cf46c57d2a9043d53da7474f8
parent 04d3c2781cba0b4ab75005de0defdb2a58178f21
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:56 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:56 +0100

 net/sched/act_api.c     |    2 +-
 net/sched/act_ipt.c     |    4 ++--
 net/sched/act_police.c  |    5 ++---
 net/sched/cls_basic.c   |    2 +-
 net/sched/cls_fw.c      |    6 +++---
 net/sched/cls_route.c   |    8 ++++----
 net/sched/cls_rsvp.h    |    4 ++--
 net/sched/cls_tcindex.c |   11 +++++------
 net/sched/cls_u32.c     |    8 ++++----
 net/sched/em_meta.c     |    2 +-
 net/sched/sch_atm.c     |    4 ++--
 11 files changed, 27 insertions(+), 29 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 41fbd49..0b8eb23 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -690,7 +690,7 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 	if (tb[TCA_ACT_INDEX] == NULL ||
 	    nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
 		goto err_out;
-	index = *(int *)nla_data(tb[TCA_ACT_INDEX]);
+	index = nla_get_u32(tb[TCA_ACT_INDEX]);
 
 	err = -ENOMEM;
 	a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 5dd701a..7ab2419 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -123,7 +123,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
 
 	if (tb[TCA_IPT_INDEX] != NULL &&
 	    nla_len(tb[TCA_IPT_INDEX]) >= sizeof(u32))
-		index = *(u32 *)nla_data(tb[TCA_IPT_INDEX]);
+		index = nla_get_u32(tb[TCA_IPT_INDEX]);
 
 	pc = tcf_hash_check(index, a, bind, &ipt_hash_info);
 	if (!pc) {
@@ -140,7 +140,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
 	}
 	ipt = to_ipt(pc);
 
-	hook = *(u32 *)nla_data(tb[TCA_IPT_HOOK]);
+	hook = nla_get_u32(tb[TCA_IPT_HOOK]);
 
 	err = -ENOMEM;
 	tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 79db6bb..62de806 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -203,7 +203,7 @@ override:
 	}
 
 	if (tb[TCA_POLICE_RESULT])
-		police->tcfp_result = *(u32*)nla_data(tb[TCA_POLICE_RESULT]);
+		police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]);
 	police->tcfp_toks = police->tcfp_burst = parm->burst;
 	police->tcfp_mtu = parm->mtu;
 	if (police->tcfp_mtu == 0) {
@@ -216,8 +216,7 @@ override:
 	police->tcf_action = parm->action;
 
 	if (tb[TCA_POLICE_AVRATE])
-		police->tcfp_ewma_rate =
-			*(u32*)nla_data(tb[TCA_POLICE_AVRATE]);
+		police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]);
 	if (est)
 		gen_replace_estimator(&police->tcf_bstats,
 				      &police->tcf_rate_est,
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 58444fe..0c872a7 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -150,7 +150,7 @@ static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f,
 		goto errout;
 
 	if (tb[TCA_BASIC_CLASSID]) {
-		f->res.classid = *(u32*)nla_data(tb[TCA_BASIC_CLASSID]);
+		f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]);
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 61ebe25..b75696d 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -203,7 +203,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
 	if (tb[TCA_FW_CLASSID]) {
 		if (nla_len(tb[TCA_FW_CLASSID]) != sizeof(u32))
 			goto errout;
-		f->res.classid = *(u32*)nla_data(tb[TCA_FW_CLASSID]);
+		f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
@@ -218,7 +218,7 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
 	if (tb[TCA_FW_MASK]) {
 		if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32))
 			goto errout;
-		mask = *(u32*)nla_data(tb[TCA_FW_MASK]);
+		mask = nla_get_u32(tb[TCA_FW_MASK]);
 		if (mask != head->mask)
 			goto errout;
 	} else if (head->mask != 0xFFFFFFFF)
@@ -264,7 +264,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
 		if (tb[TCA_FW_MASK]) {
 			if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32))
 				return -EINVAL;
-			mask = *(u32*)nla_data(tb[TCA_FW_MASK]);
+			mask = nla_get_u32(tb[TCA_FW_MASK]);
 		}
 
 		head = kzalloc(sizeof(struct fw_head), GFP_KERNEL);
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 7752586..ae97238 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -348,7 +348,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
 			goto errout;
 		if (nla_len(tb[TCA_ROUTE4_TO]) < sizeof(u32))
 			goto errout;
-		to = *(u32*)nla_data(tb[TCA_ROUTE4_TO]);
+		to = nla_get_u32(tb[TCA_ROUTE4_TO]);
 		if (to > 0xFF)
 			goto errout;
 		nhandle = to;
@@ -359,14 +359,14 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
 			goto errout;
 		if (nla_len(tb[TCA_ROUTE4_FROM]) < sizeof(u32))
 			goto errout;
-		id = *(u32*)nla_data(tb[TCA_ROUTE4_FROM]);
+		id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
 		if (id > 0xFF)
 			goto errout;
 		nhandle |= id << 16;
 	} else if (tb[TCA_ROUTE4_IIF]) {
 		if (nla_len(tb[TCA_ROUTE4_IIF]) < sizeof(u32))
 			goto errout;
-		id = *(u32*)nla_data(tb[TCA_ROUTE4_IIF]);
+		id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
 		if (id > 0x7FFF)
 			goto errout;
 		nhandle |= (id | 0x8000) << 16;
@@ -411,7 +411,7 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
 	tcf_tree_unlock(tp);
 
 	if (tb[TCA_ROUTE4_CLASSID]) {
-		f->res.classid = *(u32*)nla_data(tb[TCA_ROUTE4_CLASSID]);
+		f->res.classid = nla_get_u32(tb[TCA_ROUTE4_CLASSID]);
 		tcf_bind_filter(tp, &f->res, base);
 	}
 
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 838a3ff..61286a0 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -430,7 +430,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
 		if (f->handle != handle && handle)
 			goto errout2;
 		if (tb[TCA_RSVP_CLASSID-1]) {
-			f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]);
+			f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]);
 			tcf_bind_filter(tp, &f->res, base);
 		}
 
@@ -470,7 +470,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
 		err = -EINVAL;
 		if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4)
 			goto errout;
-		f->res.classid = *(u32*)nla_data(tb[TCA_RSVP_CLASSID-1]);
+		f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]);
 	}
 
 	err = -EINVAL;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 7d46df7..2809856 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -221,19 +221,19 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
 	if (tb[TCA_TCINDEX_HASH]) {
 		if (nla_len(tb[TCA_TCINDEX_HASH]) < sizeof(u32))
 			goto errout;
-		cp.hash = *(u32 *) nla_data(tb[TCA_TCINDEX_HASH]);
+		cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
 	}
 
 	if (tb[TCA_TCINDEX_MASK]) {
 		if (nla_len(tb[TCA_TCINDEX_MASK]) < sizeof(u16))
 			goto errout;
-		cp.mask = *(u16 *) nla_data(tb[TCA_TCINDEX_MASK]);
+		cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
 	}
 
 	if (tb[TCA_TCINDEX_SHIFT]) {
 		if (nla_len(tb[TCA_TCINDEX_SHIFT]) < sizeof(int))
 			goto errout;
-		cp.shift = *(int *) nla_data(tb[TCA_TCINDEX_SHIFT]);
+		cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
 	}
 
 	err = -EBUSY;
@@ -251,8 +251,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
 	if (tb[TCA_TCINDEX_FALL_THROUGH]) {
 		if (nla_len(tb[TCA_TCINDEX_FALL_THROUGH]) < sizeof(u32))
 			goto errout;
-		cp.fall_through =
-			*(u32 *) nla_data(tb[TCA_TCINDEX_FALL_THROUGH]);
+		cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
 	}
 
 	if (!cp.hash) {
@@ -305,7 +304,7 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
 	}
 
 	if (tb[TCA_TCINDEX_CLASSID]) {
-		cr.res.classid = *(u32 *) nla_data(tb[TCA_TCINDEX_CLASSID]);
+		cr.res.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
 		tcf_bind_filter(tp, &cr.res, base);
 	}
 
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 326711e..a4e72e8 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -474,7 +474,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
 
 	err = -EINVAL;
 	if (tb[TCA_U32_LINK]) {
-		u32 handle = *(u32*)nla_data(tb[TCA_U32_LINK]);
+		u32 handle = nla_get_u32(tb[TCA_U32_LINK]);
 		struct tc_u_hnode *ht_down = NULL;
 
 		if (TC_U32_KEY(handle))
@@ -496,7 +496,7 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
 			ht_down->refcnt--;
 	}
 	if (tb[TCA_U32_CLASSID]) {
-		n->res.classid = *(u32*)nla_data(tb[TCA_U32_CLASSID]);
+		n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
 		tcf_bind_filter(tp, &n->res, base);
 	}
 
@@ -543,7 +543,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	}
 
 	if (tb[TCA_U32_DIVISOR]) {
-		unsigned divisor = *(unsigned*)nla_data(tb[TCA_U32_DIVISOR]);
+		unsigned divisor = nla_get_u32(tb[TCA_U32_DIVISOR]);
 
 		if (--divisor > 0x100)
 			return -EINVAL;
@@ -569,7 +569,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
 	}
 
 	if (tb[TCA_U32_HASH]) {
-		htid = *(unsigned*)nla_data(tb[TCA_U32_HASH]);
+		htid = nla_get_u32(tb[TCA_U32_HASH]);
 		if (TC_U32_HTID(htid) == TC_U32_ROOT) {
 			ht = tp->root;
 			htid = ht->handle;
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 63ae6a2..d9f487d 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -600,7 +600,7 @@ static int meta_int_change(struct meta_value *dst, struct nlattr *nla)
 		dst->val = *(unsigned long *) nla_data(nla);
 		dst->len = sizeof(unsigned long);
 	} else if (nla_len(nla) == sizeof(u32)) {
-		dst->val = *(u32 *) nla_data(nla);
+		dst->val = nla_get_u32(nla);
 		dst->len = sizeof(u32);
 	} else
 		return -EINVAL;
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 4d87659..0c71f2e 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -231,7 +231,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 
 	if (!tb[TCA_ATM_FD] || nla_len(tb[TCA_ATM_FD]) < sizeof(fd))
 		return -EINVAL;
-	fd = *(int *)nla_data(tb[TCA_ATM_FD]);
+	fd = nla_get_u32(tb[TCA_ATM_FD]);
 	pr_debug("atm_tc_change: fd %d\n", fd);
 	if (tb[TCA_ATM_HDR]) {
 		hdr_len = nla_len(tb[TCA_ATM_HDR]);
@@ -246,7 +246,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 		if (nla_len(tb[TCA_ATM_EXCESS]) != sizeof(u32))
 			return -EINVAL;
 		excess = (struct atm_flow_data *)
-			atm_tc_get(sch, *(u32 *)nla_data(tb[TCA_ATM_EXCESS]));
+			atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
 		if (!excess)
 			return -ENOENT;
 	}

^ permalink raw reply related

* [NET_SCHED 09/15]: Use typeful attribute construction helpers
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: Use typeful attribute construction helpers

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 04d3c2781cba0b4ab75005de0defdb2a58178f21
tree a1b904b7f29ad1ff7cff310128b3fd67e2543278
parent ad688fbdf7dd0ebeb1b2fba0d7d2105bdf3c6de9
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:55 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:55 +0100

 net/sched/act_api.c     |    2 +-
 net/sched/act_ipt.c     |    4 ++--
 net/sched/act_police.c  |    5 ++---
 net/sched/cls_basic.c   |    2 +-
 net/sched/cls_fw.c      |    4 ++--
 net/sched/cls_route.c   |    8 ++++----
 net/sched/cls_rsvp.h    |    2 +-
 net/sched/cls_tcindex.c |   11 +++++------
 net/sched/cls_u32.c     |    8 ++++----
 net/sched/em_meta.c     |    3 +--
 net/sched/sch_atm.c     |    8 +++-----
 11 files changed, 26 insertions(+), 31 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index e33e43a..41fbd49 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -133,7 +133,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
 			p = s_p;
 		}
 	}
-	NLA_PUT(skb, TCA_FCNT, 4, &n_i);
+	NLA_PUT_U32(skb, TCA_FCNT, n_i);
 	nla_nest_end(skb, nest);
 
 	return n_i;
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index ecda51d..5dd701a 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -254,8 +254,8 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
 	strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
 
 	NLA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
-	NLA_PUT(skb, TCA_IPT_INDEX, 4, &ipt->tcf_index);
-	NLA_PUT(skb, TCA_IPT_HOOK, 4, &ipt->tcfi_hook);
+	NLA_PUT_U32(skb, TCA_IPT_INDEX, ipt->tcf_index);
+	NLA_PUT_U32(skb, TCA_IPT_HOOK, ipt->tcfi_hook);
 	NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
 	NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname);
 	tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index ee2f1b6..79db6bb 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -339,10 +339,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 		memset(&opt.peakrate, 0, sizeof(opt.peakrate));
 	NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
 	if (police->tcfp_result)
-		NLA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
-			&police->tcfp_result);
+		NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result);
 	if (police->tcfp_ewma_rate)
-		NLA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
+		NLA_PUT_U32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate);
 	return skb->len;
 
 nla_put_failure:
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 6d08b42..58444fe 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -258,7 +258,7 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
 		goto nla_put_failure;
 
 	if (f->res.classid)
-		NLA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
+		NLA_PUT_U32(skb, TCA_BASIC_CLASSID, f->res.classid);
 
 	if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
 	    tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 3107473..61ebe25 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -349,13 +349,13 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
 		goto nla_put_failure;
 
 	if (f->res.classid)
-		NLA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid);
+		NLA_PUT_U32(skb, TCA_FW_CLASSID, f->res.classid);
 #ifdef CONFIG_NET_CLS_IND
 	if (strlen(f->indev))
 		NLA_PUT_STRING(skb, TCA_FW_INDEV, f->indev);
 #endif /* CONFIG_NET_CLS_IND */
 	if (head->mask != 0xFFFFFFFF)
-		NLA_PUT(skb, TCA_FW_MASK, 4, &head->mask);
+		NLA_PUT_U32(skb, TCA_FW_MASK, head->mask);
 
 	if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
 		goto nla_put_failure;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 1ce1f36..7752586 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -565,17 +565,17 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 
 	if (!(f->handle&0x8000)) {
 		id = f->id&0xFF;
-		NLA_PUT(skb, TCA_ROUTE4_TO, sizeof(id), &id);
+		NLA_PUT_U32(skb, TCA_ROUTE4_TO, id);
 	}
 	if (f->handle&0x80000000) {
 		if ((f->handle>>16) != 0xFFFF)
-			NLA_PUT(skb, TCA_ROUTE4_IIF, sizeof(f->iif), &f->iif);
+			NLA_PUT_U32(skb, TCA_ROUTE4_IIF, f->iif);
 	} else {
 		id = f->id>>16;
-		NLA_PUT(skb, TCA_ROUTE4_FROM, sizeof(id), &id);
+		NLA_PUT_U32(skb, TCA_ROUTE4_FROM, id);
 	}
 	if (f->res.classid)
-		NLA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid);
+		NLA_PUT_U32(skb, TCA_ROUTE4_CLASSID, f->res.classid);
 
 	if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
 		goto nla_put_failure;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 77097e0..838a3ff 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -617,7 +617,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
 	pinfo.pad = 0;
 	NLA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
 	if (f->res.classid)
-		NLA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
+		NLA_PUT_U32(skb, TCA_RSVP_CLASSID, f->res.classid);
 	if (((f->handle>>8)&0xFF) != 16)
 		NLA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
 
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index cd350d3..7d46df7 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -449,11 +449,10 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
 
 	if (!fh) {
 		t->tcm_handle = ~0; /* whatever ... */
-		NLA_PUT(skb, TCA_TCINDEX_HASH, sizeof(p->hash), &p->hash);
-		NLA_PUT(skb, TCA_TCINDEX_MASK, sizeof(p->mask), &p->mask);
-		NLA_PUT(skb, TCA_TCINDEX_SHIFT, sizeof(p->shift), &p->shift);
-		NLA_PUT(skb, TCA_TCINDEX_FALL_THROUGH, sizeof(p->fall_through),
-		    &p->fall_through);
+		NLA_PUT_U32(skb, TCA_TCINDEX_HASH, p->hash);
+		NLA_PUT_U16(skb, TCA_TCINDEX_MASK, p->mask);
+		NLA_PUT_U32(skb, TCA_TCINDEX_SHIFT, p->shift);
+		NLA_PUT_U32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through);
 		nla_nest_end(skb, nest);
 	} else {
 		if (p->perfect) {
@@ -473,7 +472,7 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
 		}
 		pr_debug("handle = %d\n", t->tcm_handle);
 		if (r->res.class)
-			NLA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
+			NLA_PUT_U32(skb, TCA_TCINDEX_CLASSID, r->res.classid);
 
 		if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
 			goto nla_put_failure;
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 7a15025..326711e 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -708,19 +708,19 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
 	if (TC_U32_KEY(n->handle) == 0) {
 		struct tc_u_hnode *ht = (struct tc_u_hnode*)fh;
 		u32 divisor = ht->divisor+1;
-		NLA_PUT(skb, TCA_U32_DIVISOR, 4, &divisor);
+		NLA_PUT_U32(skb, TCA_U32_DIVISOR, divisor);
 	} else {
 		NLA_PUT(skb, TCA_U32_SEL,
 			sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key),
 			&n->sel);
 		if (n->ht_up) {
 			u32 htid = n->handle & 0xFFFFF000;
-			NLA_PUT(skb, TCA_U32_HASH, 4, &htid);
+			NLA_PUT_U32(skb, TCA_U32_HASH, htid);
 		}
 		if (n->res.classid)
-			NLA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid);
+			NLA_PUT_U32(skb, TCA_U32_CLASSID, n->res.classid);
 		if (n->ht_down)
-			NLA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle);
+			NLA_PUT_U32(skb, TCA_U32_LINK, n->ht_down->handle);
 
 #ifdef CONFIG_CLS_U32_MARK
 		if (n->mark.val || n->mark.mask)
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index dd57236..63ae6a2 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -623,8 +623,7 @@ static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
 	if (v->len == sizeof(unsigned long))
 		NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
 	else if (v->len == sizeof(u32)) {
-		u32 d = v->val;
-		NLA_PUT(skb, tlv, sizeof(d), &d);
+		NLA_PUT_U32(skb, tlv, v->val);
 	}
 
 	return 0;
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 19c0007..4d87659 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -629,14 +629,12 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
 		pvc.sap_addr.vci = flow->vcc->vci;
 		NLA_PUT(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc);
 		state = ATM_VF2VS(flow->vcc->flags);
-		NLA_PUT(skb, TCA_ATM_STATE, sizeof(state), &state);
+		NLA_PUT_U32(skb, TCA_ATM_STATE, state);
 	}
 	if (flow->excess)
-		NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(u32), &flow->classid);
+		NLA_PUT_U32(skb, TCA_ATM_EXCESS, flow->classid);
 	else {
-		static u32 zero;
-
-		NLA_PUT(skb, TCA_ATM_EXCESS, sizeof(zero), &zero);
+		NLA_PUT_U32(skb, TCA_ATM_EXCESS, 0);
 	}
 
 	nla_nest_end(skb, nest);

^ permalink raw reply related

* [NET_SCHED 11/15]: sch_api: introduce constant for rate table size
From: Patrick McHardy @ 2008-01-23 16:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, Patrick McHardy
In-Reply-To: <20080123163555.6459.69501.sendpatchset@localhost.localdomain>

[NET_SCHED]: sch_api: introduce constant for rate table size

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit b21f31e516f993016f8a1ade331bcaf71576b4e2
tree e59049e1fb3f2711d83c196d2f54b5021dc68330
parent 3e73383f7c353af51e8cc475f1c217a6b81fcecf
author Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:56 +0100
committer Patrick McHardy <kaber@trash.net> Wed, 23 Jan 2008 17:12:56 +0100

 include/linux/pkt_sched.h |    2 ++
 net/sched/sch_api.c       |    3 ++-
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 919af93..3276135 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -83,6 +83,8 @@ struct tc_ratespec
 	__u32		rate;
 };
 
+#define TC_RTAB_SIZE	1024
+
 /* FIFO section */
 
 struct tc_fifo_qopt
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 8db554d..7e3c048 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -244,7 +244,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta
 		}
 	}
 
-	if (tab == NULL || r->rate == 0 || r->cell_log == 0 || nla_len(tab) != 1024)
+	if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
+	    nla_len(tab) != TC_RTAB_SIZE)
 		return NULL;
 
 	rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);

^ permalink raw reply related


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