summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan.c2
-rw-r--r--net/8021q/vlan_dev.c3
-rw-r--r--net/bridge/br.c4
-rw-r--r--net/bridge/br_fdb.c2
-rw-r--r--net/bridge/br_input.c7
-rw-r--r--net/bridge/netfilter/ebtable_broute.c4
-rw-r--r--net/decnet/dn_dev.c4
-rw-r--r--net/ieee80211/ieee80211_tx.c3
-rw-r--r--net/ipv4/inet_diag.c69
-rw-r--r--net/ipv4/inet_lro.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c7
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c7
-rw-r--r--net/ipv4/ipvs/ip_vs_sched.c27
-rw-r--r--net/ipv4/route.c5
-rw-r--r--net/ipv4/tcp_illinois.c2
-rw-r--r--net/ipv4/tcp_input.c17
-rw-r--r--net/ipv4/tcp_output.c3
-rw-r--r--net/ipv6/addrconf.c11
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/irda/ircomm/ircomm_tty.c2
-rw-r--r--net/mac80211/ieee80211.c10
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/wep.c3
-rw-r--r--net/netfilter/xt_CONNMARK.c10
-rw-r--r--net/netfilter/xt_CONNSECMARK.c10
-rw-r--r--net/netfilter/xt_TCPMSS.c4
-rw-r--r--net/rfkill/rfkill.c14
-rw-r--r--net/rose/rose_dev.c2
-rw-r--r--net/rxrpc/Kconfig1
-rw-r--r--net/rxrpc/rxkad.c1
-rw-r--r--net/sctp/Kconfig6
-rw-r--r--net/sctp/auth.c4
-rw-r--r--net/sctp/bind_addr.c26
-rw-r--r--net/sctp/sm_make_chunk.c25
-rw-r--r--net/sctp/sm_statefuns.c2
-rw-r--r--net/sctp/socket.c18
-rw-r--r--net/unix/af_unix.c9
-rw-r--r--net/xfrm/xfrm_policy.c1
38 files changed, 204 insertions, 128 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 6567213959cb..5b183156307a 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -776,7 +776,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
case SET_VLAN_NAME_TYPE_CMD:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
- return -EPERM;
+ break;
if ((args.u.name_type >= 0) &&
(args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
vlan_name_type = args.u.name_type;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 7a36878241da..4f99bb86af5c 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -462,7 +462,8 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
* OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
*/
- if (veth->h_vlan_proto != htons(ETH_P_8021Q)) {
+ if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
+ VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR) {
int orig_headroom = skb_headroom(skb);
unsigned short veth_TCI;
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 93867bb6cc97..a90182873120 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -39,7 +39,7 @@ static int __init br_init(void)
err = br_fdb_init();
if (err)
- goto err_out1;
+ goto err_out;
err = br_netfilter_init();
if (err)
@@ -65,6 +65,8 @@ err_out3:
err_out2:
br_netfilter_fini();
err_out1:
+ br_fdb_fini();
+err_out:
llc_sap_put(br_stp_sap);
return err;
}
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index eb57502bb264..bc40377136a2 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -44,7 +44,7 @@ int __init br_fdb_init(void)
return 0;
}
-void __exit br_fdb_fini(void)
+void br_fdb_fini(void)
{
kmem_cache_destroy(br_fdb_cache);
}
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 3cedd4eeeed6..0ee79a726d91 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -122,6 +122,7 @@ static inline int is_link_local(const unsigned char *dest)
struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
{
const unsigned char *dest = eth_hdr(skb)->h_dest;
+ int (*rhook)(struct sk_buff *skb);
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
goto drop;
@@ -147,9 +148,9 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
switch (p->state) {
case BR_STATE_FORWARDING:
-
- if (br_should_route_hook) {
- if (br_should_route_hook(skb))
+ rhook = rcu_dereference(br_should_route_hook);
+ if (rhook != NULL) {
+ if (rhook(skb))
return skb;
dest = eth_hdr(skb)->h_dest;
}
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index e44519ebf1d2..be6f18681053 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -70,13 +70,13 @@ static int __init ebtable_broute_init(void)
if (ret < 0)
return ret;
/* see br_input.c */
- br_should_route_hook = ebt_broute;
+ rcu_assign_pointer(br_should_route_hook, ebt_broute);
return ret;
}
static void __exit ebtable_broute_fini(void)
{
- br_should_route_hook = NULL;
+ rcu_assign_pointer(br_should_route_hook, NULL);
synchronize_net();
ebt_unregister_table(&broute_table);
}
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 66e266fb5908..3bc82dc83b38 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -651,16 +651,18 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct dn_dev *dn_db;
struct ifaddrmsg *ifm;
struct dn_ifaddr *ifa, **ifap;
- int err = -EADDRNOTAVAIL;
+ int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
if (err < 0)
goto errout;
+ err = -ENODEV;
ifm = nlmsg_data(nlh);
if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL)
goto errout;
+ err = -EADDRNOTAVAIL;
for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) {
if (tb[IFA_LOCAL] &&
nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index a4c3c51140a3..6d06f1385e28 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -144,7 +144,8 @@ static int ieee80211_copy_snap(u8 * data, u16 h_proto)
snap->oui[1] = oui[1];
snap->oui[2] = oui[2];
- *(u16 *) (data + SNAP_SIZE) = htons(h_proto);
+ h_proto = htons(h_proto);
+ memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16));
return SNAP_SIZE + sizeof(u16);
}
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index b0170732b5e9..e468e7a7aac4 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -51,6 +51,29 @@ static struct sock *idiagnl;
#define INET_DIAG_PUT(skb, attrtype, attrlen) \
RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
+static DEFINE_MUTEX(inet_diag_table_mutex);
+
+static const struct inet_diag_handler *inet_diag_lock_handler(int type)
+{
+#ifdef CONFIG_KMOD
+ if (!inet_diag_table[type])
+ request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+ NETLINK_INET_DIAG, type);
+#endif
+
+ mutex_lock(&inet_diag_table_mutex);
+ if (!inet_diag_table[type])
+ return ERR_PTR(-ENOENT);
+
+ return inet_diag_table[type];
+}
+
+static inline void inet_diag_unlock_handler(
+ const struct inet_diag_handler *handler)
+{
+ mutex_unlock(&inet_diag_table_mutex);
+}
+
static int inet_csk_diag_fill(struct sock *sk,
struct sk_buff *skb,
int ext, u32 pid, u32 seq, u16 nlmsg_flags,
@@ -235,9 +258,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
struct inet_hashinfo *hashinfo;
const struct inet_diag_handler *handler;
- handler = inet_diag_table[nlh->nlmsg_type];
- BUG_ON(handler == NULL);
+ handler = inet_diag_lock_handler(nlh->nlmsg_type);
+ if (!handler)
+ return -ENOENT;
+
hashinfo = handler->idiag_hashinfo;
+ err = -EINVAL;
if (req->idiag_family == AF_INET) {
sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
@@ -255,11 +281,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
}
#endif
else {
- return -EINVAL;
+ goto unlock;
}
+ err = -ENOENT;
if (sk == NULL)
- return -ENOENT;
+ goto unlock;
err = -ESTALE;
if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE ||
@@ -296,6 +323,8 @@ out:
else
sock_put(sk);
}
+unlock:
+ inet_diag_unlock_handler(handler);
return err;
}
@@ -678,8 +707,10 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
const struct inet_diag_handler *handler;
struct inet_hashinfo *hashinfo;
- handler = inet_diag_table[cb->nlh->nlmsg_type];
- BUG_ON(handler == NULL);
+ handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
+ if (!handler)
+ goto no_handler;
+
hashinfo = handler->idiag_hashinfo;
s_i = cb->args[1];
@@ -743,7 +774,7 @@ skip_listen_ht:
}
if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
- return skb->len;
+ goto unlock;
for (i = s_i; i < hashinfo->ehash_size; i++) {
struct inet_ehash_bucket *head = &hashinfo->ehash[i];
@@ -805,6 +836,9 @@ next_dying:
done:
cb->args[1] = i;
cb->args[2] = num;
+unlock:
+ inet_diag_unlock_handler(handler);
+no_handler:
return skb->len;
}
@@ -816,15 +850,6 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
nlmsg_len(nlh) < hdrlen)
return -EINVAL;
-#ifdef CONFIG_KMOD
- if (inet_diag_table[nlh->nlmsg_type] == NULL)
- request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
- NETLINK_INET_DIAG, nlh->nlmsg_type);
-#endif
-
- if (inet_diag_table[nlh->nlmsg_type] == NULL)
- return -ENOENT;
-
if (nlh->nlmsg_flags & NLM_F_DUMP) {
if (nlmsg_attrlen(nlh, hdrlen)) {
struct nlattr *attr;
@@ -853,8 +878,6 @@ static void inet_diag_rcv(struct sk_buff *skb)
mutex_unlock(&inet_diag_mutex);
}
-static DEFINE_SPINLOCK(inet_diag_register_lock);
-
int inet_diag_register(const struct inet_diag_handler *h)
{
const __u16 type = h->idiag_type;
@@ -863,13 +886,13 @@ int inet_diag_register(const struct inet_diag_handler *h)
if (type >= INET_DIAG_GETSOCK_MAX)
goto out;
- spin_lock(&inet_diag_register_lock);
+ mutex_lock(&inet_diag_table_mutex);
err = -EEXIST;
if (inet_diag_table[type] == NULL) {
inet_diag_table[type] = h;
err = 0;
}
- spin_unlock(&inet_diag_register_lock);
+ mutex_unlock(&inet_diag_table_mutex);
out:
return err;
}
@@ -882,11 +905,9 @@ void inet_diag_unregister(const struct inet_diag_handler *h)
if (type >= INET_DIAG_GETSOCK_MAX)
return;
- spin_lock(&inet_diag_register_lock);
+ mutex_lock(&inet_diag_table_mutex);
inet_diag_table[type] = NULL;
- spin_unlock(&inet_diag_register_lock);
-
- synchronize_rcu();
+ mutex_unlock(&inet_diag_table_mutex);
}
EXPORT_SYMBOL_GPL(inet_diag_unregister);
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c
index ac3b1d3dba2e..9a96c277393d 100644
--- a/net/ipv4/inet_lro.c
+++ b/net/ipv4/inet_lro.c
@@ -401,10 +401,11 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr,
int data_len = len;
int hdr_len = min(len, hlen);
- skb = netdev_alloc_skb(lro_mgr->dev, hlen);
+ skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad);
if (!skb)
return NULL;
+ skb_reserve(skb, lro_mgr->frag_align_pad);
skb->len = len;
skb->data_len = len - hdr_len;
skb->truesize += true_size;
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index b843a11d7cf7..ad89644ef5d2 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -580,9 +580,14 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
static int __init ip_vs_lblc_init(void)
{
+ int ret;
+
INIT_LIST_HEAD(&ip_vs_lblc_scheduler.n_list);
sysctl_header = register_sysctl_table(lblc_root_table);
- return register_ip_vs_scheduler(&ip_vs_lblc_scheduler);
+ ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler);
+ if (ret)
+ unregister_sysctl_table(sysctl_header);
+ return ret;
}
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index e5b323a6b2f7..2a5ed85a3352 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -769,9 +769,14 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
static int __init ip_vs_lblcr_init(void)
{
+ int ret;
+
INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
sysctl_header = register_sysctl_table(lblcr_root_table);
- return register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
+ ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
+ if (ret)
+ unregister_sysctl_table(sysctl_header);
+ return ret;
}
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
index 1602304abbf9..432235861908 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/ipv4/ipvs/ip_vs_sched.c
@@ -183,19 +183,6 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
/* increase the module use count */
ip_vs_use_count_inc();
- /*
- * Make sure that the scheduler with this name doesn't exist
- * in the scheduler list.
- */
- sched = ip_vs_sched_getbyname(scheduler->name);
- if (sched) {
- ip_vs_scheduler_put(sched);
- ip_vs_use_count_dec();
- IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler "
- "already existed in the system\n", scheduler->name);
- return -EINVAL;
- }
-
write_lock_bh(&__ip_vs_sched_lock);
if (scheduler->n_list.next != &scheduler->n_list) {
@@ -207,6 +194,20 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
}
/*
+ * Make sure that the scheduler with this name doesn't exist
+ * in the scheduler list.
+ */
+ list_for_each_entry(sched, &ip_vs_schedulers, n_list) {
+ if (strcmp(scheduler->name, sched->name) == 0) {
+ write_unlock_bh(&__ip_vs_sched_lock);
+ ip_vs_use_count_dec();
+ IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler "
+ "already existed in the system\n",
+ scheduler->name);
+ return -EINVAL;
+ }
+ }
+ /*
* Add it into the d-linked scheduler list
*/
list_add(&scheduler->n_list, &ip_vs_schedulers);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index c426dec6d579..d2bc6148a737 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1161,7 +1161,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
rt->fl.oif);
#if RT_CACHE_DEBUG >= 1
- printk(KERN_DEBUG "ip_rt_advice: redirect to "
+ printk(KERN_DEBUG "ipv4_negative_advice: redirect to "
"%u.%u.%u.%u/%02x dropped\n",
NIPQUAD(rt->rt_dst), rt->fl.fl4_tos);
#endif
@@ -1252,6 +1252,7 @@ static int ip_error(struct sk_buff *skb)
break;
case ENETUNREACH:
code = ICMP_NET_UNREACH;
+ IP_INC_STATS_BH(IPSTATS_MIB_INNOROUTES);
break;
case EACCES:
code = ICMP_PKT_FILTERED;
@@ -1881,6 +1882,8 @@ no_route:
RT_CACHE_STAT_INC(in_no_route);
spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
res.type = RTN_UNREACHABLE;
+ if (err == -ESRCH)
+ err = -ENETUNREACH;
goto local_input;
/*
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
index 64f1cbaf96e8..5aa5f5496d6d 100644
--- a/net/ipv4/tcp_illinois.c
+++ b/net/ipv4/tcp_illinois.c
@@ -298,7 +298,7 @@ static u32 tcp_illinois_ssthresh(struct sock *sk)
struct illinois *ca = inet_csk_ca(sk);
/* Multiplicative decrease */
- return max((tp->snd_cwnd * ca->beta) >> BETA_SHIFT, 2U);
+ return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->beta) >> BETA_SHIFT), 2U);
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0f0c1c9829a1..b9e429d2d1de 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3003,17 +3003,13 @@ static int tcp_process_frto(struct sock *sk, int flag)
}
if (tp->frto_counter == 1) {
- /* Sending of the next skb must be allowed or no F-RTO */
- if (!tcp_send_head(sk) ||
- after(TCP_SKB_CB(tcp_send_head(sk))->end_seq,
- tp->snd_una + tp->snd_wnd)) {
- tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 2 : 3),
- flag);
- return 1;
- }
-
+ /* tcp_may_send_now needs to see updated state */
tp->snd_cwnd = tcp_packets_in_flight(tp) + 2;
tp->frto_counter = 2;
+
+ if (!tcp_may_send_now(sk))
+ tcp_enter_frto_loss(sk, 2, flag);
+
return 1;
} else {
switch (sysctl_tcp_frto_response) {
@@ -3069,6 +3065,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
}
prior_fackets = tp->fackets_out;
+ prior_in_flight = tcp_packets_in_flight(tp);
if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
/* Window is constant, pure forward advance.
@@ -3108,8 +3105,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
if (!prior_packets)
goto no_queue;
- 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, prior_fackets);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index e5130a7fe181..f4c1eef89af0 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1162,8 +1162,7 @@ int tcp_may_send_now(struct sock *sk)
return (skb &&
tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
(tcp_skb_is_last(sk, skb) ?
- TCP_NAGLE_PUSH :
- tp->nonagle)));
+ tp->nonagle : TCP_NAGLE_PUSH)));
}
/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 567664eac463..e8c347579da9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2293,6 +2293,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
break;
}
+ if (!idev && dev->mtu >= IPV6_MIN_MTU)
+ idev = ipv6_add_dev(dev);
+
if (idev)
idev->if_flags |= IF_READY;
} else {
@@ -2357,12 +2360,18 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
break;
case NETDEV_CHANGEMTU:
- if ( idev && dev->mtu >= IPV6_MIN_MTU) {
+ if (idev && dev->mtu >= IPV6_MIN_MTU) {
rt6_mtu_change(dev, dev->mtu);
idev->cnf.mtu6 = dev->mtu;
break;
}
+ if (!idev && dev->mtu >= IPV6_MIN_MTU) {
+ idev = ipv6_add_dev(dev);
+ if (idev)
+ break;
+ }
+
/* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */
case NETDEV_DOWN:
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 86e1835ce4e4..6338a9c1aa14 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -933,6 +933,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
return 0;
out_err_release:
+ if (err == -ENETUNREACH)
+ IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES);
dst_release(*dst);
*dst = NULL;
return err;
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 1120b150e211..be627e1f04d8 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -1245,6 +1245,7 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
self->flow = cmd;
}
+#ifdef CONFIG_PROC_FS
static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
{
int ret=0;
@@ -1354,7 +1355,6 @@ static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
*
*
*/
-#ifdef CONFIG_PROC_FS
static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
int *eof, void *unused)
{
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 59350b8727ec..505af1f067ab 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -216,6 +216,7 @@ static int ieee80211_open(struct net_device *dev)
res = local->ops->start(local_to_hw(local));
if (res)
return res;
+ ieee80211_hw_config(local);
}
switch (sdata->type) {
@@ -232,7 +233,6 @@ static int ieee80211_open(struct net_device *dev)
netif_tx_unlock_bh(local->mdev);
local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
- ieee80211_hw_config(local);
}
break;
case IEEE80211_IF_TYPE_STA:
@@ -334,8 +334,7 @@ static int ieee80211_stop(struct net_device *dev)
ieee80211_configure_filter(local);
netif_tx_unlock_bh(local->mdev);
- local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
- ieee80211_hw_config(local);
+ local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
}
break;
case IEEE80211_IF_TYPE_STA:
@@ -357,6 +356,11 @@ static int ieee80211_stop(struct net_device *dev)
cancel_delayed_work(&local->scan_work);
}
flush_workqueue(local->hw.workqueue);
+
+ sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
+ kfree(sdata->u.sta.extra_ie);
+ sdata->u.sta.extra_ie = NULL;
+ sdata->u.sta.extra_ie_len = 0;
/* fall through */
default:
conf.if_id = dev->ifindex;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 428a9fcf57d6..00f908d9275e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -997,7 +997,7 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
(rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
(rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
- rx->sdata->drop_unencrypted &&
+ (rx->key || rx->sdata->drop_unencrypted) &&
(rx->sdata->eapol == 0 || !ieee80211_is_eapol(rx->skb)))) {
if (net_ratelimit())
printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 9bf0e1cc530a..b5f3413403bd 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -265,7 +265,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
skb->data + hdrlen + WEP_IV_LEN,
len)) {
- printk(KERN_DEBUG "WEP decrypt failed (ICV)\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "WEP decrypt failed (ICV)\n");
ret = -1;
}
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 856793e8db7a..0621ca7de3b0 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -86,11 +86,6 @@ checkentry(const char *tablename,
{
const struct xt_connmark_target_info *matchinfo = targinfo;
- if (nf_ct_l3proto_try_module_get(target->family) < 0) {
- printk(KERN_WARNING "can't load conntrack support for "
- "proto=%d\n", target->family);
- return false;
- }
if (matchinfo->mode == XT_CONNMARK_RESTORE) {
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "CONNMARK: restore can only be "
@@ -103,6 +98,11 @@ checkentry(const char *tablename,
printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
return false;
}
+ if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", target->family);
+ return false;
+ }
return true;
}
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 021b5c8d20e2..d8feba9bdb48 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -90,11 +90,6 @@ static bool checkentry(const char *tablename, const void *entry,
{
const struct xt_connsecmark_target_info *info = targinfo;
- if (nf_ct_l3proto_try_module_get(target->family) < 0) {
- printk(KERN_WARNING "can't load conntrack support for "
- "proto=%d\n", target->family);
- return false;
- }
switch (info->mode) {
case CONNSECMARK_SAVE:
case CONNSECMARK_RESTORE:
@@ -105,6 +100,11 @@ static bool checkentry(const char *tablename, const void *entry,
return false;
}
+ if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+ printk(KERN_WARNING "can't load conntrack support for "
+ "proto=%d\n", target->family);
+ return false;
+ }
return true;
}
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 07435a602b11..8e76d1f52fbe 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -174,10 +174,8 @@ xt_tcpmss_target6(struct sk_buff *skb,
nexthdr = ipv6h->nexthdr;
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
- if (tcphoff < 0) {
- WARN_ON(1);
+ if (tcphoff < 0)
return NF_DROP;
- }
ret = tcpmss_mangle_packet(skb, targinfo, tcphoff,
sizeof(*ipv6h) + sizeof(struct tcphdr));
if (ret < 0)
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 73d60a307129..4469a7be006c 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -60,11 +60,7 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
static int rfkill_toggle_radio(struct rfkill *rfkill,
enum rfkill_state state)
{
- int retval;
-
- retval = mutex_lock_interruptible(&rfkill->mutex);
- if (retval)
- return retval;
+ int retval = 0;
if (state != rfkill->state) {
retval = rfkill->toggle_radio(rfkill->data, state);
@@ -74,7 +70,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
}
}
- mutex_unlock(&rfkill->mutex);
return retval;
}
@@ -158,12 +153,13 @@ static ssize_t rfkill_state_store(struct device *dev,
if (!capable(CAP_NET_ADMIN))
return -EPERM;
+ if (mutex_lock_interruptible(&rfkill->mutex))
+ return -ERESTARTSYS;
error = rfkill_toggle_radio(rfkill,
state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
- if (error)
- return error;
+ mutex_unlock(&rfkill->mutex);
- return count;
+ return error ? error : count;
}
static ssize_t rfkill_claim_show(struct device *dev,
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 1b6741f1d746..12cfcf09556b 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -55,13 +55,13 @@ static int rose_header(struct sk_buff *skb, struct net_device *dev,
static int rose_rebuild_header(struct sk_buff *skb)
{
+#ifdef CONFIG_INET
struct net_device *dev = skb->dev;
struct net_device_stats *stats = netdev_priv(dev);
unsigned char *bp = (unsigned char *)skb->data;
struct sk_buff *skbn;
unsigned int len;
-#ifdef CONFIG_INET
if (arp_find(bp + 7, skb)) {
return 1;
}
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index e662f1d07664..0d3103c4f11c 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -5,6 +5,7 @@
config AF_RXRPC
tristate "RxRPC session sockets"
depends on INET && EXPERIMENTAL
+ select CRYPTO
select KEYS
help
Say Y or M here to include support for RxRPC session sockets (just
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index e09a95aa68ff..8e69d6993833 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -1021,6 +1021,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
abort_code = RXKADINCONSISTENCY;
if (version != RXKAD_VERSION)
+ goto protocol_error;
abort_code = RXKADTICKETLEN;
if (ticket_len < 4 || ticket_len > MAXKRB5TICKETLEN)
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index 8210f549c492..5390bc792159 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -6,9 +6,9 @@ menuconfig IP_SCTP
tristate "The SCTP Protocol (EXPERIMENTAL)"
depends on INET && EXPERIMENTAL
depends on IPV6 || IPV6=n
- select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
- select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
- select CRYPTO_SHA1 if SCTP_HMAC_SHA1
+ select CRYPTO
+ select CRYPTO_HMAC
+ select CRYPTO_SHA1
select CRYPTO_MD5 if SCTP_HMAC_MD5
---help---
Stream Control Transmission Protocol
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 6d5fa6bb371b..97e6ebd14500 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -54,11 +54,13 @@ static struct sctp_hmac sctp_hmac_list[SCTP_AUTH_NUM_HMACS] = {
/* id 2 is reserved as well */
.hmac_id = SCTP_AUTH_HMAC_ID_RESERVED_2,
},
+#if defined (CONFIG_CRYPTO_SHA256) || defined (CONFIG_CRYPTO_SHA256_MODULE)
{
.hmac_id = SCTP_AUTH_HMAC_ID_SHA256,
.hmac_name="hmac(sha256)",
.hmac_len = SCTP_SHA256_SIG_SIZE,
}
+#endif
};
@@ -631,7 +633,7 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)
int found = 0;
int i;
- if (!param)
+ if (!param || param->param_hdr.length == 0)
return 0;
len = ntohs(param->param_hdr.length) - sizeof(sctp_paramhdr_t);
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index cae95af9a8cc..6a7d01091f0c 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -105,6 +105,32 @@ out:
return error;
}
+/* Exactly duplicate the address lists. This is necessary when doing
+ * peer-offs and accepts. We don't want to put all the current system
+ * addresses into the endpoint. That's useless. But we do want duplicat
+ * the list of bound addresses that the older endpoint used.
+ */
+int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
+ const struct sctp_bind_addr *src,
+ gfp_t gfp)
+{
+ struct sctp_sockaddr_entry *addr;
+ struct list_head *pos;
+ int error = 0;
+
+ /* All addresses share the same port. */
+ dest->port = src->port;
+
+ list_for_each(pos, &src->address_list) {
+ addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+ error = sctp_add_bind_addr(dest, &addr->a, 1, gfp);
+ if (error < 0)
+ break;
+ }
+
+ return error;
+}
+
/* Initialize the SCTP_bind_addr structure for either an endpoint or
* an association.
*/
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 5a9783c38de1..f4876291bb5e 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -77,6 +77,8 @@ static int sctp_process_param(struct sctp_association *asoc,
union sctp_params param,
const union sctp_addr *peer_addr,
gfp_t gfp);
+static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
+ const void *data);
/* What was the inbound interface for this chunk? */
int sctp_chunk_iif(const struct sctp_chunk *chunk)
@@ -207,11 +209,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
chunksize += sizeof(ecap_param);
- if (sctp_prsctp_enable) {
- chunksize += sizeof(prsctp_param);
- extensions[num_ext] = SCTP_CID_FWD_TSN;
- num_ext += 1;
- }
+
/* ADDIP: Section 4.2.7:
* An implementation supporting this extension [ADDIP] MUST list
* the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
@@ -243,7 +241,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
if (auth_chunks->length)
chunksize += ntohs(auth_chunks->length);
else
- auth_hmacs = NULL;
+ auth_chunks = NULL;
extensions[num_ext] = SCTP_CID_AUTH;
num_ext += 1;
@@ -297,7 +295,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
htons(sizeof(sctp_supported_ext_param_t) + num_ext);
sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t),
&ext_param);
- sctp_addto_chunk(retval, num_ext, extensions);
+ sctp_addto_param(retval, num_ext, extensions);
}
if (sctp_prsctp_enable)
@@ -371,20 +369,12 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
if (asoc->peer.ecn_capable)
chunksize += sizeof(ecap_param);
- /* Tell peer that we'll do PR-SCTP only if peer advertised. */
- if (asoc->peer.prsctp_capable) {
- chunksize += sizeof(prsctp_param);
- extensions[num_ext] = SCTP_CID_FWD_TSN;
- num_ext += 1;
- }
-
if (sctp_addip_enable) {
extensions[num_ext] = SCTP_CID_ASCONF;
extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
num_ext += 2;
}
- chunksize += sizeof(ext_param) + num_ext;
chunksize += sizeof(aiparam);
if (asoc->peer.auth_capable) {
@@ -407,6 +397,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
num_ext += 1;
}
+ if (num_ext)
+ chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+
/* Now allocate and fill out the chunk. */
retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
if (!retval)
@@ -428,7 +421,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
htons(sizeof(sctp_supported_ext_param_t) + num_ext);
sctp_addto_chunk(retval, sizeof(sctp_supported_ext_param_t),
&ext_param);
- sctp_addto_chunk(retval, num_ext, extensions);
+ sctp_addto_param(retval, num_ext, extensions);
}
if (asoc->peer.prsctp_capable)
sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b8bbb960723c..5fb84778846d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -959,7 +959,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
{
struct sctp_transport *transport = (struct sctp_transport *) arg;
- if (asoc->overall_error_count >= asoc->max_retrans) {
+ if (asoc->overall_error_count > asoc->max_retrans) {
sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
SCTP_ERROR(ETIMEDOUT));
/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff8bc95670ed..ea9649ca0b2a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6325,7 +6325,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
struct sctp_endpoint *newep = newsp->ep;
struct sk_buff *skb, *tmp;
struct sctp_ulpevent *event;
- int flags = 0;
+ struct sctp_bind_hashbucket *head;
/* Migrate socket buffer sizes and all the socket level options to the
* new socket.
@@ -6342,23 +6342,21 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
newsp->hmac = NULL;
/* Hook this new socket in to the bind_hash list. */
+ head = &sctp_port_hashtable[sctp_phashfn(inet_sk(oldsk)->num)];
+ sctp_local_bh_disable();
+ sctp_spin_lock(&head->lock);
pp = sctp_sk(oldsk)->bind_hash;
sk_add_bind_node(newsk, &pp->owner);
sctp_sk(newsk)->bind_hash = pp;
inet_sk(newsk)->num = inet_sk(oldsk)->num;
+ sctp_spin_unlock(&head->lock);
+ sctp_local_bh_enable();
/* Copy the bind_addr list from the original endpoint to the new
* endpoint so that we can handle restarts properly
*/
- if (PF_INET6 == assoc->base.sk->sk_family)
- flags = SCTP_ADDR6_ALLOWED;
- if (assoc->peer.ipv4_address)
- flags |= SCTP_ADDR4_PEERSUPP;
- if (assoc->peer.ipv6_address)
- flags |= SCTP_ADDR6_PEERSUPP;
- sctp_bind_addr_copy(&newsp->ep->base.bind_addr,
- &oldsp->ep->base.bind_addr,
- SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags);
+ sctp_bind_addr_dup(&newsp->ep->base.bind_addr,
+ &oldsp->ep->base.bind_addr, GFP_KERNEL);
/* Move any messages in the old socket's receive queue that are for the
* peeled off association to the new socket's receive queue.
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e835da8fc091..060bba4567d2 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1637,8 +1637,15 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
mutex_lock(&u->readlock);
skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb)
+ if (!skb) {
+ unix_state_lock(sk);
+ /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
+ if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
+ (sk->sk_shutdown & RCV_SHUTDOWN))
+ err = 0;
+ unix_state_unlock(sk);
goto out_unlock;
+ }
wake_up_interruptible_sync(&u->peer_wait);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b702bd8a3893..9a4cf2e45a15 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1344,6 +1344,7 @@ restart:
xfrm_nr += pols[0]->xfrm_nr;
switch (policy->action) {
+ default:
case XFRM_POLICY_BLOCK:
/* Prohibit the flow */
err = -EPERM;