diff options
Diffstat (limited to 'net')
37 files changed, 331 insertions, 372 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 1037748c14d..6567213959c 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -376,6 +376,7 @@ void vlan_setup(struct net_device *new_dev) new_dev->init = vlan_dev_init; new_dev->open = vlan_dev_open; new_dev->stop = vlan_dev_stop; + new_dev->set_mac_address = vlan_set_mac_address; new_dev->set_multicast_list = vlan_dev_set_multicast_list; new_dev->change_rx_flags = vlan_change_rx_flags; new_dev->destructor = free_netdev; @@ -636,6 +637,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, if (!vlandev) continue; + flgs = vlandev->flags; + if (!(flgs & IFF_UP)) + continue; + vlan_sync_address(dev, vlandev); } break; diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index cf4a80d06b3..2cd1393073e 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -60,6 +60,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); int vlan_dev_open(struct net_device* dev); int vlan_dev_stop(struct net_device* dev); +int vlan_set_mac_address(struct net_device *dev, void *p); int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); void vlan_dev_set_ingress_priority(const struct net_device *dev, u32 skb_prio, short vlan_prio); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 1a1740aa9a8..7a36878241d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -665,6 +665,32 @@ int vlan_dev_stop(struct net_device *dev) return 0; } +int vlan_set_mac_address(struct net_device *dev, void *p) +{ + struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; + struct sockaddr *addr = p; + int err; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + if (!(dev->flags & IFF_UP)) + goto out; + + if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { + err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); + if (err < 0) + return err; + } + + if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) + dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); + +out: + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + return 0; +} + int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; diff --git a/net/core/dev.c b/net/core/dev.c index be6cedab5aa..dd7e30754cb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -4330,7 +4330,6 @@ static struct hlist_head *netdev_create_hash(void) static int __net_init netdev_init(struct net *net) { INIT_LIST_HEAD(&net->dev_base_head); - rwlock_init(&dev_base_lock); net->dev_name_head = netdev_create_hash(); if (net->dev_name_head == NULL) diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index ae354057d84..647973daca2 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -168,13 +168,13 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) da = from->mc_list; while (da != NULL) { next = da->next; - if (!da->da_synced) - continue; - __dev_addr_delete(&to->mc_list, &to->mc_count, - da->da_addr, da->da_addrlen, 0); - da->da_synced = 0; - __dev_addr_delete(&from->mc_list, &from->mc_count, - da->da_addr, da->da_addrlen, 0); + if (da->da_synced) { + __dev_addr_delete(&to->mc_list, &to->mc_count, + da->da_addr, da->da_addrlen, 0); + da->da_synced = 0; + __dev_addr_delete(&from->mc_list, &from->mc_count, + da->da_addr, da->da_addrlen, 0); + } da = next; } __dev_set_rx_mode(to); diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 13de6f53f09..848132b6cb7 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -18,6 +18,28 @@ static LIST_HEAD(rules_ops); static DEFINE_SPINLOCK(rules_mod_lock); +int fib_default_rule_add(struct fib_rules_ops *ops, + u32 pref, u32 table, u32 flags) +{ + struct fib_rule *r; + + r = kzalloc(ops->rule_size, GFP_KERNEL); + if (r == NULL) + return -ENOMEM; + + atomic_set(&r->refcnt, 1); + r->action = FR_ACT_TO_TBL; + r->pref = pref; + r->table = table; + r->flags = flags; + + /* The lock is not required here, the list in unreacheable + * at the moment this function is called */ + list_add_tail(&r->list, &ops->rules_list); + return 0; +} +EXPORT_SYMBOL(fib_default_rule_add); + static void notify_rule_change(int event, struct fib_rule *rule, struct fib_rules_ops *ops, struct nlmsghdr *nlh, u32 pid); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 97eee5e8fbb..66663e5d7ac 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -293,9 +293,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rth); - rth->u.dst.__use++; - dst_hold(&rth->u.dst); - rth->u.dst.lastuse = now; + dst_use(&rth->u.dst, now); spin_unlock_bh(&dn_rt_hash_table[hash].lock); dnrt_drop(rt); @@ -308,9 +306,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * rcu_assign_pointer(rt->u.dst.dn_next, dn_rt_hash_table[hash].chain); rcu_assign_pointer(dn_rt_hash_table[hash].chain, rt); - dst_hold(&rt->u.dst); - rt->u.dst.__use++; - rt->u.dst.lastuse = now; + dst_use(&rt->u.dst, now); spin_unlock_bh(&dn_rt_hash_table[hash].lock); *rp = rt; return 0; @@ -1182,9 +1178,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl (flp->mark == rt->fl.mark) && (rt->fl.iif == 0) && (rt->fl.oif == flp->oif)) { - rt->u.dst.lastuse = jiffies; - dst_hold(&rt->u.dst); - rt->u.dst.__use++; + dst_use(&rt->u.dst, jiffies); rcu_read_unlock_bh(); *pprt = &rt->u.dst; return 0; @@ -1456,9 +1450,7 @@ int dn_route_input(struct sk_buff *skb) (rt->fl.oif == 0) && (rt->fl.mark == skb->mark) && (rt->fl.iif == cb->iif)) { - rt->u.dst.lastuse = jiffies; - dst_hold(&rt->u.dst); - rt->u.dst.__use++; + dst_use(&rt->u.dst, jiffies); rcu_read_unlock(); skb->dst = (struct dst_entry *)rt; return 0; diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index ddd3f04f091..ffebea04cc9 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -48,15 +48,6 @@ struct dn_fib_rule u8 flags; }; -static struct dn_fib_rule default_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .pref = 0x7fff, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - }, -}; - int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res) { @@ -262,8 +253,8 @@ static struct fib_rules_ops dn_fib_rules_ops = { void __init dn_fib_rules_init(void) { - list_add_tail(&default_rule.common.list, - &dn_fib_rules_ops.rules_list); + BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff, + RT_TABLE_MAIN, 0)); fib_rules_register(&dn_fib_rules_ops); } diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index ac36767b56e..e01b59aedc5 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -470,7 +470,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, { struct ieee80211softmac_device *mac = ieee80211_priv(dev); struct iw_mlme *mlme = (struct iw_mlme *)extra; - u16 reason = cpu_to_le16(mlme->reason_code); + u16 reason = mlme->reason_code; struct ieee80211softmac_network *net; int err = -EINVAL; diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index f16839c6a72..a0ada3a8d8d 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -49,33 +49,6 @@ struct fib4_rule #endif }; -static struct fib4_rule default_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .pref = 0x7FFF, - .table = RT_TABLE_DEFAULT, - .action = FR_ACT_TO_TBL, - }, -}; - -static struct fib4_rule main_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .pref = 0x7FFE, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - }, -}; - -static struct fib4_rule local_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .flags = FIB_RULE_PERMANENT, - }, -}; - #ifdef CONFIG_NET_CLS_ROUTE u32 fib_rules_tclass(struct fib_result *res) { @@ -319,11 +292,27 @@ static struct fib_rules_ops fib4_rules_ops = { .owner = THIS_MODULE, }; -void __init fib4_rules_init(void) +static int __init fib_default_rules_init(void) { - list_add_tail(&local_rule.common.list, &fib4_rules_ops.rules_list); - list_add_tail(&main_rule.common.list, &fib4_rules_ops.rules_list); - list_add_tail(&default_rule.common.list, &fib4_rules_ops.rules_list); + int err; + + err = fib_default_rule_add(&fib4_rules_ops, 0, + RT_TABLE_LOCAL, FIB_RULE_PERMANENT); + if (err < 0) + return err; + err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE, + RT_TABLE_MAIN, 0); + if (err < 0) + return err; + err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF, + RT_TABLE_DEFAULT, 0); + if (err < 0) + return err; + return 0; +} +void __init fib4_rules_init(void) +{ + BUG_ON(fib_default_rules_init()); fib_rules_register(&fib4_rules_ops); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 21b12de9e65..45651834e1e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -851,9 +851,7 @@ restart: */ rcu_assign_pointer(rt_hash_table[hash].chain, rth); - rth->u.dst.__use++; - dst_hold(&rth->u.dst); - rth->u.dst.lastuse = now; + dst_use(&rth->u.dst, now); spin_unlock_bh(rt_hash_lock_addr(hash)); rt_drop(rt); @@ -1813,11 +1811,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto martian_destination; err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); - if (err == -ENOBUFS) - goto e_nobufs; - if (err == -EINVAL) - goto e_inval; - done: in_dev_put(in_dev); if (free_res) @@ -1935,9 +1928,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth->fl.oif == 0 && rth->fl.mark == skb->mark && rth->fl.fl4_tos == tos) { - rth->u.dst.lastuse = jiffies; - dst_hold(&rth->u.dst); - rth->u.dst.__use++; + dst_use(&rth->u.dst, jiffies); RT_CACHE_STAT_INC(in_hit); rcu_read_unlock(); skb->dst = (struct dst_entry*)rth; @@ -2331,9 +2322,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) rth->fl.mark == flp->mark && !((rth->fl.fl4_tos ^ flp->fl4_tos) & (IPTOS_RT_MASK | RTO_ONLINK))) { - rth->u.dst.lastuse = jiffies; - dst_hold(&rth->u.dst); - rth->u.dst.__use++; + dst_use(&rth->u.dst, jiffies); RT_CACHE_STAT_INC(out_hit); rcu_read_unlock_bh(); *rp = rth; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ca9590f4f52..20c9440ab85 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1400,11 +1400,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ /* DSACK info lost if out-of-mem, try SACK still */ if (in_sack <= 0) in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq); - if (in_sack < 0) + if (unlikely(in_sack < 0)) break; - fack_count += tcp_skb_pcount(skb); - sacked = TCP_SKB_CB(skb)->sacked; /* Account D-SACK for retransmitted packet. */ @@ -1419,19 +1417,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if ((dup_sack && in_sack) && (sacked&TCPCB_SACKED_ACKED)) reord = min(fack_count, reord); - } else { - /* If it was in a hole, we detected reordering. */ - if (fack_count < prior_fackets && - !(sacked&TCPCB_SACKED_ACKED)) - reord = min(fack_count, reord); } /* Nothing to do; acked frame is about to be dropped. */ + fack_count += tcp_skb_pcount(skb); continue; } - if (!in_sack) + if (!in_sack) { + fack_count += tcp_skb_pcount(skb); continue; + } if (!(sacked&TCPCB_SACKED_ACKED)) { if (sacked & TCPCB_SACKED_RETRANS) { @@ -1448,12 +1444,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ tp->retransmit_skb_hint = NULL; } } else { - /* New sack for not retransmitted frame, - * which was in hole. It is reordering. - */ - if (!(sacked & TCPCB_RETRANS) && - fack_count < prior_fackets) - reord = min(fack_count, reord); + if (!(sacked & TCPCB_RETRANS)) { + /* New sack for not retransmitted frame, + * which was in hole. It is reordering. + */ + if (fack_count < prior_fackets) + reord = min(fack_count, reord); + + /* SACK enhanced F-RTO (RFC4138; Appendix B) */ + if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) + flag |= FLAG_ONLY_ORIG_SACKED; + } if (sacked & TCPCB_LOST) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; @@ -1462,24 +1463,13 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ /* clear lost hint */ tp->retransmit_skb_hint = NULL; } - /* SACK enhanced F-RTO detection. - * Set flag if and only if non-rexmitted - * segments below frto_highmark are - * SACKed (RFC4138; Appendix B). - * Clearing correct due to in-order walk - */ - if (after(end_seq, tp->frto_highmark)) { - flag &= ~FLAG_ONLY_ORIG_SACKED; - } else { - if (!(sacked & TCPCB_RETRANS)) - flag |= FLAG_ONLY_ORIG_SACKED; - } } TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; flag |= FLAG_DATA_SACKED; tp->sacked_out += tcp_skb_pcount(skb); + fack_count += tcp_skb_pcount(skb); if (fack_count > tp->fackets_out) tp->fackets_out = fack_count; @@ -1490,6 +1480,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } else { if (dup_sack && (sacked&TCPCB_RETRANS)) reord = min(fack_count, reord); + + fack_count += tcp_skb_pcount(skb); } /* D-SACK. We can detect redundant retransmission @@ -1504,6 +1496,12 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ tp->retransmit_skb_hint = NULL; } } + + /* SACK enhanced FRTO (RFC4138, Appendix B): Clearing correct + * due to in-order walk + */ + if (after(end_seq, tp->frto_highmark)) + flag &= ~FLAG_ONLY_ORIG_SACKED; } if (tp->retrans_out && @@ -1515,7 +1513,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss && (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) - tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0); + tcp_update_reordering(sk, tp->fackets_out - reord, 0); #if FASTRETRANS_DEBUG > 0 BUG_TRAP((int)tp->sacked_out >= 0); @@ -2630,7 +2628,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) * is before the ack sequence we can discard it as it's confirmed to have * arrived at the other end. */ -static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) +static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p, + int prior_fackets) { struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); @@ -2639,6 +2638,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) int fully_acked = 1; int flag = 0; int prior_packets = tp->packets_out; + u32 cnt = 0; + u32 reord = tp->packets_out; s32 seq_rtt = -1; ktime_t last_ackt = net_invalid_timestamp(); @@ -2679,10 +2680,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) if ((flag & FLAG_DATA_ACKED) || (packets_acked > 1)) flag |= FLAG_NONHEAD_RETRANS_ACKED; - } else if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + } else { + if (seq_rtt < 0) { + seq_rtt = now - scb->when; + if (fully_acked) + last_ackt = skb->tstamp; + } + if (!(sacked & TCPCB_SACKED_ACKED)) + reord = min(cnt, reord); } if (sacked & TCPCB_SACKED_ACKED) @@ -2693,12 +2698,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) if ((sacked & TCPCB_URG) && tp->urg_mode && !before(end_seq, tp->snd_up)) tp->urg_mode = 0; - } else if (seq_rtt < 0) { - seq_rtt = now - scb->when; - if (fully_acked) - last_ackt = skb->tstamp; + } else { + if (seq_rtt < 0) { + seq_rtt = now - scb->when; + if (fully_acked) + last_ackt = skb->tstamp; + } + reord = min(cnt, reord); } tp->packets_out -= packets_acked; + cnt += packets_acked; /* Initial outgoing SYN's get put onto the write_queue * just like anything else we transmit. It is not @@ -2730,13 +2739,18 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p) tcp_ack_update_rtt(sk, flag, seq_rtt); tcp_rearm_rto(sk); + if (tcp_is_reno(tp)) { + tcp_remove_reno_sacks(sk, pkts_acked); + } else { + /* Non-retransmitted hole got filled? That's reordering */ + if (reord < prior_fackets) + tcp_update_reordering(sk, tp->fackets_out - reord, 0); + } + tp->fackets_out -= min(pkts_acked, tp->fackets_out); /* hint's skb might be NULL but we don't need to care */ tp->fastpath_cnt_hint -= min_t(u32, pkts_acked, tp->fastpath_cnt_hint); - if (tcp_is_reno(tp)) - tcp_remove_reno_sacks(sk, pkts_acked); - if (ca_ops->pkts_acked) { s32 rtt_us = -1; @@ -3019,6 +3033,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) u32 ack_seq = TCP_SKB_CB(skb)->seq; u32 ack = TCP_SKB_CB(skb)->ack_seq; u32 prior_in_flight; + u32 prior_fackets; s32 seq_rtt; int prior_packets; int frto_cwnd = 0; @@ -3043,6 +3058,8 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache); } + prior_fackets = tp->fackets_out; + if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { /* Window is constant, pure forward advance. * No more checks are required. @@ -3084,7 +3101,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) prior_in_flight = tcp_packets_in_flight(tp); /* See if we can take anything off of the retransmit queue. */ - flag |= tcp_clean_rtx_queue(sk, &seq_rtt); + flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); /* Guarantee sacktag reordering detection against wrap-arounds */ if (before(tp->frto_highmark, tp->snd_una)) diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index a794a8ca8b4..978b3fd61e6 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -17,6 +17,11 @@ static struct xfrm_tunnel *tunnel4_handlers; static struct xfrm_tunnel *tunnel64_handlers; static DEFINE_MUTEX(tunnel4_mutex); +static inline struct xfrm_tunnel **fam_handlers(unsigned short family) +{ + return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; +} + int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) { struct xfrm_tunnel **pprev; @@ -25,8 +30,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) mutex_lock(&tunnel4_mutex); - for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; - *pprev; pprev = &(*pprev)->next) { + for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { if ((*pprev)->priority > priority) break; if ((*pprev)->priority == priority) @@ -53,8 +57,7 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) mutex_lock(&tunnel4_mutex); - for (pprev = (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; - *pprev; pprev = &(*pprev)->next) { + for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) { if (*pprev == handler) { *pprev = handler->next; ret = 0; @@ -118,6 +121,17 @@ static void tunnel4_err(struct sk_buff *skb, u32 info) break; } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static void tunnel64_err(struct sk_buff *skb, u32 info) +{ + struct xfrm_tunnel *handler; + + for (handler = tunnel64_handlers; handler; handler = handler->next) + if (!handler->err_handler(skb, info)) + break; +} +#endif + static struct net_protocol tunnel4_protocol = { .handler = tunnel4_rcv, .err_handler = tunnel4_err, @@ -127,7 +141,7 @@ static struct net_protocol tunnel4_protocol = { #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static struct net_protocol tunnel64_protocol = { .handler = tunnel64_rcv, - .err_handler = tunnel4_err, + .err_handler = tunnel64_err, .no_policy = 1, }; #endif diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 706622af206..428c6b0e26d 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -31,25 +31,6 @@ struct fib6_rule static struct fib_rules_ops fib6_rules_ops; -static struct fib6_rule main_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .pref = 0x7FFE, - .action = FR_ACT_TO_TBL, - .table = RT6_TABLE_MAIN, - }, -}; - -static struct fib6_rule local_rule = { - .common = { - .refcnt = ATOMIC_INIT(2), - .pref = 0, - .action = FR_ACT_TO_TBL, - .table = RT6_TABLE_LOCAL, - .flags = FIB_RULE_PERMANENT, - }, -}; - struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, pol_lookup_t lookup) { @@ -270,11 +251,23 @@ static struct fib_rules_ops fib6_rules_ops = { .owner = THIS_MODULE, }; -void __init fib6_rules_init(void) +static int __init fib6_default_rules_init(void) { - list_add_tail(&local_rule.common.list, &fib6_rules_ops.rules_list); - list_add_tail(&main_rule.common.list, &fib6_rules_ops.rules_list); + int err; + + err = fib_default_rule_add(&fib6_rules_ops, 0, + RT6_TABLE_LOCAL, FIB_RULE_PERMANENT); + if (err < 0) + return err; + err = fib_default_rule_add(&fib6_rules_ops, 0x7FFE, RT6_TABLE_MAIN, 0); + if (err < 0) + return err; + return 0; +} +void __init fib6_rules_init(void) +{ + BUG_ON(fib6_default_rules_init()); fib_rules_register(&fib6_rules_ops); } diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 36f7dbfb6db..67997a74ddc 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1037,6 +1037,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) ndmsg = nlmsg_data(nlh); ndmsg->nduseropt_family = AF_INET6; + ndmsg->nduseropt_ifindex = ra->dev->ifindex; ndmsg->nduseropt_icmp_type = icmp6h->icmp6_type; ndmsg->nduseropt_icmp_code = icmp6h->icmp6_code; ndmsg->nduseropt_opts_len = opt->nd_opt_len << 3; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 973a97abc44..6ecb5e6fae2 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -544,12 +544,8 @@ restart: rt = rt6_device_match(rt, fl->oif, flags); BACKTRACK(&fl->fl6_src); out: - dst_hold(&rt->u.dst); + dst_use(&rt->u.dst, jiffies); read_unlock_bh(&table->tb6_lock); - - rt->u.dst.lastuse = jiffies; - rt->u.dst.__use++; - return rt; } diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index a195a66e0cc..c76a9523091 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -92,11 +92,6 @@ extern int ipxrtr_route_skb(struct sk_buff *skb); extern struct ipx_route *ipxrtr_lookup(__be32 net); extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg); -#undef IPX_REFCNT_DEBUG -#ifdef IPX_REFCNT_DEBUG -atomic_t ipx_sock_nr; -#endif - struct ipx_interface *ipx_interfaces_head(void) { struct ipx_interface *rc = NULL; @@ -151,14 +146,7 @@ static void ipx_destroy_socket(struct sock *sk) { ipx_remove_socket(sk); skb_queue_purge(&sk->sk_receive_queue); -#ifdef IPX_REFCNT_DEBUG - atomic_dec(&ipx_sock_nr); - printk(KERN_DEBUG "IPX socket %p released, %d are still alive\n", sk, - atomic_read(&ipx_sock_nr)); - if (atomic_read(&sk->sk_refcnt) != 1) - printk(KERN_DEBUG "Destruction sock ipx %p delayed, cnt=%d\n", - sk, atomic_read(&sk->sk_refcnt)); -#endif + sk_refcnt_debug_dec(sk); sock_put(sk); } @@ -1384,11 +1372,8 @@ static int ipx_create(struct net *net, struct socket *sock, int protocol) sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto); if (!sk) goto out; -#ifdef IPX_REFCNT_DEBUG - atomic_inc(&ipx_sock_nr); - printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk, - atomic_read(&ipx_sock_nr)); -#endif + + sk_refcnt_debug_inc(sk); sock_init_data(sock, sk); sk->sk_no_check = 1; /* Checksum off by default */ sock->ops = &ipx_dgram_ops; @@ -1409,6 +1394,7 @@ static int ipx_release(struct socket *sock) sock_set_flag(sk, SOCK_DEAD); sock->sk = NULL; + sk_refcnt_debug_release(sk); ipx_destroy_socket(sk); out: return 0; diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 6fffb3845ab..ce176e691af 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -13,6 +13,18 @@ config MAC80211 This option enables the hardware independent IEEE 802.11 networking stack. +config MAC80211_RCSIMPLE + bool "'simple' rate control algorithm" if EMBEDDED + default y + depends on MAC80211 + help + This option allows you to turn off the 'simple' rate + control algorithm in mac80211. If you do turn it off, + you absolutely need another rate control algorithm. + + Say Y unless you know you will have another algorithm + available. + config MAC80211_LEDS bool "Enable LED triggers" depends on MAC80211 && LEDS_TRIGGERS diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 219cd9f9341..1e6237b3484 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -1,8 +1,9 @@ -obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o +obj-$(CONFIG_MAC80211) += mac80211.o mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o mac80211-objs-$(CONFIG_NET_SCHED) += wme.o +mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o mac80211-objs := \ ieee80211.o \ diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index f484ca7ade9..e0ee65a969b 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -1072,7 +1072,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); - result = ieee80211_init_rate_ctrl_alg(local, NULL); + result = ieee80211_init_rate_ctrl_alg(local, + hw->rate_control_algorithm); if (result < 0) { printk(KERN_DEBUG "%s: Failed to initialize rate control " "algorithm\n", wiphy_name(local->hw.wiphy)); @@ -1233,8 +1234,17 @@ static int __init ieee80211_init(void) BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); +#ifdef CONFIG_MAC80211_RCSIMPLE + ret = ieee80211_rate_control_register(&mac80211_rcsimple); + if (ret) + return ret; +#endif + ret = ieee80211_wme_register(); if (ret) { +#ifdef CONFIG_MAC80211_RCSIMPLE + ieee80211_rate_control_unregister(&mac80211_rcsimple); +#endif printk(KERN_DEBUG "ieee80211_init: failed to " "initialize WME (err=%d)\n", ret); return ret; @@ -1248,6 +1258,10 @@ static int __init ieee80211_init(void) static void __exit ieee80211_exit(void) { +#ifdef CONFIG_MAC80211_RCSIMPLE + ieee80211_rate_control_unregister(&mac80211_rcsimple); +#endif + ieee80211_wme_unregister(); ieee80211_debugfs_netdev_exit(); } diff --git a/net/mac80211/ieee80211_common.h b/net/mac80211/ieee80211_common.h deleted file mode 100644 index c15295d43d8..00000000000 --- a/net/mac80211/ieee80211_common.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * IEEE 802.11 driver (80211.o) -- hostapd interface - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_COMMON_H -#define IEEE80211_COMMON_H - -#include <linux/types.h> - -/* - * This is common header information with user space. It is used on all - * frames sent to wlan#ap interface. - */ - -#define IEEE80211_FI_VERSION 0x80211001 - -struct ieee80211_frame_info { - __be32 version; - __be32 length; - __be64 mactime; - __be64 hosttime; - __be32 phytype; - __be32 channel; - __be32 datarate; - __be32 antenna; - __be32 priority; - __be32 ssi_type; - __be32 ssi_signal; - __be32 ssi_noise; - __be32 preamble; - __be32 encoding; - - /* Note: this structure is otherwise identical to capture format used - * in linux-wlan-ng, but this additional field is used to provide meta - * data about the frame to hostapd. This was the easiest method for - * providing this information, but this might change in the future. */ - __be32 msg_type; -} __attribute__ ((packed)); - - -enum ieee80211_msg_type { - ieee80211_msg_normal = 0, - ieee80211_msg_tx_callback_ack = 1, - ieee80211_msg_tx_callback_fail = 2, - /* hole at 3, was ieee80211_msg_passive_scan but unused */ - /* hole at 4, was ieee80211_msg_wep_frame_unknown_key but now unused */ - ieee80211_msg_michael_mic_failure = 5, - /* hole at 6, was monitor but never sent to userspace */ - ieee80211_msg_sta_not_assoc = 7, - /* 8 was ieee80211_msg_set_aid_for_sta */ - /* 9 was ieee80211_msg_key_threshold_notification */ - /* 11 was ieee80211_msg_radar */ -}; - -struct ieee80211_msg_key_notification { - int tx_rx_count; - char ifname[IFNAMSIZ]; - u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */ -}; - - -enum ieee80211_phytype { - ieee80211_phytype_fhss_dot11_97 = 1, - ieee80211_phytype_dsss_dot11_97 = 2, - ieee80211_phytype_irbaseband = 3, - ieee80211_phytype_dsss_dot11_b = 4, - ieee80211_phytype_pbcc_dot11_b = 5, - ieee80211_phytype_ofdm_dot11_g = 6, - ieee80211_phytype_pbcc_dot11_g = 7, - ieee80211_phytype_ofdm_dot11_a = 8, -}; - -enum ieee80211_ssi_type { - ieee80211_ssi_none = 0, - ieee80211_ssi_norm = 1, /* normalized, 0-1000 */ - ieee80211_ssi_dbm = 2, - ieee80211_ssi_raw = 3, /* raw SSI */ -}; - -struct ieee80211_radar_info { - int channel; - int radar; - int radar_type; -}; - -#endif /* IEEE80211_COMMON_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4b4ed2a5803..b4e32ab3664 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -230,6 +230,7 @@ struct ieee80211_if_vlan { #define IEEE80211_STA_AUTO_SSID_SEL BIT(10) #define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) +#define IEEE80211_STA_PRIVACY_INVOKED BIT(13) struct ieee80211_if_sta { enum { IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, @@ -259,7 +260,6 @@ struct ieee80211_if_sta { unsigned long request; struct sk_buff_head skb_queue; - int key_management_enabled; unsigned long last_probe; #define IEEE80211_AUTH_ALG_OPEN BIT(0) diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 6caa3ec2cff..7027eed4d4a 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -917,7 +917,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *data, char *extra) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); int ret = 0; @@ -927,18 +926,21 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, case IW_AUTH_CIPHER_GROUP: case IW_AUTH_WPA_ENABLED: case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; case IW_AUTH_KEY_MGMT: + break; + case IW_AUTH_PRIVACY_INVOKED: if (sdata->type != IEEE80211_IF_TYPE_STA) ret = -EINVAL; else { + sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; /* - * Key management was set by wpa_supplicant, - * we only need this to associate to a network - * that has privacy enabled regardless of not - * having a key. + * Privacy invoked by wpa_supplicant, store the + * value and allow associating to a protected + * network without having a key up front. */ - sdata->u.sta.key_management_enabled = !!data->value; + if (data->value) + sdata->u.sta.flags |= + IEEE80211_STA_PRIVACY_INVOKED; } break; case IW_AUTH_80211_AUTH_ALG: @@ -948,11 +950,6 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev, else ret = -EOPNOTSUPP; break; - case IW_AUTH_PRIVACY_INVOKED: - if (local->ops->set_privacy_invoked) - ret = local->ops->set_privacy_invoked( - local_to_hw(local), data->value); - break; default: ret = -EOPNOTSUPP; break; diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index 93abb8fff14..7254bd60983 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c @@ -25,13 +25,25 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops) { struct rate_control_alg *alg; + if (!ops->name) + return -EINVAL; + + mutex_lock(&rate_ctrl_mutex); + list_for_each_entry(alg, &rate_ctrl_algs, list) { + if (!strcmp(alg->ops->name, ops->name)) { + /* don't register an algorithm twice */ + WARN_ON(1); + return -EALREADY; + } + } + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) { + mutex_unlock(&rate_ctrl_mutex); return -ENOMEM; } alg->ops = ops; - mutex_lock(&rate_ctrl_mutex); list_add_tail(&alg->list, &rate_ctrl_algs); mutex_unlock(&rate_ctrl_mutex); @@ -61,9 +73,12 @@ ieee80211_try_rate_control_ops_get(const char *name) struct rate_control_alg *alg; struct rate_control_ops *ops = NULL; + if (!name) + return NULL; + mutex_lock(&rate_ctrl_mutex); list_for_each_entry(alg, &rate_ctrl_algs, list) { - if (!name || !strcmp(alg->ops->name, name)) + if (!strcmp(alg->ops->name, name)) if (try_module_get(alg->ops->module)) { ops = alg->ops; break; @@ -80,9 +95,12 @@ ieee80211_rate_control_ops_get(const char *name) { struct rate_control_ops *ops; + if (!name) + name = "simple"; + ops = ieee80211_try_rate_control_ops_get(name); if (!ops) { - request_module("rc80211_%s", name ? name : "default"); + request_module("rc80211_%s", name); ops = ieee80211_try_rate_control_ops_get(name); } return ops; diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h index 7cd1ebab4f8..23688139ffb 100644 --- a/net/mac80211/ieee80211_rate.h +++ b/net/mac80211/ieee80211_rate.h @@ -65,6 +65,9 @@ struct rate_control_ref { struct kref kref; }; +/* default 'simple' algorithm */ +extern struct rate_control_ops mac80211_rcsimple; + int ieee80211_rate_control_register(struct rate_control_ops *ops); void ieee80211_rate_control_unregister(struct rate_control_ops *ops); diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index fda0e06453e..2079e988fc5 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -704,10 +704,11 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; - int res = 0; + int bss_privacy; + int wep_privacy; + int privacy_invoked; - if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) || - ifsta->key_management_enabled) + if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) return 0; bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, @@ -715,13 +716,16 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, if (!bss) return 0; - if (ieee80211_sta_wep_configured(dev) != - !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) - res = 1; + bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); + wep_privacy = !!ieee80211_sta_wep_configured(dev); + privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); ieee80211_rx_bss_put(dev, bss); - return res; + if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) + return 0; + + return 1; } diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index 314b8de8886..da72737364e 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c @@ -7,7 +7,6 @@ * published by the Free Software Foundation. */ -#include <linux/module.h> #include <linux/init.h> #include <linux/netdevice.h> #include <linux/types.h> @@ -29,8 +28,6 @@ #define RATE_CONTROL_INTERVAL (HZ / 20) #define RATE_CONTROL_MIN_TX 10 -MODULE_ALIAS("rc80211_default"); - static void rate_control_rate_inc(struct ieee80211_local *local, struct sta_info *sta) { @@ -394,8 +391,7 @@ static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta) } #endif -static struct rate_control_ops rate_control_simple = { - .module = THIS_MODULE, +struct rate_control_ops mac80211_rcsimple = { .name = "simple", .tx_status = rate_control_simple_tx_status, .get_rate = rate_control_simple_get_rate, @@ -410,22 +406,3 @@ static struct rate_control_ops rate_control_simple = { .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs, #endif }; - - -static int __init rate_control_simple_init(void) -{ - return ieee80211_rate_control_register(&rate_control_simple); -} - - -static void __exit rate_control_simple_exit(void) -{ - ieee80211_rate_control_unregister(&rate_control_simple); -} - - -subsys_initcall(rate_control_simple_init); -module_exit(rate_control_simple_exit); - -MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); -MODULE_LICENSE("GPL"); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index ece77766ea2..428a9fcf57d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -509,9 +509,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) rx->key->tx_rx_count++; /* TODO: add threshold stuff again */ } else { +#ifdef CONFIG_MAC80211_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "%s: RX protected frame," " but have no key\n", rx->dev->name); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index a84a23310ff..9bf0e1cc530 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -314,9 +314,11 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { +#ifdef CONFIG_MAC80211_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "%s: RX WEP frame, decrypt " "failed\n", rx->dev->name); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 6695efba57e..20cec1cb956 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -323,9 +323,12 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) &rx->u.rx.tkip_iv32, &rx->u.rx.tkip_iv16); if (res != TKIP_DECRYPT_OK || wpa_test) { - printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " - "%s (res=%d)\n", - rx->dev->name, print_mac(mac, rx->sta->addr), res); +#ifdef CONFIG_MAC80211_DEBUG + if (net_ratelimit()) + printk(KERN_DEBUG "%s: TKIP decrypt failed for RX " + "frame from %s (res=%d)\n", rx->dev->name, + print_mac(mac, rx->sta->addr), res); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } @@ -594,9 +597,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) skb->data + hdrlen + CCMP_HDR_LEN, data_len, skb->data + skb->len - CCMP_MIC_LEN, skb->data + hdrlen + CCMP_HDR_LEN)) { - printk(KERN_DEBUG "%s: CCMP decrypt failed for RX " - "frame from %s\n", rx->dev->name, - print_mac(mac, rx->sta->addr)); +#ifdef CONFIG_MAC80211_DEBUG + if (net_ratelimit()) + printk(KERN_DEBUG "%s: CCMP decrypt failed " + "for RX frame from %s\n", rx->dev->name, + print_mac(mac, rx->sta->addr)); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } } diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4cb2dfba099..eb6be5030c7 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -139,9 +139,6 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it) static HLIST_HEAD(packet_sklist); static DEFINE_RWLOCK(packet_sklist_lock); -static atomic_t packet_socks_nr; - - /* Private packet socket structures. */ struct packet_mclist @@ -236,10 +233,7 @@ static void packet_sock_destruct(struct sock *sk) return; } - atomic_dec(&packet_socks_nr); -#ifdef PACKET_REFCNT_DEBUG - printk(KERN_DEBUG "PACKET socket %p is free, %d are alive\n", sk, atomic_read(&packet_socks_nr)); -#endif + sk_refcnt_debug_dec(sk); } @@ -515,7 +509,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) + if (unlikely(po->origdev)) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -661,7 +655,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe sll->sll_hatype = dev->type; sll->sll_protocol = skb->protocol; sll->sll_pkttype = skb->pkt_type; - if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) + if (unlikely(po->origdev)) sll->sll_ifindex = orig_dev->ifindex; else sll->sll_ifindex = dev->ifindex; @@ -849,6 +843,7 @@ static int packet_release(struct socket *sock) /* Purge queues */ skb_queue_purge(&sk->sk_receive_queue); + sk_refcnt_debug_release(sk); sock_put(sk); return 0; @@ -1010,7 +1005,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol) po->num = proto; sk->sk_destruct = packet_sock_destruct; - atomic_inc(&packet_socks_nr); + sk_refcnt_debug_inc(sk); /* * Attach a protocol block diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 51d151c0e96..73d60a30712 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -27,6 +27,10 @@ #include <linux/mutex.h> #include <linux/rfkill.h> +/* Get declaration of rfkill_switch_all() to shut up sparse. */ +#include "rfkill-input.h" + + MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>"); MODULE_VERSION("1.0"); MODULE_DESCRIPTION("RF switch support"); @@ -276,21 +280,17 @@ static struct class rfkill_class = { static int rfkill_add_switch(struct rfkill *rfkill) { - int retval; - - retval = mutex_lock_interruptible(&rfkill_mutex); - if (retval) - return retval; + int error; - retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); - if (retval) - goto out; + mutex_lock(&rfkill_mutex); - list_add_tail(&rfkill->node, &rfkill_list); + error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); + if (!error) + list_add_tail(&rfkill->node, &rfkill_list); - out: mutex_unlock(&rfkill_mutex); - return retval; + + return error; } static void rfkill_remove_switch(struct rfkill *rfkill) @@ -387,20 +387,23 @@ int rfkill_register(struct rfkill *rfkill) if (!rfkill->toggle_radio) return -EINVAL; + if (rfkill->type >= RFKILL_TYPE_MAX) + return -EINVAL; + + snprintf(dev->bus_id, sizeof(dev->bus_id), + "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); + + rfkill_led_trigger_register(rfkill); error = rfkill_add_switch(rfkill); if (error) return error; - snprintf(dev->bus_id, sizeof(dev->bus_id), - "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1); - error = device_add(dev); if (error) { rfkill_remove_switch(rfkill); return error; } - rfkill_led_trigger_register(rfkill); return 0; } @@ -416,9 +419,9 @@ EXPORT_SYMBOL(rfkill_register); */ void rfkill_unregister(struct rfkill *rfkill) { - rfkill_led_trigger_unregister(rfkill); device_del(&rfkill->dev); rfkill_remove_switch(rfkill); + rfkill_led_trigger_unregister(rfkill); put_device(&rfkill->dev); } EXPORT_SYMBOL(rfkill_unregister); @@ -448,5 +451,5 @@ static void __exit rfkill_exit(void) class_unregister(&rfkill_class); } -module_init(rfkill_init); +subsys_initcall(rfkill_init); module_exit(rfkill_exit); diff --git a/net/rxrpc/ar-local.c b/net/rxrpc/ar-local.c index fe03f71f17d..f3a2bd747a8 100644 --- a/net/rxrpc/ar-local.c +++ b/net/rxrpc/ar-local.c @@ -114,7 +114,7 @@ static int rxrpc_create_local(struct rxrpc_local *local) return 0; error: - local->socket->ops->shutdown(local->socket, 2); + kernel_sock_shutdown(local->socket, SHUT_RDWR); local->socket->sk->sk_user_data = NULL; sock_release(local->socket); local->socket = NULL; @@ -267,7 +267,7 @@ static void rxrpc_destroy_local(struct work_struct *work) /* finish cleaning up the local descriptor */ rxrpc_purge_queue(&local->accept_queue); rxrpc_purge_queue(&local->reject_queue); - local->socket->ops->shutdown(local->socket, 2); + kernel_sock_shutdown(local->socket, SHUT_RDWR); sock_release(local->socket); up_read(&rxrpc_local_sem); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 53171029439..c3900820916 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -613,17 +613,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key)); n->ht_up = ht; n->handle = handle; -{ - u8 i = 0; - u32 mask = ntohl(s->hmask); - if (mask) { - while (!(mask & 1)) { - i++; - mask>>=1; - } - } - n->fshift = i; -} + n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0; #ifdef CONFIG_CLS_U32_MARK if (tb[TCA_U32_MARK-1]) { diff --git a/net/socket.c b/net/socket.c index 5d879fd3d01..74784dfe8e5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2319,6 +2319,11 @@ int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg) return err; } +int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) +{ + return sock->ops->shutdown(sock, how); +} + /* ABI emulation layers need these two */ EXPORT_SYMBOL(move_addr_to_kernel); EXPORT_SYMBOL(move_addr_to_user); @@ -2345,3 +2350,4 @@ EXPORT_SYMBOL(kernel_getsockopt); EXPORT_SYMBOL(kernel_setsockopt); EXPORT_SYMBOL(kernel_sendpage); EXPORT_SYMBOL(kernel_sock_ioctl); +EXPORT_SYMBOL(kernel_sock_shutdown); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 515e7a692f9..e835da8fc09 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -457,7 +457,7 @@ static int unix_release_sock (struct sock *sk, int embrion) * What the above comment does talk about? --ANK(980817) */ - if (atomic_read(&unix_tot_inflight)) + if (unix_tot_inflight) unix_gc(); /* Garbage collect fds */ return 0; @@ -599,15 +599,14 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) struct sock *sk = NULL; struct unix_sock *u; - if (atomic_read(&unix_nr_socks) >= 2*get_max_files()) + atomic_inc(&unix_nr_socks); + if (atomic_read(&unix_nr_socks) > 2 * get_max_files()) goto out; sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto); if (!sk) goto out; - atomic_inc(&unix_nr_socks); - sock_init_data(sock,sk); lockdep_set_class(&sk->sk_receive_queue.lock, &af_unix_sk_receive_queue_lock_key); @@ -625,6 +624,8 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) init_waitqueue_head(&u->peer_wait); unix_insert_socket(unix_sockets_unbound, sk); out: + if (sk == NULL) + atomic_dec(&unix_nr_socks); return sk; } diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 406b6433e46..ebdff3d877a 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -92,7 +92,7 @@ static LIST_HEAD(gc_inflight_list); static LIST_HEAD(gc_candidates); static DEFINE_SPINLOCK(unix_gc_lock); -atomic_t unix_tot_inflight = ATOMIC_INIT(0); +unsigned int unix_tot_inflight; static struct sock *unix_get_socket(struct file *filp) @@ -133,7 +133,7 @@ void unix_inflight(struct file *fp) } else { BUG_ON(list_empty(&u->link)); } - atomic_inc(&unix_tot_inflight); + unix_tot_inflight++; spin_unlock(&unix_gc_lock); } } @@ -147,7 +147,7 @@ void unix_notinflight(struct file *fp) BUG_ON(list_empty(&u->link)); if (atomic_dec_and_test(&u->inflight)) list_del_init(&u->link); - atomic_dec(&unix_tot_inflight); + unix_tot_inflight--; spin_unlock(&unix_gc_lock); } } @@ -161,7 +161,7 @@ static inline struct sk_buff *sock_queue_head(struct sock *sk) for (skb = sock_queue_head(sk)->next, next = skb->next; \ skb != sock_queue_head(sk); skb = next, next = skb->next) -static void scan_inflight(struct sock *x, void (*func)(struct sock *), +static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff_head *hitlist) { struct sk_buff *skb; @@ -185,9 +185,9 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *), * if it indeed does so */ struct sock *sk = unix_get_socket(*fp++); - if(sk) { + if (sk) { hit = true; - func(sk); + func(unix_sk(sk)); } } if (hit && hitlist != NULL) { @@ -199,7 +199,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct sock *), spin_unlock(&x->sk_receive_queue.lock); } -static void scan_children(struct sock *x, void (*func)(struct sock *), +static void scan_children(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff_head *hitlist) { if (x->sk_state != TCP_LISTEN) @@ -235,20 +235,18 @@ static void scan_children(struct sock *x, void (*func)(struct sock *), } } -static void dec_inflight(struct sock *sk) +static void dec_inflight(struct unix_sock *usk) { - atomic_dec(&unix_sk(sk)->inflight); + atomic_dec(&usk->inflight); } -static void inc_inflight(struct sock *sk) +static void inc_inflight(struct unix_sock *usk) { - atomic_inc(&unix_sk(sk)->inflight); + atomic_inc(&usk->inflight); } -static void inc_inflight_move_tail(struct sock *sk) +static void inc_inflight_move_tail(struct unix_sock *u) { - struct unix_sock *u = unix_sk(sk); - atomic_inc(&u->inflight); /* * If this is still a candidate, move it to the end of the |