Netdev List
 help / color / mirror / Atom feed
* [patch] arcnet: fix signed bug in probe function
From: Dan Carpenter @ 2010-07-17 17:21 UTC (permalink / raw)
  To: netdev; +Cc: kernel-janitors

probe_irq_off() returns the first irq found or if two irqs are found
then it returns the negative of the first irq found.  We can cast
dev->irq to an int so that the test for negative values works.

Signed-off-by: Dan Carpenter <error27@gmail.com>

diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index 0402da3..3727282 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -90,14 +90,14 @@ static int __init com20020isa_probe(struct net_device *dev)
 		outb(0, _INTMASK);
 		dev->irq = probe_irq_off(airqmask);
 
-		if (dev->irq <= 0) {
+		if ((int)dev->irq <= 0) {
 			BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
 			airqmask = probe_irq_on();
 			outb(NORXflag, _INTMASK);
 			udelay(5);
 			outb(0, _INTMASK);
 			dev->irq = probe_irq_off(airqmask);
-			if (dev->irq <= 0) {
+			if ((int)dev->irq <= 0) {
 				BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
 				err = -ENODEV;
 				goto out;
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 4cb4018..eb27976 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -213,7 +213,7 @@ static int __init com90io_probe(struct net_device *dev)
 		outb(0, _INTMASK);
 		dev->irq = probe_irq_off(airqmask);
 
-		if (dev->irq <= 0) {
+		if ((int)dev->irq <= 0) {
 			BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n");
 			goto err_out;
 		}

^ permalink raw reply related

* [PATCH v3 0/4] Extend Time Stamping
From: Richard Cochran @ 2010-07-17 18:48 UTC (permalink / raw)
  To: netdev

This patch set extends the packet time stamping capabilites of the
network stack in two ways.

1. The first patch presents a work-around for the TX software time
   stamping fallback problem cited in cd4d8fdad1f1. The idea is to add
   one inline function into each MAC driver. This function will act
   as hooks for current (and possible future) time stamping needs,
   once they are placed correctly within each MAC driver.

2. The other patches prepare the way for PHY drivers to offer time
   stamping.

I am preparing a new round of patches for PTP support, but it will
require the changes in this patch set in order to function. Thus I
would like to have this patch set reviewed (and hopefully merged) in
order to go forward.

Thanks,
Richard

* Patch ChangeLog
** v3
   After having received plenty of criticism on the idea of reading
   from the MDIO bus during the critical paths, this version presents
   a new approach. Now, when the CONFIG option for PHY time stamping
   is enabled, likely packets for time stamping are identified by the
   stack and presented to the PHY driver. The driver may accept the
   packet and defer its deliverly until the time stamp becomes
   available at a later time. This approach brings four main
   advantages.

   1. Now only one MAC driver hook is necessary.

   2. It leaves the option of how to get the time stamps open,
      allowing, for example, a driver to get them either via MDIO or
      PHY status frames.

   3. If reading the MDIO bus is required to get the time stamp, this
      can be done during as a work queue task.

   4. It moves the identification of PTP packets into the stack, so
      that each new PHY driver that comes only will not have to
      duplicate this logic again.

** v2
   Removed the CONFIG option for the driver hooks.


Richard Cochran (4):
  net: add driver hook for tx time stamping.
  net: preserve ifreq parameter when calling generic phy_mii_ioctl().
  net: added a BPF to help drivers detect PTP packets.
  net: support time stamping in phy devices.

 drivers/net/arm/ixp4xx_eth.c           |    3 +-
 drivers/net/au1000_eth.c               |    2 +-
 drivers/net/bcm63xx_enet.c             |    2 +-
 drivers/net/cpmac.c                    |    5 +-
 drivers/net/dnet.c                     |    2 +-
 drivers/net/ethoc.c                    |    2 +-
 drivers/net/fec.c                      |    2 +-
 drivers/net/fec_mpc52xx.c              |    2 +-
 drivers/net/fs_enet/fs_enet-main.c     |    3 +-
 drivers/net/gianfar.c                  |    2 +-
 drivers/net/macb.c                     |    2 +-
 drivers/net/mv643xx_eth.c              |    2 +-
 drivers/net/octeon/octeon_mgmt.c       |    2 +-
 drivers/net/phy/phy.c                  |    8 ++-
 drivers/net/phy/phy_device.c           |    2 +
 drivers/net/sb1250-mac.c               |    2 +-
 drivers/net/sh_eth.c                   |    2 +-
 drivers/net/smsc911x.c                 |    2 +-
 drivers/net/smsc9420.c                 |    2 +-
 drivers/net/stmmac/stmmac_main.c       |   22 ++----
 drivers/net/tc35815.c                  |    2 +-
 drivers/net/tg3.c                      |    2 +-
 drivers/net/ucc_geth.c                 |    2 +-
 drivers/staging/octeon/ethernet-mdio.c |    2 +-
 include/linux/netdevice.h              |    4 +
 include/linux/phy.h                    |   24 ++++++-
 include/linux/ptp_classify.h           |  126 ++++++++++++++++++++++++++++++++
 include/linux/skbuff.h                 |   52 +++++++++++++
 net/Kconfig                            |   10 +++
 net/core/Makefile                      |    2 +-
 net/core/dev.c                         |    3 +
 net/core/timestamping.c                |  126 ++++++++++++++++++++++++++++++++
 net/dsa/slave.c                        |    3 +-
 net/socket.c                           |    4 +
 34 files changed, 389 insertions(+), 44 deletions(-)
 create mode 100644 include/linux/ptp_classify.h
 create mode 100644 net/core/timestamping.c


^ permalink raw reply

* [PATCH 1/4] net: add driver hook for tx time stamping.
From: Richard Cochran @ 2010-07-17 18:48 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1279391885.git.richard.cochran@omicron.at>

This patch adds a hook for transmit time stamps. The transmit hook
allows a software fallback for transmit time stamps, for MACs
lacking time stamping hardware. Using the hook will still require
adding an inline function call to each MAC driver.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 include/linux/skbuff.h |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ac74ee0..a1b0400 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1947,6 +1947,27 @@ static inline ktime_t net_invalid_timestamp(void)
 extern void skb_tstamp_tx(struct sk_buff *orig_skb,
 			struct skb_shared_hwtstamps *hwtstamps);
 
+static inline void sw_tx_timestamp(struct sk_buff *skb)
+{
+	union skb_shared_tx *shtx = skb_tx(skb);
+	if (shtx->software && !shtx->in_progress)
+		skb_tstamp_tx(skb, NULL);
+}
+
+/**
+ * skb_tx_timestamp() - Driver hook for transmit timestamping
+ *
+ * Ethernet MAC Drivers should call this function in their hard_xmit()
+ * function as soon as possible after giving the sk_buff to the MAC
+ * hardware, but before freeing the sk_buff.
+ *
+ * @skb: A socket buffer.
+ */
+static inline void skb_tx_timestamp(struct sk_buff *skb)
+{
+	sw_tx_timestamp(skb);
+}
+
 extern __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len);
 extern __sum16 __skb_checksum_complete(struct sk_buff *skb);
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/4] net: preserve ifreq parameter when calling generic phy_mii_ioctl().
From: Richard Cochran @ 2010-07-17 18:48 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1279391885.git.richard.cochran@omicron.at>

The phy_mii_ioctl() function unnecessarily throws away the original ifreq.
We need access to the ifreq in order to support PHYs that can perform
hardware time stamping.

Two maverick drivers filter the ioctl commands passed to phy_mii_ioctl().
This is unnecessary since phylib will check the command in any case.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 drivers/net/arm/ixp4xx_eth.c           |    3 ++-
 drivers/net/au1000_eth.c               |    2 +-
 drivers/net/bcm63xx_enet.c             |    2 +-
 drivers/net/cpmac.c                    |    5 +----
 drivers/net/dnet.c                     |    2 +-
 drivers/net/ethoc.c                    |    2 +-
 drivers/net/fec.c                      |    2 +-
 drivers/net/fec_mpc52xx.c              |    2 +-
 drivers/net/fs_enet/fs_enet-main.c     |    3 +--
 drivers/net/gianfar.c                  |    2 +-
 drivers/net/macb.c                     |    2 +-
 drivers/net/mv643xx_eth.c              |    2 +-
 drivers/net/octeon/octeon_mgmt.c       |    2 +-
 drivers/net/phy/phy.c                  |    3 ++-
 drivers/net/sb1250-mac.c               |    2 +-
 drivers/net/sh_eth.c                   |    2 +-
 drivers/net/smsc911x.c                 |    2 +-
 drivers/net/smsc9420.c                 |    2 +-
 drivers/net/stmmac/stmmac_main.c       |   22 ++++++++--------------
 drivers/net/tc35815.c                  |    2 +-
 drivers/net/tg3.c                      |    2 +-
 drivers/net/ucc_geth.c                 |    2 +-
 drivers/staging/octeon/ethernet-mdio.c |    2 +-
 include/linux/phy.h                    |    2 +-
 net/dsa/slave.c                        |    3 +--
 25 files changed, 34 insertions(+), 43 deletions(-)

diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index ee2f842..4f1cc71 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -782,7 +782,8 @@ static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
 	if (!netif_running(dev))
 		return -EINVAL;
-	return phy_mii_ioctl(port->phydev, if_mii(req), cmd);
+
+	return phy_mii_ioctl(port->phydev, req, cmd);
 }
 
 /* ethtool support */
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index ece6128..386d4fe 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -978,7 +978,7 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!aup->phy_dev)
 		return -EINVAL; /* PHY not controllable */
 
-	return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
+	return phy_mii_ioctl(aup->phy_dev, rq, cmd);
 }
 
 static const struct net_device_ops au1000_netdev_ops = {
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index faf5add..0d2c5da 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -1496,7 +1496,7 @@ static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (priv->has_phy) {
 		if (!priv->phydev)
 			return -ENODEV;
-		return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+		return phy_mii_ioctl(priv->phydev, rq, cmd);
 	} else {
 		struct mii_if_info mii;
 
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 1756d28..cdb05bb 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -846,11 +846,8 @@ static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		return -EINVAL;
 	if (!priv->phy)
 		return -EINVAL;
-	if ((cmd == SIOCGMIIPHY) || (cmd == SIOCGMIIREG) ||
-	    (cmd == SIOCSMIIREG))
-		return phy_mii_ioctl(priv->phy, if_mii(ifr), cmd);
 
-	return -EOPNOTSUPP;
+	return phy_mii_ioctl(priv->phy, ifr, cmd);
 }
 
 static int cpmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 8b0f50b..4ea7141 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -797,7 +797,7 @@ static int dnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
 static void dnet_get_drvinfo(struct net_device *dev,
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 37ce8ac..d9f3106 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -732,7 +732,7 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		phy = priv->phy;
 	}
 
-	return phy_mii_ioctl(phy, mdio, cmd);
+	return phy_mii_ioctl(phy, ifr, cmd);
 }
 
 static int ethoc_config(struct net_device *dev, struct ifmap *map)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index b4afd7a..1670866 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -828,7 +828,7 @@ static int fec_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
 static void fec_enet_free_buffers(struct net_device *dev)
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 25e6cc6..fdbf148 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -826,7 +826,7 @@ static int mpc52xx_fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!priv->phydev)
 		return -ENOTSUPP;
 
-	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(priv->phydev, rq, cmd);
 }
 
 static const struct net_device_ops mpc52xx_fec_netdev_ops = {
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 309a0ea..f08cff9 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -963,12 +963,11 @@ static const struct ethtool_ops fs_ethtool_ops = {
 static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&rq->ifr_data;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	return phy_mii_ioctl(fep->phydev, mii, cmd);
+	return phy_mii_ioctl(fep->phydev, rq, cmd);
 }
 
 extern int fs_mii_connect(struct net_device *dev);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index fccb7a3..1d16d51 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -847,7 +847,7 @@ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!priv->phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(priv->phydev, rq, cmd);
 }
 
 static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 40797fb..ff2f158 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -1082,7 +1082,7 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
 static const struct net_device_ops macb_netdev_ops = {
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 82b720f..0561425 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2457,7 +2457,7 @@ static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 
 	if (mp->phy != NULL)
-		return phy_mii_ioctl(mp->phy, if_mii(ifr), cmd);
+		return phy_mii_ioctl(mp->phy, ifr, cmd);
 
 	return -EOPNOTSUPP;
 }
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index f4a0f08..b264f0f 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -620,7 +620,7 @@ static int octeon_mgmt_ioctl(struct net_device *netdev,
 	if (!p->phydev)
 		return -EINVAL;
 
-	return phy_mii_ioctl(p->phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(p->phydev, rq, cmd);
 }
 
 static void octeon_mgmt_adjust_link(struct net_device *netdev)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 64be466..bd88d81 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -309,8 +309,9 @@ EXPORT_SYMBOL(phy_ethtool_gset);
  * current state.  Use at own risk.
  */
 int phy_mii_ioctl(struct phy_device *phydev,
-		struct mii_ioctl_data *mii_data, int cmd)
+		struct ifreq *ifr, int cmd)
 {
+	struct mii_ioctl_data *mii_data = if_mii(ifr);
 	u16 val = mii_data->val_in;
 
 	switch (cmd) {
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 1f3acc3..e585c3f 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2532,7 +2532,7 @@ static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!netif_running(dev) || !sc->phy_dev)
 		return -EINVAL;
 
-	return phy_mii_ioctl(sc->phy_dev, if_mii(rq), cmd);
+	return phy_mii_ioctl(sc->phy_dev, rq, cmd);
 }
 
 static int sbmac_close(struct net_device *dev)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 501a55f..8279f8e 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1233,7 +1233,7 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
 	if (!phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(phydev, rq, cmd);
 }
 
 #if defined(SH_ETH_HAS_TSU)
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index cc55974..56dc2ff 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -1538,7 +1538,7 @@ static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	if (!netif_running(dev) || !pdata->phy_dev)
 		return -EINVAL;
 
-	return phy_mii_ioctl(pdata->phy_dev, if_mii(ifr), cmd);
+	return phy_mii_ioctl(pdata->phy_dev, ifr, cmd);
 }
 
 static int
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 6cdee6a..b09ee1c 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -245,7 +245,7 @@ static int smsc9420_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	if (!netif_running(dev) || !pd->phy_dev)
 		return -EINVAL;
 
-	return phy_mii_ioctl(pd->phy_dev, if_mii(ifr), cmd);
+	return phy_mii_ioctl(pd->phy_dev, ifr, cmd);
 }
 
 static int smsc9420_ethtool_get_settings(struct net_device *dev,
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index a31d580..acf0616 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -1437,24 +1437,18 @@ static void stmmac_poll_controller(struct net_device *dev)
 static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int ret = -EOPNOTSUPP;
+	int ret;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	switch (cmd) {
-	case SIOCGMIIPHY:
-	case SIOCGMIIREG:
-	case SIOCSMIIREG:
-		if (!priv->phydev)
-			return -EINVAL;
-
-		spin_lock(&priv->lock);
-		ret = phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
-		spin_unlock(&priv->lock);
-	default:
-		break;
-	}
+	if (!priv->phydev)
+		return -EINVAL;
+
+	spin_lock(&priv->lock);
+	ret = phy_mii_ioctl(priv->phydev, rq, cmd);
+	spin_unlock(&priv->lock);
+
 	return ret;
 }
 
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index be08b75..99e423a 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -2066,7 +2066,7 @@ static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		return -EINVAL;
 	if (!lp->phy_dev)
 		return -ENODEV;
-	return phy_mii_ioctl(lp->phy_dev, if_mii(rq), cmd);
+	return phy_mii_ioctl(lp->phy_dev, rq, cmd);
 }
 
 static void tc35815_chip_reset(struct net_device *dev)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 289cdc5..d4163f2 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10954,7 +10954,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 			return -EAGAIN;
 		phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
-		return phy_mii_ioctl(phydev, data, cmd);
+		return phy_mii_ioctl(phydev, ifr, cmd);
 	}
 
 	switch (cmd) {
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index dc32a62..e17dd74 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3714,7 +3714,7 @@ static int ucc_geth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!ugeth->phydev)
 		return -ENODEV;
 
-	return phy_mii_ioctl(ugeth->phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(ugeth->phydev, rq, cmd);
 }
 
 static const struct net_device_ops ucc_geth_netdev_ops = {
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 7e0be8d..10a82ef 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -113,7 +113,7 @@ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	if (!priv->phydev)
 		return -EINVAL;
 
-	return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+	return phy_mii_ioctl(priv->phydev, rq, cmd);
 }
 
 static void cvm_oct_adjust_link(struct net_device *dev)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 987e111..d63736a 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -498,7 +498,7 @@ void phy_stop_machine(struct phy_device *phydev);
 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
 int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
 int phy_mii_ioctl(struct phy_device *phydev,
-		struct mii_ioctl_data *mii_data, int cmd);
+		struct ifreq *ifr, int cmd);
 int phy_start_interrupts(struct phy_device *phydev);
 void phy_print_status(struct phy_device *phydev);
 struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 8fdca56..64ca2a6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -164,10 +164,9 @@ out:
 static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
-	struct mii_ioctl_data *mii_data = if_mii(ifr);
 
 	if (p->phy != NULL)
-		return phy_mii_ioctl(p->phy, mii_data, cmd);
+		return phy_mii_ioctl(p->phy, ifr, cmd);
 
 	return -EOPNOTSUPP;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 3/4] net: added a BPF to help drivers detect PTP packets.
From: Richard Cochran @ 2010-07-17 18:49 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1279391885.git.richard.cochran@omicron.at>

Certain kinds of hardware time stamping units in both MACs and PHYs have
the limitation that they can only time stamp PTP packets. Drivers for such
hardware are left with the task of correctly matching skbs to time stamps.
This patch adds a BPF that drivers can use to classify PTP packets when
needed.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 include/linux/ptp_classify.h |  126 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/ptp_classify.h

diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h
new file mode 100644
index 0000000..943a85a
--- /dev/null
+++ b/include/linux/ptp_classify.h
@@ -0,0 +1,126 @@
+/*
+ * PTP 1588 support
+ *
+ * This file implements a BPF that recognizes PTP event messages.
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _PTP_CLASSIFY_H_
+#define _PTP_CLASSIFY_H_
+
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/filter.h>
+#ifdef __KERNEL__
+#include <linux/in.h>
+#else
+#include <netinet/in.h>
+#endif
+
+#define PTP_CLASS_NONE  0x00 /* not a PTP event message */
+#define PTP_CLASS_V1    0x01 /* protocol version 1 */
+#define PTP_CLASS_V2    0x02 /* protocol version 2 */
+#define PTP_CLASS_VMASK 0x0f /* max protocol version is 15 */
+#define PTP_CLASS_IPV4  0x10 /* event in an IPV4 UDP packet */
+#define PTP_CLASS_IPV6  0x20 /* event in an IPV6 UDP packet */
+#define PTP_CLASS_L2    0x30 /* event in a L2 packet */
+#define PTP_CLASS_VLAN  0x40 /* event in a VLAN tagged L2 packet */
+#define PTP_CLASS_PMASK 0xf0 /* mask for the packet type field */
+
+#define PTP_CLASS_V1_IPV4 (PTP_CLASS_V1 | PTP_CLASS_IPV4)
+#define PTP_CLASS_V1_IPV6 (PTP_CLASS_V1 | PTP_CLASS_IPV6) /*probably DNE*/
+#define PTP_CLASS_V2_IPV4 (PTP_CLASS_V2 | PTP_CLASS_IPV4)
+#define PTP_CLASS_V2_IPV6 (PTP_CLASS_V2 | PTP_CLASS_IPV6)
+#define PTP_CLASS_V2_L2   (PTP_CLASS_V2 | PTP_CLASS_L2)
+#define PTP_CLASS_V2_VLAN (PTP_CLASS_V2 | PTP_CLASS_VLAN)
+
+#define PTP_EV_PORT 319
+
+#define OFF_ETYPE	12
+#define OFF_IHL		14
+#define OFF_FRAG	20
+#define OFF_PROTO4	23
+#define OFF_NEXT	6
+#define OFF_UDP_DST	2
+
+#define IP6_HLEN	40
+#define UDP_HLEN	8
+
+#define RELOFF_DST4	(ETH_HLEN + OFF_UDP_DST)
+#define OFF_DST6	(ETH_HLEN + IP6_HLEN + OFF_UDP_DST)
+#define OFF_PTP6	(ETH_HLEN + IP6_HLEN + UDP_HLEN)
+
+#define OP_AND	(BPF_ALU | BPF_AND  | BPF_K)
+#define OP_JEQ	(BPF_JMP | BPF_JEQ  | BPF_K)
+#define OP_JSET	(BPF_JMP | BPF_JSET | BPF_K)
+#define OP_LDB	(BPF_LD  | BPF_B    | BPF_ABS)
+#define OP_LDH	(BPF_LD  | BPF_H    | BPF_ABS)
+#define OP_LDHI	(BPF_LD  | BPF_H    | BPF_IND)
+#define OP_LDX	(BPF_LDX | BPF_B    | BPF_MSH)
+#define OP_OR	(BPF_ALU | BPF_OR   | BPF_K)
+#define OP_RETA	(BPF_RET | BPF_A)
+#define OP_RETK	(BPF_RET | BPF_K)
+
+static inline int ptp_filter_init(struct sock_filter *f, int len)
+{
+	if (OP_LDH == f[0].code)
+		return sk_chk_filter(f, len);
+	else
+		return 0;
+}
+
+#define PTP_FILTER \
+	{OP_LDH,	0,   0, OFF_ETYPE		}, /*              */ \
+	{OP_JEQ,	0,  12, ETH_P_IP		}, /* f goto L20   */ \
+	{OP_LDB,	0,   0, OFF_PROTO4		}, /*              */ \
+	{OP_JEQ,	0,   9, IPPROTO_UDP		}, /* f goto L10   */ \
+	{OP_LDH,	0,   0, OFF_FRAG		}, /*              */ \
+	{OP_JSET,	7,   0, 0x1fff			}, /* t goto L11   */ \
+	{OP_LDX,	0,   0, OFF_IHL			}, /*              */ \
+	{OP_LDHI,	0,   0, RELOFF_DST4		}, /*              */ \
+	{OP_JEQ,	0,   4, PTP_EV_PORT		}, /* f goto L12   */ \
+	{OP_LDHI,	0,   0, ETH_HLEN + UDP_HLEN	}, /*              */ \
+	{OP_AND,	0,   0, PTP_CLASS_VMASK		}, /*              */ \
+	{OP_OR,		0,   0, PTP_CLASS_IPV4		}, /*              */ \
+	{OP_RETA,	0,   0, 0			}, /*              */ \
+/*L1x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		}, /*              */ \
+/*L20*/	{OP_JEQ,	0,   9, ETH_P_IPV6		}, /* f goto L40   */ \
+	{OP_LDB,	0,   0, ETH_HLEN + OFF_NEXT	}, /*              */ \
+	{OP_JEQ,	0,   6, IPPROTO_UDP		}, /* f goto L30   */ \
+	{OP_LDH,	0,   0, OFF_DST6		}, /*              */ \
+	{OP_JEQ,	0,   4, PTP_EV_PORT		}, /* f goto L31   */ \
+	{OP_LDH,	0,   0, OFF_PTP6		}, /*              */ \
+	{OP_AND,	0,   0, PTP_CLASS_VMASK		}, /*              */ \
+	{OP_OR,		0,   0, PTP_CLASS_IPV6		}, /*              */ \
+	{OP_RETA,	0,   0, 0			}, /*              */ \
+/*L3x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		}, /*              */ \
+/*L40*/	{OP_JEQ,	0,   6, ETH_P_8021Q		}, /* f goto L50   */ \
+	{OP_LDH,	0,   0, OFF_ETYPE + 4		}, /*              */ \
+	{OP_JEQ,	0,   9, ETH_P_1588		}, /* f goto L60   */ \
+	{OP_LDH,	0,   0, ETH_HLEN + VLAN_HLEN	}, /*              */ \
+	{OP_AND,	0,   0, PTP_CLASS_VMASK		}, /*              */ \
+	{OP_OR,		0,   0, PTP_CLASS_VLAN		}, /*              */ \
+	{OP_RETA,	0,   0, 0			}, /*              */ \
+/*L50*/	{OP_JEQ,	0,   4, ETH_P_1588		}, /* f goto L61   */ \
+	{OP_LDH,	0,   0, ETH_HLEN		}, /*              */ \
+	{OP_AND,	0,   0, PTP_CLASS_VMASK		}, /*              */ \
+	{OP_OR,		0,   0, PTP_CLASS_L2		}, /*              */ \
+	{OP_RETA,	0,   0, 0			}, /*              */ \
+/*L6x*/	{OP_RETK,	0,   0, PTP_CLASS_NONE		},
+
+#endif
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 4/4] net: support time stamping in phy devices.
From: Richard Cochran @ 2010-07-17 18:49 UTC (permalink / raw)
  To: netdev
In-Reply-To: <cover.1279391885.git.richard.cochran@omicron.at>

This patch adds a new networking option to allow hardware time stamps
from PHY devices. When enabled, likely candidates among incoming and
outgoing network packets are offered to the PHY driver for possible
time stamping. When accepted by the PHY driver, incoming packets are
deferred for later delivery by the driver.

The patch also adds phylib driver methods for the SIOCSHWTSTAMP ioctl
and callbacks for transmit and receive time stamping. Drivers may
optionally implement these functions.

Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
---
 drivers/net/phy/phy.c        |    5 ++
 drivers/net/phy/phy_device.c |    2 +
 include/linux/netdevice.h    |    4 +
 include/linux/phy.h          |   22 +++++++
 include/linux/skbuff.h       |   31 ++++++++++
 net/Kconfig                  |   10 +++
 net/core/Makefile            |    2 +-
 net/core/dev.c               |    3 +
 net/core/timestamping.c      |  126 ++++++++++++++++++++++++++++++++++++++++++
 net/socket.c                 |    4 +
 10 files changed, 208 insertions(+), 1 deletions(-)
 create mode 100644 net/core/timestamping.c

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index bd88d81..5130db8 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -361,6 +361,11 @@ int phy_mii_ioctl(struct phy_device *phydev,
 		}
 		break;
 
+	case SIOCSHWTSTAMP:
+		if (phydev->drv->hwtstamp)
+			return phydev->drv->hwtstamp(phydev, ifr);
+		/* fall through */
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 1a99bb2..c076119 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -460,6 +460,7 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 	}
 
 	phydev->attached_dev = dev;
+	dev->phydev = phydev;
 
 	phydev->dev_flags = flags;
 
@@ -513,6 +514,7 @@ EXPORT_SYMBOL(phy_attach);
  */
 void phy_detach(struct phy_device *phydev)
 {
+	phydev->attached_dev->phydev = NULL;
 	phydev->attached_dev = NULL;
 
 	/* If the device had no specific driver before (i.e. - it
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 8fa5e5a..131e9c8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -54,6 +54,7 @@
 
 struct vlan_group;
 struct netpoll_info;
+struct phy_device;
 /* 802.11 specific */
 struct wireless_dev;
 					/* source back-compat hooks */
@@ -1077,6 +1078,9 @@ struct net_device {
 #endif
 	/* n-tuple filter list attached to this device */
 	struct ethtool_rx_ntuple_list ethtool_ntuple_list;
+
+	/* phy device may attach itself for hardware timestamping */
+	struct phy_device *phydev;
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d63736a..6b0a782 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -234,6 +234,8 @@ enum phy_state {
 	PHY_RESUMING
 };
 
+struct sk_buff;
+
 /* phy_device: An instance of a PHY
  *
  * drv: Pointer to the driver for this PHY instance
@@ -402,6 +404,26 @@ struct phy_driver {
 	/* Clears up any memory if needed */
 	void (*remove)(struct phy_device *phydev);
 
+	/* Handles SIOCSHWTSTAMP ioctl for hardware time stamping. */
+	int  (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr);
+
+	/*
+	 * Requests a Rx timestamp for 'skb'. If the skb is accepted,
+	 * the phy driver promises to deliver it using netif_rx() as
+	 * soon as a timestamp becomes available. One of the
+	 * PTP_CLASS_ values is passed in 'type'. The function must
+	 * return true if the skb is accepted for delivery.
+	 */
+	bool (*rxtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
+
+	/*
+	 * Requests a Tx timestamp for 'skb'. The phy driver promises
+	 * to deliver it to the socket's error queue as soon as a
+	 * timestamp becomes available. One of the PTP_CLASS_ values
+	 * is passed in 'type'.
+	 */
+	void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type);
+
 	struct device_driver driver;
 };
 #define to_phy_driver(d) container_of(d, struct phy_driver, driver)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a1b0400..f5aa87e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1933,6 +1933,36 @@ static inline ktime_t net_invalid_timestamp(void)
 	return ktime_set(0, 0);
 }
 
+extern void skb_timestamping_init(void);
+
+#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
+
+extern void skb_clone_tx_timestamp(struct sk_buff *skb);
+extern bool skb_defer_rx_timestamp(struct sk_buff *skb);
+
+#else /* CONFIG_NETWORK_PHY_TIMESTAMPING */
+
+static inline void skb_clone_tx_timestamp(struct sk_buff *skb)
+{
+}
+
+static inline bool skb_defer_rx_timestamp(struct sk_buff *skb)
+{
+	return false;
+}
+
+#endif /* !CONFIG_NETWORK_PHY_TIMESTAMPING */
+
+/**
+ * skb_complete_tx_timestamp() - deliver cloned skb with tx timestamps
+ *
+ * @skb: clone of the the original outgoing packet
+ * @hwtstamps: hardware time stamps
+ *
+ */
+void skb_complete_tx_timestamp(struct sk_buff *skb,
+			       struct skb_shared_hwtstamps *hwtstamps);
+
 /**
  * skb_tstamp_tx - queue clone of skb with send time stamps
  * @orig_skb:	the original outgoing packet
@@ -1965,6 +1995,7 @@ static inline void sw_tx_timestamp(struct sk_buff *skb)
  */
 static inline void skb_tx_timestamp(struct sk_buff *skb)
 {
+	skb_clone_tx_timestamp(skb);
 	sw_tx_timestamp(skb);
 }
 
diff --git a/net/Kconfig b/net/Kconfig
index 0d68b40..b325094 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -86,6 +86,16 @@ config NETWORK_SECMARK
 	  to nfmark, but designated for security purposes.
 	  If you are unsure how to answer this question, answer N.
 
+config NETWORK_PHY_TIMESTAMPING
+	bool "Timestamping in PHY devices"
+	depends on EXPERIMENTAL
+	help
+	  This allows timestamping of network packets by PHYs with
+	  hardware timestamping capabilities. This option adds some
+	  overhead in the transmit and receive paths.
+
+	  If you are unsure how to answer this question, answer N.
+
 menuconfig NETFILTER
 	bool "Network packet filtering framework (Netfilter)"
 	---help---
diff --git a/net/core/Makefile b/net/core/Makefile
index 51c3eec..8a04dd2 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -18,4 +18,4 @@ obj-$(CONFIG_NET_DMA) += user_dma.o
 obj-$(CONFIG_FIB_RULES) += fib_rules.o
 obj-$(CONFIG_TRACEPOINTS) += net-traces.o
 obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o
-
+obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
diff --git a/net/core/dev.c b/net/core/dev.c
index e85cc5f..0804c79 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2939,6 +2939,9 @@ int netif_receive_skb(struct sk_buff *skb)
 	if (netdev_tstamp_prequeue)
 		net_timestamp_check(skb);
 
+	if (skb_defer_rx_timestamp(skb))
+		return NET_RX_SUCCESS;
+
 #ifdef CONFIG_RPS
 	{
 		struct rps_dev_flow voidflow, *rflow = &voidflow;
diff --git a/net/core/timestamping.c b/net/core/timestamping.c
new file mode 100644
index 0000000..0ae6c22
--- /dev/null
+++ b/net/core/timestamping.c
@@ -0,0 +1,126 @@
+/*
+ * PTP 1588 clock support - support for timestamping in PHY devices
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errqueue.h>
+#include <linux/phy.h>
+#include <linux/ptp_classify.h>
+#include <linux/skbuff.h>
+
+static struct sock_filter ptp_filter[] = {
+	PTP_FILTER
+};
+
+static unsigned int classify(struct sk_buff *skb)
+{
+	if (likely(skb->dev &&
+		   skb->dev->phydev &&
+		   skb->dev->phydev->drv))
+		return sk_run_filter(skb, ptp_filter, ARRAY_SIZE(ptp_filter));
+	else
+		return PTP_CLASS_NONE;
+}
+
+void skb_clone_tx_timestamp(struct sk_buff *skb)
+{
+	struct phy_device *phydev;
+	struct sk_buff *clone;
+	struct sock *sk = skb->sk;
+	unsigned int type;
+
+	if (!sk)
+		return;
+
+	type = classify(skb);
+
+	switch (type) {
+	case PTP_CLASS_V1_IPV4:
+	case PTP_CLASS_V1_IPV6:
+	case PTP_CLASS_V2_IPV4:
+	case PTP_CLASS_V2_IPV6:
+	case PTP_CLASS_V2_L2:
+	case PTP_CLASS_V2_VLAN:
+		phydev = skb->dev->phydev;
+		if (likely(phydev->drv->txtstamp)) {
+			clone = skb_clone(skb, GFP_ATOMIC);
+			if (!clone)
+				return;
+			clone->sk = sk;
+			phydev->drv->txtstamp(phydev, clone, type);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+void skb_complete_tx_timestamp(struct sk_buff *skb,
+			       struct skb_shared_hwtstamps *hwtstamps)
+{
+	struct sock *sk = skb->sk;
+	struct sock_exterr_skb *serr;
+	int err;
+
+	if (!hwtstamps)
+		return;
+
+	*skb_hwtstamps(skb) = *hwtstamps;
+	serr = SKB_EXT_ERR(skb);
+	memset(serr, 0, sizeof(*serr));
+	serr->ee.ee_errno = ENOMSG;
+	serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
+	skb->sk = NULL;
+	err = sock_queue_err_skb(sk, skb);
+	if (err)
+		kfree_skb(skb);
+}
+EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);
+
+bool skb_defer_rx_timestamp(struct sk_buff *skb)
+{
+	struct phy_device *phydev;
+	unsigned int type;
+
+	skb_push(skb, ETH_HLEN);
+
+	type = classify(skb);
+
+	skb_pull(skb, ETH_HLEN);
+
+	switch (type) {
+	case PTP_CLASS_V1_IPV4:
+	case PTP_CLASS_V1_IPV6:
+	case PTP_CLASS_V2_IPV4:
+	case PTP_CLASS_V2_IPV6:
+	case PTP_CLASS_V2_L2:
+	case PTP_CLASS_V2_VLAN:
+		phydev = skb->dev->phydev;
+		if (likely(phydev->drv->rxtstamp))
+			return phydev->drv->rxtstamp(phydev, skb, type);
+		break;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+void __init skb_timestamping_init(void)
+{
+	BUG_ON(sk_chk_filter(ptp_filter, ARRAY_SIZE(ptp_filter)));
+}
diff --git a/net/socket.c b/net/socket.c
index acfa173..b8a03b8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2403,6 +2403,10 @@ static int __init sock_init(void)
 	netfilter_init();
 #endif
 
+#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING
+	skb_timestamping_init();
+#endif
+
 	return 0;
 }
 
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] LSM: Add post recvmsg() hook.
From: Paul Moore @ 2010-07-17 20:34 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: davem, kuznet, pekkas, jmorris, yoshfuji, kaber, netdev,
	linux-security-module
In-Reply-To: <201007171017.DFC73498.SFFFOMLVJOHOtQ@I-love.SAKURA.ne.jp>

On Friday, July 16, 2010 09:17:10 pm Tetsuo Handa wrote:
> David Miller wrote:
> > From: Tetsuo Handa
> > Date: Sat, 17 Jul 2010 01:14:38 +0900
> > 
> > > Below is a patch for post recvmsg() operation. I modified the patch to
> > > call skb_recv_datagram() again (for udp_recvmsg(), raw_recvmsg(),
> > > udpv6_recvmsg()) if LSM dicided to drop the message. (Regarding
> > > rawv6_recvmsg(), I didn't do so in accordance with the comment at
> > > "csum_copy_err:".)
> > > What do you think about this verion?
> > 
> > This looks fine, but regardless of that comment I think the IPV6 raw
> > recvmsg() should loop just as the IPV4 one does in your patch.
> 
> Thank you, David.
> I updated to call skb_recv_datagram() for rawv6_recvmsg() case too.
> 
> NETWORKING [IPv4/IPv6] maintainers and Paul, is below patch fine for you?

Comments below ...

> >From b43154a90bc7494ec1ee301e692d2bbf29c8f2f8 Mon Sep 17 00:00:00 2001
> 
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Date: Sat, 17 Jul 2010 09:52:38 +0900
> Subject: [PATCH] LSM: Add post recvmsg() hook.
> 
> Current pre recvmsg hook (i.e. security_socket_recvmsg()) has two problems.
> 
> One is that it will cause eating 100% of CPU time if the caller does not
> close() the socket when recvmsg() failed due to security_socket_recvmsg(),
> for subsequent select() notifies the caller of readiness for recvmsg()
> since the datagram which would have been already picked up if
> security_socket_recvmsg() did not return error is remaining in the queue.
> 
> The other is that it is racy if LSM module wants to do filtering based on
> "which process can pick up datagrams from which source" because the process
> which picks up the datagram is not known until skb_recv_datagram() and lock
> is not held between security_socket_recvmsg() and skb_recv_datagram().
> 
> This patch introduces post recvmsg hook (i.e.
> security_socket_post_recvmsg()) in order to solve above problems at the
> cost of ability to pick up the datagram which would have been picked up if
> preceding security_socket_post_recvmsg() did not return error.

We've had discussions before about the merits of queuing inbound packets to 
the socket buffer only to later reject them when the application reads from 
the socket.  I'd be much happier to see you drop the packets before queuing 
them to the socket, e.g. security_sock_rcv_skb(), but I understand that isn't 
possible with TOMOYO's approach to security.

At least we're not talking about TCP sockets :)

I'll go ahead and add my ACK to this patch, but I wonder if it makes more 
sense in the UDP path to add the LSM hook after the decision to calculate the 
checksum prior to the copy?  If we're going to reject the packet due to a bad 
checksum we might as well do that before we waste our time with the LSM 
processing - right?  Although, if we end up doing checksum verification with 
the copy in the majority of the cases it may not be worth it.

Acked-by: Paul Moore <paul.moore@hp.com>

> ---
>  include/linux/security.h |   14 ++++++++++++++
>  net/ipv4/raw.c           |   12 +++++++++---
>  net/ipv4/udp.c           |    9 ++++++++-
>  net/ipv6/raw.c           |   12 +++++++++---
>  net/ipv6/udp.c           |    9 ++++++++-
>  security/capability.c    |    6 ++++++
>  security/security.c      |    6 ++++++
>  7 files changed, 60 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 723a93d..409c44d 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -879,6 +879,12 @@ static inline void security_free_mnt_opts(struct
> security_mnt_opts *opts) *	@size contains the size of message structure.
>   *	@flags contains the operational flags.
>   *	Return 0 if permission is granted.
> + * @socket_post_recvmsg:
> + *	Check permission after receiving a message from a socket.
> + *	The message is discarded if permission is not granted.
> + *	@sk contains the sock structure.
> + *	@skb contains the sk_buff structure.
> + *	Return 0 if permission is granted.
>   * @socket_getsockname:
>   *	Check permission before the local address (name) of the socket object
>   *	@sock is retrieved.
> @@ -1575,6 +1581,7 @@ struct security_operations {
>  			       struct msghdr *msg, int size);
>  	int (*socket_recvmsg) (struct socket *sock,
>  			       struct msghdr *msg, int size, int flags);
> +	int (*socket_post_recvmsg) (struct sock *sk, struct sk_buff *skb);
>  	int (*socket_getsockname) (struct socket *sock);
>  	int (*socket_getpeername) (struct socket *sock);
>  	int (*socket_getsockopt) (struct socket *sock, int level, int optname);
> @@ -2526,6 +2533,7 @@ int security_socket_accept(struct socket *sock,
> struct socket *newsock); int security_socket_sendmsg(struct socket *sock,
> struct msghdr *msg, int size); int security_socket_recvmsg(struct socket
> *sock, struct msghdr *msg, int size, int flags);
> +int security_socket_post_recvmsg(struct sock *sk, struct sk_buff *skb);
>  int security_socket_getsockname(struct socket *sock);
>  int security_socket_getpeername(struct socket *sock);
>  int security_socket_getsockopt(struct socket *sock, int level, int
> optname); @@ -2617,6 +2625,12 @@ static inline int
> security_socket_recvmsg(struct socket *sock, return 0;
>  }
> 
> +static inline int security_socket_post_recvmsg(struct sock *sk,
> +					       struct sk_buff *skb)
> +{
> +	return 0;
> +}
> +
>  static inline int security_socket_getsockname(struct socket *sock)
>  {
>  	return 0;
> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
> index 2c7a163..69652d4 100644
> --- a/net/ipv4/raw.c
> +++ b/net/ipv4/raw.c
> @@ -676,9 +676,15 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock
> *sk, struct msghdr *msg, goto out;
>  	}
> 
> -	skb = skb_recv_datagram(sk, flags, noblock, &err);
> -	if (!skb)
> -		goto out;
> +	for (;;) {
> +		skb = skb_recv_datagram(sk, flags, noblock, &err);
> +		if (!skb)
> +			goto out;
> +		err = security_socket_post_recvmsg(sk, skb);
> +		if (likely(!err))
> +			break;
> +		skb_kill_datagram(sk, skb, flags);
> +	}
> 
>  	copied = skb->len;
>  	if (len < copied) {
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index 5858574..9145685 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -1125,6 +1125,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk,
> struct msghdr *msg, int err;
>  	int is_udplite = IS_UDPLITE(sk);
>  	bool slow;
> +	bool update_stat;
> 
>  	/*
>  	 *	Check any passed addresses
> @@ -1140,6 +1141,12 @@ try_again:
>  				  &peeked, &err);
>  	if (!skb)
>  		goto out;
> +	err = security_socket_post_recvmsg(sk, skb);
> +	if (err) {
> +		update_stat = false;
> +		goto csum_copy_err;
> +	}
> +	update_stat = true;
> 
>  	ulen = skb->len - sizeof(struct udphdr);
>  	if (len > ulen)
> @@ -1200,7 +1207,7 @@ out:
> 
>  csum_copy_err:
>  	slow = lock_sock_fast(sk);
> -	if (!skb_kill_datagram(sk, skb, flags))
> +	if (!skb_kill_datagram(sk, skb, flags) && update_stat)
>  		UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
>  	unlock_sock_fast(sk, slow);
> 
> diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
> index 4a4dcbe..6915b01 100644
> --- a/net/ipv6/raw.c
> +++ b/net/ipv6/raw.c
> @@ -464,9 +464,15 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct
> sock *sk, if (np->rxpmtu && np->rxopt.bits.rxpmtu)
>  		return ipv6_recv_rxpmtu(sk, msg, len);
> 
> -	skb = skb_recv_datagram(sk, flags, noblock, &err);
> -	if (!skb)
> -		goto out;
> +	for (;;) {
> +		skb = skb_recv_datagram(sk, flags, noblock, &err);
> +		if (!skb)
> +			goto out;
> +		err = security_socket_post_recvmsg(sk, skb);
> +		if (likely(!err))
> +			break;
> +		skb_kill_datagram(sk, skb, flags);
> +	}
> 
>  	copied = skb->len;
>  	if (copied > len) {
> diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
> index 87be586..6cae276 100644
> --- a/net/ipv6/udp.c
> +++ b/net/ipv6/udp.c
> @@ -329,6 +329,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
>  	int is_udplite = IS_UDPLITE(sk);
>  	int is_udp4;
>  	bool slow;
> +	bool update_stat;
> 
>  	if (addr_len)
>  		*addr_len=sizeof(struct sockaddr_in6);
> @@ -344,6 +345,12 @@ try_again:
>  				  &peeked, &err);
>  	if (!skb)
>  		goto out;
> +	err = security_socket_post_recvmsg(sk, skb);
> +	if (err) {
> +		update_stat = false;
> +		goto csum_copy_err;
> +	}
> +	update_stat = true;
> 
>  	ulen = skb->len - sizeof(struct udphdr);
>  	if (len > ulen)
> @@ -426,7 +433,7 @@ out:
> 
>  csum_copy_err:
>  	slow = lock_sock_fast(sk);
> -	if (!skb_kill_datagram(sk, skb, flags)) {
> +	if (!skb_kill_datagram(sk, skb, flags) && update_stat) {
>  		if (is_udp4)
>  			UDP_INC_STATS_USER(sock_net(sk),
>  					UDP_MIB_INERRORS, is_udplite);
> diff --git a/security/capability.c b/security/capability.c
> index 4aeb699..709aea3 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -597,6 +597,11 @@ static int cap_socket_recvmsg(struct socket *sock,
> struct msghdr *msg, return 0;
>  }
> 
> +static int cap_socket_post_recvmsg(struct sock *sk, struct sk_buff *skb)
> +{
> +	return 0;
> +}
> +
>  static int cap_socket_getsockname(struct socket *sock)
>  {
>  	return 0;
> @@ -1001,6 +1006,7 @@ void __init security_fixup_ops(struct
> security_operations *ops) set_to_cap_if_null(ops, socket_accept);
>  	set_to_cap_if_null(ops, socket_sendmsg);
>  	set_to_cap_if_null(ops, socket_recvmsg);
> +	set_to_cap_if_null(ops, socket_post_recvmsg);
>  	set_to_cap_if_null(ops, socket_getsockname);
>  	set_to_cap_if_null(ops, socket_getpeername);
>  	set_to_cap_if_null(ops, socket_setsockopt);
> diff --git a/security/security.c b/security/security.c
> index e8c87b8..4291bd7 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1037,6 +1037,12 @@ int security_socket_recvmsg(struct socket *sock,
> struct msghdr *msg, return security_ops->socket_recvmsg(sock, msg, size,
> flags);
>  }
> 
> +int security_socket_post_recvmsg(struct sock *sk, struct sk_buff *skb)
> +{
> +	return security_ops->socket_post_recvmsg(sk, skb);
> +}
> +EXPORT_SYMBOL(security_socket_post_recvmsg);
> +
>  int security_socket_getsockname(struct socket *sock)
>  {
>  	return security_ops->socket_getsockname(sock);

-- 
paul moore
linux @ hp

^ permalink raw reply

* charity projects,
From: king @ 2010-07-17 22:36 UTC (permalink / raw)





^ permalink raw reply

* Re: [PATCH 2.6.35-rc1] net-next: vmxnet3 fixes [4/5] Do not reset when the device is not opened
From: David Miller @ 2010-07-17 23:35 UTC (permalink / raw)
  To: sbhatewara; +Cc: netdev, linux-kernel, pv-drivers, ronghua, matthieu
In-Reply-To: <alpine.LRH.2.00.1007160108240.12503@localhost.localdomain>

From: Shreyas Bhatewara <sbhatewara@vmware.com>
Date: Fri, 16 Jul 2010 01:17:29 -0700 (PDT)

> 
> 
> On Thu, 15 Jul 2010, David Miller wrote:
> 
>> From: Shreyas Bhatewara <sbhatewara@vmware.com>
>> Date: Thu, 15 Jul 2010 18:20:52 -0700 (PDT)
>> 
>> > Is this what you suggest :
>> > 
>> > ---
>> > 
>> > Hold rtnl_lock to get the right link state.
>> 
>> It ought to work, but make sure that it is legal to take the
>> RTNL semaphore in all contexts in which this code block
>> might be called.
>> 
> 
> This code block is called only from the workqueue handler, which runs in
> process context, so it is legal to take rtnl semaphore.
> Tested this code by simulating event interrupts (which schedule this 
> code) at considerable frequency while the interface was brought up and
> down in a loop. Similar stress testing had revealed the bug originally. 

Awesome, please submit this formally.  The copy you sent lacked a commit
message and signoff.

^ permalink raw reply

* Re: Kexec Reboot Network Issue
From: Eric W. Biederman @ 2010-07-18  4:25 UTC (permalink / raw)
  To: Simon Horman; +Cc: Richard Genthner, Michael Chan, Matt Carlson, netdev, kexec
In-Reply-To: <20100716071547.GB20761@verge.net.au>

Simon Horman <horms@verge.net.au> writes:

> [ CCed Michael Chan, Matt Carlson and Netdev ]
>
> On Thu, Jul 15, 2010 at 11:35:43AM -0400, Richard Genthner wrote:
>> On 07/15/2010 10:20 AM, Simon Horman wrote:
>> >On Thu, Jul 15, 2010 at 07:59:07AM -0400, Richard Genthner wrote:
>> >>I'm currently using the following string:
>> >>
>> >>kexex --type=elf-x86_64 --args-linux -l /boot/vmlinuz-2.6.18-12.el5
>> >>--initrid=/boot/initrd-2.6.18-128.el6.img --append="`cat
>> >>/proc/cmdline`"
>> >>kexec -e
>> >>
>> >>Some times we can get to the box from any subnet, other times we can
>> >>only get to the box from the same subnet only. Our solution to this
>> >>is to down the iface and then restart networking. Has anyone else
>> >>run into this issue?
>> >Hi Richard,
>> >
>> >could you be more specific about which NIC you are using?
>> >And is it at all possible to test a newer kernel version?
>> >
>> >What I suspect is happening is that the NIC is getting into an unknown
>> >state. And what I'm hoping is that is a problem thats already been
>> >addressed.
>>
>> I would try a different kenerl but our cluster fs has us locked to
>> this kernel until we finish the upgrade to the new cluster fs
>> version. heres ethtool on the iface
>> 
>> from lshw
>> *-network
>>                 description: Ethernet interface
>>                 product: NetXtreme BCM5721 Gigabit Ethernet PCI Express
>>                 vendor: Broadcom Corporation
>>                 physical id: 0
>>                 bus info: pci@0000:03:00.0
>>                 logical name: eth0
>>                 version: 21
>>                 serial: 00:25:64:3b:9c:ae
>>                 size: 1GB/s
>>                 capacity: 1GB/s
>>                 width: 64 bits
>>                 clock: 33MHz
>>                 capabilities: pm vpd msi pciexpress bus_master
>> cap_list ethernet physical tp 10bt 10bt-fd 100bt 100bt-fd 1000bt
>> 1000bt-fd autonegotiation
>>                 configuration: autonegotiation=on broadcast=yes
>> driver=tg3 driverversion=3.93 duplex=full firmware=5721-v3.65,
>> ASFIPMI v6.25 ip=172.16.1.123 latency=0 link=yes module=tg3
>> multicast=yes port=twisted pair speed=1GB/s
>
> Hi Richard,
>
> first, please don't top-post, its not the done thing in these parts.
>
> I had a quick hunt through the git change log and the onl changed that
> jumped out was "[TG3]: Fix msi issue with kexec/kdump"[1], but this
> seems to have been back-ported to the initrd-2.6.18-128.el5 (I assume
> you meant 5 not 6) kernel.
>
> [1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ee6a99b539a50b4e9398938a0a6d37f8bf911550
>
> In any case I strongly suspect that the problem is a kernel problem and as
> such can't be solved modifying the kernel or at least tg.ko module (which
> is probably in the initrd). I suggest logging bug report with Red Hat.

The classic workaround is to rmmod the driver before calling kexec.
Frequently driver remove methods used by rmmod are much more tested
then the shutdown methods used by kexec and reboot.


Eric

^ permalink raw reply

* Re: [PATCH] LSM: Add post recvmsg() hook.
From: Eric Dumazet @ 2010-07-18  8:33 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: davem, kuznet, pekkas, jmorris, yoshfuji, kaber, paul.moore,
	netdev, linux-security-module
In-Reply-To: <201007171017.DFC73498.SFFFOMLVJOHOtQ@I-love.SAKURA.ne.jp>

Le samedi 17 juillet 2010 à 10:17 +0900, Tetsuo Handa a écrit :
> David Miller wrote:
> > From: Tetsuo Handa
> > Date: Sat, 17 Jul 2010 01:14:38 +0900
> > 
> > > Below is a patch for post recvmsg() operation. I modified the patch to call
> > > skb_recv_datagram() again (for udp_recvmsg(), raw_recvmsg(), udpv6_recvmsg())
> > > if LSM dicided to drop the message. (Regarding rawv6_recvmsg(), I didn't do so
> > > in accordance with the comment at "csum_copy_err:".)
> > > What do you think about this verion?
> > 
> > This looks fine, but regardless of that comment I think the IPV6 raw recvmsg()
> > should loop just as the IPV4 one does in your patch.
> > 
> Thank you, David.
> I updated to call skb_recv_datagram() for rawv6_recvmsg() case too.
> 
> NETWORKING [IPv4/IPv6] maintainers and Paul, is below patch fine for you?
> 
> Regards.
> ----------------------------------------
> >From b43154a90bc7494ec1ee301e692d2bbf29c8f2f8 Mon Sep 17 00:00:00 2001
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Date: Sat, 17 Jul 2010 09:52:38 +0900
> Subject: [PATCH] LSM: Add post recvmsg() hook.
> 
> Current pre recvmsg hook (i.e. security_socket_recvmsg()) has two problems.
> 
> One is that it will cause eating 100% of CPU time if the caller does not
> close() the socket when recvmsg() failed due to security_socket_recvmsg(), for
> subsequent select() notifies the caller of readiness for recvmsg() since the
> datagram which would have been already picked up if security_socket_recvmsg()
> did not return error is remaining in the queue.
> 
> The other is that it is racy if LSM module wants to do filtering based on
> "which process can pick up datagrams from which source" because the process
> which picks up the datagram is not known until skb_recv_datagram() and lock
> is not held between security_socket_recvmsg() and skb_recv_datagram().
> 
> This patch introduces post recvmsg hook (i.e. security_socket_post_recvmsg())
> in order to solve above problems at the cost of ability to pick up the datagram
> which would have been picked up if preceding security_socket_post_recvmsg() did
> not return error.
> 
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

I read this patch and could not find out if an SNMP counter was
increased in the case a frame was not delivered but dropped in kernel
land.



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

^ permalink raw reply

* Re: [PATCH] LSM: Add post recvmsg() hook.
From: Tetsuo Handa @ 2010-07-18 10:49 UTC (permalink / raw)
  To: eric.dumazet
  Cc: davem, kuznet, pekkas, jmorris, yoshfuji, kaber, paul.moore,
	netdev, linux-security-module
In-Reply-To: <1279441990.2476.26.camel@edumazet-laptop>

Eric Dumazet wrote:
> I read this patch and could not find out if an SNMP counter was
> increased in the case a frame was not delivered but dropped in kernel
> land.

UDP_MIB_INDATAGRAMS and UDP_MIB_INERRORS will not be increased
if dropped by security_socket_post_recvmsg()'s decision.
Should we increment UDP_MIB_INDATAGRAMS and/or UDP_MIB_INERRORS?

udpInDatagrams
    "The total number of UDP datagrams delivered to UDP users."

udpNoPorts
    "The total number of received UDP datagrams for which there was no
     application at the destination port."

udpInErrors
    "The number of received UDP datagrams that could not be delivered for
     reasons other than the lack of an application at the destination port."

^ permalink raw reply

* Re: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)
From: Pedro Garcia @ 2010-07-18 16:43 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy, Ben Hutchings, David Miller, Eric Dumazet
In-Reply-To: <1278015554.2782.11.camel@edumazet-laptop>

On Thu, 01 Jul 2010 22:19:14 +0200, Eric Dumazet <eric.dumazet@gmail.com>
wrote:

> Seems fine but you need to respin your patch against latest net-next-2.6
> tree.
> 
> Check your tree got commit 9618e2ffd78aaa (vlan: 64 bit rx counters)
> 
> Thanks !

The patch applied to the lastest tree:

- Without the 8021q module loaded in the kernel, all 802.1p packets 
(VLAN 0 but QoS tagging) are silently discarded (as expected, as 
the protocol is not loaded).
 
- Without this patch in 8021q module, these packets are forwarded to 
the module, but they are discarded also if VLAN 0 is not configured,
which should not be the default behaviour, as VLAN 0 is not really
a VLANed packet but a 802.1p packet. Defining VLAN 0 makes it almost
impossible to communicate with mixed 802.1p and non 802.1p devices on
the same network due to arp table issues.

- Changed logic to skip vlan specific code in vlan_skb_recv if VLAN 
is 0 and we have not defined a VLAN with ID 0, but we accept the 
packet with the encapsulated proto and pass it later to netif_rx.

- In the vlan device event handler, added some logic to add VLAN 0 
to HW filter in devices that support it (this prevented any traffic
in VLAN 0 to reach the stack in e1000e with HW filter under 2.6.35,
and probably also with other HW filtered cards, so we fix it here).

- In the vlan unregister logic, prevent the elimination of VLAN 0 
in devices with HW filter.

- The default behaviour is to ignore the VLAN 0 tagging and accept
the packet as if it was not tagged, but we can still define a 
VLAN 0 if desired (so it is backwards compatible).

Signed-off-by: Pedro Garcia <pedro.netdev@dondevamos.com>
--
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 3c1c8c1..a2ad152 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -155,9 +155,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 	BUG_ON(!grp);
 
 	/* Take it out of our own structures, but be sure to interlock with
-	 * HW accelerating devices or SW vlan input packet processing.
+	 * HW accelerating devices or SW vlan input packet processing if
+	 * VLAN is not 0 (leave it there for 802.1p).
 	 */
-	if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+	if (vlan_id && (real_dev->features & NETIF_F_HW_VLAN_FILTER))
 		ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id);
 
 	grp->nr_vlans--;
@@ -419,6 +420,14 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 	if (is_vlan_dev(dev))
 		__vlan_device_event(dev, event);
 
+	if ((event == NETDEV_UP) &&
+	    (dev->features & NETIF_F_HW_VLAN_FILTER) &&
+	    dev->netdev_ops->ndo_vlan_rx_add_vid) {
+		pr_info("8021q: adding VLAN 0 to HW filter on device %s\n",
+			dev->name);
+		dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0);
+	}
+
 	grp = __vlan_find_group(dev);
 	if (!grp)
 		goto out;
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 1b9406a..01ddb04 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -8,6 +8,9 @@
 int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 		      u16 vlan_tci, int polling)
 {
+	struct net_device *vlan_dev;
+	u16 vlan_id;
+
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
 
@@ -16,9 +19,12 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 
 	skb->skb_iif = skb->dev->ifindex;
 	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
+	vlan_id = vlan_tci & VLAN_VID_MASK;
+	vlan_dev = vlan_group_get_device(grp, vlan_id);
 
-	if (!skb->dev)
+	if (vlan_dev)
+		skb->dev = vlan_dev;
+	else if (vlan_id)
 		goto drop;
 
 	return (polling ? netif_receive_skb(skb) : netif_rx(skb));
@@ -83,15 +89,20 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
 		unsigned int vlan_tci, struct sk_buff *skb)
 {
 	struct sk_buff *p;
+	struct net_device *vlan_dev;
+	u16 vlan_id;
 
 	if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
 		skb->deliver_no_wcard = 1;
 
 	skb->skb_iif = skb->dev->ifindex;
 	__vlan_hwaccel_put_tag(skb, vlan_tci);
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
+	vlan_id = vlan_tci & VLAN_VID_MASK;
+	vlan_dev = vlan_group_get_device(grp, vlan_id);
 
-	if (!skb->dev)
+	if (vlan_dev)
+		skb->dev = vlan_dev;
+	else if (vlan_id)
 		goto drop;
 
 	for (p = napi->gro_list; p; p = p->next) {
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 7cb285f..3d59c9b 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -142,6 +142,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 {
 	struct vlan_hdr *vhdr;
 	struct vlan_rx_stats *rx_stats;
+	struct net_device *vlan_dev;
 	u16 vlan_id;
 	u16 vlan_tci;
 
@@ -157,55 +158,71 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	vlan_id = vlan_tci & VLAN_VID_MASK;
 
 	rcu_read_lock();
-	skb->dev = __find_vlan_dev(dev, vlan_id);
-	if (!skb->dev) {
-		pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
-			 __func__, vlan_id, dev->name);
-		goto err_unlock;
-	}
-
-	rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
-			       smp_processor_id());
-	u64_stats_update_begin(&rx_stats->syncp);
-	rx_stats->rx_packets++;
-	rx_stats->rx_bytes += skb->len;
-
-	skb_pull_rcsum(skb, VLAN_HLEN);
-
-	skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);
+	vlan_dev = __find_vlan_dev(dev, vlan_id);
 
-	pr_debug("%s: priority: %u for TCI: %hu\n",
-		 __func__, skb->priority, vlan_tci);
-
-	switch (skb->pkt_type) {
-	case PACKET_BROADCAST: /* Yeah, stats collect these together.. */
-		/* stats->broadcast ++; // no such counter :-( */
-		break;
-
-	case PACKET_MULTICAST:
-		rx_stats->rx_multicast++;
-		break;
+	/* If the VLAN device is defined, we use it.
+	 * If not, and the VID is 0, it is a 802.1p packet (not
+	 * really a VLAN), so we will just netif_rx it later to the
+	 * original interface, but with the skb->proto set to the
+	 * wrapped proto: we do nothing here.
+	 */
 
-	case PACKET_OTHERHOST:
-		/* Our lower layer thinks this is not local, let's make sure.
-		 * This allows the VLAN to have a different MAC than the
-		 * underlying device, and still route correctly.
-		 */
-		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
-					skb->dev->dev_addr))
-			skb->pkt_type = PACKET_HOST;
-		break;
-	default:
-		break;
+	if (!vlan_dev) {
+		if (vlan_id) {
+			pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
+				 __func__, vlan_id, dev->name);
+			goto err_unlock;
+		}
+		rx_stats = NULL;
+	} else {
+		skb->dev = vlan_dev;
+
+		rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
+					smp_processor_id());
+		u64_stats_update_begin(&rx_stats->syncp);
+		rx_stats->rx_packets++;
+		rx_stats->rx_bytes += skb->len;
+
+		skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);
+
+		pr_debug("%s: priority: %u for TCI: %hu\n",
+			 __func__, skb->priority, vlan_tci);
+
+		switch (skb->pkt_type) {
+		case PACKET_BROADCAST:
+			/* Yeah, stats collect these together.. */
+			/* stats->broadcast ++; // no such counter :-( */
+			break;
+
+		case PACKET_MULTICAST:
+			rx_stats->rx_multicast++;
+			break;
+
+		case PACKET_OTHERHOST:
+			/* Our lower layer thinks this is not local, let's make
+			 * sure.
+			 * This allows the VLAN to have a different MAC than the
+			 * underlying device, and still route correctly.
+			 */
+			if (!compare_ether_addr(eth_hdr(skb)->h_dest,
+						skb->dev->dev_addr))
+				skb->pkt_type = PACKET_HOST;
+			break;
+		default:
+			break;
+		}
+		u64_stats_update_end(&rx_stats->syncp);
 	}
-	u64_stats_update_end(&rx_stats->syncp);
 
+	skb_pull_rcsum(skb, VLAN_HLEN);
 	vlan_set_encap_proto(skb, vhdr);
 
-	skb = vlan_check_reorder_header(skb);
-	if (!skb) {
-		rx_stats->rx_errors++;
-		goto err_unlock;
+	if (vlan_dev) {
+		skb = vlan_check_reorder_header(skb);
+		if (!skb) {
+			rx_stats->rx_errors++;
+			goto err_unlock;
+		}
 	}
 
 	netif_rx(skb);


^ permalink raw reply related

* Re: [PATCH 1/2] Remove REDWOOD_[456] config options and conditional code
From: Artem Bityutskiy @ 2010-07-18 16:52 UTC (permalink / raw)
  To: Josh Boyer
  Cc: Christian Dietrich, Milton Miller, Matt Porter,
	Benjamin Herrenschmidt, Paul Mackerras, Solomon Peachy,
	David Woodhouse, Mike Frysinger, Jiri Kosina, Artem Bityutskiy,
	Alexander Kurz, David S. Miller, Randy Dunlap, John Linn,
	Florian Fainelli, Nicolas Pitre, Joe Perches, Ladislav Michl,
	David Brown, linuxppc-dev, linux-kernel, linux-mtd, netdev,
	vamos-dev
In-Reply-To: <20100716142055.GA11736@zod.rchland.ibm.com>

On Fri, 2010-07-16 at 10:20 -0400, Josh Boyer wrote:
> On Fri, Jul 16, 2010 at 02:29:02PM +0200, Christian Dietrich wrote:
> >The config options for REDWOOD_[456] were commented out in the powerpc
> >Kconfig. The ifdefs referencing this options therefore are dead and all
> >references to this can be removed (Also dependencies in other KConfig
> >files).
> >
> >Signed-off-by: Christian Dietrich <qy03fugy@stud.informatik.uni-erlangen.de>
> >Signed-off-by: Christoph Egger <siccegge@cs.fau.de>
> 
> This seems fine with me.
> 
> The only question is which tree it coms through.  I'm happy to take it
> in via mine if the netdev and MTD people are fine with that.  Otherwise,
> my ack is below.
> 
> Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>

You know how slow MTD people may be sometimes, so I'd suggest you to
merge this via whatever tree. David is in CC, he'll complain if he is
unhappy, I think.

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)


^ permalink raw reply

* Re: [PATCH] LSM: Add post recvmsg() hook.
From: David Miller @ 2010-07-18 21:25 UTC (permalink / raw)
  To: penguin-kernel
  Cc: eric.dumazet, kuznet, pekkas, jmorris, yoshfuji, kaber,
	paul.moore, netdev, linux-security-module
In-Reply-To: <201007181949.IFC00070.OMHQVSFOLJFFOt@I-love.SAKURA.ne.jp>

From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Sun, 18 Jul 2010 19:49:11 +0900

> Eric Dumazet wrote:
>> I read this patch and could not find out if an SNMP counter was
>> increased in the case a frame was not delivered but dropped in kernel
>> land.
> 
> UDP_MIB_INDATAGRAMS and UDP_MIB_INERRORS will not be increased
> if dropped by security_socket_post_recvmsg()'s decision.
> Should we increment UDP_MIB_INDATAGRAMS and/or UDP_MIB_INERRORS?

This decision should be guided by what we do for in the case
of the other existing security hooks.

I don't think it makes any sense to make the post recvmsg() hook
behave any differently from the existing hooks in this regard.

^ permalink raw reply

* Re: [PATCH v2 1/2] bnx2: allocate with GFP_KERNEL flag on RX path init
From: David Miller @ 2010-07-18 21:43 UTC (permalink / raw)
  To: mchan; +Cc: sgruszka, netdev
In-Reply-To: <1279315478.18129.41.camel@nseg_linux_HP1.broadcom.com>

From: "Michael Chan" <mchan@broadcom.com>
Date: Fri, 16 Jul 2010 14:24:38 -0700

> 
> On Fri, 2010-07-16 at 01:55 -0700, Stanislaw Gruszka wrote:
>> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> 
> Acked-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/2] bnx2: use device model DMA API
From: David Miller @ 2010-07-18 21:43 UTC (permalink / raw)
  To: mchan; +Cc: sgruszka, netdev
In-Reply-To: <1279315759.18129.43.camel@nseg_linux_HP1.broadcom.com>

From: "Michael Chan" <mchan@broadcom.com>
Date: Fri, 16 Jul 2010 14:29:19 -0700

> 
> On Thu, 2010-07-15 at 07:25 -0700, Stanislaw Gruszka wrote:
>> Use DMA API as PCI equivalents will be deprecated. This change also allow
>> to allocate with GFP_KERNEL in some places.
>> 
>> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> 
> Acked-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2.6.35-rc1] net-next: vmxnet3 fixes [3/5] Initialize link state at probe time
From: David Miller @ 2010-07-18 21:49 UTC (permalink / raw)
  To: sbhatewara; +Cc: netdev, linux-kernel, pv-drivers
In-Reply-To: <alpine.LRH.2.00.1007160050030.12503@localhost.localdomain>

From: Shreyas Bhatewara <sbhatewara@vmware.com>
Date: Fri, 16 Jul 2010 00:51:14 -0700 (PDT)

> Initialize vmxnet3 link state at probe time
> 
> This change initializes the state of link at the time when driver is
> loaded. The ethtool output for 'link detected' and 'link speed'
> is thus valid even before the interface is brought up.
> 
> Signed-off-by: Shreyas Bhatewara <sbhatewara@vmware.com>

Applied.

I'm still (patiently) waiting for the formal resubmission of patch #4
so I can also then apply patch #5.  Please post it at your next
possible convenience.

Thanks.

^ permalink raw reply

* Re: Badness with the kernel version 2.6.35-rc1-git1 running on P6 box
From: David Miller @ 2010-07-18 21:51 UTC (permalink / raw)
  To: eric.dumazet
  Cc: dipraksh, linux-kernel, linuxppc-dev, sachinp, benh, netdev,
	ossthema
In-Reply-To: <1279282842.2549.16.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 16 Jul 2010 14:20:42 +0200

> Le vendredi 16 juillet 2010 à 11:56 +0200, Eric Dumazet a écrit :
> 
>> [PATCH] ehea: ehea_get_stats() should use GFP_KERNEL
>> 
>> ehea_get_stats() is called in process context and should use GFP_KERNEL
>> allocation instead of GFP_ATOMIC.
>> 
>> Clearing stats at beginning of ehea_get_stats() is racy in case of
>> concurrent stat readers.
>> 
>> get_stats() can also use netdev net_device_stats, instead of a private
>> copy.
>> 
>> Reported-by: divya <dipraksh@linux.vnet.ibm.com>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> ---
>>  drivers/net/ehea/ehea.h      |    1 -
>>  drivers/net/ehea/ehea_main.c |    6 ++----
>>  2 files changed, 2 insertions(+), 5 deletions(-)
>> 
>> 
> 
> Hmm, net-next-2.6 contains following patch :

If people think ehea usage is ubiquitous enough to deserve a backport
of this to net-2.6, fine.  But personally I don't think it's worth it.

Can someone close the kernel bugzilla 16406 created for this bug?  This
patch we have already obviously would fix this issue.

^ permalink raw reply

* Re: [PATCH NEXT 1/1] qlcnic: fix pci resource leak
From: David Miller @ 2010-07-18 21:52 UTC (permalink / raw)
  To: amit.salecha; +Cc: netdev, ameen.rahman
In-Reply-To: <1279352378-22692-1-git-send-email-amit.salecha@qlogic.com>

From: amit.salecha@qlogic.com
Date: Sat, 17 Jul 2010 00:39:38 -0700

> From: Amit Kumar Salecha <amit.salecha@qlogic.com>
> 
> pci_get_domain_bus_and_slot: caller must decrement the
> reference count by calling pci_dev_put().
> 
> Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] IPv6: fix CoA check in RH2 input handler (mip6_rthdr_input())
From: David Miller @ 2010-07-18 22:05 UTC (permalink / raw)
  To: arno; +Cc: yoshfuji, netdev
In-Reply-To: <87aapr7lu3.fsf@small.ssi.corp>

From: arno@natisbad.org (Arnaud Ebalard)
Date: Fri, 16 Jul 2010 12:38:44 +0200

> The input handler for Type 2 Routing Header (mip6_rthdr_input())
> checks if the CoA in the packet matches the CoA in the XFRM state.
> 
> Current check is buggy: it compares the adddress in the Type 2
> Routing Header, i.e. the HoA, against the expected CoA in the state.
> The comparison should be made against the address in the destination
> field of the IPv6 header.
> 
> The bug remained unnoticed because the main (and possibly only current)
> user of the code (UMIP MIPv6 Daemon) initializes the XFRM state with the
> unspecified address, i.e. explicitly allows everything.
> 
> Yoshifuji-san, can you ack that one?
> 
> Signed-off-by: Arnaud Ebalard <arno@natisbad.org>

I've reviewed this and it definitely looks correct to me.

Applied, thanks Arnaud.

^ permalink raw reply

* Re: [PATCH 5/5] net: dccp: fix sign bug
From: David Miller @ 2010-07-18 22:07 UTC (permalink / raw)
  To: segooon; +Cc: kernel-janitors, acme, gerrit, dccp, netdev
In-Reply-To: <1279380060-15394-1-git-send-email-segooon@gmail.com>

From: Kulikov Vasiliy <segooon@gmail.com>
Date: Sat, 17 Jul 2010 19:21:00 +0400

> 'gap' is unsigned, so this code is wrong:
> 
>     gap = -new_head;
>     ...
>     if (gap > 0) { ... }
> 
> Make 'gap' signed.
> 
> 
> The semantic patch that finds this problem (many false-positive results):
> (http://coccinelle.lip6.fr/)
...
> Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>

Applied, thanks.

^ permalink raw reply

* Re: [patch] arcnet: fix signed bug in probe function
From: David Miller @ 2010-07-18 22:07 UTC (permalink / raw)
  To: error27; +Cc: netdev, kernel-janitors
In-Reply-To: <20100717172127.GI17585@bicker>

From: Dan Carpenter <error27@gmail.com>
Date: Sat, 17 Jul 2010 19:21:28 +0200

> probe_irq_off() returns the first irq found or if two irqs are found
> then it returns the negative of the first irq found.  We can cast
> dev->irq to an int so that the test for negative values works.
> 
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH] Remove MAX_SOCK_ADDR constant
From: David Miller @ 2010-07-18 22:29 UTC (permalink / raw)
  To: penguin-kernel; +Cc: yoshfuji, netdev
In-Reply-To: <201007172138.GJF90644.VFOSFFMOLJHtQO@I-love.SAKURA.ne.jp>

From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Sat, 17 Jul 2010 21:38:05 +0900

> MAX_SOCK_ADDR is no longer used because commit 230b1839 "net: Use standard
> structures for generic socket address structures." replaced
> "char address[MAX_SOCK_ADDR];" with "struct sockaddr_storage address;".
> 
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)
From: David Miller @ 2010-07-18 22:39 UTC (permalink / raw)
  To: pedro.netdev; +Cc: netdev, kaber, bhutchings, eric.dumazet
In-Reply-To: <957a5becb6e742b6dc3255b68bef3ba8@dondevamos.com>

From: Pedro Garcia <pedro.netdev@dondevamos.com>
Date: Sun, 18 Jul 2010 18:43:25 +0200

> - Without the 8021q module loaded in the kernel, all 802.1p packets 
> (VLAN 0 but QoS tagging) are silently discarded (as expected, as 
> the protocol is not loaded).
>  
> - Without this patch in 8021q module, these packets are forwarded to 
> the module, but they are discarded also if VLAN 0 is not configured,
> which should not be the default behaviour, as VLAN 0 is not really
> a VLANed packet but a 802.1p packet. Defining VLAN 0 makes it almost
> impossible to communicate with mixed 802.1p and non 802.1p devices on
> the same network due to arp table issues.
> 
> - Changed logic to skip vlan specific code in vlan_skb_recv if VLAN 
> is 0 and we have not defined a VLAN with ID 0, but we accept the 
> packet with the encapsulated proto and pass it later to netif_rx.
> 
> - In the vlan device event handler, added some logic to add VLAN 0 
> to HW filter in devices that support it (this prevented any traffic
> in VLAN 0 to reach the stack in e1000e with HW filter under 2.6.35,
> and probably also with other HW filtered cards, so we fix it here).
> 
> - In the vlan unregister logic, prevent the elimination of VLAN 0 
> in devices with HW filter.
> 
> - The default behaviour is to ignore the VLAN 0 tagging and accept
> the packet as if it was not tagged, but we can still define a 
> VLAN 0 if desired (so it is backwards compatible).
> 
> Signed-off-by: Pedro Garcia <pedro.netdev@dondevamos.com>

Applied, thanks Pedro.

^ permalink raw reply


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