Commit c5dd2733 authored by Linus Torvalds's avatar Linus Torvalds

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

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [TG3]: Add missing unlock in tg3_open() error path.
  [IPV6]: Fix address/interface handling in UDP and DCCP, according to the scoping architecture.
  [IRDA]: Lockdep fix.
  [BLUETOOTH]: Fix unaligned access in hci_send_to_sock.
  [XFRM]: nlmsg length not computed correctly in the presence of subpolicies
  [XFRM]: Sub-policies broke policy events
  [IGMP]: Fix IGMPV3_EXP() normalization bit shift value.
  [Bluetooth] Ignore L2CAP config requests on disconnect
  [Bluetooth] Always include MTU in L2CAP config responses
  [Bluetooth] Check if RFCOMM session is still attached to the TTY
  [Bluetooth] Handling pending connect attempts after inquiry
  [Bluetooth] Attach low-level connections to the Bluetooth bus
  [IPV6] IP6TUNNEL: Add missing nf_reset() on input path.
  [IPV6] IP6TUNNEL: Delete all tunnel device when unloading module.
  [IPV6] ROUTE: Do not enable router reachability probing in router mode.
  [IPV6] ROUTE: Prefer reachable nexthop only if the caller requests.
  [IPV6] ROUTE: Try to use router which is not known unreachable.
parents 6af6e1ef 12862086
...@@ -6979,8 +6979,10 @@ static int tg3_open(struct net_device *dev) ...@@ -6979,8 +6979,10 @@ static int tg3_open(struct net_device *dev)
tg3_full_lock(tp, 0); tg3_full_lock(tp, 0);
err = tg3_set_power_state(tp, PCI_D0); err = tg3_set_power_state(tp, PCI_D0);
if (err) if (err) {
tg3_full_unlock(tp);
return err; return err;
}
tg3_disable_ints(tp); tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
......
...@@ -191,7 +191,7 @@ struct ip_mc_list ...@@ -191,7 +191,7 @@ struct ip_mc_list
#define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value)) #define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
#define IGMPV3_EXP(thresh, nbmant, nbexp, value) \ #define IGMPV3_EXP(thresh, nbmant, nbexp, value) \
((value) < (thresh) ? (value) : \ ((value) < (thresh) ? (value) : \
((IGMPV3_MASK(value, nbmant) | (1<<(nbmant+nbexp))) << \ ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \
(IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp)))) (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
#define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value) #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb) static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{ {
__u8 status; __u8 status;
struct hci_conn *pend;
BT_DBG("%s ocf 0x%x", hdev->name, ocf); BT_DBG("%s ocf 0x%x", hdev->name, ocf);
...@@ -71,6 +72,15 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb ...@@ -71,6 +72,15 @@ static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
clear_bit(HCI_INQUIRY, &hdev->flags); clear_bit(HCI_INQUIRY, &hdev->flags);
hci_req_complete(hdev, status); hci_req_complete(hdev, status);
} }
hci_dev_lock(hdev);
pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
if (pend)
hci_acl_connect(pend);
hci_dev_unlock(hdev);
break; break;
default: default:
...@@ -565,11 +575,20 @@ static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status) ...@@ -565,11 +575,20 @@ static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
__u8 status = *((__u8 *) skb->data); __u8 status = *((__u8 *) skb->data);
struct hci_conn *pend;
BT_DBG("%s status %d", hdev->name, status); BT_DBG("%s status %d", hdev->name, status);
clear_bit(HCI_INQUIRY, &hdev->flags); clear_bit(HCI_INQUIRY, &hdev->flags);
hci_req_complete(hdev, status); hci_req_complete(hdev, status);
hci_dev_lock(hdev);
pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
if (pend)
hci_acl_connect(pend);
hci_dev_unlock(hdev);
} }
/* Inquiry Result */ /* Inquiry Result */
......
...@@ -120,10 +120,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -120,10 +120,13 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (!hci_test_bit(evt, &flt->event_mask)) if (!hci_test_bit(evt, &flt->event_mask))
continue; continue;
if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && if (flt->opcode &&
flt->opcode != *(__u16 *)(skb->data + 3)) || ((evt == HCI_EV_CMD_COMPLETE &&
flt->opcode !=
get_unaligned((__u16 *)(skb->data + 3))) ||
(evt == HCI_EV_CMD_STATUS && (evt == HCI_EV_CMD_STATUS &&
flt->opcode != *(__u16 *)(skb->data + 4)))) flt->opcode !=
get_unaligned((__u16 *)(skb->data + 4)))))
continue; continue;
} }
......
...@@ -259,7 +259,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn) ...@@ -259,7 +259,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
BT_DBG("conn %p", conn); BT_DBG("conn %p", conn);
conn->dev.bus = &bt_bus;
conn->dev.parent = &hdev->dev; conn->dev.parent = &hdev->dev;
conn->dev.release = bt_release; conn->dev.release = bt_release;
snprintf(conn->dev.bus_id, BUS_ID_SIZE, snprintf(conn->dev.bus_id, BUS_ID_SIZE,
......
...@@ -1353,12 +1353,12 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr) ...@@ -1353,12 +1353,12 @@ static inline int l2cap_conf_output(struct sock *sk, void **ptr)
/* Configure output options and let the other side know /* Configure output options and let the other side know
* which ones we don't like. */ * which ones we don't like. */
if (pi->conf_mtu < pi->omtu) { if (pi->conf_mtu < pi->omtu)
l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
result = L2CAP_CONF_UNACCEPT; result = L2CAP_CONF_UNACCEPT;
} else { else
pi->omtu = pi->conf_mtu; pi->omtu = pi->conf_mtu;
}
l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
BT_DBG("sk %p result %d", sk, result); BT_DBG("sk %p result %d", sk, result);
return result; return result;
...@@ -1533,6 +1533,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr ...@@ -1533,6 +1533,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
return -ENOENT; return -ENOENT;
if (sk->sk_state == BT_DISCONN)
goto unlock;
l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req)); l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
if (flags & 0x0001) { if (flags & 0x0001) {
......
...@@ -765,7 +765,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) ...@@ -765,7 +765,7 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
BT_DBG("tty %p termios %p", tty, old); BT_DBG("tty %p termios %p", tty, old);
if (!dev) if (!dev || !dev->dlc || !dev->dlc->session)
return; return;
/* Handle turning off CRTSCTS */ /* Handle turning off CRTSCTS */
......
...@@ -277,7 +277,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -277,7 +277,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
__u64 seq; __u64 seq;
sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport, sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
&hdr->saddr, dh->dccph_sport, skb->dev->ifindex); &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
if (sk == NULL) { if (sk == NULL) {
ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
......
...@@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb) ...@@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb)
skb->dev = t->dev; skb->dev = t->dev;
dst_release(skb->dst); dst_release(skb->dst);
skb->dst = NULL; skb->dst = NULL;
nf_reset(skb);
if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); ipv6_copy_dscp(ipv6h, skb->nh.ipv6h);
ip6ip6_ecn_decapsulate(ipv6h, skb); ip6ip6_ecn_decapsulate(ipv6h, skb);
...@@ -1149,6 +1150,20 @@ static int __init ip6_tunnel_init(void) ...@@ -1149,6 +1150,20 @@ static int __init ip6_tunnel_init(void)
return err; return err;
} }
static void __exit ip6ip6_destroy_tunnels(void)
{
int h;
struct ip6_tnl *t;
for (h = 0; h < HASH_SIZE; h++) {
while ((t = tnls_r_l[h]) != NULL)
unregister_netdevice(t->dev);
}
t = tnls_wc[0];
unregister_netdevice(t->dev);
}
/** /**
* ip6_tunnel_cleanup - free resources and unregister protocol * ip6_tunnel_cleanup - free resources and unregister protocol
**/ **/
...@@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void) ...@@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void)
if (xfrm6_tunnel_deregister(&ip6ip6_handler)) if (xfrm6_tunnel_deregister(&ip6ip6_handler))
printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
unregister_netdev(ip6ip6_fb_tnl_dev); rtnl_lock();
ip6ip6_destroy_tunnels();
rtnl_unlock();
} }
module_init(ip6_tunnel_init); module_init(ip6_tunnel_init);
......
...@@ -330,6 +330,8 @@ static int inline rt6_check_neigh(struct rt6_info *rt) ...@@ -330,6 +330,8 @@ static int inline rt6_check_neigh(struct rt6_info *rt)
read_lock_bh(&neigh->lock); read_lock_bh(&neigh->lock);
if (neigh->nud_state & NUD_VALID) if (neigh->nud_state & NUD_VALID)
m = 2; m = 2;
else if (!(neigh->nud_state & NUD_FAILED))
m = 1;
read_unlock_bh(&neigh->lock); read_unlock_bh(&neigh->lock);
} }
return m; return m;
...@@ -347,9 +349,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif, ...@@ -347,9 +349,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
#endif #endif
n = rt6_check_neigh(rt); n = rt6_check_neigh(rt);
if (n > 1) if (!n && (strict & RT6_LOOKUP_F_REACHABLE))
m |= 16;
else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
return -1; return -1;
return m; return m;
} }
...@@ -380,10 +380,11 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, ...@@ -380,10 +380,11 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
continue; continue;
if (m > mpri) { if (m > mpri) {
if (strict & RT6_LOOKUP_F_REACHABLE)
rt6_probe(match); rt6_probe(match);
match = rt; match = rt;
mpri = m; mpri = m;
} else { } else if (strict & RT6_LOOKUP_F_REACHABLE) {
rt6_probe(rt); rt6_probe(rt);
} }
} }
...@@ -636,7 +637,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table, ...@@ -636,7 +637,7 @@ static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
int strict = 0; int strict = 0;
int attempts = 3; int attempts = 3;
int err; int err;
int reachable = RT6_LOOKUP_F_REACHABLE; int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
strict |= flags & RT6_LOOKUP_F_IFACE; strict |= flags & RT6_LOOKUP_F_IFACE;
...@@ -733,7 +734,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table, ...@@ -733,7 +734,7 @@ static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
int strict = 0; int strict = 0;
int attempts = 3; int attempts = 3;
int err; int err;
int reachable = RT6_LOOKUP_F_REACHABLE; int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
strict |= flags & RT6_LOOKUP_F_IFACE; strict |= flags & RT6_LOOKUP_F_IFACE;
......
...@@ -242,14 +242,13 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -242,14 +242,13 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
{ {
struct ipv6_pinfo *np; struct ipv6_pinfo *np;
struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
struct net_device *dev = skb->dev;
struct in6_addr *saddr = &hdr->saddr; struct in6_addr *saddr = &hdr->saddr;
struct in6_addr *daddr = &hdr->daddr; struct in6_addr *daddr = &hdr->daddr;
struct udphdr *uh = (struct udphdr*)(skb->data+offset); struct udphdr *uh = (struct udphdr*)(skb->data+offset);
struct sock *sk; struct sock *sk;
int err; int err;
sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex); sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb));
if (sk == NULL) if (sk == NULL)
return; return;
...@@ -348,7 +347,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh, ...@@ -348,7 +347,7 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
read_lock(&udp_hash_lock); read_lock(&udp_hash_lock);
sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
dif = skb->dev->ifindex; dif = inet6_iif(skb);
sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
if (!sk) { if (!sk) {
kfree_skb(skb); kfree_skb(skb);
...@@ -429,7 +428,7 @@ static int udpv6_rcv(struct sk_buff **pskb) ...@@ -429,7 +428,7 @@ static int udpv6_rcv(struct sk_buff **pskb)
* check socket cache ... must talk to Alan about his plans * check socket cache ... must talk to Alan about his plans
* for sock caches... i'll skip this for now. * for sock caches... i'll skip this for now.
*/ */
sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex); sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb));
if (sk == NULL) { if (sk == NULL) {
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
......
...@@ -1678,7 +1678,8 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) ...@@ -1678,7 +1678,8 @@ static int irlmp_slsap_inuse(__u8 slsap_sel)
* every IrLAP connection and check every LSAP associated with each * every IrLAP connection and check every LSAP associated with each
* the connection. * the connection.
*/ */
spin_lock_irqsave(&irlmp->links->hb_spinlock, flags); spin_lock_irqsave_nested(&irlmp->links->hb_spinlock, flags,
SINGLE_DEPTH_NESTING);
lap = (struct lap_cb *) hashbin_get_first(irlmp->links); lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
while (lap != NULL) { while (lap != NULL) {
IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;); IRDA_ASSERT(lap->magic == LMP_LAP_MAGIC, goto errlap;);
......
...@@ -1927,6 +1927,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt, ...@@ -1927,6 +1927,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
#ifdef CONFIG_XFRM_SUB_POLICY
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -2034,6 +2037,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve ...@@ -2034,6 +2037,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
len += RTA_SPACE(xfrm_user_sec_ctx_size(xp)); len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
#ifdef CONFIG_XFRM_SUB_POLICY
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -2060,6 +2066,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event * ...@@ -2060,6 +2066,9 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
len += RTA_SPACE(headlen); len += RTA_SPACE(headlen);
headlen = sizeof(*id); headlen = sizeof(*id);
} }
#ifdef CONFIG_XFRM_SUB_POLICY
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif
len += NLMSG_SPACE(headlen); len += NLMSG_SPACE(headlen);
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
...@@ -2106,10 +2115,12 @@ static int xfrm_notify_policy_flush(struct km_event *c) ...@@ -2106,10 +2115,12 @@ static int xfrm_notify_policy_flush(struct km_event *c)
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *b; unsigned char *b;
int len = 0;
#ifdef CONFIG_XFRM_SUB_POLICY #ifdef CONFIG_XFRM_SUB_POLICY
struct xfrm_userpolicy_type upt; struct xfrm_userpolicy_type upt;
len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
#endif #endif
int len = NLMSG_LENGTH(0); len += NLMSG_LENGTH(0);
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
......
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