Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 2/3] af_packet: fix for sending VLAN frames via packet_mmap
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <1375436261-6746-1-git-send-email-phil@nwl.cc>

Since tpacket_fill_skb() parses the protocol field in ethernet frames'
headers, it's easy to see if any passed frame is a VLAN one and account
for the extended size.

But as the real protocol does not turn up before tpacket_fill_skb()
runs which in turn also checks the frame length, move the max frame
length calculation into the function.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/packet/af_packet.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e549e17..ce7b4f0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1924,7 +1924,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		__be16 proto, unsigned char *addr, int hlen)
 {
 	union tpacket_uhdr ph;
-	int to_write, offset, len, tp_len, nr_frags, len_max;
+	int to_write, offset, len, tp_len, nr_frags, len_max, max_frame_len;
 	struct socket *sock = po->sk.sk_socket;
 	struct page *page;
 	void *data;
@@ -1947,10 +1947,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		tp_len = ph.h1->tp_len;
 		break;
 	}
-	if (unlikely(tp_len > size_max)) {
-		pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
-		return -EMSGSIZE;
-	}
 
 	skb_reserve(skb, hlen);
 	skb_reset_network_header(skb);
@@ -2013,6 +2009,18 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		to_write -= dev->hard_header_len;
 	}
 
+	max_frame_len = dev->mtu + dev->hard_header_len;
+	if (skb->protocol == htons(ETH_P_8021Q))
+		max_frame_len += VLAN_HLEN;
+
+	if (size_max > max_frame_len)
+		size_max = max_frame_len;
+
+	if (unlikely(tp_len > size_max)) {
+		pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
+		return -EMSGSIZE;
+	}
+
 	offset = offset_in_page(data);
 	len_max = PAGE_SIZE - offset;
 	len = ((to_write > len_max) ? len_max : to_write);
@@ -2051,7 +2059,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	struct net_device *dev;
 	__be16 proto;
 	bool need_rls_dev = false;
-	int err, reserve = 0;
+	int err;
 	void *ph;
 	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
 	int tp_len, size_max;
@@ -2084,8 +2092,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	if (unlikely(dev == NULL))
 		goto out;
 
-	reserve = dev->hard_header_len;
-
 	err = -ENETDOWN;
 	if (unlikely(!(dev->flags & IFF_UP)))
 		goto out_put;
@@ -2093,9 +2099,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	size_max = po->tx_ring.frame_size
 		- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
-	if (size_max > dev->mtu + reserve)
-		size_max = dev->mtu + reserve;
-
 	do {
 		ph = packet_current_frame(po, &po->tx_ring,
 				TP_STATUS_SEND_REQUEST);
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2 1/3] af_packet: when sending ethernet frames, parse header for skb->protocol
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20130801.181208.804928209108880255.davem@davemloft.net>

This may be necessary when the SKB is passed to other layers on the go,
which check the protocol field on their own. An example is a VLAN packet
sent out using AF_PACKET on a bridge interface. The bridging code checks
the SKB size, accounting for any VLAN header only if the protocol field
is set accordingly.

Note that eth_type_trans() sets skb->dev to the passed argument, so this
can be skipped in packet_snd() for ethernet frames, as well.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since V1:
- minor lingual review of the comment
- added note about setting skb->dev for non-ethernet frames only
---
 net/packet/af_packet.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 20a1bd0..e549e17 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -88,6 +88,7 @@
 #include <linux/virtio_net.h>
 #include <linux/errqueue.h>
 #include <linux/net_tstamp.h>
+#include <linux/if_arp.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -2005,6 +2006,9 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		if (unlikely(err))
 			return err;
 
+		if (dev->type == ARPHRD_ETHER)
+			skb->protocol = eth_type_trans(skb, dev);
+
 		data += dev->hard_header_len;
 		to_write -= dev->hard_header_len;
 	}
@@ -2324,6 +2328,13 @@ static int packet_snd(struct socket *sock,
 
 	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
+	if (dev->type == ARPHRD_ETHER) {
+		skb->protocol = eth_type_trans(skb, dev);
+	} else {
+		skb->protocol = proto;
+		skb->dev = dev;
+	}
+
 	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
 		/* Earlier code assumed this would be a VLAN pkt,
 		 * double-check this now that we have the actual
@@ -2338,8 +2349,6 @@ static int packet_snd(struct socket *sock,
 		}
 	}
 
-	skb->protocol = proto;
-	skb->dev = dev;
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
 
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2 3/3] af_packet: simplify VLAN frame check in packet_snd
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <1375436261-6746-2-git-send-email-phil@nwl.cc>

For ethernet frames, eth_type_trans() already parses the header, so one
can skip this when checking the frame size.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/packet/af_packet.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ce7b4f0..bbe1ece 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2333,23 +2333,16 @@ static int packet_snd(struct socket *sock,
 
 	if (dev->type == ARPHRD_ETHER) {
 		skb->protocol = eth_type_trans(skb, dev);
+		if (skb->protocol == htons(ETH_P_8021Q))
+			reserve += VLAN_HLEN;
 	} else {
 		skb->protocol = proto;
 		skb->dev = dev;
 	}
 
 	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
-		/* Earlier code assumed this would be a VLAN pkt,
-		 * double-check this now that we have the actual
-		 * packet in hand.
-		 */
-		struct ethhdr *ehdr;
-		skb_reset_mac_header(skb);
-		ehdr = eth_hdr(skb);
-		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-			err = -EMSGSIZE;
-			goto out_free;
-		}
+		err = -EMSGSIZE;
+		goto out_free;
 	}
 
 	skb->priority = sk->sk_priority;
-- 
1.8.1.5

^ permalink raw reply related

* Re: [PATCH v4] net: Add MOXA ART SoCs ethernet driver
From: Mark Rutland @ 2013-08-02 10:04 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: netdev@vger.kernel.org, davem@davemloft.net,
	linux-doc@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, arm@kernel.org, florian@openwrt.org,
	joe@perches.com
In-Reply-To: <1375349968-16059-1-git-send-email-jonas.jensen@gmail.com>

On Thu, Aug 01, 2013 at 10:39:28AM +0100, Jonas Jensen wrote:
> The MOXA UC-711X hardware(s) has an ethernet controller that seem to be
> developed internally. The IC used is "RTL8201CP".
>
> Since there is no public documentation, this driver is mostly the one
> published by MOXA that has been heavily cleaned up / ported from linux 2.6.9.
>
> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
> ---

[...]

> diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
> new file mode 100644
> index 0000000..1fc44ff
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
> @@ -0,0 +1,25 @@
> +MOXA ART Ethernet Controller
> +
> +Required properties:
> +
> +- compatible : Must be "moxa,moxart-mac"
> +- reg : Should contain registers location and length
> +  index 0 : main register

I assume there's more than one register in the main register bank?

Are there any other register banks not used by this driver?

> +  index 1 : mac address (stored on flash)

Is that flash a part of the MAC unit?

Is it only 6 bytes long (judging by the examples), or is the th only
portion used by the driver?

If it's bigger, I'd prefer to describe the whole of flash. This driver
will know the offset within it, and can choose to map only the protion
it wants to use. Another driver may choose to do more interesting
things. We need to describe the hardware, not how we expect it to be
used...

If it's not associated with the MAC, I'm not sure this is the best way
of describing the linkage...

> +- interrupts : Should contain the mac interrupt number

Is there no need to link this to a phy, or is it a fixed-link device?

> +
> +Example:
> +
> +       mac0: mac@90900000 {
> +               compatible = "moxa,moxart-mac";
> +               reg =   <0x90900000 0x100>,
> +                       <0x80000050 0x6>;
> +               interrupts = <25 0>;
> +       };
> +
> +       mac1: mac@92000000 {
> +               compatible = "moxa,moxart-mac";
> +               reg =   <0x92000000 0x100>,
> +                       <0x80000056 0x6>;
> +               interrupts = <27 0>;
> +       };

[...]

> diff --git a/drivers/net/ethernet/moxa/moxart_ether.h b/drivers/net/ethernet/moxa/moxart_ether.h
> new file mode 100644
> index 0000000..790b6a9
> --- /dev/null
> +++ b/drivers/net/ethernet/moxa/moxart_ether.h
> @@ -0,0 +1,513 @@
> +/* MOXA ART Ethernet (RTL8201CP) driver.
> + *
> + * Copyright (C) 2013 Jonas Jensen
> + *
> + * Jonas Jensen <jonas.jensen@gmail.com>
> + *
> + * Based on code from
> + * Moxa Technology Co., Ltd. <www.moxa.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#ifndef _MOXART_ETHERNET_H
> +#define _MOXART_ETHERNET_H
> +
> +#define TX_DESC_NUM            64
> +#define TX_DESC_NUM_MASK       (TX_DESC_NUM-1)
> +#define TX_NEXT(N)             (((N) + 1) & (TX_DESC_NUM_MASK))
> +#define TX_BUF_SIZE            1600
> +
> +#define RX_DESC_NUM            64
> +#define RX_DESC_NUM_MASK       (RX_DESC_NUM-1)
> +#define RX_NEXT(N)             (((N) + 1) & (RX_DESC_NUM_MASK))
> +#define RX_BUF_SIZE            1600
> +
> +struct tx_desc_t {
> +       union {
> +#define TXDMA_OWN              BIT(31)
> +#define TXPKT_EXSCOL           BIT(1)
> +#define TXPKT_LATECOL          BIT(0)
> +               unsigned int ui;
> +
> +               struct {
> +                       /* is aborted due to late collision */
> +                       unsigned int tx_pkt_late_col:1;
> +
> +                       /* is aborted after 16 collisions */
> +                       unsigned int rx_pkt_exs_col:1;
> +
> +                       unsigned int reserved1:29;
> +
> +                       /* is owned by the MAC controller */
> +                       unsigned int tx_dma_own:1;
> +               } ubit;
> +       } txdes0;

Unless I've misunderstood the later code, this is the format of data
shared with the device? Bitfields aren't portable, and you can't rely on
the padding here being what you expect...

Similarly, the other structures below used in this way below seem scary
to me.

> +
> +       union {
> +#define EDOTR                  BIT(31)
> +#define TXIC                   BIT(30)
> +#define TX2FIC                 BIT(29)
> +#define FTS                    BIT(28)
> +#define LTS                    BIT(27)
> +#define TXBUF_SIZE_MASK                0x7ff
> +#define TXBUF_SIZE_MAX         (TXBUF_SIZE_MASK+1)
> +               unsigned int ui;
> +
> +               struct {
> +                       /* transmit buffer size in byte */
> +                       unsigned int tx_buf_size:11;
> +
> +                       unsigned int reserved2:16;
> +
> +                       /* is the last descriptor of a Tx packet */
> +                       unsigned int lts:1;
> +
> +                       /* is the first descriptor of a Tx packet */
> +                       unsigned int fts:1;
> +
> +                       /* transmit to FIFO interrupt on completion */
> +                       unsigned int tx2_fic:1;
> +
> +                       /* transmit interrupt on completion */
> +                       unsigned int tx_ic:1;
> +
> +                       /* end descriptor of transmit ring */
> +                       unsigned int edotr:1;
> +               } ubit;
> +       } txdes1;
> +
> +       struct {
> +               /* transmit buffer physical base address */
> +               unsigned int addr_phys;
> +
> +               /* transmit buffer virtual base address */
> +               unsigned char *addr_virt;
> +       } txdes2;
> +};
> +
> +struct rx_desc_t {
> +       union {
> +#define RXDMA_OWN              BIT(31)
> +#define FRS                    BIT(29)
> +#define LRS                    BIT(28)
> +#define RX_ODD_NB              BIT(22)
> +#define RUNT                   BIT(21)
> +#define FTL                    BIT(20)
> +#define CRC_ERR                        BIT(19)
> +#define RX_ERR                 BIT(18)
> +#define BROADCAST_RXDES0       BIT(17)
> +#define MULTICAST_RXDES0       BIT(16)
> +#define RFL_MASK               0x7ff
> +#define RFL_MAX                        (RFL_MASK+1)
> +               unsigned int ui;
> +
> +               struct {
> +                       /* receive frame length */
> +                       unsigned int recv_frame_len:11;
> +                       unsigned int reserved1:5;
> +
> +                       /* multicast frame */
> +                       unsigned int multicast:1;
> +
> +                       /* broadcast frame */
> +                       unsigned int broadcast:1;
> +                       unsigned int rx_err:1;          /* receive error */
> +                       unsigned int crc_err:1;         /* CRC error */
> +                       unsigned int ftl:1;             /* frame too long */
> +
> +                       /* runt packet, less than 64 bytes */
> +                       unsigned int runt:1;
> +
> +                       /* receive odd nibbles */
> +                       unsigned int rx_odd_nb:1;
> +                       unsigned int reserved2:5;
> +
> +                       /* last receive segment descriptor */
> +                       unsigned int lrs:1;
> +
> +                       /* first receive segment descriptor */
> +                       unsigned int frs:1;
> +
> +                       unsigned int reserved3:1;
> +                       unsigned int rx_dma_own:1;      /* RXDMA onwership */
> +               } ubit;
> +       } rxdes0;
> +
> +       union {
> +#define EDORR                  BIT(31)
> +#define RXBUF_SIZE_MASK                0x7ff
> +#define RXBUF_SIZE_MAX         (RXBUF_SIZE_MASK+1)
> +               unsigned int ui;
> +
> +               struct {
> +                       /* receive buffer size */
> +                       unsigned int rx_buf_size:11;
> +
> +                       unsigned int reserved4:20;
> +
> +                       /* end descriptor of receive ring */
> +                       unsigned int edorr:1;
> +               } ubit;
> +       } rxdes1;
> +
> +       struct {
> +               /* receive buffer physical base address */
> +               unsigned int addr_phys;
> +
> +               /* receive buffer virtual base address */
> +               unsigned char *addr_virt;
> +       } rxdes2;
> +};
> +
> +struct mac_control_reg_t {
> +
> +/* RXDMA has received packets into RX buffer successfully */
> +#define RPKT_FINISH            BIT(0)
> +/* receive buffer unavailable */
> +#define NORXBUF                        BIT(1)
> +/* TXDMA has moved data into the TX FIFO */
> +#define XPKT_FINISH            BIT(2)
> +/* transmit buffer unavailable */
> +#define NOTXBUF                        BIT(3)
> +/* packets transmitted to ethernet successfully */
> +#define XPKT_OK_INT_STS                BIT(4)
> +/* packets transmitted to ethernet lost due to late
> + * collision or excessive collision
> + */
> +#define XPKT_LOST_INT_STS      BIT(5)
> +/* packets received into RX FIFO successfully */
> +#define RPKT_SAV               BIT(6)
> +/* received packet lost due to RX FIFO full */
> +#define RPKT_LOST_INT_STS      BIT(7)
> +#define AHB_ERR                        BIT(8)          /* AHB error */
> +#define PHYSTS_CHG             BIT(9)          /* PHY link status change */
> +       unsigned int isr;                       /* interrupt status, 0x0 */
> +
> +#define RPKT_FINISH_M          BIT(0)          /* interrupt mask of ISR[0] */
> +#define NORXBUF_M              BIT(1)          /* interrupt mask of ISR[1] */
> +#define XPKT_FINISH_M          BIT(2)          /* interrupt mask of ISR[2] */
> +#define NOTXBUF_M              BIT(3)          /* interrupt mask of ISR[3] */
> +#define XPKT_OK_M              BIT(4)          /* interrupt mask of ISR[4] */
> +#define XPKT_LOST_M            BIT(5)          /* interrupt mask of ISR[5] */
> +#define RPKT_SAV_M             BIT(6)          /* interrupt mask of ISR[6] */
> +#define RPKT_LOST_M            BIT(7)          /* interrupt mask of ISR[7] */
> +#define AHB_ERR_M              BIT(8)          /* interrupt mask of ISR[8] */
> +#define PHYSTS_CHG_M           BIT(9)          /* interrupt mask of ISR[9] */
> +       unsigned int imr;                       /* interrupt mask, 0x4 */
> +
> +/* the most significant 2 bytes of MAC address */
> +#define MAC_MADR_MASK          0xffff
> +       /* MAC most significant address, 0x8 */
> +       unsigned int mac_madr;
> +
> +       /* MAC least significant address, 0xc */
> +       unsigned int mac_ldar;
> +
> +       /* multicast address hash table 0, 0x10 */
> +       unsigned int matht0;
> +
> +       /* multicast address hash table 1, 0x14 */
> +       unsigned int matht1;
> +
> +       /* transmit poll demand, 0x18 */
> +       unsigned int txpd;
> +
> +       /* receive poll demand, 0x1c */
> +       unsigned int rxpd;
> +
> +       /* transmit ring base address, 0x20 */
> +       unsigned int txr_badr;
> +
> +       /* receive ring base address, 0x24 */
> +       unsigned int rxr_badr;
> +
> +/* defines the period of TX cycle time */
> +#define TXINT_TIME_SEL         BIT(15)
> +#define TXINT_THR_MASK         0x7000
> +#define TXINT_CNT_MASK         0xf00
> +/* defines the period of RX cycle time */
> +#define RXINT_TIME_SEL         BIT(7)
> +#define RXINT_THR_MASK         0x70
> +#define RXINT_CNT_MASK         0xF
> +       /* interrupt timer control, 0x28 */
> +       unsigned int itc;
> +
> +/* defines the period of TX poll time */
> +#define TXPOLL_TIME_SEL                BIT(12)
> +#define TXPOLL_CNT_MASK                0xf00
> +#define TXPOLL_CNT_SHIFT_BIT   8
> +/* defines the period of RX poll time */
> +#define RXPOLL_TIME_SEL                BIT(4)
> +#define RXPOLL_CNT_MASK                0xF
> +#define RXPOLL_CNT_SHIFT_BIT   0
> +       /* automatic polling timer control, 0x2c */
> +       unsigned int aptc;
> +
> +/* enable RX FIFO threshold arbitration */
> +#define RX_THR_EN              BIT(9)
> +#define RXFIFO_HTHR_MASK       0x1c0
> +#define RXFIFO_LTHR_MASK       0x38
> +/* use INCR16 burst command in AHB bus */
> +#define INCR16_EN              BIT(2)
> +/* use INCR8 burst command in AHB bus */
> +#define INCR8_EN               BIT(1)
> +/* use INCR4 burst command in AHB bus */
> +#define INCR4_EN               BIT(0)
> +       /* DMA burst length and arbitration control, 0x30 */
> +       unsigned int dblac;
> +
> +       unsigned int reserved1[21];             /* 0x34 - 0x84 */
> +
> +#define RX_BROADPKT            BIT(17)         /* receive boradcast packet */
> +/* receive all multicast packet */
> +#define RX_MULTIPKT            BIT(16)
> +#define FULLDUP                        BIT(15)         /* full duplex */
> +/* append CRC to transmitted packet */
> +#define CRC_APD                        BIT(14)
> +/* do not check incoming packet's destination address */
> +#define RCV_ALL                        BIT(12)
> +/* store incoming packet even if its length is great than 1518 bytes */
> +#define RX_FTL                 BIT(11)
> +/* store incoming packet even if its length is less than 64 bytes */
> +#define RX_RUNT                        BIT(10)
> +/* enable storing incoming packet if the packet passes hash table
> + * address filtering and is a multicast packet
> + */
> +#define HT_MULTI_EN            BIT(9)
> +#define RCV_EN                 BIT(8)          /* receiver enable */
> +/* enable packet reception when transmitting packet in half duplex mode */
> +#define ENRX_IN_HALFTX         BIT(6)
> +#define XMT_EN                 BIT(5)          /* transmitter enable */
> +/* disable CRC check when receiving packets */
> +#define CRC_DIS                        BIT(4)
> +#define LOOP_EN                        BIT(3)          /* internal loop-back */
> +/* software reset, last 64 AHB bus clocks */
> +#define SW_RST                 BIT(2)
> +#define RDMA_EN                        BIT(1)          /* enable receive DMA chan */
> +#define XDMA_EN                        BIT(0)          /* enable transmit DMA chan */
> +       unsigned int maccr;                     /* MAC control, 0x88 */
> +
> +#define COL_EXCEED             BIT(11)         /* collisions exceeds 16 */
> +/* transmitter detects late collision */
> +#define LATE_COL               BIT(10)
> +/* packet transmitted to ethernet lost due to late collision
> + * or excessive collision
> + */
> +#define XPKT_LOST              BIT(9)
> +/* packets transmitted to ethernet successfully */
> +#define XPKT_OK                        BIT(8)
> +/* receiver detects a runt packet */
> +#define RUNT_MAC_STS           BIT(7)
> +/* receiver detects a frame that is too long */
> +#define FTL_MAC_STS            BIT(6)
> +#define CRC_ERR_MAC_STS                BIT(5)
> +/* received packets list due to RX FIFO full */
> +#define RPKT_LOST              BIT(4)
> +/* packets received into RX FIFO successfully */
> +#define RPKT_SAVE              BIT(3)
> +/* incoming packet dropped due to collision */
> +#define COL                    BIT(2)
> +#define MCPU_BROADCAST         BIT(1)
> +#define MCPU_MULTICAST         BIT(0)
> +       unsigned int macsr;                     /* MAC status, 0x8c */
> +
> +/* initialize a write sequence to PHY by setting this bit to 1
> + * this bit would be auto cleared after the write operation is finished.
> + */
> +#define MIIWR                  BIT(27)
> +#define MIIRD                  BIT(26)
> +#define REGAD_MASK             0x3e00000
> +#define PHYAD_MASK             0x1f0000
> +#define MIIRDATA_MASK          0xffff
> +       unsigned int phycr;                     /* PHY control, 0x90 */
> +
> +#define MIIWDATA_MASK          0xffff
> +       unsigned int phywdata;                  /* PHY write data, 0x94 */
> +
> +#define PAUSE_TIME_MASK                0xffff0000
> +#define FC_HIGH_MASK           0xf000
> +#define FC_LOW_MASK            0xf00
> +#define RX_PAUSE               BIT(4)          /* receive pause frame */
> +/* packet transmission is paused due to receive */
> +#define TXPAUSED               BIT(3)
> +       /* pause frame */
> +/* enable flow control threshold mode. */
> +#define FCTHR_EN               BIT(2)
> +#define TX_PAUSE               BIT(1)          /* transmit pause frame */
> +#define FC_EN                  BIT(0)          /* flow control mode enable */
> +       unsigned int fcr;                       /* flow control, 0x98 */
> +
> +#define BK_LOW_MASK            0xf00
> +#define BKJAM_LEN_MASK         0xf0
> +#define BK_MODE                        BIT(1)          /* back pressure address mode */
> +#define BK_EN                  BIT(0)          /* back pressure mode enable */
> +       unsigned int bpr;                       /* back pressure, 0x9c */
> +
> +       unsigned int reserved2[9];              /* 0xa0 - 0xc0 */
> +
> +#define TEST_SEED_MASK      0x3fff
> +       unsigned int ts;                        /* test seed, 0xc4 */
> +
> +#define TXD_REQ                        BIT(31)         /* TXDMA request */
> +#define RXD_REQ                        BIT(30)         /* RXDMA request */
> +#define DARB_TXGNT             BIT(29)         /* TXDMA grant */
> +#define DARB_RXGNT             BIT(28)         /* RXDMA grant */
> +#define TXFIFO_EMPTY           BIT(27)         /* TX FIFO is empty */
> +#define RXFIFO_EMPTY           BIT(26)         /* RX FIFO is empty */
> +#define TXDMA2_SM_MASK         0x7000
> +#define TXDMA1_SM_MASK         0xf00
> +#define RXDMA2_SM_MASK         0x70
> +#define RXDMA1_SM_MASK         0xF
> +       unsigned int dmafifos;                  /* DMA/FIFO state, 0xc8 */
> +
> +#define SINGLE_PKT             BIT(26)         /* single packet mode */
> +/* automatic polling timer test mode */
> +#define PTIMER_TEST            BIT(25)
> +#define ITIMER_TEST            BIT(24)         /* interrupt timer test mode */
> +#define TEST_SEED_SEL          BIT(22)         /* test seed select */
> +#define SEED_SEL               BIT(21)         /* seed select */
> +#define TEST_MODE              BIT(20)         /* transmission test mode */
> +#define TEST_TIME_MASK         0xffc00
> +#define TEST_EXCEL_MASK                0x3e0
> +       unsigned int tm;                        /* test mode, 0xcc */
> +
> +       unsigned int reserved3;                 /* 0xd0 */
> +
> +#define TX_MCOL_MASK           0xffff0000
> +#define TX_MCOL_SHIFT_BIT      16
> +#define TX_SCOL_MASK           0xffff
> +#define TX_SCOL_SHIFT_BIT      0
> +       /* TX_MCOL and TX_SCOL counter, 0xd4 */
> +       unsigned int txmcol_xscol;
> +
> +#define RPF_MASK               0xffff0000
> +#define RPF_SHIFT_BIT          16
> +#define AEP_MASK               0xffff
> +#define AEP_SHIFT_BIT          0
> +       unsigned int rpf_aep;                   /* RPF and AEP counter, 0xd8 */
> +
> +#define XM_MASK                        0xffff0000
> +#define XM_SHIFT_BIT           16
> +#define PG_MASK                        0xffff
> +#define PG_SHIFT_BIT           0
> +       unsigned int xm_pg;                     /* XM and PG counter, 0xdc */
> +
> +#define RUNT_CNT_MASK          0xffff0000
> +#define RUNT_CNT_SHIFT_BIT     16
> +#define TLCC_MASK              0xffff
> +#define TLCC_SHIFT_BIT         0
> +       /* RUNT_CNT and TLCC counter, 0xe0 */
> +       unsigned int runtcnt_tlcc;
> +
> +#define CRCER_CNT_MASK         0xffff0000
> +#define CRCER_CNT_SHIFT_BIT    16
> +#define FTL_CNT_MASK           0xffff
> +#define FTL_CNT_SHIFT_BIT      0
> +       /* CRCER_CNT and FTL_CNT counter, 0xe4 */
> +       unsigned int crcercnt_ftlcnt;
> +
> +#define RLC_MASK               0xffff0000
> +#define RLC_SHIFT_BIT          16
> +#define RCC_MASK               0xffff
> +#define RCC_SHIFT_BIT          0
> +       unsigned int rlc_rcc;           /* RLC and RCC counter, 0xe8 */
> +
> +       unsigned int broc;              /* BROC counter, 0xec */
> +       unsigned int mulca;             /* MULCA counter, 0xf0 */
> +       unsigned int rp;                /* RP counter, 0xf4 */
> +       unsigned int xp;                /* XP counter, 0xf8 */
> +};

I don't think you can rely on the fields to be the size you expect (int
is not necessarily 32 bits), and nor can you expect them to have the
padding you expect (a 64 bit arch could pad ints to 64 bits). I think it
would be better to just #define the offsets explicitly, which will be
safe and easy to verify.

Thanks,
Mark.

^ permalink raw reply

* Linux IPV6_SUBTREES not functioning
From: Teco Boot @ 2013-08-02 10:15 UTC (permalink / raw)
  To: netdev; +Cc: boutier

For destination & source address routing, I prefer the single routing table approach with IPV6_SUBTREES over the multiple tables with ip rules approach.
Can some take a look at my findings? It looks broken. It seems the source address check in route cache is missing.

Teco


Output:
==========
this is my system:
Linux ubuntu 3.8.0-25-generic #37-Ubuntu SMP Thu Jun 6 20:47:30 UTC 2013 i686 i686 i686 GNU/Linux
CONFIG_IPV6_SUBTREES=y
... clean up for our experiment
... add a link-local
... add default
... add some source address specific defaults
====> now I have this routing table
default from 2001:db8:10::/48 via fe80::10 dev eth0  metric 1024 
default from 2001:db8:11::/48 via fe80::11 dev eth0  metric 1024 
default from 2001:db8:12::/48 via fe80::12 dev eth0  metric 1024 
fe80::1 dev eth0  proto kernel  metric 256 
default via fe80::ff dev eth0  metric 1024 
====> show route to same destination
2001:db8:babe::1 from 2001:db8:10::1 via fe80::10 dev eth0  metric 0 \    cache 
2001:db8:babe::1 from 2001:db8:11::1 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:babe::1 from 2001:db8:12::1 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:babe::1 from 2001:db8:1::1 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:babe::1 from :: via fe80::ff dev eth0  metric 0 \    cache 
====> show route to different destinations
2001:db8:cafe::10 from 2001:db8:10::1 via fe80::10 dev eth0  metric 0 \    cache 
2001:db8:cafe::11 from 2001:db8:11::1 via fe80::11 dev eth0  metric 0 \    cache 
2001:db8:cafe::12 from 2001:db8:12::1 via fe80::12 dev eth0  metric 0 \    cache 
2001:db8:cafe::21 from 2001:db8:1::1 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:cafe::22 from :: via fe80::ff dev eth0  metric 0 \    cache 
====> now the route cache is
2001:db8:babe::1 from 2001:db8:10::/48 via fe80::10 dev eth0  metric 0 \    cache 
2001:db8:babe::1 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:cafe::10 from 2001:db8:10::/48 via fe80::10 dev eth0  metric 0 \    cache 
2001:db8:cafe::11 from 2001:db8:11::/48 via fe80::11 dev eth0  metric 0 \    cache 
2001:db8:cafe::12 from 2001:db8:12::/48 via fe80::12 dev eth0  metric 0 \    cache 
2001:db8:cafe::21 via fe80::ff dev eth0  metric 0 \    cache 
2001:db8:cafe::22 via fe80::ff dev eth0  metric 0 \    cache 
 


My script:
=======
#!/bin/sh

echo "this is my system:" 
uname -a
grep IPV6_SUBTREES /boot/config-3.8.0-25-generic

echo ... clean up for our experiment
ip -6 address flush dev eth0
ip -6 route flush table all

echo ... add a link-local
ip address add fe80::1 dev eth0

echo ... add default
ip -6 route add default via fe80::ff dev eth0

echo ... add some source address specific defaults
ip -6 route add default from 2001:db8:10::/48 via fe80::10 dev eth0
ip -6 route add default from 2001:db8:11::/48 via fe80::11 dev eth0
ip -6 route add default from 2001:db8:12::/48 via fe80::12 dev eth0

echo -n "====> "
echo now I have this routing table
ip -6 -o route show table main

echo -n "====> "
echo show route to same destination
ip -6 -o route get 2001:db8:babe::1 from 2001:db8:10::1
ip -6 -o route get 2001:db8:babe::1 from 2001:db8:11::1
ip -6 -o route get 2001:db8:babe::1 from 2001:db8:12::1
ip -6 -o route get 2001:db8:babe::1 from 2001:db8:1::1
ip -6 -o route get 2001:db8:babe::1

echo -n "====> "
echo show route to different destinations
ip -6 -o route get 2001:db8:cafe::10 from 2001:db8:10::1
ip -6 -o route get 2001:db8:cafe::11 from 2001:db8:11::1
ip -6 -o route get 2001:db8:cafe::12 from 2001:db8:12::1
ip -6 -o route get 2001:db8:cafe::21 from 2001:db8:1::1
ip -6 -o route get 2001:db8:cafe::22
echo -n "====> "
echo now the route cache is
ip -6 -o route show cache

^ permalink raw reply

* [PATCH net] net: mlx5: fix sizeof usage in health_care's reg_handler
From: Daniel Borkmann @ 2013-08-02 10:16 UTC (permalink / raw)
  To: davem; +Cc: netdev, Or Gerlitz

In mlx5's function health_care() the callback handler reg_handler() is
being called that checks the devices registers like:

  reg_handler(dev->pdev, health->health, sizeof(health->health));

health->health is a pointer to the member "struct health_buffer __iomem
*health" of mlx5_core_health, where health buffer itself looks like:

  struct health_buffer {
        __be32          assert_var[5];
        __be32          rsvd0[3];
        __be32          assert_exit_ptr;
        __be32          assert_callra;
        __be32          rsvd1[2];
        ...
        __be16          ext_sync;
  };

Therefore, I strongly assume sizeof(*health->health) is being meant
to be passed as an argument. Interestingly, there are actually no
in-tree users of mlx5_[un]register_health_report_handler(), but some
debugging modules might want to know the correct size instead.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/health.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
index 748f10a..3592e43 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -101,7 +101,7 @@ static void health_care(struct work_struct *work)
 		spin_lock_irq(&health_lock);
 		if (reg_handler)
 			reg_handler(dev->pdev, health->health,
-				    sizeof(health->health));
+				    sizeof(*health->health));
 
 		list_del_init(&health->list);
 		spin_unlock_irq(&health_lock);
-- 
1.7.11.7

^ permalink raw reply related

* Re: [PATCH net] net: rtm_to_ifaddr: free ifa if ifa_cacheinfo processing fails
From: Jiri Pirko @ 2013-08-02 10:22 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev
In-Reply-To: <1375435963-30009-1-git-send-email-dborkman@redhat.com>

Fri, Aug 02, 2013 at 11:32:43AM CEST, dborkman@redhat.com wrote:
>Commit 5c766d642 ("ipv4: introduce address lifetime") leaves the ifa
>resource that was allocated via inet_alloc_ifa() unfreed when returning
>the function with -EINVAL. Thus, free it first via inet_free_ifa().
>
>Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Reviewed-by: Jiri Pirko <jiri@resnulli.us>

^ permalink raw reply

* Re: [PATCH v4] net: Add MOXA ART SoCs ethernet driver
From: Florian Fainelli @ 2013-08-02 10:23 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Jonas Jensen, netdev@vger.kernel.org, davem@davemloft.net,
	linux-doc@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, arm@kernel.org, joe@perches.com
In-Reply-To: <20130802100406.GC2884@e106331-lin.cambridge.arm.com>

2013/8/2 Mark Rutland <mark.rutland@arm.com>:
> On Thu, Aug 01, 2013 at 10:39:28AM +0100, Jonas Jensen wrote:
>> The MOXA UC-711X hardware(s) has an ethernet controller that seem to be
>> developed internally. The IC used is "RTL8201CP".
>>
>> Since there is no public documentation, this driver is mostly the one
>> published by MOXA that has been heavily cleaned up / ported from linux 2.6.9.
>>
>> Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
>> ---
>
> [...]
>
>> diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
>> new file mode 100644
>> index 0000000..1fc44ff
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt
>> @@ -0,0 +1,25 @@
>> +MOXA ART Ethernet Controller
>> +
>> +Required properties:
>> +
>> +- compatible : Must be "moxa,moxart-mac"
>> +- reg : Should contain registers location and length
>> +  index 0 : main register
>
> I assume there's more than one register in the main register bank?
>
> Are there any other register banks not used by this driver?
>
>> +  index 1 : mac address (stored on flash)
>
> Is that flash a part of the MAC unit?
>
> Is it only 6 bytes long (judging by the examples), or is the th only
> portion used by the driver?
>
> If it's bigger, I'd prefer to describe the whole of flash. This driver
> will know the offset within it, and can choose to map only the protion
> it wants to use. Another driver may choose to do more interesting
> things. We need to describe the hardware, not how we expect it to be
> used...
>
> If it's not associated with the MAC, I'm not sure this is the best way
> of describing the linkage...

I also do not quite like it, this is very unusual. Here is how you
could potentially solve this:

- generate a random ethernet MAC adddress and later on let user-space
fetch the MAC address from the flash and set it correctly
- have some early code in arch/arm/mach-moxart which fetches the MAC
address from the flash and then update the ethernet node
local-mac-address property accordingly

Ideally, fetching the MAC address from whatever backend storage is
something that should really be left to user-space...

>
>> +- interrupts : Should contain the mac interrupt number
>
> Is there no need to link this to a phy, or is it a fixed-link device?
>
>> +
>> +Example:
>> +
>> +       mac0: mac@90900000 {
>> +               compatible = "moxa,moxart-mac";
>> +               reg =   <0x90900000 0x100>,
>> +                       <0x80000050 0x6>;
>> +               interrupts = <25 0>;
>> +       };
>> +
>> +       mac1: mac@92000000 {
>> +               compatible = "moxa,moxart-mac";
>> +               reg =   <0x92000000 0x100>,
>> +                       <0x80000056 0x6>;
>> +               interrupts = <27 0>;
>> +       };
>
> [...]
>
>> diff --git a/drivers/net/ethernet/moxa/moxart_ether.h b/drivers/net/ethernet/moxa/moxart_ether.h
>> new file mode 100644
>> index 0000000..790b6a9
>> --- /dev/null
>> +++ b/drivers/net/ethernet/moxa/moxart_ether.h
>> @@ -0,0 +1,513 @@
>> +/* MOXA ART Ethernet (RTL8201CP) driver.
>> + *
>> + * Copyright (C) 2013 Jonas Jensen
>> + *
>> + * Jonas Jensen <jonas.jensen@gmail.com>
>> + *
>> + * Based on code from
>> + * Moxa Technology Co., Ltd. <www.moxa.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2.  This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef _MOXART_ETHERNET_H
>> +#define _MOXART_ETHERNET_H
>> +
>> +#define TX_DESC_NUM            64
>> +#define TX_DESC_NUM_MASK       (TX_DESC_NUM-1)
>> +#define TX_NEXT(N)             (((N) + 1) & (TX_DESC_NUM_MASK))
>> +#define TX_BUF_SIZE            1600
>> +
>> +#define RX_DESC_NUM            64
>> +#define RX_DESC_NUM_MASK       (RX_DESC_NUM-1)
>> +#define RX_NEXT(N)             (((N) + 1) & (RX_DESC_NUM_MASK))
>> +#define RX_BUF_SIZE            1600
>> +
>> +struct tx_desc_t {
>> +       union {
>> +#define TXDMA_OWN              BIT(31)
>> +#define TXPKT_EXSCOL           BIT(1)
>> +#define TXPKT_LATECOL          BIT(0)
>> +               unsigned int ui;
>> +
>> +               struct {
>> +                       /* is aborted due to late collision */
>> +                       unsigned int tx_pkt_late_col:1;
>> +
>> +                       /* is aborted after 16 collisions */
>> +                       unsigned int rx_pkt_exs_col:1;
>> +
>> +                       unsigned int reserved1:29;
>> +
>> +                       /* is owned by the MAC controller */
>> +                       unsigned int tx_dma_own:1;
>> +               } ubit;
>> +       } txdes0;
>
> Unless I've misunderstood the later code, this is the format of data
> shared with the device? Bitfields aren't portable, and you can't rely on
> the padding here being what you expect...
>
> Similarly, the other structures below used in this way below seem scary
> to me.
>
>> +
>> +       union {
>> +#define EDOTR                  BIT(31)
>> +#define TXIC                   BIT(30)
>> +#define TX2FIC                 BIT(29)
>> +#define FTS                    BIT(28)
>> +#define LTS                    BIT(27)
>> +#define TXBUF_SIZE_MASK                0x7ff
>> +#define TXBUF_SIZE_MAX         (TXBUF_SIZE_MASK+1)
>> +               unsigned int ui;
>> +
>> +               struct {
>> +                       /* transmit buffer size in byte */
>> +                       unsigned int tx_buf_size:11;
>> +
>> +                       unsigned int reserved2:16;
>> +
>> +                       /* is the last descriptor of a Tx packet */
>> +                       unsigned int lts:1;
>> +
>> +                       /* is the first descriptor of a Tx packet */
>> +                       unsigned int fts:1;
>> +
>> +                       /* transmit to FIFO interrupt on completion */
>> +                       unsigned int tx2_fic:1;
>> +
>> +                       /* transmit interrupt on completion */
>> +                       unsigned int tx_ic:1;
>> +
>> +                       /* end descriptor of transmit ring */
>> +                       unsigned int edotr:1;
>> +               } ubit;
>> +       } txdes1;
>> +
>> +       struct {
>> +               /* transmit buffer physical base address */
>> +               unsigned int addr_phys;
>> +
>> +               /* transmit buffer virtual base address */
>> +               unsigned char *addr_virt;
>> +       } txdes2;
>> +};
>> +
>> +struct rx_desc_t {
>> +       union {
>> +#define RXDMA_OWN              BIT(31)
>> +#define FRS                    BIT(29)
>> +#define LRS                    BIT(28)
>> +#define RX_ODD_NB              BIT(22)
>> +#define RUNT                   BIT(21)
>> +#define FTL                    BIT(20)
>> +#define CRC_ERR                        BIT(19)
>> +#define RX_ERR                 BIT(18)
>> +#define BROADCAST_RXDES0       BIT(17)
>> +#define MULTICAST_RXDES0       BIT(16)
>> +#define RFL_MASK               0x7ff
>> +#define RFL_MAX                        (RFL_MASK+1)
>> +               unsigned int ui;
>> +
>> +               struct {
>> +                       /* receive frame length */
>> +                       unsigned int recv_frame_len:11;
>> +                       unsigned int reserved1:5;
>> +
>> +                       /* multicast frame */
>> +                       unsigned int multicast:1;
>> +
>> +                       /* broadcast frame */
>> +                       unsigned int broadcast:1;
>> +                       unsigned int rx_err:1;          /* receive error */
>> +                       unsigned int crc_err:1;         /* CRC error */
>> +                       unsigned int ftl:1;             /* frame too long */
>> +
>> +                       /* runt packet, less than 64 bytes */
>> +                       unsigned int runt:1;
>> +
>> +                       /* receive odd nibbles */
>> +                       unsigned int rx_odd_nb:1;
>> +                       unsigned int reserved2:5;
>> +
>> +                       /* last receive segment descriptor */
>> +                       unsigned int lrs:1;
>> +
>> +                       /* first receive segment descriptor */
>> +                       unsigned int frs:1;
>> +
>> +                       unsigned int reserved3:1;
>> +                       unsigned int rx_dma_own:1;      /* RXDMA onwership */
>> +               } ubit;
>> +       } rxdes0;
>> +
>> +       union {
>> +#define EDORR                  BIT(31)
>> +#define RXBUF_SIZE_MASK                0x7ff
>> +#define RXBUF_SIZE_MAX         (RXBUF_SIZE_MASK+1)
>> +               unsigned int ui;
>> +
>> +               struct {
>> +                       /* receive buffer size */
>> +                       unsigned int rx_buf_size:11;
>> +
>> +                       unsigned int reserved4:20;
>> +
>> +                       /* end descriptor of receive ring */
>> +                       unsigned int edorr:1;
>> +               } ubit;
>> +       } rxdes1;
>> +
>> +       struct {
>> +               /* receive buffer physical base address */
>> +               unsigned int addr_phys;
>> +
>> +               /* receive buffer virtual base address */
>> +               unsigned char *addr_virt;
>> +       } rxdes2;
>> +};
>> +
>> +struct mac_control_reg_t {
>> +
>> +/* RXDMA has received packets into RX buffer successfully */
>> +#define RPKT_FINISH            BIT(0)
>> +/* receive buffer unavailable */
>> +#define NORXBUF                        BIT(1)
>> +/* TXDMA has moved data into the TX FIFO */
>> +#define XPKT_FINISH            BIT(2)
>> +/* transmit buffer unavailable */
>> +#define NOTXBUF                        BIT(3)
>> +/* packets transmitted to ethernet successfully */
>> +#define XPKT_OK_INT_STS                BIT(4)
>> +/* packets transmitted to ethernet lost due to late
>> + * collision or excessive collision
>> + */
>> +#define XPKT_LOST_INT_STS      BIT(5)
>> +/* packets received into RX FIFO successfully */
>> +#define RPKT_SAV               BIT(6)
>> +/* received packet lost due to RX FIFO full */
>> +#define RPKT_LOST_INT_STS      BIT(7)
>> +#define AHB_ERR                        BIT(8)          /* AHB error */
>> +#define PHYSTS_CHG             BIT(9)          /* PHY link status change */
>> +       unsigned int isr;                       /* interrupt status, 0x0 */
>> +
>> +#define RPKT_FINISH_M          BIT(0)          /* interrupt mask of ISR[0] */
>> +#define NORXBUF_M              BIT(1)          /* interrupt mask of ISR[1] */
>> +#define XPKT_FINISH_M          BIT(2)          /* interrupt mask of ISR[2] */
>> +#define NOTXBUF_M              BIT(3)          /* interrupt mask of ISR[3] */
>> +#define XPKT_OK_M              BIT(4)          /* interrupt mask of ISR[4] */
>> +#define XPKT_LOST_M            BIT(5)          /* interrupt mask of ISR[5] */
>> +#define RPKT_SAV_M             BIT(6)          /* interrupt mask of ISR[6] */
>> +#define RPKT_LOST_M            BIT(7)          /* interrupt mask of ISR[7] */
>> +#define AHB_ERR_M              BIT(8)          /* interrupt mask of ISR[8] */
>> +#define PHYSTS_CHG_M           BIT(9)          /* interrupt mask of ISR[9] */
>> +       unsigned int imr;                       /* interrupt mask, 0x4 */
>> +
>> +/* the most significant 2 bytes of MAC address */
>> +#define MAC_MADR_MASK          0xffff
>> +       /* MAC most significant address, 0x8 */
>> +       unsigned int mac_madr;
>> +
>> +       /* MAC least significant address, 0xc */
>> +       unsigned int mac_ldar;
>> +
>> +       /* multicast address hash table 0, 0x10 */
>> +       unsigned int matht0;
>> +
>> +       /* multicast address hash table 1, 0x14 */
>> +       unsigned int matht1;
>> +
>> +       /* transmit poll demand, 0x18 */
>> +       unsigned int txpd;
>> +
>> +       /* receive poll demand, 0x1c */
>> +       unsigned int rxpd;
>> +
>> +       /* transmit ring base address, 0x20 */
>> +       unsigned int txr_badr;
>> +
>> +       /* receive ring base address, 0x24 */
>> +       unsigned int rxr_badr;
>> +
>> +/* defines the period of TX cycle time */
>> +#define TXINT_TIME_SEL         BIT(15)
>> +#define TXINT_THR_MASK         0x7000
>> +#define TXINT_CNT_MASK         0xf00
>> +/* defines the period of RX cycle time */
>> +#define RXINT_TIME_SEL         BIT(7)
>> +#define RXINT_THR_MASK         0x70
>> +#define RXINT_CNT_MASK         0xF
>> +       /* interrupt timer control, 0x28 */
>> +       unsigned int itc;
>> +
>> +/* defines the period of TX poll time */
>> +#define TXPOLL_TIME_SEL                BIT(12)
>> +#define TXPOLL_CNT_MASK                0xf00
>> +#define TXPOLL_CNT_SHIFT_BIT   8
>> +/* defines the period of RX poll time */
>> +#define RXPOLL_TIME_SEL                BIT(4)
>> +#define RXPOLL_CNT_MASK                0xF
>> +#define RXPOLL_CNT_SHIFT_BIT   0
>> +       /* automatic polling timer control, 0x2c */
>> +       unsigned int aptc;
>> +
>> +/* enable RX FIFO threshold arbitration */
>> +#define RX_THR_EN              BIT(9)
>> +#define RXFIFO_HTHR_MASK       0x1c0
>> +#define RXFIFO_LTHR_MASK       0x38
>> +/* use INCR16 burst command in AHB bus */
>> +#define INCR16_EN              BIT(2)
>> +/* use INCR8 burst command in AHB bus */
>> +#define INCR8_EN               BIT(1)
>> +/* use INCR4 burst command in AHB bus */
>> +#define INCR4_EN               BIT(0)
>> +       /* DMA burst length and arbitration control, 0x30 */
>> +       unsigned int dblac;
>> +
>> +       unsigned int reserved1[21];             /* 0x34 - 0x84 */
>> +
>> +#define RX_BROADPKT            BIT(17)         /* receive boradcast packet */
>> +/* receive all multicast packet */
>> +#define RX_MULTIPKT            BIT(16)
>> +#define FULLDUP                        BIT(15)         /* full duplex */
>> +/* append CRC to transmitted packet */
>> +#define CRC_APD                        BIT(14)
>> +/* do not check incoming packet's destination address */
>> +#define RCV_ALL                        BIT(12)
>> +/* store incoming packet even if its length is great than 1518 bytes */
>> +#define RX_FTL                 BIT(11)
>> +/* store incoming packet even if its length is less than 64 bytes */
>> +#define RX_RUNT                        BIT(10)
>> +/* enable storing incoming packet if the packet passes hash table
>> + * address filtering and is a multicast packet
>> + */
>> +#define HT_MULTI_EN            BIT(9)
>> +#define RCV_EN                 BIT(8)          /* receiver enable */
>> +/* enable packet reception when transmitting packet in half duplex mode */
>> +#define ENRX_IN_HALFTX         BIT(6)
>> +#define XMT_EN                 BIT(5)          /* transmitter enable */
>> +/* disable CRC check when receiving packets */
>> +#define CRC_DIS                        BIT(4)
>> +#define LOOP_EN                        BIT(3)          /* internal loop-back */
>> +/* software reset, last 64 AHB bus clocks */
>> +#define SW_RST                 BIT(2)
>> +#define RDMA_EN                        BIT(1)          /* enable receive DMA chan */
>> +#define XDMA_EN                        BIT(0)          /* enable transmit DMA chan */
>> +       unsigned int maccr;                     /* MAC control, 0x88 */
>> +
>> +#define COL_EXCEED             BIT(11)         /* collisions exceeds 16 */
>> +/* transmitter detects late collision */
>> +#define LATE_COL               BIT(10)
>> +/* packet transmitted to ethernet lost due to late collision
>> + * or excessive collision
>> + */
>> +#define XPKT_LOST              BIT(9)
>> +/* packets transmitted to ethernet successfully */
>> +#define XPKT_OK                        BIT(8)
>> +/* receiver detects a runt packet */
>> +#define RUNT_MAC_STS           BIT(7)
>> +/* receiver detects a frame that is too long */
>> +#define FTL_MAC_STS            BIT(6)
>> +#define CRC_ERR_MAC_STS                BIT(5)
>> +/* received packets list due to RX FIFO full */
>> +#define RPKT_LOST              BIT(4)
>> +/* packets received into RX FIFO successfully */
>> +#define RPKT_SAVE              BIT(3)
>> +/* incoming packet dropped due to collision */
>> +#define COL                    BIT(2)
>> +#define MCPU_BROADCAST         BIT(1)
>> +#define MCPU_MULTICAST         BIT(0)
>> +       unsigned int macsr;                     /* MAC status, 0x8c */
>> +
>> +/* initialize a write sequence to PHY by setting this bit to 1
>> + * this bit would be auto cleared after the write operation is finished.
>> + */
>> +#define MIIWR                  BIT(27)
>> +#define MIIRD                  BIT(26)
>> +#define REGAD_MASK             0x3e00000
>> +#define PHYAD_MASK             0x1f0000
>> +#define MIIRDATA_MASK          0xffff
>> +       unsigned int phycr;                     /* PHY control, 0x90 */
>> +
>> +#define MIIWDATA_MASK          0xffff
>> +       unsigned int phywdata;                  /* PHY write data, 0x94 */
>> +
>> +#define PAUSE_TIME_MASK                0xffff0000
>> +#define FC_HIGH_MASK           0xf000
>> +#define FC_LOW_MASK            0xf00
>> +#define RX_PAUSE               BIT(4)          /* receive pause frame */
>> +/* packet transmission is paused due to receive */
>> +#define TXPAUSED               BIT(3)
>> +       /* pause frame */
>> +/* enable flow control threshold mode. */
>> +#define FCTHR_EN               BIT(2)
>> +#define TX_PAUSE               BIT(1)          /* transmit pause frame */
>> +#define FC_EN                  BIT(0)          /* flow control mode enable */
>> +       unsigned int fcr;                       /* flow control, 0x98 */
>> +
>> +#define BK_LOW_MASK            0xf00
>> +#define BKJAM_LEN_MASK         0xf0
>> +#define BK_MODE                        BIT(1)          /* back pressure address mode */
>> +#define BK_EN                  BIT(0)          /* back pressure mode enable */
>> +       unsigned int bpr;                       /* back pressure, 0x9c */
>> +
>> +       unsigned int reserved2[9];              /* 0xa0 - 0xc0 */
>> +
>> +#define TEST_SEED_MASK      0x3fff
>> +       unsigned int ts;                        /* test seed, 0xc4 */
>> +
>> +#define TXD_REQ                        BIT(31)         /* TXDMA request */
>> +#define RXD_REQ                        BIT(30)         /* RXDMA request */
>> +#define DARB_TXGNT             BIT(29)         /* TXDMA grant */
>> +#define DARB_RXGNT             BIT(28)         /* RXDMA grant */
>> +#define TXFIFO_EMPTY           BIT(27)         /* TX FIFO is empty */
>> +#define RXFIFO_EMPTY           BIT(26)         /* RX FIFO is empty */
>> +#define TXDMA2_SM_MASK         0x7000
>> +#define TXDMA1_SM_MASK         0xf00
>> +#define RXDMA2_SM_MASK         0x70
>> +#define RXDMA1_SM_MASK         0xF
>> +       unsigned int dmafifos;                  /* DMA/FIFO state, 0xc8 */
>> +
>> +#define SINGLE_PKT             BIT(26)         /* single packet mode */
>> +/* automatic polling timer test mode */
>> +#define PTIMER_TEST            BIT(25)
>> +#define ITIMER_TEST            BIT(24)         /* interrupt timer test mode */
>> +#define TEST_SEED_SEL          BIT(22)         /* test seed select */
>> +#define SEED_SEL               BIT(21)         /* seed select */
>> +#define TEST_MODE              BIT(20)         /* transmission test mode */
>> +#define TEST_TIME_MASK         0xffc00
>> +#define TEST_EXCEL_MASK                0x3e0
>> +       unsigned int tm;                        /* test mode, 0xcc */
>> +
>> +       unsigned int reserved3;                 /* 0xd0 */
>> +
>> +#define TX_MCOL_MASK           0xffff0000
>> +#define TX_MCOL_SHIFT_BIT      16
>> +#define TX_SCOL_MASK           0xffff
>> +#define TX_SCOL_SHIFT_BIT      0
>> +       /* TX_MCOL and TX_SCOL counter, 0xd4 */
>> +       unsigned int txmcol_xscol;
>> +
>> +#define RPF_MASK               0xffff0000
>> +#define RPF_SHIFT_BIT          16
>> +#define AEP_MASK               0xffff
>> +#define AEP_SHIFT_BIT          0
>> +       unsigned int rpf_aep;                   /* RPF and AEP counter, 0xd8 */
>> +
>> +#define XM_MASK                        0xffff0000
>> +#define XM_SHIFT_BIT           16
>> +#define PG_MASK                        0xffff
>> +#define PG_SHIFT_BIT           0
>> +       unsigned int xm_pg;                     /* XM and PG counter, 0xdc */
>> +
>> +#define RUNT_CNT_MASK          0xffff0000
>> +#define RUNT_CNT_SHIFT_BIT     16
>> +#define TLCC_MASK              0xffff
>> +#define TLCC_SHIFT_BIT         0
>> +       /* RUNT_CNT and TLCC counter, 0xe0 */
>> +       unsigned int runtcnt_tlcc;
>> +
>> +#define CRCER_CNT_MASK         0xffff0000
>> +#define CRCER_CNT_SHIFT_BIT    16
>> +#define FTL_CNT_MASK           0xffff
>> +#define FTL_CNT_SHIFT_BIT      0
>> +       /* CRCER_CNT and FTL_CNT counter, 0xe4 */
>> +       unsigned int crcercnt_ftlcnt;
>> +
>> +#define RLC_MASK               0xffff0000
>> +#define RLC_SHIFT_BIT          16
>> +#define RCC_MASK               0xffff
>> +#define RCC_SHIFT_BIT          0
>> +       unsigned int rlc_rcc;           /* RLC and RCC counter, 0xe8 */
>> +
>> +       unsigned int broc;              /* BROC counter, 0xec */
>> +       unsigned int mulca;             /* MULCA counter, 0xf0 */
>> +       unsigned int rp;                /* RP counter, 0xf4 */
>> +       unsigned int xp;                /* XP counter, 0xf8 */
>> +};
>
> I don't think you can rely on the fields to be the size you expect (int
> is not necessarily 32 bits), and nor can you expect them to have the
> padding you expect (a 64 bit arch could pad ints to 64 bits). I think it
> would be better to just #define the offsets explicitly, which will be
> safe and easy to verify.
>
> Thanks,
> Mark.



-- 
Florian

^ permalink raw reply

* Re: [Cluster-devel] [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions
From: Christoph Hellwig @ 2013-08-02 10:31 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev, linux-cifs, linux-nfs, cluster-devel, Trond Myklebust,
	linux-kernel, Steve French, David S. Miller
In-Reply-To: <1375427674-21735-7-git-send-email-amwang@redhat.com>

On Fri, Aug 02, 2013 at 03:14:32PM +0800, Cong Wang wrote:
> From: Cong Wang <amwang@redhat.com>
> 
> nfs and cifs define some helper functions for sockaddr,
> they can use the generic functions for union inet_addr too.
> 
> Since some dlm code needs to compare ->sin_port, introduce a
> generic function inet_addr_equal_strict() for it.

Would sound more useful to have a sockaddr_equal case that can be used
on any sockaddr.  For cases that no current user handles just return
false.

^ permalink raw reply

* Re: [PATCH 2/2] igb: Expose RSS indirection table for ethtool
From: Ben Hutchings @ 2013-08-02 11:52 UTC (permalink / raw)
  To: Laura Mihaela Vasilescu
  Cc: netdev, carolyn.wyborny, anjali.singhai, jeffrey.t.kirsher,
	alexander.h.duyck
In-Reply-To: <1375260212-19351-2-git-send-email-laura.vasilescu@rosedu.org>

On Wed, 2013-07-31 at 11:43 +0300, Laura Mihaela Vasilescu wrote:
[...]
> +static int igb_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
> +{
> +	struct igb_adapter *adapter = netdev_priv(netdev);
> +	struct e1000_hw *hw = &adapter->hw;
> +	int i;
> +	u32 num_queues;
> +
> +	num_queues = adapter->rss_queues;
> +
> +	switch (hw->mac.type) {
> +	case e1000_82576:
> +		/* 82576 supports 2 RSS queues for SR-IOV */
> +		if (adapter->vfs_allocated_count)
> +			num_queues = 2;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	/* Verify user input. */
> +	for (i = 0; i < IGB_RETA_SIZE; i++)
> +		if (indir[i] > num_queues)
> +			return -EINVAL;
[...]

Surely the comparison should be >= ?

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: bonding + arp monitoring fails if interface is a vlan
From: Nikolay Aleksandrov @ 2013-08-02 11:58 UTC (permalink / raw)
  To: Santiago Garcia Mantinan; +Cc: netdev
In-Reply-To: <20130801121142.GA444@www.manty.net>

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

On 08/01/2013 02:11 PM, Santiago Garcia Mantinan wrote:
> Hi!
> 
> I'm trying to setup a bond of a couple of vlans, these vlans are different
> paths to an upstream switch from a local switch.  I want to do arp
> monitoring of the link in order for the bonding interface to know which path
> is ok and wich one is broken.  If I set it up using arp monitoring and
> without using vlans it works ok, it also works if I set it up using vlans
> but without arp monitoring, so the broken setup seems to be with bonding +
> arp monitoring + vlans. Here is a schema:
> 
>  -------------
> |Remote Switch|
>  -------------
>    |      |
>    P      P
>    A      A
>    T      T
>    H      H
>    1      2
>    |      |
>  ------------
> |Local switch|
>  ------------
>       |
>       | VLAN for PATH1
>       | VLAN for PATH2
>       |
>  Linux machine
> 
> The broken setup seems to work but arp monitoring makes it loose the logical
> link from time to time, thus changing to other slave if available.  What I
> saw when monitoring this with tcpdump is that all the arp requests were
> going out and that all the replies where coming in, so acording to the
> traffic seen on tcpdump the link should have been stable, but
> /proc/net/bonding/bond0 showed the link failures increasing and when testing
> with just a vlan interface I was loosing ping when the link was going down.
> 
> I've tried this on Debian wheezy with its 3.2.46 kernel and also the 3.10.3
> version in unstable, the tests where done on a couple of machines using a 32
> bits kernel with different nics (r8169 and skge).
> 
> I created a small lab to replicate the problem, on this setup I avoided all
> the switching and I directly connected the machine with bonding to another
> Linux on which I just had eth0.1002 configured with ip 192.168.1.1, the
> results where the same as in the full scenario, link on the bonding slave
> was going down from time to time.
> 
> This is the setup on the bonding interface.
> 
> auto bond0
> iface bond0 inet static
>         address 192.168.1.2
>         netmask 255.255.255.0
>         bond-slaves eth0.1002
>         bond-mode active-backup
>         bond-arp_validate 0
>         bond-arp_interval 5000
>         bond-arp_ip_target 192.168.1.1
>         pre-up ip link set eth0 up || true
>         pre-up ip link add link eth0 name eth0.1002 type vlan id 1002 || true
>         down ip link delete eth0.1002 || true
> 
I believe that it is because dev_trans_start() returns 0 for 8021q devices and
so the calculations if the slave has transmitted are wrong, and the flip-flop
happens.
Please try the attached patch, it should resolve your issue (basically it gets
the dev_trans_start of the vlan's underlying device if a vlan is found).

The patch is against Linus' tree.

Cheers,
 Nik



[-- Attachment #2: bond-trans-start.patch --]
[-- Type: text/x-patch, Size: 1729 bytes --]

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 07f257d4..6aac0ae 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -665,6 +665,16 @@ static int bond_check_dev_link(struct bonding *bond,
 	return reporting ? -1 : BMSR_LSTATUS;
 }
 
+static unsigned long bond_dev_trans_start(struct net_device *dev)
+{
+        struct net_device *real_dev = dev;
+
+        if (dev->priv_flags & IFF_802_1Q_VLAN)
+                real_dev = vlan_dev_real_dev(dev);
+
+        return dev_trans_start(real_dev);
+}
+
 /*----------------------------- Multicast list ------------------------------*/
 
 /*
@@ -2750,7 +2760,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
 	 *       so it can wait
 	 */
 	bond_for_each_slave(bond, slave, i) {
-		unsigned long trans_start = dev_trans_start(slave->dev);
+		unsigned long trans_start = bond_dev_trans_start(slave->dev);
 
 		if (slave->link != BOND_LINK_UP) {
 			if (time_in_range(jiffies,
@@ -2912,7 +2922,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
 		 * - (more than 2*delta since receive AND
 		 *    the bond has an IP address)
 		 */
-		trans_start = dev_trans_start(slave->dev);
+		trans_start = bond_dev_trans_start(slave->dev);
 		if (bond_is_active_slave(slave) &&
 		    (!time_in_range(jiffies,
 			trans_start - delta_in_ticks,
@@ -2947,7 +2957,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
 			continue;
 
 		case BOND_LINK_UP:
-			trans_start = dev_trans_start(slave->dev);
+			trans_start = bond_dev_trans_start(slave->dev);
 			if ((!bond->curr_active_slave &&
 			     time_in_range(jiffies,
 					   trans_start - delta_in_ticks,

^ permalink raw reply related

* Re: [PATCH] sis900: Fix the tx queue timeout issue
From: Ben Hutchings @ 2013-08-02 12:03 UTC (permalink / raw)
  To: Denis Kirjanov; +Cc: venza, davem, netdev
In-Reply-To: <1375281782-2332-1-git-send-email-kda@linux-powerpc.org>

On Wed, 2013-07-31 at 18:43 +0400, Denis Kirjanov wrote:
[...]
> We are trying to initiate a frame transmission even
> if we are not ready to do so due auto negotiation progress:
> 
> timer routine checks the link status and if it's up calls
> netif_carrier_on() allowing upper layer to start the tx queue

Right.  So why is sis900_start_xmit() still being called?  Is this
handling the case where the link just went down and the TX scheduler has
not yet reacted to this?

Would it actually hurt if a packet is queued at this point?  I see no
reason to think it would.  In that case you could remove the entire
if-statement.

Ben.

> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
> ---
>  drivers/net/ethernet/sis/sis900.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
> index eb4aea3..9516734 100644
> --- a/drivers/net/ethernet/sis/sis900.c
> +++ b/drivers/net/ethernet/sis/sis900.c
> @@ -1613,9 +1613,13 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
>  	unsigned int  count_dirty_tx;
>  
>  	/* Don't transmit data before the complete of auto-negotiation */
> -	if(!sis_priv->autong_complete){
> -		netif_stop_queue(net_dev);
> -		return NETDEV_TX_BUSY;
> +	if (unlikely(!sis_priv->autong_complete)) {
> +		if (netif_msg_tx_err(sis_priv) && net_ratelimit())
> +			printk(KERN_DEBUG "%s: Auto negotiation in progress\n",
> +					net_dev->name);
> +		net_dev->stats.tx_dropped++;
> +		dev_kfree_skb(skb);
> +		return NETDEV_TX_OK;
>  	}
>  
>  	spin_lock_irqsave(&sis_priv->lock, flags);

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH] sis900: Fix the tx queue timeout issue
From: Denis Kirjanov @ 2013-08-02 12:13 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Denis Kirjanov, venza, davem, netdev
In-Reply-To: <1375445019.11783.5.camel@deadeye.wl.decadent.org.uk>

On 8/2/13, Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Wed, 2013-07-31 at 18:43 +0400, Denis Kirjanov wrote:
> [...]
>> We are trying to initiate a frame transmission even
>> if we are not ready to do so due auto negotiation progress:
>>
>> timer routine checks the link status and if it's up calls
>> netif_carrier_on() allowing upper layer to start the tx queue
>
> Right.  So why is sis900_start_xmit() still being called?  Is this
> handling the case where the link just went down and the TX scheduler has
> not yet reacted to this?
>
> Would it actually hurt if a packet is queued at this point?  I see no
> reason to think it would.  In that case you could remove the entire
> if-statement.

Yeah, it's completely wrong to handle such issue in tx path and it
must be removed.
I've prepared an another patch... I'll send it shortly.

Thanks.

> Ben.
>
>> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
>> ---
>>  drivers/net/ethernet/sis/sis900.c | 10 +++++++---
>>  1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/sis/sis900.c
>> b/drivers/net/ethernet/sis/sis900.c
>> index eb4aea3..9516734 100644
>> --- a/drivers/net/ethernet/sis/sis900.c
>> +++ b/drivers/net/ethernet/sis/sis900.c
>> @@ -1613,9 +1613,13 @@ sis900_start_xmit(struct sk_buff *skb, struct
>> net_device *net_dev)
>>  	unsigned int  count_dirty_tx;
>>
>>  	/* Don't transmit data before the complete of auto-negotiation */
>> -	if(!sis_priv->autong_complete){
>> -		netif_stop_queue(net_dev);
>> -		return NETDEV_TX_BUSY;
>> +	if (unlikely(!sis_priv->autong_complete)) {
>> +		if (netif_msg_tx_err(sis_priv) && net_ratelimit())
>> +			printk(KERN_DEBUG "%s: Auto negotiation in progress\n",
>> +					net_dev->name);
>> +		net_dev->stats.tx_dropped++;
>> +		dev_kfree_skb(skb);
>> +		return NETDEV_TX_OK;
>>  	}
>>
>>  	spin_lock_irqsave(&sis_priv->lock, flags);
>
> --
> Ben Hutchings, Staff Engineer, Solarflare
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Regards,
Denis

^ permalink raw reply

* Re: [PATCH ethtool] ethtool: Add string/define to display Port Type for Backplane Ethernet
From: Ben Hutchings @ 2013-08-02 12:40 UTC (permalink / raw)
  To: Somnath Kotur; +Cc: netdev
In-Reply-To: <4f5874f0-845c-429e-8c14-fc948ed7a2e8@CMEXHTCAS1.ad.emulex.com>

On Fri, 2013-08-02 at 10:36 +0530, Somnath Kotur wrote:
> Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
> ---
>  ethtool-copy.h |    1 +
>  ethtool.c      |    3 +++
>  2 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/ethtool-copy.h b/ethtool-copy.h
> index b5515c2..33ff7d3 100644
> --- a/ethtool-copy.h
> +++ b/ethtool-copy.h
> @@ -989,6 +989,7 @@ enum ethtool_sfeatures_retval_bits {
>  #define PORT_FIBRE		0x03
>  #define PORT_BNC		0x04
>  #define PORT_DA			0x05
> +#define PORT_BACKPLANE		0x06
>  #define PORT_NONE		0xef
>  #define PORT_OTHER		0xff
>  

Needs to be updated in the kernel first.

> diff --git a/ethtool.c b/ethtool.c
> index b24b572..4db42b3 100644
> --- a/ethtool.c
> +++ b/ethtool.c
> @@ -625,6 +625,9 @@ static int dump_ecmd(struct ethtool_cmd *ep)
>  	case PORT_DA:
>  		fprintf(stdout, "Direct Attach Copper\n");
>  		break;
> +	case PORT_BACKPLANE:
> +		fprintf(stdout, "BackPlane\n");
> +		break;

Why the capital P?  I don't think I've seen it written that way before.

Ben.

>  	case PORT_NONE:
>  		fprintf(stdout, "None\n");
>  		break;

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: changing dev->needed_headroom/needed_tailroom?
From: Eric Dumazet @ 2013-08-02 13:11 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Johannes Berg, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1375433758.24371.20.camel-nDn/Rdv9kqW9Jme8/bJn5UCKIB8iOfG2tUK59QYPAWc@public.gmane.org>

On Fri, 2013-08-02 at 10:55 +0200, Ben Hutchings wrote:

> I don't think this is safe when the interface is running (even if
> carrier is off).  Some functions may read dev->needed_headroom twice and
> rely on getting the same value each time.

It should be no problem. Remaining unsafe places should be fixed.

We already had this discussion in the past, and some patches were
issued. Check commit ae641949df01b85117845bec45328eab6d6fada1
("net: Remove all uses of LL_ALLOCATED_SPACE")




--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net-next] htb: fix sign extension bug
From: Eric Dumazet @ 2013-08-02 13:36 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Cong Wang, netdev
In-Reply-To: <20130801223207.2a9c69e9@nehalam.linuxnetplumber.net>

On Thu, 2013-08-01 at 22:32 -0700, Stephen Hemminger wrote:
> When userspace passes a large priority value 
> the assignment of the unsigned value hopt->prio
> to  signed int cl->prio causes cl->prio to become negative and the
> comparison is with TC_HTB_NUMPRIO is always false.
> 
> The result is that HTB crashes by referencing outside
> the array when processing packets. With this patch the large value
> wraps around like other values outside the normal range.
> 
> See: https://bugzilla.kernel.org/show_bug.cgi?id=60669
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> 
> --- a/net/sched/sch_htb.c	2013-06-20 09:22:46.489542435 -0700
> +++ b/net/sched/sch_htb.c	2013-08-01 22:12:43.736307055 -0700
> @@ -100,7 +100,7 @@ struct htb_class {
>  	struct psched_ratecfg	ceil;
>  	s64			buffer, cbuffer;/* token bucket depth/rate */
>  	s64			mbuffer;	/* max wait time */
> -	int			prio;		/* these two are used only by leaves... */
> +	u32			prio;		/* these two are used only by leaves... */
>  	int			quantum;	/* but stored for parent-to-leaf return */
>  
>  	struct tcf_proto	*filter_list;	/* class attached filters */
> --

Thanks Stephen.

Acked-by: Eric Dumazet <edumazet@google.com>

It seems appropriate for net tree (and stable)

We probably should report an error from htb_change_class() ?

^ permalink raw reply

* Re: [Patch net-next v2 5/8] sunrpc: use generic union inet_addr
From: Jeff Layton @ 2013-08-02 13:36 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev, David S. Miller, Trond Myklebust, J. Bruce Fields,
	linux-nfs
In-Reply-To: <1375427674-21735-6-git-send-email-amwang@redhat.com>

On Fri,  2 Aug 2013 15:14:31 +0800
Cong Wang <amwang@redhat.com> wrote:

> From: Cong Wang <amwang@redhat.com>
> 
> sunrpc defines some helper functions for sockaddr, actually they
> can re-use the generic functions for union inet_addr too.

Only some of these patches in this series have made it to lists to
which I'm subscribed, so I may be missing some context here...

I'm not sure I really understand the value of "union inet_addr". Why
not just use the conventional method of passing around "struct sockaddr"
pointers, and then casting them to struct sockaddr_in/sockaddr_in6
depending on what the sa_family is set to?

With that you wouldn't need to leave the (now pointless) rpc_* wrappers
in place and could just call your new helpers directly.

> 
> Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
> Cc: "J. Bruce Fields" <bfields@fieldses.org>
> Cc: linux-nfs@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>
> ---
>  include/linux/sunrpc/addr.h |  118 +++----------------------------------------
>  include/net/inet_addr.h     |   74 +++++++++++++++++++++------
>  net/core/utils.c            |   25 +++++++++
>  3 files changed, 89 insertions(+), 128 deletions(-)
> 
> diff --git a/include/linux/sunrpc/addr.h b/include/linux/sunrpc/addr.h
> index 07d8e53..10d07f6 100644
> --- a/include/linux/sunrpc/addr.h
> +++ b/include/linux/sunrpc/addr.h
> @@ -11,6 +11,7 @@
>  #include <linux/in.h>
>  #include <linux/in6.h>
>  #include <net/ipv6.h>
> +#include <net/inet_addr.h>
>  
>  size_t		rpc_ntop(const struct sockaddr *, char *, const size_t);
>  size_t		rpc_pton(struct net *, const char *, const size_t,
> @@ -21,135 +22,30 @@ size_t		rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
>  
>  static inline unsigned short rpc_get_port(const struct sockaddr *sap)
>  {
> -	switch (sap->sa_family) {
> -	case AF_INET:
> -		return ntohs(((struct sockaddr_in *)sap)->sin_port);
> -	case AF_INET6:
> -		return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
> -	}
> -	return 0;
> +	return inet_addr_get_port((const union inet_addr *)sap);
>  }
>  
>  static inline void rpc_set_port(struct sockaddr *sap,
>  				const unsigned short port)
>  {
> -	switch (sap->sa_family) {
> -	case AF_INET:
> -		((struct sockaddr_in *)sap)->sin_port = htons(port);
> -		break;
> -	case AF_INET6:
> -		((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
> -		break;
> -	}
> +	inet_addr_set_port((union inet_addr *)sap, port);
>  }
>  
>  #define IPV6_SCOPE_DELIMITER		'%'
>  #define IPV6_SCOPE_ID_LEN		sizeof("%nnnnnnnnnn")
>  
> -static inline bool __rpc_cmp_addr4(const struct sockaddr *sap1,
> -				   const struct sockaddr *sap2)
> -{
> -	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
> -	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
> -
> -	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
> -}
> -
> -static inline bool __rpc_copy_addr4(struct sockaddr *dst,
> -				    const struct sockaddr *src)
> -{
> -	const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
> -	struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
> -
> -	dsin->sin_family = ssin->sin_family;
> -	dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
> -	return true;
> -}
> -
> -#if IS_ENABLED(CONFIG_IPV6)
> -static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
> -				   const struct sockaddr *sap2)
> -{
> -	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
> -	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
> -
> -	if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
> -		return false;
> -	else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
> -		return sin1->sin6_scope_id == sin2->sin6_scope_id;
> -
> -	return true;
> -}
> -
> -static inline bool __rpc_copy_addr6(struct sockaddr *dst,
> -				    const struct sockaddr *src)
> -{
> -	const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
> -	struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;
> -
> -	dsin6->sin6_family = ssin6->sin6_family;
> -	dsin6->sin6_addr = ssin6->sin6_addr;
> -	dsin6->sin6_scope_id = ssin6->sin6_scope_id;
> -	return true;
> -}
> -#else	/* !(IS_ENABLED(CONFIG_IPV6) */
> -static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
> -				   const struct sockaddr *sap2)
> -{
> -	return false;
> -}
> -
> -static inline bool __rpc_copy_addr6(struct sockaddr *dst,
> -				    const struct sockaddr *src)
> -{
> -	return false;
> -}
> -#endif	/* !(IS_ENABLED(CONFIG_IPV6) */
> -
> -/**
> - * rpc_cmp_addr - compare the address portion of two sockaddrs.
> - * @sap1: first sockaddr
> - * @sap2: second sockaddr
> - *
> - * Just compares the family and address portion. Ignores port, but
> - * compares the scope if it's a link-local address.
> - *
> - * Returns true if the addrs are equal, false if they aren't.
> - */
>  static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
>  				const struct sockaddr *sap2)
>  {
> -	if (sap1->sa_family == sap2->sa_family) {
> -		switch (sap1->sa_family) {
> -		case AF_INET:
> -			return __rpc_cmp_addr4(sap1, sap2);
> -		case AF_INET6:
> -			return __rpc_cmp_addr6(sap1, sap2);
> -		}
> -	}
> -	return false;
> +	return inet_addr_equal((const union inet_addr *)sap1,
> +			       (const union inet_addr *)sap2);
>  }
>  
> -/**
> - * rpc_copy_addr - copy the address portion of one sockaddr to another
> - * @dst: destination sockaddr
> - * @src: source sockaddr
> - *
> - * Just copies the address portion and family. Ignores port, scope, etc.
> - * Caller is responsible for making certain that dst is large enough to hold
> - * the address in src. Returns true if address family is supported. Returns
> - * false otherwise.
> - */
>  static inline bool rpc_copy_addr(struct sockaddr *dst,
>  				 const struct sockaddr *src)
>  {
> -	switch (src->sa_family) {
> -	case AF_INET:
> -		return __rpc_copy_addr4(dst, src);
> -	case AF_INET6:
> -		return __rpc_copy_addr6(dst, src);
> -	}
> -	return false;
> +	return inet_addr_copy((union inet_addr *)dst,
> +			      (const union inet_addr *)src);
>  }
>  
>  /**
> diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
> index ee80df4..e846050 100644
> --- a/include/net/inet_addr.h
> +++ b/include/net/inet_addr.h
> @@ -36,17 +36,6 @@ bool in_addr_gen_equal(const struct in_addr_gen *a, const struct in_addr_gen *b)
>  }
>  
>  #if IS_ENABLED(CONFIG_IPV6)
> -static inline
> -bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
> -{
> -	if (a->sa.sa_family != b->sa.sa_family)
> -		return false;
> -	if (a->sa.sa_family == AF_INET6)
> -		return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
> -	else
> -		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
> -}
> -
>  static inline bool inet_addr_any(const union inet_addr *ipa)
>  {
>  	if (ipa->sa.sa_family == AF_INET6)
> @@ -65,12 +54,6 @@ static inline bool inet_addr_multicast(const union inet_addr *ipa)
>  
>  #else /* !CONFIG_IPV6 */
>  
> -static inline
> -bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
> -{
> -	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
> -}
> -
>  static inline bool inet_addr_any(const union inet_addr *ipa)
>  {
>  	return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
> @@ -82,6 +65,63 @@ static inline bool inet_addr_multicast(const union inet_addr *ipa)
>  }
>  #endif
>  
> +/**
> + * inet_addr_copy - copy the address portion of one inet_addr to another
> + * @dst: destination sockaddr
> + * @src: source sockaddr
> + *
> + * Just copies the address portion and family. Ignores port, scope, etc.
> + * Caller is responsible for making certain that dst is large enough to hold
> + * the address in src. Returns true if address family is supported. Returns
> + * false otherwise.
> + */
> +static inline bool inet_addr_copy(union inet_addr *dst,
> +				  const union inet_addr *src)
> +{
> +	dst->sa.sa_family = src->sa.sa_family;
> +
> +	switch (src->sa.sa_family) {
> +	case AF_INET:
> +		dst->sin.sin_addr.s_addr = src->sin.sin_addr.s_addr;
> +		return true;
> +#if IS_ENABLED(CONFIG_IPV6)
> +	case AF_INET6:
> +		dst->sin6.sin6_addr = src->sin6.sin6_addr;
> +		dst->sin6.sin6_scope_id = src->sin6.sin6_scope_id;
> +		return true;
> +#endif
> +	}
> +
> +	return false;
> +}
> +
> +static inline
> +unsigned short inet_addr_get_port(const union inet_addr *sap)
> +{
> +	switch (sap->sa.sa_family) {
> +	case AF_INET:
> +		return ntohs(sap->sin.sin_port);
> +	case AF_INET6:
> +		return ntohs(sap->sin6.sin6_port);
> +	}
> +	return 0;
> +}
> +
> +static inline
> +void inet_addr_set_port(union inet_addr *sap,
> +			const unsigned short port)
> +{
> +	switch (sap->sa.sa_family) {
> +	case AF_INET:
> +		sap->sin.sin_port = htons(port);
> +		break;
> +	case AF_INET6:
> +		sap->sin6.sin6_port = htons(port);
> +		break;
> +	}
> +}
> +
> +bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b);
>  int simple_inet_pton(const char *str, union inet_addr *addr);
>  
>  #endif
> diff --git a/net/core/utils.c b/net/core/utils.c
> index 22dd621..837bb18 100644
> --- a/net/core/utils.c
> +++ b/net/core/utils.c
> @@ -374,3 +374,28 @@ int simple_inet_pton(const char *str, union inet_addr *addr)
>  	return -EINVAL;
>  }
>  EXPORT_SYMBOL(simple_inet_pton);
> +
> +#if IS_ENABLED(CONFIG_IPV6)
> +bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
> +{
> +	if (a->sa.sa_family != b->sa.sa_family)
> +		return false;
> +	else if (a->sa.sa_family == AF_INET6) {
> +		if (!ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr))
> +			return false;
> +		else if (__ipv6_addr_needs_scope_id(__ipv6_addr_type(&a->sin6.sin6_addr)))
> +			return a->sin6.sin6_scope_id == b->sin6.sin6_scope_id;
> +		else
> +			return true;
> +	} else
> +		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
> +}
> +#else
> +bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
> +{
> +	if (a->sa.sa_family == AF_UNSPEC)
> +		return a->sa.sa_family == b->sa.sa_family;
> +	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
> +}
> +#endif
> +EXPORT_SYMBOL(inet_addr_equal);


-- 
Jeff Layton <jlayton@redhat.com>

^ permalink raw reply

* [PATCH v3] sis900: Fix the tx queue timeout issue
From: Denis Kirjanov @ 2013-08-02  9:50 UTC (permalink / raw)
  To: davem, venza; +Cc: bhutchings, B38611, netdev, Denis Kirjanov

[  198.720048] ------------[ cut here ]------------
[  198.720108] WARNING: CPU: 0 PID: 0 at net/sched/sch_generic.c:255 dev_watchdog+0x229/0x240()
[  198.720118] NETDEV WATCHDOG: eth0 (sis900): transmit queue 0 timed out
[  198.720125] Modules linked in: bridge stp llc dmfe sundance 3c59x sis900 mii
[  198.720159] CPU: 0 PID: 0 Comm: swapper Not tainted 3.11.0-rc3+ #12
[  198.720167] Hardware name: System Manufacturer System Name/TUSI-M, BIOS ASUS TUSI-M ACPI BIOS
Revision 1013 Beta 001 12/14/2001
[  198.720175]  000000ff c13fa6b9 c169ddcc c12208d6 c169ddf8 c1031e4d c1664a84 c169de24
[  198.720197]  00000000 c165f5ea 000000ff c13fa6b9 00000001 000000ff c1664a84 c169de10
[  198.720217]  c1031f13 00000009 c169de08 c1664a84 c169de24 c169de50 c13fa6b9 c165f5ea
[  198.720240] Call Trace:
[  198.720257]  [<c13fa6b9>] ? dev_watchdog+0x229/0x240
[  198.720274]  [<c12208d6>] dump_stack+0x16/0x20
[  198.720306]  [<c1031e4d>] warn_slowpath_common+0x7d/0xa0
[  198.720318]  [<c13fa6b9>] ? dev_watchdog+0x229/0x240
[  198.720330]  [<c1031f13>] warn_slowpath_fmt+0x33/0x40
[  198.720342]  [<c13fa6b9>] dev_watchdog+0x229/0x240
[  198.720357]  [<c103f158>] call_timer_fn+0x78/0x150
[  198.720369]  [<c103f0e0>] ? internal_add_timer+0x40/0x40
[  198.720381]  [<c13fa490>] ? dev_init_scheduler+0xa0/0xa0
[  198.720392]  [<c103f33f>] run_timer_softirq+0x10f/0x200
[  198.720412]  [<c103954f>] ? __do_softirq+0x6f/0x210
[  198.720424]  [<c13fa490>] ? dev_init_scheduler+0xa0/0xa0
[  198.720435]  [<c1039598>] __do_softirq+0xb8/0x210
[  198.720467]  [<c14b54d2>] ? _raw_spin_unlock+0x22/0x30
[  198.720484]  [<c1003245>] ? handle_irq+0x25/0xd0
[  198.720496]  [<c1039c0c>] irq_exit+0x9c/0xb0
[  198.720508]  [<c14bc9d7>] do_IRQ+0x47/0x94
[  198.720534]  [<c1056078>] ? hrtimer_start+0x28/0x30
[  198.720564]  [<c14bc8b1>] common_interrupt+0x31/0x38
[  198.720589]  [<c1008692>] ? default_idle+0x22/0xa0
[  198.720600]  [<c10083c7>] arch_cpu_idle+0x17/0x30
[  198.720631]  [<c106d23d>] cpu_startup_entry+0xcd/0x180
[  198.720643]  [<c14ae30a>] rest_init+0xaa/0xb0
[  198.720654]  [<c14ae260>] ? reciprocal_value+0x50/0x50
[  198.720668]  [<c17044e0>] ? repair_env_string+0x60/0x60
[  198.720679]  [<c1704bda>] start_kernel+0x29a/0x350
[  198.720690]  [<c17044e0>] ? repair_env_string+0x60/0x60
[  198.720721]  [<c1704269>] i386_start_kernel+0x39/0xa0
[  198.720729] ---[ end trace 81e0a6266f5c73a8 ]---
[  198.720740] eth0: Transmit timeout, status 00000204 00000000

timer routine checks the link status and if it's up calls
netif_carrier_on() allowing upper layer to start the tx queue
even if the auto-negotiation process is not finished.

Also remove ugly auto-negotiation check from the sis900_start_xmit()

CC: Duan Fugang <B38611@freescale.com>
CC: Ben Hutchings <bhutchings@solarflare.com>

Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
---
v1->v2: use netdev_dbg() instead of printk()
v2->v3:
 handle link change from timer,
 remove auto-negotiation check from xmit path
---
 drivers/net/ethernet/sis/sis900.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index eb4aea3..f5d7ad7 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -1318,7 +1318,7 @@ static void sis900_timer(unsigned long data)
 		if (duplex){
 			sis900_set_mode(sis_priv, speed, duplex);
 			sis630_set_eq(net_dev, sis_priv->chipset_rev);
-			netif_start_queue(net_dev);
+			netif_carrier_on(net_dev);
 		}
 
 		sis_priv->timer.expires = jiffies + HZ;
@@ -1336,10 +1336,8 @@ static void sis900_timer(unsigned long data)
 		status = sis900_default_phy(net_dev);
 		mii_phy = sis_priv->mii;
 
-		if (status & MII_STAT_LINK){
+		if (status & MII_STAT_LINK)
 			sis900_check_mode(net_dev, mii_phy);
-			netif_carrier_on(net_dev);
-		}
 	} else {
 	/* Link ON -> OFF */
                 if (!(status & MII_STAT_LINK)){
@@ -1612,12 +1610,6 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 	unsigned int  index_cur_tx, index_dirty_tx;
 	unsigned int  count_dirty_tx;
 
-	/* Don't transmit data before the complete of auto-negotiation */
-	if(!sis_priv->autong_complete){
-		netif_stop_queue(net_dev);
-		return NETDEV_TX_BUSY;
-	}
-
 	spin_lock_irqsave(&sis_priv->lock, flags);
 
 	/* Calculate the next Tx descriptor entry. */
-- 
1.8.0.2

^ permalink raw reply related

* [PATCH net-next 0/2] icmpv6_filter: correct minimum ICMPv6 message size
From: Werner Almesberger @ 2013-08-02 13:50 UTC (permalink / raw)
  To: netdev

These two patches correct the minimum ICMPv6 message size enforced
by net/ipv6/raw.c:icmpv6_filter

The first patch corrects a type error. Because of the error, ICMPv6
raw sockets on 32 bit systems accepted ICMPv6 messages as small as
4 bytes, while 64 bit systems required at least 8 bytes.

The second patch reduces the amount of data we require from eight
(i.e., the ICMPv6 header plus four bytes of message body) to four
bytes. This is needed for protocols like RPL (RFC 6550) that use
ICMPv6 messages with bodies smaller than four bytes.

Note that applications that assume that the kernel will not pass
such short ICMPv6 messages on raw sockets may misbehave on 64 bit
systems after applying these patches. However, even if such
applications exist, they would already have that vulnerability on
32 bit systems.

- Werner

Werner Almesberger (2):
  icmpv6_filter: fix "_hdr" incorrectly being a pointer
  icmpv6_filter: allow ICMPv6 messages with bodies < 4 bytes

 net/ipv6/raw.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

-- 
1.8.1.2

^ permalink raw reply

* [PATCH net-next 1/2] icmpv6_filter: fix "_hdr" incorrectly being a pointer
From: Werner Almesberger @ 2013-08-02 13:51 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1375417279.git.werner@almesberger.net>

"_hdr" should hold the ICMPv6 header while "hdr" is the pointer to it.
This worked by accident.

Signed-off-by: Werner Almesberger <werner@almesberger.net>
---
 net/ipv6/raw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index c45f7a5..164fb5f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -108,7 +108,7 @@ found:
  */
 static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
 {
-	struct icmp6hdr *_hdr;
+	struct icmp6hdr _hdr;
 	const struct icmp6hdr *hdr;
 
 	hdr = skb_header_pointer(skb, skb_transport_offset(skb),
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH net-next 2/2] icmpv6_filter: allow ICMPv6 messages with bodies < 4 bytes
From: Werner Almesberger @ 2013-08-02 13:51 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1375417279.git.werner@almesberger.net>

By using sizeof(_hdr), net/ipv6/raw.c:icmpv6_filter implicitly assumes
that any valid ICMPv6 message is at least eight bytes long, i.e., that
the message body is at least four bytes.

The DIS message of RPL (RFC 6550 section 6.2, from the 6LoWPAN world),
has a minimum length of only six bytes, and is thus blocked by
icmpv6_filter.

RFC 4443 seems to allow even a zero-sized body, making the minimum
allowable message size four bytes.

Signed-off-by: Werner Almesberger <werner@almesberger.net>
---
 net/ipv6/raw.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 164fb5f..c1e5334 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -63,6 +63,8 @@
 #include <linux/seq_file.h>
 #include <linux/export.h>
 
+#define	ICMPV6_HDRLEN	4	/* ICMPv6 header, RFC 4443 Section 2.1 */
+
 static struct raw_hashinfo raw_v6_hashinfo = {
 	.lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
 };
@@ -111,8 +113,11 @@ static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
 	struct icmp6hdr _hdr;
 	const struct icmp6hdr *hdr;
 
+	/* We require only the four bytes of the ICMPv6 header, not any
+	 * additional bytes of message body in "struct icmp6hdr".
+	 */
 	hdr = skb_header_pointer(skb, skb_transport_offset(skb),
-				 sizeof(_hdr), &_hdr);
+				 ICMPV6_HDRLEN, &_hdr);
 	if (hdr) {
 		const __u32 *data = &raw6_sk(sk)->filter.data[0];
 		unsigned int type = hdr->icmp6_type;
-- 
1.8.1.2

^ permalink raw reply related

* Re: [Patch net-next v2 8/8] selinux: use generic union inet_addr
From: Paul Moore @ 2013-08-02 14:34 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev, David S. Miller, James Morris, Stephen Smalley,
	Eric Paris, linux-kernel, linux-security-module
In-Reply-To: <1375427674-21735-9-git-send-email-amwang@redhat.com>

On Friday, August 02, 2013 03:14:34 PM Cong Wang wrote:
> From: Cong Wang <amwang@redhat.com>
> 
> selinux has some similar definition like union inet_addr,
> it can re-use the generic union inet_addr too.
> 
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Stephen Smalley <sds@tycho.nsa.gov>
> Cc: Eric Paris <eparis@parisplace.org>
> Cc: Paul Moore <pmoore@redhat.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-security-module@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>

Perhaps I'm confusing this with another patch but I though DaveM said he 
wasn't going to merge these patches?

-- 
paul moore
security and virtualization @ redhat


^ permalink raw reply

* [PATCH] net: check net.core.somaxconn sysctl values
From: Roman Gushchin @ 2013-08-02 14:36 UTC (permalink / raw)
  To: davem
  Cc: eric.dumazet, raise.sail, ebiederm, netdev, linux-kernel,
	Roman Gushchin
In-Reply-To: <20130801.141836.1104130035137318887.davem@davemloft.net>

It's possible to assign an invalid value to the net.core.somaxconn
sysctl variable, because there is no checks at all.

The sk_max_ack_backlog field of the sock structure is defined as
unsigned short. Therefore, the backlog argument in inet_listen()
shouldn't exceed USHRT_MAX. The backlog argument in the listen() syscall
is truncated to the somaxconn value. So, the somaxconn value shouldn't
exceed 65535 (USHRT_MAX).
Also, negative values of somaxconn are meaningless.

before:
$ sysctl -w net.core.somaxconn=256
net.core.somaxconn = 256
$ sysctl -w net.core.somaxconn=65536
net.core.somaxconn = 65536
$ sysctl -w net.core.somaxconn=-100
net.core.somaxconn = -100

after:
$ sysctl -w net.core.somaxconn=256
net.core.somaxconn = 256
$ sysctl -w net.core.somaxconn=65536
error: "Invalid argument" setting key "net.core.somaxconn"
$ sysctl -w net.core.somaxconn=-100
error: "Invalid argument" setting key "net.core.somaxconn"

Based on a prior patch from Changli Gao.

Signed-off-by: Roman Gushchin <klamm@yandex-team.ru>
Reported-by: Changli Gao <xiaosuo@gmail.com>
Suggested-by: Eric Dumazet <edumazet@google.com>
Acked-by: Eric Dumazet <edumazet@google.com>
---
 net/core/sysctl_net_core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 6609686..7c37dcd 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -21,7 +21,9 @@
 #include <net/net_ratelimit.h>
 #include <net/busy_poll.h>
 
+static int zero = 0;
 static int one = 1;
+static int ushort_max = USHRT_MAX;
 
 #ifdef CONFIG_RPS
 static int rps_sock_flow_sysctl(struct ctl_table *table, int write,
@@ -339,7 +341,9 @@ static struct ctl_table netns_core_table[] = {
 		.data		= &init_net.core.sysctl_somaxconn,
 		.maxlen		= sizeof(int),
 		.mode		= 0644,
-		.proc_handler	= proc_dointvec
+		.extra1		= &zero,
+		.extra2		= &ushort_max,
+		.proc_handler	= proc_dointvec_minmax
 	},
 	{ }
 };
-- 
1.8.1.2

^ permalink raw reply related

* Re: [PATCH net-next] sctp: Don't lookup dst if transport dst is still valid
From: Vlad Yasevich @ 2013-08-02 14:57 UTC (permalink / raw)
  To: Fan Du; +Cc: nhorman, davem, netdev
In-Reply-To: <1375411513-12551-1-git-send-email-fan.du@windriver.com>

On 08/01/2013 10:45 PM, Fan Du wrote:
> When sctp sits on IPv6, sctp_transport_dst_check pass cookie as ZERO,
> as a result ip6_dst_check always fail out. This behaviour makes
> transport->dst useless, because every sctp_packet_transmit must look
> for valid dst.
>
> Add a dst_cookie into sctp_transport, and set the cookie whenever we
> get new dst for sctp_transport. So dst validness could be checked
> against it.
>
> Since I have split genid for IPv4 and IPv6, also delete/add IPv6 address
> will also bump IPv6 genid. So issues we discussed in:
> http://marc.info/?l=linux-netdev&m=137404469219410&w=4
> have all been sloved for this patch.
>
> Signed-off-by: Fan Du <fan.du@windriver.com>

Acked-by: Vlad Yasevich <vyasevich@gmail.com>

-vlad

> ---
>   include/net/sctp/sctp.h    |    2 +-
>   include/net/sctp/structs.h |    1 +
>   net/sctp/ipv6.c            |    2 +-
>   3 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> index 554cf88..cb28df9 100644
> --- a/include/net/sctp/sctp.h
> +++ b/include/net/sctp/sctp.h
> @@ -613,7 +613,7 @@ static inline void sctp_v4_map_v6(union sctp_addr *addr)
>    */
>   static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
>   {
> -	if (t->dst && !dst_check(t->dst, 0)) {
> +	if (t->dst && !dst_check(t->dst, t->dst_cookie)) {
>   		dst_release(t->dst);
>   		t->dst = NULL;
>   	}
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 75c4c16..c0f4e29 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -946,6 +946,7 @@ struct sctp_transport {
>   	__u64 hb_nonce;
>
>   	struct rcu_head rcu;
> +	u32 dst_cookie;
>   };
>
>   struct sctp_transport *sctp_transport_new(struct net *, const union sctp_addr *,
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index 85d688f..5a9402e 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -351,7 +351,7 @@ out:
>
>   		rt = (struct rt6_info *)dst;
>   		t->dst = dst;
> -
> +		t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
>   		pr_debug("rt6_dst:%pI6 rt6_src:%pI6\n", &rt->rt6i_dst.addr,
>   			 &fl6->saddr);
>   	} else {
>

^ permalink raw reply

* [PATCH v2] fib_rules: add route suppression based on ifgroup
From: Stefan Tomanek @ 2013-08-02 15:19 UTC (permalink / raw)
  To: netdev

This change adds the ability to suppress a routing decision based upon the
interface group the selected interface belongs to. This allows it to
exclude specific devices from a routing decision.

Signed-off-by: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
---
 include/net/fib_rules.h        |    2 ++
 include/uapi/linux/fib_rules.h |    2 +-
 net/core/fib_rules.c           |   10 ++++++++++
 net/ipv4/fib_rules.c           |   23 +++++++++++++++++------
 net/ipv6/fib6_rules.c          |   16 +++++++++++++---
 5 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 2f286dc..d13c461 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -18,6 +18,7 @@ struct fib_rule {
 	u32			pref;
 	u32			flags;
 	u32			table;
+	int			suppress_ifgroup;
 	u8			table_prefixlen_min;
 	u8			action;
 	u32			target;
@@ -84,6 +85,7 @@ struct fib_rules_ops {
 	[FRA_FWMASK]	= { .type = NLA_U32 }, \
 	[FRA_TABLE]     = { .type = NLA_U32 }, \
 	[FRA_TABLE_PREFIXLEN_MIN] = { .type = NLA_U8 }, \
+	[FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
 	[FRA_GOTO]	= { .type = NLA_U32 }
 
 static inline void fib_rule_get(struct fib_rule *rule)
diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 59cd31b..63e3116 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -44,7 +44,7 @@ enum {
 	FRA_FWMARK,	/* mark */
 	FRA_FLOW,	/* flow/class id */
 	FRA_UNUSED6,
-	FRA_UNUSED7,
+	FRA_SUPPRESS_IFGROUP,
 	FRA_TABLE_PREFIXLEN_MIN,
 	FRA_TABLE,	/* Extended table id */
 	FRA_FWMASK,	/* mask for netfilter mark */
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 2ef5040..5040a61 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -343,6 +343,9 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh)
 	if (tb[FRA_TABLE_PREFIXLEN_MIN])
 		rule->table_prefixlen_min = nla_get_u8(tb[FRA_TABLE_PREFIXLEN_MIN]);
 
+	if (tb[FRA_SUPPRESS_IFGROUP])
+		rule->suppress_ifgroup = nla_get_u32(tb[FRA_SUPPRESS_IFGROUP]);
+
 	if (!tb[FRA_PRIORITY] && ops->default_pref)
 		rule->pref = ops->default_pref(ops);
 
@@ -529,6 +532,7 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
 			 + nla_total_size(4) /* FRA_PRIORITY */
 			 + nla_total_size(4) /* FRA_TABLE */
 			 + nla_total_size(1) /* FRA_TABLE_PREFIXLEN_MIN */
+			 + nla_total_size(4) /* FRA_SUPPRESS_IFGROUP */
 			 + nla_total_size(4) /* FRA_FWMARK */
 			 + nla_total_size(4); /* FRA_FWMASK */
 
@@ -588,6 +592,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
 	    (rule->target &&
 	     nla_put_u32(skb, FRA_GOTO, rule->target)))
 		goto nla_put_failure;
+
+	if (rule->suppress_ifgroup != -1) {
+		if (nla_put_u32(skb, FRA_SUPPRESS_IFGROUP, rule->suppress_ifgroup))
+			goto nla_put_failure;
+	}
+
 	if (ops->fill(rule, skb, frh) < 0)
 		goto nla_put_failure;
 
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 9f29066..b78fd28 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -103,16 +103,27 @@ errout:
 
 static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
 {
+	struct fib_result *result = (struct fib_result *) arg->result;
+	struct net_device *dev = result->fi->fib_dev;
+
 	/* do not accept result if the route does
 	 * not meet the required prefix length
 	 */
-	struct fib_result *result = (struct fib_result *) arg->result;
-	if (result->prefixlen < rule->table_prefixlen_min) {
-		if (!(arg->flags & FIB_LOOKUP_NOREF))
-			fib_info_put(result->fi);
-		return true;
-	}
+	if (result->prefixlen < rule->table_prefixlen_min)
+		goto suppress_route;
+
+	/* do not accept result if the route uses a device
+	 * belonging to a forbidden interface group
+	 */
+	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
+		goto suppress_route;
+
 	return false;
+
+suppress_route:
+	if (!(arg->flags & FIB_LOOKUP_NOREF))
+		fib_info_put(result->fi);
+	return true;
 }
 
 static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 554a4fb..3628326 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -122,14 +122,24 @@ out:
 static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
 {
 	struct rt6_info *rt = (struct rt6_info *) arg->result;
+	struct net_device *dev = rt->rt6i_idev->dev;
 	/* do not accept result if the route does
 	 * not meet the required prefix length
 	 */
-	if (rt->rt6i_dst.plen < rule->table_prefixlen_min) {
+	if (rt->rt6i_dst.plen < rule->table_prefixlen_min)
+		goto suppress_route;
+
+	/* do not accept result if the route uses a device
+	 * belonging to a forbidden interface group
+	 */
+	if (rule->suppress_ifgroup != -1 && dev && dev->group == rule->suppress_ifgroup)
+		goto suppress_route;
+
+	return false;
+
+suppress_route:
 		ip6_rt_put(rt);
 		return true;
-	}
-	return false;
 }
 
 static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
-- 
1.7.10.4

^ 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