Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  [TOKENRING]: rif_timer not initialized properly
  [NETFILTER]: bridge: fix double POST_ROUTING invocation
  [NETFILTER]: xt_helper: Do not bypass RCU
  [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit
  [MACVLAN]: Prevent nesting macvlan devices
  [VLAN]: nested VLAN: fix lockdep's recursive locking warning
  [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache
  [BLUETOOTH]: Always send explicit hci_ll wake-up acks.
  [BLUETOOTH]: rfcomm tty BUG_ON() code fix
  [AX25] af_ax25: Possible circular locking.
  [AX25]: Kill user triggable printks.
  [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
  [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms
  [NIU]: Support for Marvell PHY
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 8c3e62a1..b91d45a 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -204,6 +204,19 @@
 	spin_lock_irqsave(&ll->hcill_lock, flags);
 
 	switch (ll->hcill_state) {
+	case HCILL_ASLEEP_TO_AWAKE:
+		/*
+		 * This state means that both the host and the BRF chip
+		 * have simultaneously sent a wake-up-indication packet.
+		 * Traditionaly, in this case, receiving a wake-up-indication
+		 * was enough and an additional wake-up-ack wasn't needed.
+		 * This has changed with the BRF6350, which does require an
+		 * explicit wake-up-ack. Other BRF versions, which do not
+		 * require an explicit ack here, do accept it, thus it is
+		 * perfectly safe to always send one.
+		 */
+		BT_DBG("dual wake-up-indication");
+		/* deliberate fall-through - do not add break */
 	case HCILL_ASLEEP:
 		/* acknowledge device wake up */
 		if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
@@ -211,16 +224,8 @@
 			goto out;
 		}
 		break;
-	case HCILL_ASLEEP_TO_AWAKE:
-		/*
-		 * this state means that a wake-up-indication
-		 * is already on its way to the device,
-		 * and will serve as the required wake-up-ack
-		 */
-		BT_DBG("dual wake-up-indication");
-		break;
 	default:
-		/* any other state are illegal */
+		/* any other state is illegal */
 		BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
 		break;
 	}
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 2e4bcd5..e8dc2f4 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -384,6 +384,13 @@
 	if (lowerdev == NULL)
 		return -ENODEV;
 
+	/* Don't allow macvlans on top of other macvlans - its not really
+	 * wrong, but lockdep can't handle it and its not useful for anything
+	 * you couldn't do directly on top of the real device.
+	 */
+	if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops)
+		return -ENODEV;
+
 	if (!tb[IFLA_MTU])
 		dev->mtu = lowerdev->mtu;
 	else if (dev->mtu > lowerdev->mtu)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 9a0c6d3..3bbcea1 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -801,22 +801,90 @@
 	return 0;
 }
 
-static int xcvr_init_10g(struct niu *np)
+static int mrvl88x2011_act_led(struct niu *np, int val)
+{
+	int	err;
+
+	err  = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+		MRVL88X2011_LED_8_TO_11_CTL);
+	if (err < 0)
+		return err;
+
+	err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
+	err |=  MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
+
+	return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+			  MRVL88X2011_LED_8_TO_11_CTL, err);
+}
+
+static int mrvl88x2011_led_blink_rate(struct niu *np, int rate)
+{
+	int	err;
+
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+			MRVL88X2011_LED_BLINK_CTL);
+	if (err >= 0) {
+		err &= ~MRVL88X2011_LED_BLKRATE_MASK;
+		err |= (rate << 4);
+
+		err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+				 MRVL88X2011_LED_BLINK_CTL, err);
+	}
+
+	return err;
+}
+
+static int xcvr_init_10g_mrvl88x2011(struct niu *np)
+{
+	int	err;
+
+	/* Set LED functions */
+	err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
+	if (err)
+		return err;
+
+	/* led activity */
+	err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF);
+	if (err)
+		return err;
+
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+			MRVL88X2011_GENERAL_CTL);
+	if (err < 0)
+		return err;
+
+	err |= MRVL88X2011_ENA_XFPREFCLK;
+
+	err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+			 MRVL88X2011_GENERAL_CTL, err);
+	if (err < 0)
+		return err;
+
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+			MRVL88X2011_PMA_PMD_CTL_1);
+	if (err < 0)
+		return err;
+
+	if (np->link_config.loopback_mode == LOOPBACK_MAC)
+		err |= MRVL88X2011_LOOPBACK;
+	else
+		err &= ~MRVL88X2011_LOOPBACK;
+
+	err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+			 MRVL88X2011_PMA_PMD_CTL_1, err);
+	if (err < 0)
+		return err;
+
+	/* Enable PMD  */
+	return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+			  MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
+}
+
+static int xcvr_init_10g_bcm8704(struct niu *np)
 {
 	struct niu_link_config *lp = &np->link_config;
 	u16 analog_stat0, tx_alarm_status;
 	int err;
-	u64 val;
-
-	val = nr64_mac(XMAC_CONFIG);
-	val &= ~XMAC_CONFIG_LED_POLARITY;
-	val |= XMAC_CONFIG_FORCE_LED_ON;
-	nw64_mac(XMAC_CONFIG, val);
-
-	/* XXX shared resource, lock parent XXX */
-	val = nr64(MIF_CONFIG);
-	val |= MIF_CONFIG_INDIRECT_MODE;
-	nw64(MIF_CONFIG, val);
 
 	err = bcm8704_reset(np);
 	if (err)
@@ -896,6 +964,38 @@
 	return 0;
 }
 
+static int xcvr_init_10g(struct niu *np)
+{
+	int phy_id, err;
+	u64 val;
+
+	val = nr64_mac(XMAC_CONFIG);
+	val &= ~XMAC_CONFIG_LED_POLARITY;
+	val |= XMAC_CONFIG_FORCE_LED_ON;
+	nw64_mac(XMAC_CONFIG, val);
+
+	/* XXX shared resource, lock parent XXX */
+	val = nr64(MIF_CONFIG);
+	val |= MIF_CONFIG_INDIRECT_MODE;
+	nw64(MIF_CONFIG, val);
+
+	phy_id = phy_decode(np->parent->port_phy, np->port);
+	phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+	/* handle different phy types */
+	switch (phy_id & NIU_PHY_ID_MASK) {
+	case NIU_PHY_ID_MRVL88X2011:
+		err = xcvr_init_10g_mrvl88x2011(np);
+		break;
+
+	default: /* bcom 8704 */
+		err = xcvr_init_10g_bcm8704(np);
+		break;
+	}
+
+	return 0;
+}
+
 static int mii_reset(struct niu *np)
 {
 	int limit, err;
@@ -1082,19 +1182,68 @@
 	return 0;
 }
 
-static int link_status_10g(struct niu *np, int *link_up_p)
+static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
 {
-	unsigned long flags;
-	int err, link_up;
+	int err, link_up, pma_status, pcs_status;
 
 	link_up = 0;
 
-	spin_lock_irqsave(&np->lock, flags);
-
-	err = -EINVAL;
-	if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+			MRVL88X2011_10G_PMD_STATUS_2);
+	if (err < 0)
 		goto out;
 
+	/* Check PMA/PMD Register: 1.0001.2 == 1 */
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+			MRVL88X2011_PMA_PMD_STATUS_1);
+	if (err < 0)
+		goto out;
+
+	pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+        /* Check PMC Register : 3.0001.2 == 1: read twice */
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+			MRVL88X2011_PMA_PMD_STATUS_1);
+	if (err < 0)
+		goto out;
+
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+			MRVL88X2011_PMA_PMD_STATUS_1);
+	if (err < 0)
+		goto out;
+
+	pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+        /* Check XGXS Register : 4.0018.[0-3,12] */
+	err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
+			MRVL88X2011_10G_XGXS_LANE_STAT);
+	if (err < 0)
+		goto out;
+
+	if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
+		    PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
+		    PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC |
+		    0x800))
+		link_up = (pma_status && pcs_status) ? 1 : 0;
+
+	np->link_config.active_speed = SPEED_10000;
+	np->link_config.active_duplex = DUPLEX_FULL;
+	err = 0;
+out:
+	mrvl88x2011_act_led(np, (link_up ?
+				 MRVL88X2011_LED_CTL_PCS_ACT :
+				 MRVL88X2011_LED_CTL_OFF));
+
+	*link_up_p = link_up;
+	return err;
+}
+
+static int link_status_10g_bcom(struct niu *np, int *link_up_p)
+{
+	int err, link_up;
+
+	link_up = 0;
+
 	err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
 			BCM8704_PMD_RCV_SIGDET);
 	if (err < 0)
@@ -1134,9 +1283,37 @@
 	err = 0;
 
 out:
+	*link_up_p = link_up;
+	return err;
+}
+
+static int link_status_10g(struct niu *np, int *link_up_p)
+{
+	unsigned long flags;
+	int err = -EINVAL;
+
+	spin_lock_irqsave(&np->lock, flags);
+
+	if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
+		int phy_id;
+
+		phy_id = phy_decode(np->parent->port_phy, np->port);
+		phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+		/* handle different phy types */
+		switch (phy_id & NIU_PHY_ID_MASK) {
+		case NIU_PHY_ID_MRVL88X2011:
+			err = link_status_10g_mrvl(np, link_up_p);
+			break;
+
+		default: /* bcom 8704 */
+			err = link_status_10g_bcom(np, link_up_p);
+			break;
+		}
+	}
+
 	spin_unlock_irqrestore(&np->lock, flags);
 
-	*link_up_p = link_up;
 	return err;
 }
 
@@ -6297,7 +6474,8 @@
 	if (dev_id_1 < 0 || dev_id_2 < 0)
 		return 0;
 	if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
-		if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
+		if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
+		    ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
 			return 0;
 	} else {
 		if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 10e3f11..0e8626a 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -2538,6 +2538,39 @@
 #define NIU_PHY_ID_MASK			0xfffff0f0
 #define NIU_PHY_ID_BCM8704		0x00206030
 #define NIU_PHY_ID_BCM5464R		0x002060b0
+#define NIU_PHY_ID_MRVL88X2011		0x01410020
+
+/* MRVL88X2011 register addresses */
+#define MRVL88X2011_USER_DEV1_ADDR	1
+#define MRVL88X2011_USER_DEV2_ADDR	2
+#define MRVL88X2011_USER_DEV3_ADDR	3
+#define MRVL88X2011_USER_DEV4_ADDR	4
+#define MRVL88X2011_PMA_PMD_CTL_1	0x0000
+#define MRVL88X2011_PMA_PMD_STATUS_1	0x0001
+#define MRVL88X2011_10G_PMD_STATUS_2	0x0008
+#define MRVL88X2011_10G_PMD_TX_DIS	0x0009
+#define MRVL88X2011_10G_XGXS_LANE_STAT	0x0018
+#define MRVL88X2011_GENERAL_CTL		0x8300
+#define MRVL88X2011_LED_BLINK_CTL	0x8303
+#define MRVL88X2011_LED_8_TO_11_CTL	0x8306
+
+/* MRVL88X2011 register control */
+#define MRVL88X2011_ENA_XFPREFCLK	0x0001
+#define MRVL88X2011_ENA_PMDTX		0x0000
+#define MRVL88X2011_LOOPBACK            0x1
+#define MRVL88X2011_LED_ACT		0x1
+#define MRVL88X2011_LNK_STATUS_OK	0x4
+#define MRVL88X2011_LED_BLKRATE_MASK	0x70
+#define MRVL88X2011_LED_BLKRATE_034MS	0x0
+#define MRVL88X2011_LED_BLKRATE_067MS	0x1
+#define MRVL88X2011_LED_BLKRATE_134MS	0x2
+#define MRVL88X2011_LED_BLKRATE_269MS	0x3
+#define MRVL88X2011_LED_BLKRATE_538MS	0x4
+#define MRVL88X2011_LED_CTL_OFF		0x0
+#define MRVL88X2011_LED_CTL_PCS_ACT	0x5
+#define MRVL88X2011_LED_CTL_MASK	0x7
+#define MRVL88X2011_LED(n,v)		((v)<<((n)*4))
+#define MRVL88X2011_LED_STAT(n,v)	((v)>>((n)*4))
 
 #define BCM8704_PMA_PMD_DEV_ADDR	1
 #define BCM8704_PCS_DEV_ADDR		2
diff --git a/net/802/tr.c b/net/802/tr.c
index a2bd0f2..1e115e5 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -642,7 +642,7 @@
 static int __init rif_init(void)
 {
 	init_timer(&rif_timer);
-	rif_timer.expires  = sysctl_tr_rif_timeout;
+	rif_timer.expires  = jiffies + sysctl_tr_rif_timeout;
 	rif_timer.data     = 0L;
 	rif_timer.function = rif_check_expire;
 	add_timer(&rif_timer);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 4add9bd..032bf44 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -323,6 +323,7 @@
 static int vlan_dev_init(struct net_device *dev)
 {
 	struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+	int subclass = 0;
 
 	/* IFF_BROADCAST|IFF_MULTICAST; ??? */
 	dev->flags  = real_dev->flags & ~IFF_UP;
@@ -349,7 +350,11 @@
 		dev->hard_start_xmit = vlan_dev_hard_start_xmit;
 	}
 
-	lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
+	if (real_dev->priv_flags & IFF_802_1Q_VLAN)
+		subclass = 1;
+
+	lockdep_set_class_and_subclass(&dev->_xmit_lock,
+				&vlan_netdev_xmit_lock_key, subclass);
 	return 0;
 }
 
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 8378afd..b4725ff 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -87,10 +87,22 @@
 		return;
 
 	spin_lock_bh(&ax25_list_lock);
+again:
 	ax25_for_each(s, node, &ax25_list) {
 		if (s->ax25_dev == ax25_dev) {
 			s->ax25_dev = NULL;
+			spin_unlock_bh(&ax25_list_lock);
 			ax25_disconnect(s, ENETUNREACH);
+			spin_lock_bh(&ax25_list_lock);
+
+			/* The entry could have been deleted from the
+			 * list meanwhile and thus the next pointer is
+			 * no longer valid.  Play it safe and restart
+			 * the scan.  Forward progress is ensured
+			 * because we set s->ax25_dev to NULL and we
+			 * are never passed a NULL 'dev' argument.
+			 */
+			goto again;
 		}
 	}
 	spin_unlock_bh(&ax25_list_lock);
@@ -1109,21 +1121,19 @@
 	 * some sanity checks. code further down depends on this
 	 */
 
-	if (addr_len == sizeof(struct sockaddr_ax25)) {
-		/* support for this will go away in early 2.5.x */
-		printk(KERN_WARNING "ax25_connect(): %s uses obsolete socket structure\n",
-			current->comm);
-	}
-	else if (addr_len != sizeof(struct full_sockaddr_ax25)) {
-		/* support for old structure may go away some time */
+	if (addr_len == sizeof(struct sockaddr_ax25))
+		/* support for this will go away in early 2.5.x
+		 * ax25_connect(): uses obsolete socket structure
+		 */
+		;
+	else if (addr_len != sizeof(struct full_sockaddr_ax25))
+		/* support for old structure may go away some time
+		 * ax25_connect(): uses old (6 digipeater) socket structure.
+		 */
 		if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
-		    (addr_len > sizeof(struct full_sockaddr_ax25))) {
+		    (addr_len > sizeof(struct full_sockaddr_ax25)))
 			return -EINVAL;
-		}
 
-		printk(KERN_WARNING "ax25_connect(): %s uses old (6 digipeater) socket structure.\n",
-			current->comm);
-	}
 
 	if (fsa->fsa_ax25.sax25_family != AF_AX25)
 		return -EINVAL;
@@ -1467,21 +1477,20 @@
 			goto out;
 		}
 
-		if (addr_len == sizeof(struct sockaddr_ax25)) {
-			printk(KERN_WARNING "ax25_sendmsg(): %s uses obsolete socket structure\n",
-				current->comm);
-		}
-		else if (addr_len != sizeof(struct full_sockaddr_ax25)) {
-			/* support for old structure may go away some time */
+		if (addr_len == sizeof(struct sockaddr_ax25))
+			/* ax25_sendmsg(): uses obsolete socket structure */
+			;
+		else if (addr_len != sizeof(struct full_sockaddr_ax25))
+			/* support for old structure may go away some time
+			 * ax25_sendmsg(): uses old (6 digipeater)
+			 * socket structure.
+			 */
 			if ((addr_len < sizeof(struct sockaddr_ax25) + sizeof(ax25_address) * 6) ||
 			    (addr_len > sizeof(struct full_sockaddr_ax25))) {
 				err = -EINVAL;
 				goto out;
 			}
 
-			printk(KERN_WARNING "ax25_sendmsg(): %s uses old (6 digipeater) socket structure.\n",
-				current->comm);
-		}
 
 		if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
 			int ct           = 0;
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index e447651..a6a758d 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -95,9 +95,10 @@
 
 	BT_DBG("dev %p dlc %p", dev, dlc);
 
-	write_lock_bh(&rfcomm_dev_lock);
-	list_del_init(&dev->list);
-	write_unlock_bh(&rfcomm_dev_lock);
+	/* Refcount should only hit zero when called from rfcomm_dev_del()
+	   which will have taken us off the list. Everything else are
+	   refcounting bugs. */
+	BUG_ON(!list_empty(&dev->list));
 
 	rfcomm_dlc_lock(dlc);
 	/* Detach DLC if it's owned by this dev */
@@ -109,11 +110,6 @@
 
 	tty_unregister_device(rfcomm_tty_driver, dev->id);
 
-	/* Refcount should only hit zero when called from rfcomm_dev_del()
-	   which will have taken us off the list. Everything else are
-	   refcounting bugs. */
-	BUG_ON(!list_empty(&dev->list));
-
 	kfree(dev);
 
 	/* It's safe to call module_put() here because socket still
@@ -313,7 +309,15 @@
 {
 	BT_DBG("dev %p", dev);
 
-	set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+	if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
+		BUG_ON(1);
+	else
+		set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
+
+	write_lock_bh(&rfcomm_dev_lock);
+	list_del_init(&dev->list);
+	write_unlock_bh(&rfcomm_dev_lock);
+
 	rfcomm_dev_put(dev);
 }
 
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index c1757c7..5d8b939 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -247,8 +247,9 @@
  * Let us first consider the case that ip_route_input() succeeds:
  *
  * If skb->dst->dev equals the logical bridge device the packet
- * came in on, we can consider this bridging. We then call
- * skb->dst->output() which will make the packet enter br_nf_local_out()
+ * came in on, we can consider this bridging. The packet is passed
+ * through the neighbour output function to build a new destination
+ * MAC address, which will make the packet enter br_nf_local_out()
  * not much later. In that function it is assured that the iptables
  * FORWARD chain is traversed for the packet.
  *
@@ -285,12 +286,17 @@
 	skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
 
 	skb->dev = bridge_parent(skb->dev);
-	if (!skb->dev)
-		kfree_skb(skb);
-	else {
+	if (skb->dev) {
+		struct dst_entry *dst = skb->dst;
+
 		nf_bridge_pull_encap_header(skb);
-		skb->dst->output(skb);
+
+		if (dst->hh)
+			return neigh_hh_output(dst->hh, skb);
+		else if (dst->neighbour)
+			return dst->neighbour->output(skb);
 	}
+	kfree_skb(skb);
 	return 0;
 }
 
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 29b8ee4..cc8a2f1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1316,8 +1316,6 @@
 			*p = parms->next;
 			parms->dead = 1;
 			write_unlock_bh(&tbl->lock);
-			if (parms->dev)
-				dev_put(parms->dev);
 			call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
 			return;
 		}
@@ -1328,6 +1326,8 @@
 
 void neigh_parms_destroy(struct neigh_parms *parms)
 {
+	if (parms->dev)
+		dev_put(parms->dev);
 	kfree(parms);
 }
 
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 66663e5..0e10ff2 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1665,12 +1665,12 @@
 			break;
 		rcu_read_unlock_bh();
 	}
-	return rt;
+	return rcu_dereference(rt);
 }
 
 static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_route *rt)
 {
-	struct dn_rt_cache_iter_state *s = rcu_dereference(seq->private);
+	struct dn_rt_cache_iter_state *s = seq->private;
 
 	rt = rt->u.dst.dn_next;
 	while(!rt) {
@@ -1680,7 +1680,7 @@
 		rcu_read_lock_bh();
 		rt = dn_rt_hash_table[s->bucket].chain;
 	}
-	return rt;
+	return rcu_dereference(rt);
 }
 
 static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d337706..28484f3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -283,12 +283,12 @@
 			break;
 		rcu_read_unlock_bh();
 	}
-	return r;
+	return rcu_dereference(r);
 }
 
 static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
 {
-	struct rt_cache_iter_state *st = rcu_dereference(seq->private);
+	struct rt_cache_iter_state *st = seq->private;
 
 	r = r->u.dst.rt_next;
 	while (!r) {
@@ -298,7 +298,7 @@
 		rcu_read_lock_bh();
 		r = rt_hash_table[st->bucket].chain;
 	}
-	return r;
+	return rcu_dereference(r);
 }
 
 static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 34ba150..41df9a5 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -47,7 +47,7 @@
 			memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
 			eui64[3] = 0xff;
 			eui64[4] = 0xfe;
-			eui64[0] |= 0x02;
+			eui64[0] ^= 0x02;
 
 			i = 0;
 			while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 0a1f4c6..d842c4a 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -56,8 +56,8 @@
 	if (info->name[0] == '\0')
 		ret = !ret;
 	else
-		ret ^= !strncmp(master_help->helper->name, info->name,
-				strlen(master_help->helper->name));
+		ret ^= !strncmp(helper->name, info->name,
+				strlen(helper->name));
 	return ret;
 }