summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/802/tr.c2
-rw-r--r--net/8021q/vlan.c7
-rw-r--r--net/ax25/af_ax25.c51
-rw-r--r--net/bluetooth/rfcomm/tty.c22
-rw-r--r--net/bridge/br_netfilter.c18
-rw-r--r--net/core/neighbour.c4
-rw-r--r--net/decnet/dn_route.c6
-rw-r--r--net/ipv4/route.c6
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c2
-rw-r--r--net/netfilter/xt_helper.c4
10 files changed, 73 insertions, 49 deletions
diff --git a/net/802/tr.c b/net/802/tr.c
index a2bd0f2e3af..1e115e5beab 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -642,7 +642,7 @@ struct net_device *alloc_trdev(int sizeof_priv)
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 4add9bd4bc8..032bf44eca5 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -323,6 +323,7 @@ static const struct header_ops vlan_header_ops = {
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 @@ static int vlan_dev_init(struct net_device *dev)
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 8378afd54b3..b4725ff317c 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev)
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 @@ static int __must_check ax25_connect(struct socket *sock,
* 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 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
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 e447651a2db..a6a758dd1f7 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -95,9 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
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 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
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 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
{
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 c1757c79dfb..5d8b939eded 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -247,8 +247,9 @@ static void __br_dnat_complain(void)
* 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 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
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 29b8ee4e35d..cc8a2f190ac 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
*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_release(struct neigh_table *tbl, struct neigh_parms *parms)
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 66663e5d7ac..0e10ff21e29 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1665,12 +1665,12 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq)
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 @@ static struct dn_route *dn_rt_cache_get_next(struct seq_file *seq, struct dn_rou
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 d3377069ce0..28484f396b0 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -283,12 +283,12 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
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 @@ static struct rtable *rt_cache_get_next(struct seq_file *seq, struct rtable *r)
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 34ba150bfe5..41df9a578c7 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -47,7 +47,7 @@ match(const struct sk_buff *skb,
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 0a1f4c6bcde..d842c4a6d63 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -56,8 +56,8 @@ match(const struct sk_buff *skb,
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;
}