Commit 612166c7 authored by Linus Torvalds's avatar Linus Torvalds

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
parents f885b519 1b310fca
...@@ -204,6 +204,19 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) ...@@ -204,6 +204,19 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
spin_lock_irqsave(&ll->hcill_lock, flags); spin_lock_irqsave(&ll->hcill_lock, flags);
switch (ll->hcill_state) { 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: case HCILL_ASLEEP:
/* acknowledge device wake up */ /* acknowledge device wake up */
if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) { if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
...@@ -211,16 +224,8 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu) ...@@ -211,16 +224,8 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
goto out; goto out;
} }
break; 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: default:
/* any other state are illegal */ /* any other state is illegal */
BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state); BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
break; break;
} }
......
...@@ -384,6 +384,13 @@ static int macvlan_newlink(struct net_device *dev, ...@@ -384,6 +384,13 @@ static int macvlan_newlink(struct net_device *dev,
if (lowerdev == NULL) if (lowerdev == NULL)
return -ENODEV; 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]) if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu; dev->mtu = lowerdev->mtu;
else if (dev->mtu > lowerdev->mtu) else if (dev->mtu > lowerdev->mtu)
......
...@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np) ...@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np)
return 0; return 0;
} }
static int xcvr_init_10g(struct niu *np) static int mrvl88x2011_act_led(struct niu *np, int val)
{ {
struct niu_link_config *lp = &np->link_config;
u16 analog_stat0, tx_alarm_status;
int err; int err;
u64 val;
val = nr64_mac(XMAC_CONFIG); err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
val &= ~XMAC_CONFIG_LED_POLARITY; MRVL88X2011_LED_8_TO_11_CTL);
val |= XMAC_CONFIG_FORCE_LED_ON; if (err < 0)
nw64_mac(XMAC_CONFIG, val); return err;
/* XXX shared resource, lock parent XXX */ err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
val = nr64(MIF_CONFIG); err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
val |= MIF_CONFIG_INDIRECT_MODE;
nw64(MIF_CONFIG, 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;
err = bcm8704_reset(np); err = bcm8704_reset(np);
if (err) if (err)
...@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np) ...@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np)
return 0; 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) static int mii_reset(struct niu *np)
{ {
int limit, err; int limit, err;
...@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up) ...@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up)
return 0; 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, pma_status, pcs_status;
int err, link_up;
link_up = 0; link_up = 0;
spin_lock_irqsave(&np->lock, flags); err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
MRVL88X2011_10G_PMD_STATUS_2);
if (err < 0)
goto out;
err = -EINVAL; /* Check PMA/PMD Register: 1.0001.2 == 1 */
if (np->link_config.loopback_mode != LOOPBACK_DISABLED) 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; 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, err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET); BCM8704_PMD_RCV_SIGDET);
if (err < 0) if (err < 0)
...@@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p) ...@@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p)
err = 0; err = 0;
out: 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); spin_unlock_irqrestore(&np->lock, flags);
*link_up_p = link_up;
return err; return err;
} }
...@@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent, ...@@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent,
if (dev_id_1 < 0 || dev_id_2 < 0) if (dev_id_1 < 0 || dev_id_2 < 0)
return 0; return 0;
if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { 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; return 0;
} else { } else {
if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
......
...@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 { ...@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK 0xfffff0f0 #define NIU_PHY_ID_MASK 0xfffff0f0
#define NIU_PHY_ID_BCM8704 0x00206030 #define NIU_PHY_ID_BCM8704 0x00206030
#define NIU_PHY_ID_BCM5464R 0x002060b0 #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_PMA_PMD_DEV_ADDR 1
#define BCM8704_PCS_DEV_ADDR 2 #define BCM8704_PCS_DEV_ADDR 2
......
...@@ -642,7 +642,7 @@ struct net_device *alloc_trdev(int sizeof_priv) ...@@ -642,7 +642,7 @@ struct net_device *alloc_trdev(int sizeof_priv)
static int __init rif_init(void) static int __init rif_init(void)
{ {
init_timer(&rif_timer); 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.data = 0L;
rif_timer.function = rif_check_expire; rif_timer.function = rif_check_expire;
add_timer(&rif_timer); add_timer(&rif_timer);
......
...@@ -323,6 +323,7 @@ static const struct header_ops vlan_header_ops = { ...@@ -323,6 +323,7 @@ static const struct header_ops vlan_header_ops = {
static int vlan_dev_init(struct net_device *dev) static int vlan_dev_init(struct net_device *dev)
{ {
struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
int subclass = 0;
/* IFF_BROADCAST|IFF_MULTICAST; ??? */ /* IFF_BROADCAST|IFF_MULTICAST; ??? */
dev->flags = real_dev->flags & ~IFF_UP; dev->flags = real_dev->flags & ~IFF_UP;
...@@ -349,7 +350,11 @@ static int vlan_dev_init(struct net_device *dev) ...@@ -349,7 +350,11 @@ static int vlan_dev_init(struct net_device *dev)
dev->hard_start_xmit = vlan_dev_hard_start_xmit; 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; return 0;
} }
......
...@@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev) ...@@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev)
return; return;
spin_lock_bh(&ax25_list_lock); spin_lock_bh(&ax25_list_lock);
again:
ax25_for_each(s, node, &ax25_list) { ax25_for_each(s, node, &ax25_list) {
if (s->ax25_dev == ax25_dev) { if (s->ax25_dev == ax25_dev) {
s->ax25_dev = NULL; s->ax25_dev = NULL;
spin_unlock_bh(&ax25_list_lock);
ax25_disconnect(s, ENETUNREACH); 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); spin_unlock_bh(&ax25_list_lock);
...@@ -1109,21 +1121,19 @@ static int __must_check ax25_connect(struct socket *sock, ...@@ -1109,21 +1121,19 @@ static int __must_check ax25_connect(struct socket *sock,
* some sanity checks. code further down depends on this * some sanity checks. code further down depends on this
*/ */
if (addr_len == sizeof(struct sockaddr_ax25)) { if (addr_len == sizeof(struct sockaddr_ax25))
/* support for this will go away in early 2.5.x */ /* support for this will go away in early 2.5.x
printk(KERN_WARNING "ax25_connect(): %s uses obsolete socket structure\n", * ax25_connect(): uses obsolete socket structure
current->comm); */
} ;
else if (addr_len != sizeof(struct full_sockaddr_ax25)) { else if (addr_len != sizeof(struct full_sockaddr_ax25))
/* support for old structure may go away some time */ /* 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) || 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; 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) if (fsa->fsa_ax25.sax25_family != AF_AX25)
return -EINVAL; return -EINVAL;
...@@ -1467,21 +1477,20 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1467,21 +1477,20 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
goto out; goto out;
} }
if (addr_len == sizeof(struct sockaddr_ax25)) { if (addr_len == sizeof(struct sockaddr_ax25))
printk(KERN_WARNING "ax25_sendmsg(): %s uses obsolete socket structure\n", /* ax25_sendmsg(): uses obsolete socket structure */
current->comm); ;
} else if (addr_len != sizeof(struct full_sockaddr_ax25))
else if (addr_len != sizeof(struct full_sockaddr_ax25)) { /* support for old structure may go away some time
/* 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) || 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))) {
err = -EINVAL; err = -EINVAL;
goto out; 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) { if (addr_len > sizeof(struct sockaddr_ax25) && usax->sax25_ndigis != 0) {
int ct = 0; int ct = 0;
......
...@@ -95,9 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) ...@@ -95,9 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
BT_DBG("dev %p dlc %p", dev, dlc); BT_DBG("dev %p dlc %p", dev, dlc);
write_lock_bh(&rfcomm_dev_lock); /* Refcount should only hit zero when called from rfcomm_dev_del()
list_del_init(&dev->list); which will have taken us off the list. Everything else are
write_unlock_bh(&rfcomm_dev_lock); refcounting bugs. */
BUG_ON(!list_empty(&dev->list));
rfcomm_dlc_lock(dlc); rfcomm_dlc_lock(dlc);
/* Detach DLC if it's owned by this dev */ /* Detach DLC if it's owned by this dev */
...@@ -109,11 +110,6 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev) ...@@ -109,11 +110,6 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
tty_unregister_device(rfcomm_tty_driver, dev->id); 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); kfree(dev);
/* It's safe to call module_put() here because socket still /* It's safe to call module_put() here because socket still
...@@ -313,7 +309,15 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev) ...@@ -313,7 +309,15 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
{ {
BT_DBG("dev %p", dev); BT_DBG("dev %p", dev);
if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
BUG_ON(1);
else
set_bit(RFCOMM_TTY_RELEASED, &dev->flags); 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); rfcomm_dev_put(dev);
} }
......
...@@ -247,8 +247,9 @@ static void __br_dnat_complain(void) ...@@ -247,8 +247,9 @@ static void __br_dnat_complain(void)
* Let us first consider the case that ip_route_input() succeeds: * Let us first consider the case that ip_route_input() succeeds:
* *
* If skb->dst->dev equals the logical bridge device the packet * If skb->dst->dev equals the logical bridge device the packet
* came in on, we can consider this bridging. We then call * came in on, we can consider this bridging. The packet is passed
* skb->dst->output() which will make the packet enter br_nf_local_out() * 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 * not much later. In that function it is assured that the iptables
* FORWARD chain is traversed for the packet. * FORWARD chain is traversed for the packet.
* *
...@@ -285,12 +286,17 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) ...@@ -285,12 +286,17 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
skb->dev = bridge_parent(skb->dev); skb->dev = bridge_parent(skb->dev);
if (!skb->dev) if (skb->dev) {
kfree_skb(skb); struct dst_entry *dst = skb->dst;
else {
nf_bridge_pull_encap_header(skb); 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; return 0;
} }
......
...@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) ...@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
*p = parms->next; *p = parms->next;
parms->dead = 1; parms->dead = 1;
write_unlock_bh(&tbl->lock); write_unlock_bh(&tbl->lock);
if (parms->dev)
dev_put(parms->dev);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms); call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
return; return;
} }
...@@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms) ...@@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
void neigh_parms_destroy(struct neigh_parms *parms) void neigh_parms_destroy(struct neigh_parms *parms)
{ {
if (parms->dev)
dev_put(parms->dev);
kfree(parms); kfree(parms);
} }
......
...@@ -1665,12 +1665,12 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq) ...@@ -1665,12 +1665,12 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq)
break; break;
rcu_read_unlock_bh(); 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) 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; rt = rt->u.dst.dn_next;
while(!rt) { while(!rt) {
...@@ -1680,7 +1680,7 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou ...@@ -1680,7 +1680,7 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou
rcu_read_lock_bh(); rcu_read_lock_bh();
rt = dn_rt_hash_table[s->bucket].chain; 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) static void *dn_rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
......
...@@ -283,12 +283,12 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq) ...@@ -283,12 +283,12 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
break; break;
rcu_read_unlock_bh(); rcu_read_unlock_bh();
} }
return r; return rcu_dereference(r);
} }
static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *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; r = r->u.dst.rt_next;
while (!r) { while (!r) {
...@@ -298,7 +298,7 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r) ...@@ -298,7 +298,7 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
rcu_read_lock_bh(); rcu_read_lock_bh();
r = rt_hash_table[st->bucket].chain; 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) static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
......
...@@ -47,7 +47,7 @@ match(const struct sk_buff *skb, ...@@ -47,7 +47,7 @@ match(const struct sk_buff *skb,
memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3); memcpy(eui64 + 5, eth_hdr(skb)->h_source + 3, 3);
eui64[3] = 0xff; eui64[3] = 0xff;
eui64[4] = 0xfe; eui64[4] = 0xfe;
eui64[0] |= 0x02; eui64[0] ^= 0x02;
i = 0; i = 0;
while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i] while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
......
...@@ -56,8 +56,8 @@ match(const struct sk_buff *skb, ...@@ -56,8 +56,8 @@ match(const struct sk_buff *skb,
if (info->name[0] == '\0') if (info->name[0] == '\0')
ret = !ret; ret = !ret;
else else
ret ^= !strncmp(master_help->helper->name, info->name, ret ^= !strncmp(helper->name, info->name,
strlen(master_help->helper->name)); strlen(helper->name));
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment