summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan.c14
-rw-r--r--net/atm/common.c2
-rw-r--r--net/ax25/af_ax25.c1
-rw-r--r--net/batman-adv/bat_iv_ogm.c6
-rw-r--r--net/bluetooth/af_bluetooth.c4
-rw-r--r--net/bluetooth/rfcomm/sock.c1
-rw-r--r--net/bluetooth/sco.c2
-rw-r--r--net/bridge/br_mdb.c4
-rw-r--r--net/bridge/br_netlink.c1
-rw-r--r--net/caif/caif_socket.c2
-rw-r--r--net/can/gw.c6
-rw-r--r--net/core/dev.c113
-rw-r--r--net/core/dev_addr_lists.c6
-rw-r--r--net/core/dst.c1
-rw-r--r--net/core/flow.c2
-rw-r--r--net/core/rtnetlink.c7
-rw-r--r--net/core/scm.c4
-rw-r--r--net/core/skbuff.c6
-rw-r--r--net/core/sock.c11
-rw-r--r--net/core/sock_diag.c3
-rw-r--r--net/dcb/dcbnl.c8
-rw-r--r--net/ieee802154/6lowpan.c2
-rw-r--r--net/ieee802154/6lowpan.h2
-rw-r--r--net/ipv4/af_inet.c11
-rw-r--r--net/ipv4/esp4.c6
-rw-r--r--net/ipv4/icmp.c53
-rw-r--r--net/ipv4/inet_fragment.c20
-rw-r--r--net/ipv4/ip_fragment.c26
-rw-r--r--net/ipv4/ip_gre.c5
-rw-r--r--net/ipv4/ip_options.c5
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/netfilter/ipt_rpfilter.c8
-rw-r--r--net/ipv4/ping.c4
-rw-r--r--net/ipv4/syncookies.c4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_input.c77
-rw-r--r--net/ipv4/tcp_ipv4.c14
-rw-r--r--net/ipv4/tcp_output.c34
-rw-r--r--net/ipv6/addrconf.c53
-rw-r--r--net/ipv6/ip6_input.c24
-rw-r--r--net/ipv6/netfilter/ip6t_NPT.c2
-rw-r--r--net/ipv6/netfilter/ip6t_rpfilter.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c12
-rw-r--r--net/ipv6/reassembly.c21
-rw-r--r--net/ipv6/route.c11
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/irda/af_irda.c8
-rw-r--r--net/iucv/af_iucv.c2
-rw-r--r--net/l2tp/l2tp_ip6.c1
-rw-r--r--net/l2tp/l2tp_ppp.c1
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/mac80211/cfg.c6
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c43
-rw-r--r--net/mac80211/offchannel.c23
-rw-r--r--net/mac80211/pm.c4
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/sta_info.c12
-rw-r--r--net/netfilter/core.c6
-rw-r--r--net/netfilter/ipset/ip_set_core.c3
-rw-r--r--net/netfilter/ipset/ip_set_list_set.c10
-rw-r--r--net/netfilter/ipvs/ip_vs_pe_sip.c6
-rw-r--r--net/netfilter/nf_conntrack_helper.c4
-rw-r--r--net/netfilter/nf_conntrack_netlink.c3
-rw-r--r--net/netfilter/nf_conntrack_sip.c2
-rw-r--r--net/netfilter/nf_nat_core.c40
-rw-r--r--net/netlabel/netlabel_unlabeled.c27
-rw-r--r--net/netlink/genetlink.c1
-rw-r--r--net/netrom/af_netrom.c1
-rw-r--r--net/nfc/llcp/sock.c3
-rw-r--r--net/packet/af_packet.c5
-rw-r--r--net/rds/ib_rdma.c3
-rw-r--r--net/rds/message.c3
-rw-r--r--net/rose/af_rose.c1
-rw-r--r--net/sched/sch_cbq.c5
-rw-r--r--net/sched/sch_fq_codel.c2
-rw-r--r--net/sctp/associola.c2
-rw-r--r--net/sctp/sm_statefuns.c2
-rw-r--r--net/sctp/socket.c6
-rw-r--r--net/sunrpc/clnt.c4
-rw-r--r--net/sunrpc/sched.c9
-rw-r--r--net/sunrpc/svc.c9
-rw-r--r--net/sunrpc/svc_xprt.c72
-rw-r--r--net/sunrpc/xprt.c6
-rw-r--r--net/tipc/socket.c7
-rw-r--r--net/unix/af_unix.c9
-rw-r--r--net/wireless/reg.c2
89 files changed, 342 insertions, 648 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index acc74ad..a292e80 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -86,6 +86,13 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
grp = &vlan_info->grp;
+ /* Take it out of our own structures, but be sure to interlock with
+ * HW accelerating devices or SW vlan input packet processing if
+ * VLAN is not 0 (leave it there for 802.1p).
+ */
+ if (vlan_id)
+ vlan_vid_del(real_dev, vlan_id);
+
grp->nr_vlan_devs--;
if (vlan->flags & VLAN_FLAG_GVRP)
@@ -101,13 +108,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
if (grp->nr_vlan_devs == 0)
vlan_gvrp_uninit_applicant(real_dev);
- /* Take it out of our own structures, but be sure to interlock with
- * HW accelerating devices or SW vlan input packet processing if
- * VLAN is not 0 (leave it there for 802.1p).
- */
- if (vlan_id)
- vlan_vid_del(real_dev, vlan_id);
-
/* Get rid of the vlan's reference to real_dev */
dev_put(real_dev);
}
diff --git a/net/atm/common.c b/net/atm/common.c
index cf4b7e6..806fc0a 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -532,8 +532,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
struct sk_buff *skb;
int copied, error = -EINVAL;
- msg->msg_namelen = 0;
-
if (sock->state != SS_CONNECTED)
return -ENOTCONN;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index d53a123..779095d 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1647,7 +1647,6 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
ax25_address src;
const unsigned char *mac = skb_mac_header(skb);
- memset(sax, 0, sizeof(struct full_sockaddr_ax25));
ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
&digi, NULL, NULL);
sax->sax25_family = AF_AX25;
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 1ee94d0..7d02ebd 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -1298,8 +1298,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
/* unpack the aggregated packets and process them one by one */
- while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
- batadv_ogm_packet->tt_num_changes)) {
+ do {
tt_buff = packet_buff + buff_pos + BATADV_OGM_HLEN;
batadv_iv_ogm_process(ethhdr, batadv_ogm_packet, tt_buff,
@@ -1310,7 +1309,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
packet_pos = packet_buff + buff_pos;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
- }
+ } while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
+ batadv_ogm_packet->tt_num_changes));
kfree_skb(skb);
return NET_RX_SUCCESS;
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index b04795e..5355df6 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -230,8 +230,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags & (MSG_OOB))
return -EOPNOTSUPP;
- msg->msg_namelen = 0;
-
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) {
if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -239,6 +237,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return err;
}
+ msg->msg_namelen = 0;
+
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 970fc13..ce3f665 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -610,7 +610,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
- msg->msg_namelen = 0;
return 0;
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index cc16d1b..57f250c 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -361,7 +361,6 @@ static void __sco_sock_close(struct sock *sk)
sco_chan_del(sk, ECONNRESET);
break;
- case BT_CONNECT2:
case BT_CONNECT:
case BT_DISCONN:
sco_chan_del(sk, ECONNRESET);
@@ -667,7 +666,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
hci_conn_accept(pi->conn->hcon, 0);
sk->sk_state = BT_CONFIG;
- msg->msg_namelen = 0;
release_sock(sk);
return 0;
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 2897e40..acc9f4c 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -82,7 +82,6 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
port = p->port;
if (port) {
struct br_mdb_entry e;
- memset(&e, 0, sizeof(e));
e.ifindex = port->dev->ifindex;
e.state = p->state;
if (p->addr.proto == htons(ETH_P_IP))
@@ -139,7 +138,6 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
break;
bpm = nlmsg_data(nlh);
- memset(bpm, 0, sizeof(*bpm));
bpm->ifindex = dev->ifindex;
if (br_mdb_fill_info(skb, cb, dev) < 0)
goto out;
@@ -175,7 +173,6 @@ static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
return -EMSGSIZE;
bpm = nlmsg_data(nlh);
- memset(bpm, 0, sizeof(*bpm));
bpm->family = AF_BRIDGE;
bpm->ifindex = dev->ifindex;
nest = nla_nest_start(skb, MDBA_MDB);
@@ -233,7 +230,6 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
{
struct br_mdb_entry entry;
- memset(&entry, 0, sizeof(entry));
entry.ifindex = port->dev->ifindex;
entry.addr.proto = group->proto;
entry.addr.u.ip4 = group->u.ip4;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 580e176..5dc66ab 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -28,7 +28,6 @@ static inline size_t br_port_info_size(void)
+ nla_total_size(1) /* IFLA_BRPORT_MODE */
+ nla_total_size(1) /* IFLA_BRPORT_GUARD */
+ nla_total_size(1) /* IFLA_BRPORT_PROTECT */
- + nla_total_size(1) /* IFLA_BRPORT_FAST_LEAVE */
+ 0;
}
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index ff2ff3c..095259f 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
if (m->msg_flags&MSG_OOB)
goto read_error;
- m->msg_namelen = 0;
-
skb = skb_recv_datagram(sk, flags, 0 , &ret);
if (!skb)
goto read_error;
diff --git a/net/can/gw.c b/net/can/gw.c
index 28e7bdc..574dda78e 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -436,7 +436,7 @@ static int cgw_notifier(struct notifier_block *nb,
if (gwj->src.dev == dev || gwj->dst.dev == dev) {
hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kmem_cache_free(cgw_cache, gwj);
+ kfree(gwj);
}
}
}
@@ -829,7 +829,7 @@ static void cgw_remove_all_jobs(void)
hlist_for_each_entry_safe(gwj, n, nx, &cgw_list, list) {
hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kmem_cache_free(cgw_cache, gwj);
+ kfree(gwj);
}
}
@@ -885,7 +885,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
hlist_del(&gwj->list);
cgw_unregister_filter(gwj);
- kmem_cache_free(cgw_cache, gwj);
+ kfree(gwj);
err = 0;
break;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index 67c8074..147a682 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -203,7 +203,7 @@ static struct list_head offload_base __read_mostly;
DEFINE_RWLOCK(dev_base_lock);
EXPORT_SYMBOL(dev_base_lock);
-DEFINE_MUTEX(devnet_rename_mutex);
+seqcount_t devnet_rename_seq;
static inline void dev_base_seq_inc(struct net *net)
{
@@ -225,14 +225,14 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex)
static inline void rps_lock(struct softnet_data *sd)
{
#ifdef CONFIG_RPS
- raw_spin_lock(&sd->input_pkt_queue.raw_lock);
+ spin_lock(&sd->input_pkt_queue.lock);
#endif
}
static inline void rps_unlock(struct softnet_data *sd)
{
#ifdef CONFIG_RPS
- raw_spin_unlock(&sd->input_pkt_queue.raw_lock);
+ spin_unlock(&sd->input_pkt_queue.lock);
#endif
}
@@ -1093,11 +1093,10 @@ int dev_change_name(struct net_device *dev, const char *newname)
if (dev->flags & IFF_UP)
return -EBUSY;
-
- mutex_lock(&devnet_rename_mutex);
+ write_seqcount_begin(&devnet_rename_seq);
if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
- mutex_unlock(&devnet_rename_mutex);
+ write_seqcount_end(&devnet_rename_seq);
return 0;
}
@@ -1105,7 +1104,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
err = dev_get_valid_name(net, dev, newname);
if (err < 0) {
- mutex_unlock(&devnet_rename_mutex);
+ write_seqcount_end(&devnet_rename_seq);
return err;
}
@@ -1113,11 +1112,11 @@ rollback:
ret = device_rename(&dev->dev, dev->name);
if (ret) {
memcpy(dev->name, oldname, IFNAMSIZ);
- mutex_unlock(&devnet_rename_mutex);
+ write_seqcount_end(&devnet_rename_seq);
return ret;
}
- mutex_unlock(&devnet_rename_mutex);
+ write_seqcount_end(&devnet_rename_seq);
write_lock_bh(&dev_base_lock);
hlist_del_rcu(&dev->name_hlist);
@@ -1136,7 +1135,7 @@ rollback:
/* err >= 0 after dev_alloc_name() or stores the first errno */
if (err >= 0) {
err = ret;
- mutex_lock(&devnet_rename_mutex);
+ write_seqcount_begin(&devnet_rename_seq);
memcpy(dev->name, oldname, IFNAMSIZ);
goto rollback;
} else {
@@ -1592,6 +1591,7 @@ void net_enable_timestamp(void)
return;
}
#endif
+ WARN_ON(in_interrupt());
static_key_slow_inc(&netstamp_needed);
}
EXPORT_SYMBOL(net_enable_timestamp);
@@ -1738,7 +1738,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
skb->mark = 0;
secpath_reset(skb);
nf_reset(skb);
- nf_reset_trace(skb);
return netif_rx(skb);
}
EXPORT_SYMBOL_GPL(dev_forward_skb);
@@ -1947,7 +1946,6 @@ static inline void __netif_reschedule(struct Qdisc *q)
sd->output_queue_tailp = &q->next_sched;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
- preempt_check_resched_rt();
}
void __netif_schedule(struct Qdisc *q)
@@ -1969,7 +1967,6 @@ void dev_kfree_skb_irq(struct sk_buff *skb)
sd->completion_queue = skb;
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_restore(flags);
- preempt_check_resched_rt();
}
}
EXPORT_SYMBOL(dev_kfree_skb_irq);
@@ -2021,9 +2018,6 @@ static void skb_warn_bad_offload(const struct sk_buff *skb)
struct net_device *dev = skb->dev;
const char *driver = "";
- if (!net_ratelimit())
- return;
-
if (dev && dev->dev.parent)
driver = dev_driver_string(dev->dev.parent);
@@ -3084,7 +3078,6 @@ enqueue:
rps_unlock(sd);
local_irq_restore(flags);
- preempt_check_resched_rt();
atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
@@ -3122,7 +3115,7 @@ int netif_rx(struct sk_buff *skb)
struct rps_dev_flow voidflow, *rflow = &voidflow;
int cpu;
- migrate_disable();
+ preempt_disable();
rcu_read_lock();
cpu = get_rps_cpu(skb->dev, skb, &rflow);
@@ -3132,13 +3125,13 @@ int netif_rx(struct sk_buff *skb)
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
rcu_read_unlock();
- migrate_enable();
+ preempt_enable();
} else
#endif
{
unsigned int qtail;
- ret = enqueue_to_backlog(skb, get_cpu_light(), &qtail);
- put_cpu_light();
+ ret = enqueue_to_backlog(skb, get_cpu(), &qtail);
+ put_cpu();
}
return ret;
}
@@ -3148,44 +3141,16 @@ int netif_rx_ni(struct sk_buff *skb)
{
int err;
- local_bh_disable();
+ preempt_disable();
err = netif_rx(skb);
- local_bh_enable();
+ if (local_softirq_pending())
+ do_softirq();
+ preempt_enable();
return err;
}
EXPORT_SYMBOL(netif_rx_ni);
-#ifdef CONFIG_PREEMPT_RT_FULL
-/*
- * RT runs ksoftirqd as a real time thread and the root_lock is a
- * "sleeping spinlock". If the trylock fails then we can go into an
- * infinite loop when ksoftirqd preempted the task which actually
- * holds the lock, because we requeue q and raise NET_TX softirq
- * causing ksoftirqd to loop forever.
- *
- * It's safe to use spin_lock on RT here as softirqs run in thread
- * context and cannot deadlock against the thread which is holding
- * root_lock.
- *
- * On !RT the trylock might fail, but there we bail out from the
- * softirq loop after 10 attempts which we can't do on RT. And the
- * task holding root_lock cannot be preempted, so the only downside of
- * that trylock is that we need 10 loops to decide that we should have
- * given up in the first one :)
- */
-static inline int take_root_lock(spinlock_t *lock)
-{
- spin_lock(lock);
- return 1;
-}
-#else
-static inline int take_root_lock(spinlock_t *lock)
-{
- return spin_trylock(lock);
-}
-#endif
-
static void net_tx_action(struct softirq_action *h)
{
struct softnet_data *sd = &__get_cpu_var(softnet_data);
@@ -3224,7 +3189,7 @@ static void net_tx_action(struct softirq_action *h)
head = head->next_sched;
root_lock = qdisc_lock(q);
- if (take_root_lock(root_lock)) {
+ if (spin_trylock(root_lock)) {
smp_mb__before_clear_bit();
clear_bit(__QDISC_STATE_SCHED,
&q->state);
@@ -3338,7 +3303,6 @@ int netdev_rx_handler_register(struct net_device *dev,
if (dev->rx_handler)
return -EBUSY;
- /* Note: rx_handler_data must be set before rx_handler */
rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
rcu_assign_pointer(dev->rx_handler, rx_handler);
@@ -3359,11 +3323,6 @@ void netdev_rx_handler_unregister(struct net_device *dev)
ASSERT_RTNL();
RCU_INIT_POINTER(dev->rx_handler, NULL);
- /* a reader seeing a non NULL rx_handler in a rcu_read_lock()
- * section has a guarantee to see a non NULL rx_handler_data
- * as well.
- */
- synchronize_net();
RCU_INIT_POINTER(dev->rx_handler_data, NULL);
}
EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
@@ -3486,7 +3445,6 @@ ncls:
}
switch (rx_handler(&skb)) {
case RX_HANDLER_CONSUMED:
- ret = NET_RX_SUCCESS;
goto unlock;
case RX_HANDLER_ANOTHER:
goto another_round;
@@ -3595,7 +3553,7 @@ static void flush_backlog(void *arg)
skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) {
if (skb->dev == dev) {
__skb_unlink(skb, &sd->input_pkt_queue);
- __skb_queue_tail(&sd->tofree_queue, skb);
+ kfree_skb(skb);
input_queue_head_incr(sd);
}
}
@@ -3604,13 +3562,10 @@ static void flush_backlog(void *arg)
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
if (skb->dev == dev) {
__skb_unlink(skb, &sd->process_queue);
- __skb_queue_tail(&sd->tofree_queue, skb);
+ kfree_skb(skb);
input_queue_head_incr(sd);
}
}
-
- if (!skb_queue_empty(&sd->tofree_queue))
- raise_softirq_irqoff(NET_RX_SOFTIRQ);
}
static int napi_gro_complete(struct sk_buff *skb)
@@ -3969,7 +3924,6 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
} else
#endif
local_irq_enable();
- preempt_check_resched_rt();
}
static int process_backlog(struct napi_struct *napi, int quota)
@@ -4042,7 +3996,6 @@ void __napi_schedule(struct napi_struct *n)
local_irq_save(flags);
____napi_schedule(&__get_cpu_var(softnet_data), n);
local_irq_restore(flags);
- preempt_check_resched_rt();
}
EXPORT_SYMBOL(__napi_schedule);
@@ -4117,17 +4070,10 @@ static void net_rx_action(struct softirq_action *h)
struct softnet_data *sd = &__get_cpu_var(softnet_data);
unsigned long time_limit = jiffies + 2;
int budget = netdev_budget;
- struct sk_buff *skb;
void *have;
local_irq_disable();
- while ((skb = __skb_dequeue(&sd->tofree_queue))) {
- local_irq_enable();
- kfree_skb(skb);
- local_irq_disable();
- }
-
while (!list_empty(&sd->poll_list)) {
struct napi_struct *n;
int work, weight;
@@ -4250,6 +4196,7 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg)
{
struct net_device *dev;
struct ifreq ifr;
+ unsigned seq;
/*
* Fetch the caller's info block.
@@ -4258,18 +4205,19 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg)
if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
return -EFAULT;
- mutex_lock(&devnet_rename_mutex);
+retry:
+ seq = read_seqcount_begin(&devnet_rename_seq);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, ifr.ifr_ifindex);
if (!dev) {
rcu_read_unlock();
- mutex_unlock(&devnet_rename_mutex);
return -ENODEV;
}
strcpy(ifr.ifr_name, dev->name);
rcu_read_unlock();
- mutex_unlock(&devnet_rename_mutex);
+ if (read_seqcount_retry(&devnet_rename_seq, seq))
+ goto retry;
if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
return -EFAULT;
@@ -6597,7 +6545,6 @@ static int dev_cpu_callback(struct notifier_block *nfb,
raise_softirq_irqoff(NET_TX_SOFTIRQ);
local_irq_enable();
- preempt_check_resched_rt();
/* Process offline CPU's input_pkt_queue */
while ((skb = __skb_dequeue(&oldsd->process_queue))) {
@@ -6608,9 +6555,6 @@ static int dev_cpu_callback(struct notifier_block *nfb,
netif_rx(skb);
input_queue_head_incr(oldsd);
}
- while ((skb = __skb_dequeue(&oldsd->tofree_queue))) {
- kfree_skb(skb);
- }
return NOTIFY_OK;
}
@@ -6883,9 +6827,8 @@ static int __init net_dev_init(void)
struct softnet_data *sd = &per_cpu(softnet_data, i);
memset(sd, 0, sizeof(*sd));
- skb_queue_head_init_raw(&sd->input_pkt_queue);
- skb_queue_head_init_raw(&sd->process_queue);
- skb_queue_head_init_raw(&sd->tofree_queue);
+ skb_queue_head_init(&sd->input_pkt_queue);
+ skb_queue_head_init(&sd->process_queue);
sd->completion_queue = NULL;
INIT_LIST_HEAD(&sd->poll_list);
sd->output_queue = NULL;
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 7841d87..b079c7b 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -38,7 +38,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
ha->type = addr_type;
ha->refcount = 1;
ha->global_use = global;
- ha->synced = 0;
+ ha->synced = false;
list_add_tail_rcu(&ha->list, &list->list);
list->count++;
@@ -166,7 +166,7 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
addr_len, ha->type);
if (err)
break;
- ha->synced++;
+ ha->synced = true;
ha->refcount++;
} else if (ha->refcount == 1) {
__hw_addr_del(to_list, ha->addr, addr_len, ha->type);
@@ -187,7 +187,7 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
if (ha->synced) {
__hw_addr_del(to_list, ha->addr,
addr_len, ha->type);
- ha->synced--;
+ ha->synced = false;
__hw_addr_del(from_list, ha->addr,
addr_len, ha->type);
}
diff --git a/net/core/dst.c b/net/core/dst.c
index 35fd12f..ee6153e 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -179,7 +179,6 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
dst_init_metrics(dst, dst_default_metrics, true);
dst->expires = 0UL;
dst->path = dst;
- dst->from = NULL;
#ifdef CONFIG_XFRM
dst->xfrm = NULL;
#endif
diff --git a/net/core/flow.c b/net/core/flow.c
index 3bad824..b0901ee 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -329,7 +329,7 @@ static void flow_cache_flush_per_cpu(void *data)
struct flow_flush_info *info = data;
struct tasklet_struct *tasklet;
- tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet;
+ tasklet = this_cpu_ptr(&info->cache->percpu->flush_tasklet);
tasklet->data = (unsigned long)info;
tasklet_schedule(tasklet);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 055fb13..1868625 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -976,7 +976,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
* report anything.
*/
ivi.spoofchk = -1;
- memset(ivi.mac, 0, sizeof(ivi.mac));
if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
break;
vf_mac.vf =
@@ -1068,7 +1067,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
rcu_read_lock();
cb->seq = net->dev_base_seq;
- if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
+ if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
ifla_policy) >= 0) {
if (tb[IFLA_EXT_MASK])
@@ -1924,7 +1923,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
u32 ext_filter_mask = 0;
u16 min_ifinfo_dump_size = 0;
- if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
+ if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
ifla_policy) >= 0) {
if (tb[IFLA_EXT_MASK])
ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
@@ -2539,7 +2538,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
struct rtattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
while (RTA_OK(attr, attrlen)) {
- unsigned int flavor = attr->rta_type & NLA_TYPE_MASK;
+ unsigned int flavor = attr->rta_type;
if (flavor) {
if (flavor > rta_max[sz_idx])
return -EINVAL;
diff --git a/net/core/scm.c b/net/core/scm.c
index 2dc6cda..905dcc6 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -24,7 +24,6 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/security.h>
-#include <linux/pid_namespace.h>
#include <linux/pid.h>
#include <linux/nsproxy.h>
#include <linux/slab.h>
@@ -53,8 +52,7 @@ static __inline__ int scm_check_creds(struct ucred *creds)
if (!uid_valid(uid) || !gid_valid(gid))
return -EINVAL;
- if ((creds->pid == task_tgid_vnr(current) ||
- ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) &&
+ if ((creds->pid == task_tgid_vnr(current) || nsown_capable(CAP_SYS_ADMIN)) &&
((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) ||
uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) &&
((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1a9dda5..fe1a598 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -60,7 +60,6 @@
#include <linux/scatterlist.h>
#include <linux/errqueue.h>
#include <linux/prefetch.h>
-#include <linux/locallock.h>
#include <net/protocol.h>
#include <net/dst.h>
@@ -348,7 +347,6 @@ struct netdev_alloc_cache {
unsigned int pagecnt_bias;
};
static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
-static DEFINE_LOCAL_IRQ_LOCK(netdev_alloc_lock);
#define NETDEV_FRAG_PAGE_MAX_ORDER get_order(32768)
#define NETDEV_FRAG_PAGE_MAX_SIZE (PAGE_SIZE << NETDEV_FRAG_PAGE_MAX_ORDER)
@@ -361,7 +359,7 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
int order;
unsigned long flags;
- local_lock_irqsave(netdev_alloc_lock, flags);
+ local_irq_save(flags);
nc = &__get_cpu_var(netdev_alloc_cache);
if (unlikely(!nc->frag.page)) {
refill:
@@ -395,7 +393,7 @@ recycle:
nc->frag.offset += fragsz;
nc->pagecnt_bias--;
end:
- local_unlock_irqrestore(netdev_alloc_lock, flags);
+ local_irq_restore(flags);
return data;
}
diff --git a/net/core/sock.c b/net/core/sock.c
index 2754c99..bc131d4 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -571,6 +571,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
struct net *net = sock_net(sk);
struct net_device *dev;
char devname[IFNAMSIZ];
+ unsigned seq;
if (sk->sk_bound_dev_if == 0) {
len = 0;
@@ -581,19 +582,20 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
if (len < IFNAMSIZ)
goto out;
- mutex_lock(&devnet_rename_mutex);
+retry:
+ seq = read_seqcount_begin(&devnet_rename_seq);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if);
ret = -ENODEV;
if (!dev) {
rcu_read_unlock();
- mutex_unlock(&devnet_rename_mutex);
goto out;
}
strcpy(devname, dev->name);
rcu_read_unlock();
- mutex_unlock(&devnet_rename_mutex);
+ if (read_seqcount_retry(&devnet_rename_seq, seq))
+ goto retry;
len = strlen(devname) + 1;
@@ -2285,11 +2287,12 @@ void lock_sock_nested(struct sock *sk, int subclass)
if (sk->sk_lock.owned)
__lock_sock(sk);
sk->sk_lock.owned = 1;
- spin_unlock_bh(&sk->sk_lock.slock);
+ spin_unlock(&sk->sk_lock.slock);
/*
* The sk_lock has mutex_lock() semantics here:
*/
mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_);
+ local_bh_enable();
}
EXPORT_SYMBOL(lock_sock_nested);
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index 750f44f..602cd63 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -121,9 +121,6 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (nlmsg_len(nlh) < sizeof(*req))
return -EINVAL;
- if (req->sdiag_family >= AF_MAX)
- return -EINVAL;
-
hndl = sock_diag_lock_handler(req->sdiag_family);
if (hndl == NULL)
err = -ENOENT;
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 21291f1..1b588e2 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -284,7 +284,6 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
if (!netdev->dcbnl_ops->getpermhwaddr)
return -EOPNOTSUPP;
- memset(perm_addr, 0, sizeof(perm_addr));
netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr);
@@ -1043,7 +1042,6 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getets) {
struct ieee_ets ets;
- memset(&ets, 0, sizeof(ets));
err = ops->ieee_getets(netdev, &ets);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
@@ -1052,7 +1050,6 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getmaxrate) {
struct ieee_maxrate maxrate;
- memset(&maxrate, 0, sizeof(maxrate));
err = ops->ieee_getmaxrate(netdev, &maxrate);
if (!err) {
err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
@@ -1064,7 +1061,6 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_getpfc) {
struct ieee_pfc pfc;
- memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
@@ -1098,7 +1094,6 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
/* get peer info if available */
if (ops->ieee_peer_getets) {
struct ieee_ets ets;
- memset(&ets, 0, sizeof(ets));
err = ops->ieee_peer_getets(netdev, &ets);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
@@ -1107,7 +1102,6 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->ieee_peer_getpfc) {
struct ieee_pfc pfc;
- memset(&pfc, 0, sizeof(pfc));
err = ops->ieee_peer_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
@@ -1286,7 +1280,6 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
/* peer info if available */
if (ops->cee_peer_getpg) {
struct cee_pg pg;
- memset(&pg, 0, sizeof(pg));
err = ops->cee_peer_getpg(netdev, &pg);
if (!err &&
nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg))
@@ -1295,7 +1288,6 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
if (ops->cee_peer_getpfc) {
struct cee_pfc pfc;
- memset(&pfc, 0, sizeof(pfc));
err = ops->cee_peer_getpfc(netdev, &pfc);
if (!err &&
nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc))
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 76c3d0a..f651da6 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -1234,7 +1234,7 @@ static inline int __init lowpan_netlink_init(void)
return rtnl_link_register(&lowpan_link_ops);
}
-static inline void lowpan_netlink_fini(void)
+static inline void __init lowpan_netlink_fini(void)
{
rtnl_link_unregister(&lowpan_link_ops);
}
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h
index bba5f83..8c2251f 100644
--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
@@ -84,7 +84,7 @@
(memcmp(addr1, addr2, length >> 3) == 0)
/* local link, i.e. FE80::/10 */
-#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))
+#define is_addr_link_local(a) (((a)->s6_addr16[0]) == 0x80FE)
/*
* check whether we can compress the IID to 16 bits,
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index fcf104e..24b384b 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -248,12 +248,8 @@ EXPORT_SYMBOL(inet_listen);
u32 inet_ehash_secret __read_mostly;
EXPORT_SYMBOL(inet_ehash_secret);
-u32 ipv6_hash_secret __read_mostly;
-EXPORT_SYMBOL(ipv6_hash_secret);
-
/*
- * inet_ehash_secret must be set exactly once, and to a non nul value
- * ipv6_hash_secret must be set exactly once.
+ * inet_ehash_secret must be set exactly once
*/
void build_ehash_secret(void)
{
@@ -263,8 +259,7 @@ void build_ehash_secret(void)
get_random_bytes(&rnd, sizeof(rnd));
} while (rnd == 0);
- if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
- get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
+ cmpxchg(&inet_ehash_secret, 0, rnd);
}
EXPORT_SYMBOL(build_ehash_secret);
@@ -1595,7 +1590,7 @@ static const struct net_offload udp_offload = {
static const struct net_protocol icmp_protocol = {
.handler = icmp_rcv,
- .err_handler = icmp_err,
+ .err_handler = ping_err,
.no_policy = 1,
.netns_ok = 1,
};
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 4cfe34d..3b4f0cd 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -139,6 +139,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
/* skb is pure payload to encrypt */
+ err = -ENOMEM;
+
esp = x->data;
aead = esp->aead;
alen = crypto_aead_authsize(aead);
@@ -174,10 +176,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
}
tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen);
- if (!tmp) {
- err = -ENOMEM;
+ if (!tmp)
goto error;
- }
seqhi = esp_tmp_seqhi(tmp);
iv = esp_tmp_iv(aead, tmp, seqhilen);
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index d8bbe94..17ff9fd 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -69,7 +69,6 @@
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
-#include <linux/sysrq.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/inet.h>
@@ -769,30 +768,6 @@ static void icmp_redirect(struct sk_buff *skb)
}
/*
- * 32bit and 64bit have different timestamp length, so we check for
- * the cookie at offset 20 and verify it is repeated at offset 50
- */
-#define CO_POS0 20
-#define CO_POS1 50
-#define CO_SIZE sizeof(int)
-#define ICMP_SYSRQ_SIZE 57
-
-/*
- * We got a ICMP_SYSRQ_SIZE sized ping request. Check for the cookie
- * pattern and if it matches send the next byte as a trigger to sysrq.
- */
-static void icmp_check_sysrq(struct net *net, struct sk_buff *skb)
-{
- int cookie = htonl(net->ipv4.sysctl_icmp_echo_sysrq);
- char *p = skb->data;
-
- if (!memcmp(&cookie, p + CO_POS0, CO_SIZE) &&
- !memcmp(&cookie, p + CO_POS1, CO_SIZE) &&
- p[CO_POS0 + CO_SIZE] == p[CO_POS1 + CO_SIZE])
- handle_sysrq(p[CO_POS0 + CO_SIZE]);
-}
-
-/*
* Handle ICMP_ECHO ("ping") requests.
*
* RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo
@@ -819,11 +794,6 @@ static void icmp_echo(struct sk_buff *skb)
icmp_param.data_len = skb->len;
icmp_param.head_len = sizeof(struct icmphdr);
icmp_reply(&icmp_param, skb);
-
- if (skb->len == ICMP_SYSRQ_SIZE &&
- net->ipv4.sysctl_icmp_echo_sysrq) {
- icmp_check_sysrq(net, skb);
- }
}
}
@@ -964,29 +934,6 @@ error:
goto drop;
}
-void icmp_err(struct sk_buff *skb, u32 info)
-{
- struct iphdr *iph = (struct iphdr *)skb->data;
- struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
- int type = icmp_hdr(skb)->type;
- int code = icmp_hdr(skb)->code;
- struct net *net = dev_net(skb->dev);
-
- /*
- * Use ping_err to handle all icmp errors except those
- * triggered by ICMP_ECHOREPLY which sent from kernel.
- */
- if (icmph->type != ICMP_ECHOREPLY) {
- ping_err(skb, info);
- return;
- }
-
- if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
- ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0);
- else if (type == ICMP_REDIRECT)
- ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0);
-}
-
/*
* This table is the definition of how we handle ICMP.
*/
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 03f5af7..4750d2b 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -21,7 +21,6 @@
#include <linux/rtnetlink.h>
#include <linux/slab.h>
-#include <net/sock.h>
#include <net/inet_frag.h>
static void inet_frag_secret_rebuild(unsigned long dummy)
@@ -277,7 +276,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
{
struct inet_frag_queue *q;
struct hlist_node *n;
- int depth = 0;
hlist_for_each_entry(q, n, &f->hash[hash], list) {
if (q->net == nf && f->match(q, key)) {
@@ -285,25 +283,9 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
read_unlock(&f->lock);
return q;
}
- depth++;
}
read_unlock(&f->lock);
- if (depth <= INETFRAGS_MAXDEPTH)
- return inet_frag_create(nf, f, key);
- else
- return ERR_PTR(-ENOBUFS);
+ return inet_frag_create(nf, f, key);
}
EXPORT_SYMBOL(inet_frag_find);
-
-void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q,
- const char *prefix)
-{
- static const char msg[] = "inet_frag_find: Fragment hash bucket"
- " list length grew over limit " __stringify(INETFRAGS_MAXDEPTH)
- ". Dropping fragment.\n";
-
- if (PTR_ERR(q) == -ENOBUFS)
- LIMIT_NETDEBUG(KERN_WARNING "%s%s", prefix, msg);
-}
-EXPORT_SYMBOL(inet_frag_maybe_warn_overflow);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 0fcfee3..eb9d63a 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -255,7 +255,8 @@ static void ip_expire(unsigned long arg)
if (!head->dev)
goto out_rcu_unlock;
- /* skb has no dst, perform route lookup again */
+ /* skb dst is stale, drop it, and perform route lookup again */
+ skb_dst_drop(head);
iph = ip_hdr(head);
err = ip_route_input_noref(head, iph->daddr, iph->saddr,
iph->tos, head->dev);
@@ -298,11 +299,14 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
- return NULL;
- }
+ if (q == NULL)
+ goto out_nomem;
+
return container_of(q, struct ipq, q);
+
+out_nomem:
+ LIMIT_NETDEBUG(KERN_ERR pr_fmt("ip_frag_create: no memory left !\n"));
+ return NULL;
}
/* Is the fragment too far ahead to be part of ipq? */
@@ -524,16 +528,8 @@ found:
qp->q.max_size = skb->len + ihl;
if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
- qp->q.meat == qp->q.len) {
- unsigned long orefdst = skb->_skb_refdst;
-
- skb->_skb_refdst = 0UL;
- err = ip_frag_reasm(qp, prev, dev);
- skb->_skb_refdst = orefdst;
- return err;
- }
-
- skb_dst_drop(skb);
+ qp->q.meat == qp->q.len)
+ return ip_frag_reasm(qp, prev, dev);
write_lock(&ip4_frags.lock);
list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a85062b..e81b1ca 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -761,7 +761,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
gre_hlen = 0;
- tiph = (const struct iphdr *)skb->data;
+ if (skb->protocol == htons(ETH_P_IP))
+ tiph = (const struct iphdr *)skb->data;
+ else
+ tiph = &tunnel->parms.iph;
} else {
gre_hlen = tunnel->hlen;
tiph = &tunnel->parms.iph;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 8433ffe..a47fc1d 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -370,6 +370,7 @@ int ip_options_compile(struct net *net,
}
switch (optptr[3]&0xF) {
case IPOPT_TS_TSONLY:
+ opt->ts = optptr - iph;
if (skb)
timeptr = &optptr[optptr[2]-1];
opt->ts_needtime = 1;
@@ -380,6 +381,7 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 2;
goto error;
}
+ opt->ts = optptr - iph;
if (rt) {
spec_dst_fill(&spec_dst, skb);
memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
@@ -394,6 +396,7 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 2;
goto error;
}
+ opt->ts = optptr - iph;
{
__be32 addr;
memcpy(&addr, &optptr[optptr[2]-1], 4);
@@ -426,12 +429,12 @@ int ip_options_compile(struct net *net,
pp_ptr = optptr + 3;
goto error;
}
+ opt->ts = optptr - iph;
if (skb) {
optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4);
opt->is_changed = 1;
}
}
- opt->ts = optptr - iph;
break;
case IPOPT_RA:
if (optlen < 4) {
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 253692b..3e98ed2 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1508,8 +1508,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
if (IS_ERR(rt))
return;
- get_cpu_light();
- inet = &__get_cpu_var(unicast_sock);
+ inet = &get_cpu_var(unicast_sock);
inet->tos = arg->tos;
sk = &inet->sk;
@@ -1533,7 +1532,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
ip_push_pending_frames(sk, &fl4);
}
- put_cpu_light();
+ put_cpu_var(unicast_sock);
ip_rt_put(rt);
}
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index c49dcd0..c301300 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -66,12 +66,6 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
return dev_match;
}
-static bool rpfilter_is_local(const struct sk_buff *skb)
-{
- const struct rtable *rt = skb_rtable(skb);
- return rt && (rt->rt_flags & RTCF_LOCAL);
-}
-
static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_rpfilter_info *info;
@@ -82,7 +76,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
info = par->matchinfo;
invert = info->flags & XT_RPFILTER_INVERT;
- if (rpfilter_is_local(skb))
+ if (par->in->flags & IFF_LOOPBACK)
return true ^ invert;
iph = ip_hdr(skb);
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index dc454cc..6f9c072 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -322,8 +322,8 @@ void ping_err(struct sk_buff *skb, u32 info)
struct iphdr *iph = (struct iphdr *)skb->data;
struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2));
struct inet_sock *inet_sock;
- int type = icmp_hdr(skb)->type;
- int code = icmp_hdr(skb)->code;
+ int type = icmph->type;
+ int code = icmph->code;
struct net *net = dev_net(skb->dev);
struct sock *sk;
int harderr;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index f962f19..b236ef0 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -348,8 +348,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
* hasn't changed since we received the original syn, but I see
* no easy way to do this.
*/
- flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark,
- RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
+ flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
+ RT_SCOPE_UNIVERSE, IPPROTO_TCP,
inet_sk_flowi_flags(sk),
(opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
ireq->loc_addr, th->source, th->dest);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 44bf3b0..d84400b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -815,13 +815,6 @@ static struct ctl_table ipv4_net_table[] = {
.proc_handler = proc_dointvec
},
{
- .procname = "icmp_echo_sysrq",
- .data = &init_net.ipv4.sysctl_icmp_echo_sysrq,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec
- },
- {
.procname = "icmp_ignore_bogus_error_responses",
.data = &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses,
.maxlen = sizeof(int),
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 45b63ca..2aa69c8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -773,7 +773,7 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
* Make sure that we have exactly size bytes
* available to the caller, no more, no less.
*/
- skb->reserved_tailroom = skb->end - skb->tail - size;
+ skb->avail_size = size;
return skb;
}
__kfree_skb(skb);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index b4e8b79..ad70a96 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -116,7 +116,6 @@ int sysctl_tcp_early_retrans __read_mostly = 2;
#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */
#define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */
#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */
-#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */
#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -2065,8 +2064,11 @@ void tcp_enter_loss(struct sock *sk, int how)
if (tcp_is_reno(tp))
tcp_reset_reno_sack(tp);
- tp->undo_marker = tp->snd_una;
- if (how) {
+ if (!how) {
+ /* Push undo marker, if it was plain RTO and nothing
+ * was retransmitted. */
+ tp->undo_marker = tp->snd_una;
+ } else {
tp->sacked_out = 0;
tp->fackets_out = 0;
}
@@ -3573,27 +3575,6 @@ static void tcp_send_challenge_ack(struct sock *sk)
}
}
-static void tcp_store_ts_recent(struct tcp_sock *tp)
-{
- tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
- tp->rx_opt.ts_recent_stamp = get_seconds();
-}
-
-static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
-{
- if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
- /* PAWS bug workaround wrt. ACK frames, the PAWS discard
- * extra check below makes sure this can only happen
- * for pure ACK frames. -DaveM
- *
- * Not only, also it occurs for expired timestamps.
- */
-
- if (tcp_paws_check(&tp->rx_opt, 0))
- tcp_store_ts_recent(tp);
- }
-}
-
/* This routine deals with incoming acks, but not outgoing ones. */
static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
{
@@ -3646,12 +3627,6 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
prior_fackets = tp->fackets_out;
prior_in_flight = tcp_packets_in_flight(tp);
- /* ts_recent update must be made after we are sure that the packet
- * is in window.
- */
- if (flag & FLAG_UPDATE_TS_RECENT)
- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
/* Window is constant, pure forward advance.
* No more checks are required.
@@ -3968,6 +3943,27 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th)
EXPORT_SYMBOL(tcp_parse_md5sig_option);
#endif
+static inline void tcp_store_ts_recent(struct tcp_sock *tp)
+{
+ tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
+ tp->rx_opt.ts_recent_stamp = get_seconds();
+}
+
+static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
+{
+ if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
+ /* PAWS bug workaround wrt. ACK frames, the PAWS discard
+ * extra check below makes sure this can only happen
+ * for pure ACK frames. -DaveM
+ *
+ * Not only, also it occurs for expired timestamps.
+ */
+
+ if (tcp_paws_check(&tp->rx_opt, 0))
+ tcp_store_ts_recent(tp);
+ }
+}
+
/* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM
*
* It is not fatal. If this ACK does _not_ change critical state (seqs, window)
@@ -5502,9 +5498,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
if (tcp_checksum_complete_user(sk, skb))
goto csum_error;
- if ((int)skb->truesize > sk->sk_forward_alloc)
- goto step5;
-
/* Predicted packet is in window by definition.
* seq == rcv_nxt and rcv_wup <= rcv_nxt.
* Hence, check seq<=rcv_wup reduces to:
@@ -5516,6 +5509,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
tcp_rcv_rtt_measure_ts(sk, skb);
+ if ((int)skb->truesize > sk->sk_forward_alloc)
+ goto step5;
+
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS);
/* Bulk data transfer: receiver */
@@ -5563,9 +5559,14 @@ slow_path:
return 0;
step5:
- if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
+ if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
goto discard;
+ /* ts_recent update must be made after we are sure that the packet
+ * is in window.
+ */
+ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
tcp_rcv_rtt_measure_ts(sk, skb);
/* Process urgent data. */
@@ -5999,8 +6000,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
/* step 5: check the ACK field */
if (true) {
- int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
- FLAG_UPDATE_TS_RECENT) > 0;
+ int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;
switch (sk->sk_state) {
case TCP_SYN_RECV:
@@ -6151,6 +6151,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
}
}
+ /* ts_recent update must be made after we are sure that the packet
+ * is in window.
+ */
+ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
/* step 6: check the URG bit */
tcp_urg(sk, skb, th);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d9130a9..eadb693 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -274,6 +274,13 @@ static void tcp_v4_mtu_reduced(struct sock *sk)
struct inet_sock *inet = inet_sk(sk);
u32 mtu = tcp_sk(sk)->mtu_info;
+ /* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
+ * send out by Linux are always <576bytes so they should go through
+ * unfragmented).
+ */
+ if (sk->sk_state == TCP_LISTEN)
+ return;
+
dst = inet_csk_update_pmtu(sk, mtu);
if (!dst)
return;
@@ -401,13 +408,6 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
goto out;
if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
- /* We are not interested in TCP_LISTEN and open_requests
- * (SYN-ACKs send out by Linux are always <576bytes so
- * they should go through unfragmented).
- */
- if (sk->sk_state == TCP_LISTEN)
- goto out;
-
tp->mtu_info = info;
if (!sock_owned_by_user(sk)) {
tcp_v4_mtu_reduced(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a9f50ee..5d45159 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1298,6 +1298,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
eat = min_t(int, len, skb_headlen(skb));
if (eat) {
__skb_pull(skb, eat);
+ skb->avail_size -= eat;
len -= eat;
if (!len)
return;
@@ -1350,8 +1351,8 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
return 0;
}
-/* Calculate MSS not accounting any TCP options. */
-static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
+/* Calculate MSS. Not accounting for SACKs here. */
+int tcp_mtu_to_mss(struct sock *sk, int pmtu)
{
const struct tcp_sock *tp = tcp_sk(sk);
const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -1380,15 +1381,11 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)
/* Then reserve room for full set of TCP options and 8 bytes of data */
if (mss_now < 48)
mss_now = 48;
- return mss_now;
-}
-/* Calculate MSS. Not accounting for SACKs here. */
-int tcp_mtu_to_mss(struct sock *sk, int pmtu)
-{
- /* Subtract TCP options size, not including SACKs */
- return __tcp_mtu_to_mss(sk, pmtu) -
- (tcp_sk(sk)->tcp_header_len - sizeof(struct tcphdr));
+ /* Now subtract TCP options size, not including SACKs */
+ mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
+
+ return mss_now;
}
/* Inverse of above */
@@ -1809,11 +1806,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
goto send_now;
}
- /* Ok, it looks like it is advisable to defer.
- * Do not rearm the timer if already set to not break TCP ACK clocking.
- */
- if (!tp->tso_deferred)
- tp->tso_deferred = 1 | (jiffies << 1);
+ /* Ok, it looks like it is advisable to defer. */
+ tp->tso_deferred = 1 | (jiffies << 1);
return true;
@@ -2388,12 +2382,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
*/
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- /* make sure skb->data is aligned on arches that require it
- * and check if ack-trimming & collapsing extended the headroom
- * beyond what csum_start can cover.
- */
- if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
- skb_headroom(skb) >= 0xFFFF)) {
+ /* make sure skb->data is aligned on arches that require it */
+ if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
GFP_ATOMIC);
return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
@@ -2940,7 +2930,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
*/
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->rx_opt.mss_clamp)
tp->rx_opt.mss_clamp = tp->rx_opt.user_mss;
- space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) -
+ space = tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) -
MAX_TCP_OPTION_SPACE;
syn_data = skb_copy_expand(syn, skb_headroom(syn), space,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e8676c2..1b5d8cb 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2525,9 +2525,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
static void init_loopback(struct net_device *dev)
{
struct inet6_dev *idev;
- struct net_device *sp_dev;
- struct inet6_ifaddr *sp_ifa;
- struct rt6_info *sp_rt;
/* ::1 */
@@ -2539,30 +2536,6 @@ static void init_loopback(struct net_device *dev)
}
add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
-
- /* Add routes to other interface's IPv6 addresses */
- for_each_netdev(dev_net(dev), sp_dev) {
- if (!strcmp(sp_dev->name, dev->name))
- continue;
-
- idev = __in6_dev_get(sp_dev);
- if (!idev)
- continue;
-
- read_lock_bh(&idev->lock);
- list_for_each_entry(sp_ifa, &idev->addr_list, if_list) {
-
- if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
- continue;
-
- sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
-
- /* Failure cases are ignored */
- if (!IS_ERR(sp_rt))
- ip6_ins_rt(sp_rt);
- }
- read_unlock_bh(&idev->lock);
- }
}
static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
@@ -4814,20 +4787,26 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
static int __net_init addrconf_init_net(struct net *net)
{
- int err = -ENOMEM;
+ int err;
struct ipv6_devconf *all, *dflt;
- all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
- if (all == NULL)
- goto err_alloc_all;
+ err = -ENOMEM;
+ all = &ipv6_devconf;
+ dflt = &ipv6_devconf_dflt;
- dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
- if (dflt == NULL)
- goto err_alloc_dflt;
+ if (!net_eq(net, &init_net)) {
+ all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
+ if (all == NULL)
+ goto err_alloc_all;
- /* these will be inherited by all namespaces */
- dflt->autoconf = ipv6_defaults.autoconf;
- dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
+ dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
+ if (dflt == NULL)
+ goto err_alloc_dflt;
+ } else {
+ /* these will be inherited by all namespaces */
+ dflt->autoconf = ipv6_defaults.autoconf;
+ dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
+ }
net->ipv6.devconf_all = all;
net->ipv6.devconf_dflt = dflt;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index dee9964..a52d864 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -118,27 +118,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
ipv6_addr_loopback(&hdr->daddr))
goto err;
- /* RFC4291 Errata ID: 3480
- * Interface-Local scope spans only a single interface on a
- * node and is useful only for loopback transmission of
- * multicast. Packets with interface-local scope received
- * from another node must be discarded.
- */
- if (!(skb->pkt_type == PACKET_LOOPBACK ||
- dev->flags & IFF_LOOPBACK) &&
- ipv6_addr_is_multicast(&hdr->daddr) &&
- IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
- goto err;
-
- /* RFC4291 2.7
- * Nodes must not originate a packet to a multicast address whose scope
- * field contains the reserved value 0; if such a packet is received, it
- * must be silently dropped.
- */
- if (ipv6_addr_is_multicast(&hdr->daddr) &&
- IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0)
- goto err;
-
/*
* RFC4291 2.7
* Multicast addresses must not be used as source addresses in IPv6
@@ -291,8 +270,7 @@ int ip6_mc_input(struct sk_buff *skb)
* IPv6 multicast router mode is now supported ;)
*/
if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
- !(ipv6_addr_type(&hdr->daddr) &
- (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
+ !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) &&
likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
/*
* Okay, we try to forward - split and duplicate
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c
index 0ea43c7..83acc14 100644
--- a/net/ipv6/netfilter/ip6t_NPT.c
+++ b/net/ipv6/netfilter/ip6t_NPT.c
@@ -57,7 +57,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,
if (pfx_len - i >= 32)
mask = 0;
else
- mask = htonl((1 << (i - pfx_len + 32)) - 1);
+ mask = htonl(~((1 << (pfx_len - i)) - 1));
idx = i / 32;
addr->s6_addr32[idx] &= mask;
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index e0983f3..5060d54 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -71,12 +71,6 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb,
return ret;
}
-static bool rpfilter_is_local(const struct sk_buff *skb)
-{
- const struct rt6_info *rt = (const void *) skb_dst(skb);
- return rt && (rt->rt6i_flags & RTF_LOCAL);
-}
-
static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_rpfilter_info *info = par->matchinfo;
@@ -84,7 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
struct ipv6hdr *iph;
bool invert = info->flags & XT_RPFILTER_INVERT;
- if (rpfilter_is_local(skb))
+ if (par->in->flags & IFF_LOOPBACK)
return true ^ invert;
iph = ipv6_hdr(skb);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 2f3a018..3dacecc 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -14,8 +14,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#define pr_fmt(fmt) "IPv6-nf: " fmt
-
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -182,11 +180,13 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
q = inet_frag_find(&net->nf_frag.frags, &nf_frags, &arg, hash);
local_bh_enable();
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
- return NULL;
- }
+ if (q == NULL)
+ goto oom;
+
return container_of(q, struct frag_queue, q);
+
+oom:
+ return NULL;
}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 7a610a6..e5253ec 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -26,9 +26,6 @@
* YOSHIFUJI,H. @USAGI Always remove fragment header to
* calculate ICV correctly.
*/
-
-#define pr_fmt(fmt) "IPv6: " fmt
-
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -200,10 +197,9 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
- if (IS_ERR_OR_NULL(q)) {
- inet_frag_maybe_warn_overflow(q, pr_fmt());
+ if (q == NULL)
return NULL;
- }
+
return container_of(q, struct frag_queue, q);
}
@@ -342,17 +338,8 @@ found:
}
if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
- fq->q.meat == fq->q.len) {
- int res;
- unsigned long orefdst = skb->_skb_refdst;
-
- skb->_skb_refdst = 0UL;
- res = ip6_frag_reasm(fq, prev, dev);
- skb->_skb_refdst = orefdst;
- return res;
- }
-
- skb_dst_drop(skb);
+ fq->q.meat == fq->q.len)
+ return ip6_frag_reasm(fq, prev, dev);
write_lock(&ip6_frags.lock);
list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 59bf61d..1003ef5 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -304,7 +304,6 @@ static void ip6_dst_destroy(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *)dst;
struct inet6_dev *idev = rt->rt6i_idev;
- struct dst_entry *from = dst->from;
if (rt->n)
neigh_release(rt->n);
@@ -317,8 +316,8 @@ static void ip6_dst_destroy(struct dst_entry *dst)
in6_dev_put(idev);
}
- dst->from = NULL;
- dst_release(from);
+ if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from)
+ dst_release(dst->from);
if (rt6_has_peer(rt)) {
struct inet_peer *peer = rt6_peer_ptr(rt);
@@ -1065,6 +1064,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
rt->rt6i_gateway = ort->rt6i_gateway;
rt->rt6i_flags = ort->rt6i_flags;
+ rt6_clean_expires(rt);
rt->rt6i_metric = 0;
memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
@@ -1875,6 +1875,8 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort,
if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
(RTF_DEFAULT | RTF_ADDRCONF))
rt6_set_from(rt, ort);
+ else
+ rt6_clean_expires(rt);
rt->rt6i_metric = 0;
#ifdef CONFIG_IPV6_SUBTREES
@@ -2006,8 +2008,7 @@ void rt6_purge_dflt_routers(struct net *net)
restart:
read_lock_bh(&table->tb6_lock);
for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
- if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
- (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
+ if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);
ip6_del_rt(rt);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 89dfedd..4f435371 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -386,17 +386,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
if (dst)
dst->ops->redirect(dst, sk, skb);
- goto out;
}
if (type == ICMPV6_PKT_TOOBIG) {
- /* We are not interested in TCP_LISTEN and open_requests
- * (SYN-ACKs send out by Linux are always <576bytes so
- * they should go through unfragmented).
- */
- if (sk->sk_state == TCP_LISTEN)
- goto out;
-
tp->mtu_info = ntohl(info);
if (!sock_owned_by_user(sk))
tcp_v6_mtu_reduced(sk);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8f32718..c984413 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -236,8 +236,6 @@ static void xfrm6_dst_destroy(struct dst_entry *dst)
{
struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
- if (likely(xdst->u.rt6.n))
- neigh_release(xdst->u.rt6.n);
if (likely(xdst->u.rt6.rt6i_idev))
in6_dev_put(xdst->u.rt6.rt6i_idev);
dst_destroy_metrics_generic(dst);
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 3c9bd59..b833677 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1386,8 +1386,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __func__);
- msg->msg_namelen = 0;
-
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (!skb)
@@ -2586,10 +2584,8 @@ bed:
NULL, NULL, NULL);
/* Check if the we got some results */
- if (!self->cachedaddr) {
- err = -EAGAIN; /* Didn't find any devices */
- goto out;
- }
+ if (!self->cachedaddr)
+ return -EAGAIN; /* Didn't find any devices */
daddr = self->cachedaddr;
/* Cleanup */
self->cachedaddr = 0;
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 625bc50..cd6f7a9 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1331,8 +1331,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sk_buff *skb, *rskb, *cskb;
int err = 0;
- msg->msg_namelen = 0;
-
if ((sk->sk_state == IUCV_DISCONN) &&
skb_queue_empty(&iucv->backlog_skb_q) &&
skb_queue_empty(&sk->sk_receive_queue) &&
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 9e1822e..8ee4a86 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -684,7 +684,6 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
lsa->l2tp_addr = ipv6_hdr(skb)->saddr;
lsa->l2tp_flowinfo = 0;
lsa->l2tp_scope_id = 0;
- lsa->l2tp_conn_id = 0;
if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL)
lsa->l2tp_scope_id = IP6CB(skb)->iif;
}
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 044e9e1..716605c 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -355,7 +355,6 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
l2tp_xmit_skb(session, skb, session->hdr_len);
sock_put(ps->tunnel_sock);
- sock_put(sk);
return error;
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 48aaa89..8870988 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
int target; /* Read at least this many bytes */
long timeo;
- msg->msg_namelen = 0;
-
lock_sock(sk);
copied = -ENOTCONN;
if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 49c48c6..0479c64 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2499,7 +2499,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
list_del(&dep->list);
mutex_unlock(&local->mtx);
- ieee80211_roc_notify_destroy(dep, true);
+ ieee80211_roc_notify_destroy(dep);
return 0;
}
@@ -2539,7 +2539,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
ieee80211_start_next_roc(local);
mutex_unlock(&local->mtx);
- ieee80211_roc_notify_destroy(found, true);
+ ieee80211_roc_notify_destroy(found);
} else {
/* work may be pending so use it all the time */
found->abort = true;
@@ -2549,8 +2549,6 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
/* work will clean up etc */
flush_delayed_work(&found->work);
- WARN_ON(!found->to_be_freed);
- kfree(found);
}
return 0;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 55d8f89..2ed065c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -346,7 +346,6 @@ struct ieee80211_roc_work {
struct ieee80211_channel *chan;
bool started, abort, hw_begun, notified;
- bool to_be_freed;
unsigned long hw_start_time;
@@ -1364,7 +1363,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local);
void ieee80211_roc_setup(struct ieee80211_local *local);
void ieee80211_start_next_roc(struct ieee80211_local *local);
void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata);
-void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free);
+void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc);
void ieee80211_sw_roc_work(struct work_struct *work);
void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a1a7997..5107248 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1812,8 +1812,6 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
transmit_frame, frame_buf);
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
- ieee80211_wake_queues_by_reason(&sdata->local->hw,
- IEEE80211_QUEUE_STOP_REASON_CSA);
mutex_unlock(&ifmgd->mtx);
/*
@@ -1858,6 +1856,8 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work)
container_of(work, struct ieee80211_sub_if_data,
u.mgd.csa_connection_drop_work);
+ ieee80211_wake_queues_by_reason(&sdata->local->hw,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
__ieee80211_disconnect(sdata, true);
}
@@ -3401,10 +3401,6 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
ret = 0;
out:
- /* don't print the message below for VHT mismatch if VHT is disabled */
- if (ret & IEEE80211_STA_DISABLE_VHT)
- vht_chandef = *chandef;
-
while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
IEEE80211_CHAN_DISABLED)) {
if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
@@ -3723,16 +3719,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
/* prep auth_data so we don't go into idle on disassoc */
ifmgd->auth_data = auth_data;
- if (ifmgd->associated) {
- u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
-
- ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_UNSPECIFIED,
- false, frame_buf);
-
- __cfg80211_send_deauth(sdata->dev, frame_buf,
- sizeof(frame_buf));
- }
+ if (ifmgd->associated)
+ ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -3791,16 +3779,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
mutex_lock(&ifmgd->mtx);
- if (ifmgd->associated) {
- u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
-
- ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_UNSPECIFIED,
- false, frame_buf);
-
- __cfg80211_send_deauth(sdata->dev, frame_buf,
- sizeof(frame_buf));
- }
+ if (ifmgd->associated)
+ ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
err = -EBUSY;
@@ -4092,17 +4072,6 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- /*
- * Make sure some work items will not run after this,
- * they will not do anything but might not have been
- * cancelled when disconnecting.
- */
- cancel_work_sync(&ifmgd->monitor_work);
- cancel_work_sync(&ifmgd->beacon_connection_loss_work);
- cancel_work_sync(&ifmgd->request_smps_work);
- cancel_work_sync(&ifmgd->csa_connection_drop_work);
- cancel_work_sync(&ifmgd->chswitch_work);
-
mutex_lock(&ifmgd->mtx);
if (ifmgd->assoc_data)
ieee80211_destroy_assoc_data(sdata, false);
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 7acbdaa..a3ad4c3 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -299,13 +299,10 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
}
}
-void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free)
+void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
{
struct ieee80211_roc_work *dep, *tmp;
- if (WARN_ON(roc->to_be_freed))
- return;
-
/* was never transmitted */
if (roc->frame) {
cfg80211_mgmt_tx_status(&roc->sdata->wdev,
@@ -321,12 +318,9 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free)
GFP_KERNEL);
list_for_each_entry_safe(dep, tmp, &roc->dependents, list)
- ieee80211_roc_notify_destroy(dep, true);
+ ieee80211_roc_notify_destroy(dep);
- if (free)
- kfree(roc);
- else
- roc->to_be_freed = true;
+ kfree(roc);
}
void ieee80211_sw_roc_work(struct work_struct *work)
@@ -339,9 +333,6 @@ void ieee80211_sw_roc_work(struct work_struct *work)
mutex_lock(&local->mtx);
- if (roc->to_be_freed)
- goto out_unlock;
-
if (roc->abort)
goto finish;
@@ -381,7 +372,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
finish:
list_del(&roc->list);
started = roc->started;
- ieee80211_roc_notify_destroy(roc, !roc->abort);
+ ieee80211_roc_notify_destroy(roc);
if (started) {
drv_flush(local, false);
@@ -421,7 +412,7 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
list_del(&roc->list);
- ieee80211_roc_notify_destroy(roc, true);
+ ieee80211_roc_notify_destroy(roc);
/* if there's another roc, start it now */
ieee80211_start_next_roc(local);
@@ -471,14 +462,12 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
if (local->ops->remain_on_channel) {
list_del(&roc->list);
- ieee80211_roc_notify_destroy(roc, true);
+ ieee80211_roc_notify_destroy(roc);
} else {
ieee80211_queue_delayed_work(&local->hw, &roc->work, 0);
/* work will clean up etc */
flush_delayed_work(&roc->work);
- WARN_ON(!roc->to_be_freed);
- kfree(roc);
}
}
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 64619f4..79a48f3 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -52,8 +52,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
ieee80211_stop_queues_by_reason(hw,
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
- /* flush out all packets and station cleanup call_rcu()s */
- rcu_barrier();
+ /* flush out all packets */
+ synchronize_net();
drv_flush(local, false);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c58f3cd..580704e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3144,7 +3144,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct ieee80211_supported_band *sband;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- WARN_ON_ONCE_NONRT(softirq_count() == 0);
+ WARN_ON_ONCE(softirq_count() == 0);
if (WARN_ON(status->band >= IEEE80211_NUM_BANDS))
goto drop;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c8b32a0..ca9fde1 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -756,7 +756,6 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
struct ieee80211_local *local;
struct ieee80211_sub_if_data *sdata;
int ret, i;
- bool have_key = false;
might_sleep();
@@ -784,19 +783,12 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
list_del_rcu(&sta->list);
mutex_lock(&local->key_mtx);
- for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+ for (i = 0; i < NUM_DEFAULT_KEYS; i++)
__ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
- have_key = true;
- }
- if (sta->ptk) {
+ if (sta->ptk)
__ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
- have_key = true;
- }
mutex_unlock(&local->key_mtx);
- if (!have_key)
- synchronize_net();
-
sta->dead = true;
local->num_sta--;
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index c646ec8..a9c488b 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -20,17 +20,11 @@
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/slab.h>
-#include <linux/locallock.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include "nf_internals.h"
-#ifdef CONFIG_PREEMPT_RT_BASE
-DEFINE_LOCAL_IRQ_LOCK(xt_write_lock);
-EXPORT_PER_CPU_SYMBOL(xt_write_lock);
-#endif
-
static DEFINE_MUTEX(afinfo_mutex);
const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 38ca630..6d6d8f2 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1470,8 +1470,7 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
if (ret == -EAGAIN)
ret = 1;
- return (ret < 0 && ret != -ENOTEMPTY) ? ret :
- ret > 0 ? 0 : -IPSET_ERR_EXIST;
+ return ret < 0 ? ret : ret > 0 ? 0 : -IPSET_ERR_EXIST;
}
/* Get headed data of a set */
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 09c744a..8371c2b 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -174,13 +174,9 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
{
const struct set_elem *e = list_set_elem(map, i);
- if (e->id != IPSET_INVALID_ID) {
- const struct set_elem *x = list_set_elem(map, map->size - 1);
-
- /* Last element replaced or pushed off */
- if (x->id != IPSET_INVALID_ID)
- ip_set_put_byindex(x->id);
- }
+ if (i == map->size - 1 && e->id != IPSET_INVALID_ID)
+ /* Last element replaced: e.g. add new,before,last */
+ ip_set_put_byindex(e->id);
if (with_timeout(map->timeout))
list_elem_tadd(map, i, id, ip_set_timeout_set(timeout));
else
diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
index e5920fb..12475ef 100644
--- a/net/netfilter/ipvs/ip_vs_pe_sip.c
+++ b/net/netfilter/ipvs/ip_vs_pe_sip.c
@@ -37,10 +37,14 @@ static int get_callid(const char *dptr, unsigned int dataoff,
if (ret > 0)
break;
if (!ret)
- return -EINVAL;
+ return 0;
dataoff += *matchoff;
}
+ /* Empty callid is useless */
+ if (!*matchlen)
+ return -EINVAL;
+
/* Too large is useless */
if (*matchlen > IP_VS_PEDATA_MAXLEN)
return -EINVAL;
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 91527d5..884f2b3 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -236,9 +236,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
/* We only allow helper re-assignment of the same sort since
* we cannot reallocate the helper extension area.
*/
- struct nf_conntrack_helper *tmp = rcu_dereference(help->helper);
-
- if (tmp && tmp->help != helper->help) {
+ if (help->helper != helper) {
RCU_INIT_POINTER(help->helper, NULL);
goto out;
}
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a081915..627b0e5 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1705,9 +1705,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
if (nlh->nlmsg_flags & NLM_F_CREATE) {
enum ip_conntrack_events events;
- if (!cda[CTA_TUPLE_ORIG] || !cda[CTA_TUPLE_REPLY])
- return -EINVAL;
-
ct = ctnetlink_create_conntrack(net, zone, cda, &otuple,
&rtuple, u3);
if (IS_ERR(ct))
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index b4e0d1c..df8f4f2 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1547,7 +1547,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
msglen = origlen = end - dptr;
if (msglen > datalen)
- return NF_ACCEPT;
+ return NF_DROP;
ret = process_sip_msg(skb, ct, protoff, dataoff,
&dptr, &msglen);
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 4bc2aaf..5f2f910 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -468,22 +468,33 @@ EXPORT_SYMBOL_GPL(nf_nat_packet);
struct nf_nat_proto_clean {
u8 l3proto;
u8 l4proto;
+ bool hash;
};
-/* kill conntracks with affected NAT section */
-static int nf_nat_proto_remove(struct nf_conn *i, void *data)
+/* Clear NAT section of all conntracks, in case we're loaded again. */
+static int nf_nat_proto_clean(struct nf_conn *i, void *data)
{
const struct nf_nat_proto_clean *clean = data;
struct nf_conn_nat *nat = nfct_nat(i);
if (!nat)
return 0;
-
+ if (!(i->status & IPS_SRC_NAT_DONE))
+ return 0;
if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) ||
(clean->l4proto && nf_ct_protonum(i) != clean->l4proto))
return 0;
- return i->status & IPS_NAT_MASK ? 1 : 0;
+ if (clean->hash) {
+ spin_lock_bh(&nf_nat_lock);
+ hlist_del_rcu(&nat->bysource);
+ spin_unlock_bh(&nf_nat_lock);
+ } else {
+ memset(nat, 0, sizeof(*nat));
+ i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK |
+ IPS_SEQ_ADJUST);
+ }
+ return 0;
}
static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
@@ -495,8 +506,16 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
struct net *net;
rtnl_lock();
+ /* Step 1 - remove from bysource hash */
+ clean.hash = true;
for_each_net(net)
- nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean);
+ nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
+ synchronize_rcu();
+
+ /* Step 2 - clean NAT section */
+ clean.hash = false;
+ for_each_net(net)
+ nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
rtnl_unlock();
}
@@ -508,9 +527,16 @@ static void nf_nat_l3proto_clean(u8 l3proto)
struct net *net;
rtnl_lock();
+ /* Step 1 - remove from bysource hash */
+ clean.hash = true;
+ for_each_net(net)
+ nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
+ synchronize_rcu();
+ /* Step 2 - clean NAT section */
+ clean.hash = false;
for_each_net(net)
- nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean);
+ nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean);
rtnl_unlock();
}
@@ -748,7 +774,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
{
struct nf_nat_proto_clean clean = {};
- nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean);
+ nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean);
synchronize_rcu();
nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
}
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8a6c6ea..847d495 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1189,6 +1189,8 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
struct netlbl_unlhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
+ u32 skip_addr4 = cb->args[2];
+ u32 skip_addr6 = cb->args[3];
u32 iter_bkt;
u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_unlhsh_iface *iface;
@@ -1213,7 +1215,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
continue;
netlbl_af4list_foreach_rcu(addr4,
&iface->addr4_list) {
- if (iter_addr4++ < cb->args[2])
+ if (iter_addr4++ < skip_addr4)
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1229,7 +1231,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6,
&iface->addr6_list) {
- if (iter_addr6++ < cb->args[3])
+ if (iter_addr6++ < skip_addr6)
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@@ -1248,10 +1250,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
unlabel_staticlist_return:
rcu_read_unlock();
- cb->args[0] = iter_bkt;
- cb->args[1] = iter_chain;
- cb->args[2] = iter_addr4;
- cb->args[3] = iter_addr6;
+ cb->args[0] = skip_bkt;
+ cb->args[1] = skip_chain;
+ cb->args[2] = skip_addr4;
+ cb->args[3] = skip_addr6;
return skb->len;
}
@@ -1271,9 +1273,12 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
{
struct netlbl_unlhsh_walk_arg cb_arg;
struct netlbl_unlhsh_iface *iface;
- u32 iter_addr4 = 0, iter_addr6 = 0;
+ u32 skip_addr4 = cb->args[0];
+ u32 skip_addr6 = cb->args[1];
+ u32 iter_addr4 = 0;
struct netlbl_af4list *addr4;
#if IS_ENABLED(CONFIG_IPV6)
+ u32 iter_addr6 = 0;
struct netlbl_af6list *addr6;
#endif
@@ -1287,7 +1292,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
goto unlabel_staticlistdef_return;
netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
- if (iter_addr4++ < cb->args[0])
+ if (iter_addr4++ < skip_addr4)
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1300,7 +1305,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
}
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
- if (iter_addr6++ < cb->args[1])
+ if (iter_addr6++ < skip_addr6)
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@@ -1315,8 +1320,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
unlabel_staticlistdef_return:
rcu_read_unlock();
- cb->args[0] = iter_addr4;
- cb->args[1] = iter_addr6;
+ cb->args[0] = skip_addr4;
+ cb->args[1] = skip_addr6;
return skb->len;
}
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 5a55be3..f2aabb6 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -142,7 +142,6 @@ int genl_register_mc_group(struct genl_family *family,
int err = 0;
BUG_ON(grp->name[0] == '\0');
- BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL);
genl_lock();
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 14c106b..7261eb8 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1177,7 +1177,6 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
}
if (sax != NULL) {
- memset(sax, 0, sizeof(sax));
sax->sax25_family = AF_NETROM;
skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
AX25_ADDR_LEN);
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 48fb1de..fea22eb 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -644,8 +644,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
pr_debug("%p %zu\n", sk, len);
- msg->msg_namelen = 0;
-
lock_sock(sk);
if (sk->sk_state == LLCP_CLOSED &&
@@ -686,7 +684,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap);
- memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sa_family = AF_NFC;
sockaddr.nfc_protocol = NFC_PROTO_NFC_DEP;
sockaddr.dsap = ui_cb->dsap;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 92a2359..c111bd0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -88,7 +88,6 @@
#include <linux/virtio_net.h>
#include <linux/errqueue.h>
#include <linux/net_tstamp.h>
-#include <linux/delay.h>
#ifdef CONFIG_INET
#include <net/inet_common.h>
@@ -554,7 +553,7 @@ static void prb_retire_rx_blk_timer_expired(unsigned long data)
if (BLOCK_NUM_PKTS(pbd)) {
while (atomic_read(&pkc->blk_fill_in_prog)) {
/* Waiting for skb_copy_bits to finish... */
- cpu_chill();
+ cpu_relax();
}
}
@@ -808,7 +807,7 @@ static void prb_retire_current_block(struct tpacket_kbdq_core *pkc,
if (!(status & TP_STATUS_BLK_TMO)) {
while (atomic_read(&pkc->blk_fill_in_prog)) {
/* Waiting for skb_copy_bits to finish... */
- cpu_chill();
+ cpu_relax();
}
}
prb_close_block(pkc, pbd, po, status);
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 5a44c6e..e8fdb17 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -34,7 +34,6 @@
#include <linux/slab.h>
#include <linux/rculist.h>
#include <linux/llist.h>
-#include <linux/delay.h>
#include "rds.h"
#include "ib.h"
@@ -287,7 +286,7 @@ static inline void wait_clean_list_grace(void)
for_each_online_cpu(cpu) {
flag = &per_cpu(clean_list_grace, cpu);
while (test_bit(CLEAN_LIST_BUSY_BIT, flag))
- cpu_chill();
+ cpu_relax();
}
}
diff --git a/net/rds/message.c b/net/rds/message.c
index aff589c..f0a4658 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -197,9 +197,6 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp)
{
struct rds_message *rm;
- if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message))
- return NULL;
-
rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp);
if (!rm)
goto out;
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 7f645d1..c4719ce 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1257,7 +1257,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (srose != NULL) {
- memset(srose, 0, msg->msg_namelen);
srose->srose_family = AF_ROSE;
srose->srose_addr = rose->dest_addr;
srose->srose_call = rose->dest_call;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index ced81a1..0e19948 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -962,11 +962,8 @@ cbq_dequeue(struct Qdisc *sch)
cbq_update(q);
if ((incr -= incr2) < 0)
incr = 0;
- q->now += incr;
- } else {
- if (now > q->now)
- q->now = now;
}
+ q->now += incr;
q->now_rt = now;
for (;;) {
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 5578628..4e606fc 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -195,7 +195,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
flow->deficit = q->quantum;
flow->dropped = 0;
}
- if (++sch->q.qlen <= sch->limit)
+ if (++sch->q.qlen < sch->limit)
return NET_XMIT_SUCCESS;
q->drop_overlimit++;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 67c6823..b45ed1f 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1080,7 +1080,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
transports) {
if (transport == active)
- continue;
+ break;
list_for_each_entry(chunk, &transport->transmitted,
transmitted_list) {
if (key == chunk->subh.data_hdr->tsn) {
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index de1a013..5131fcf 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2082,7 +2082,7 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(struct net *net,
}
/* Delete the tempory new association. */
- sctp_add_cmd_sf(commands, SCTP_CMD_SET_ASOC, SCTP_ASOC(new_asoc));
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
/* Restore association pointer to provide SCTP command interpeter
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9ef5c73..cedd9bf 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5653,9 +5653,6 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
if (len < sizeof(sctp_assoc_t))
return -EINVAL;
- /* Allow the struct to grow and fill in as much as possible */
- len = min_t(size_t, len, sizeof(sas));
-
if (copy_from_user(&sas, optval, len))
return -EFAULT;
@@ -5689,6 +5686,9 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
/* Mark beginning of a new observation period */
asoc->stats.max_obs_rto = asoc->rto_min;
+ /* Allow the struct to grow and fill in as much as possible */
+ len = min_t(size_t, len, sizeof(sas));
+
if (put_user(len, optlen))
return -EFAULT;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 716aa41..507b5e8 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -511,7 +511,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
new = rpc_new_client(args, xprt);
if (IS_ERR(new)) {
err = PTR_ERR(new);
- goto out_err;
+ goto out_put;
}
atomic_inc(&clnt->cl_count);
@@ -524,6 +524,8 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
new->cl_chatty = clnt->cl_chatty;
return new;
+out_put:
+ xprt_put(xprt);
out_err:
dprintk("RPC: %s: returned error %d\n", __func__, err);
return ERR_PTR(err);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index f8529fc..fb20f25 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -180,8 +180,6 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
task->tk_waitqueue = queue;
queue->qlen++;
- /* barrier matches the read in rpc_wake_up_task_queue_locked() */
- smp_wmb();
rpc_set_queued(task);
dprintk("RPC: %5u added to queue %p \"%s\"\n",
@@ -432,11 +430,8 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task
*/
static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task)
{
- if (RPC_IS_QUEUED(task)) {
- smp_rmb();
- if (task->tk_waitqueue == queue)
- __rpc_do_wake_up_task(queue, task);
- }
+ if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue)
+ __rpc_do_wake_up_task(queue, task);
}
/*
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 2d34b6b..dbf12ac 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -515,6 +515,15 @@ EXPORT_SYMBOL_GPL(svc_create_pooled);
void svc_shutdown_net(struct svc_serv *serv, struct net *net)
{
+ /*
+ * The set of xprts (contained in the sv_tempsocks and
+ * sv_permsocks lists) is now constant, since it is modified
+ * only by accepting new sockets (done by service threads in
+ * svc_recv) or aging old ones (done by sv_temptimer), or
+ * configuration changes (excluded by whatever locking the
+ * caller is using--nfsd_mutex in the case of nfsd). So it's
+ * safe to traverse those lists and shut everything down:
+ */
svc_close_net(serv, net);
if (serv->sv_shutdown)
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index ca71056..b8e47fa 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -856,6 +856,7 @@ static void svc_age_temp_xprts(unsigned long closure)
struct svc_serv *serv = (struct svc_serv *)closure;
struct svc_xprt *xprt;
struct list_head *le, *next;
+ LIST_HEAD(to_be_aged);
dprintk("svc_age_temp_xprts\n");
@@ -876,15 +877,25 @@ static void svc_age_temp_xprts(unsigned long closure)
if (atomic_read(&xprt->xpt_ref.refcount) > 1 ||
test_bit(XPT_BUSY, &xprt->xpt_flags))
continue;
- list_del_init(le);
+ svc_xprt_get(xprt);
+ list_move(le, &to_be_aged);
set_bit(XPT_CLOSE, &xprt->xpt_flags);
set_bit(XPT_DETACHED, &xprt->xpt_flags);
+ }
+ spin_unlock_bh(&serv->sv_lock);
+
+ while (!list_empty(&to_be_aged)) {
+ le = to_be_aged.next;
+ /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */
+ list_del_init(le);
+ xprt = list_entry(le, struct svc_xprt, xpt_list);
+
dprintk("queuing xprt %p for closing\n", xprt);
/* a thread will dequeue and close it soon */
svc_xprt_enqueue(xprt);
+ svc_xprt_put(xprt);
}
- spin_unlock_bh(&serv->sv_lock);
mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ);
}
@@ -948,24 +959,21 @@ void svc_close_xprt(struct svc_xprt *xprt)
}
EXPORT_SYMBOL_GPL(svc_close_xprt);
-static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
+static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
{
struct svc_xprt *xprt;
- int ret = 0;
spin_lock(&serv->sv_lock);
list_for_each_entry(xprt, xprt_list, xpt_list) {
if (xprt->xpt_net != net)
continue;
- ret++;
set_bit(XPT_CLOSE, &xprt->xpt_flags);
- svc_xprt_enqueue(xprt);
+ set_bit(XPT_BUSY, &xprt->xpt_flags);
}
spin_unlock(&serv->sv_lock);
- return ret;
}
-static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net)
+static void svc_clear_pools(struct svc_serv *serv, struct net *net)
{
struct svc_pool *pool;
struct svc_xprt *xprt;
@@ -980,46 +988,42 @@ static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net)
if (xprt->xpt_net != net)
continue;
list_del_init(&xprt->xpt_ready);
- spin_unlock_bh(&pool->sp_lock);
- return xprt;
}
spin_unlock_bh(&pool->sp_lock);
}
- return NULL;
}
-static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
+static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
{
struct svc_xprt *xprt;
+ struct svc_xprt *tmp;
+ LIST_HEAD(victims);
- while ((xprt = svc_dequeue_net(serv, net))) {
- set_bit(XPT_CLOSE, &xprt->xpt_flags);
- svc_delete_xprt(xprt);
+ spin_lock(&serv->sv_lock);
+ list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
+ if (xprt->xpt_net != net)
+ continue;
+ list_move(&xprt->xpt_list, &victims);
}
+ spin_unlock(&serv->sv_lock);
+
+ list_for_each_entry_safe(xprt, tmp, &victims, xpt_list)
+ svc_delete_xprt(xprt);
}
-/*
- * Server threads may still be running (especially in the case where the
- * service is still running in other network namespaces).
- *
- * So we shut down sockets the same way we would on a running server, by
- * setting XPT_CLOSE, enqueuing, and letting a thread pick it up to do
- * the close. In the case there are no such other threads,
- * threads running, svc_clean_up_xprts() does a simple version of a
- * server's main event loop, and in the case where there are other
- * threads, we may need to wait a little while and then check again to
- * see if they're done.
- */
void svc_close_net(struct svc_serv *serv, struct net *net)
{
- int delay = 0;
-
- while (svc_close_list(serv, &serv->sv_permsocks, net) +
- svc_close_list(serv, &serv->sv_tempsocks, net)) {
+ svc_close_list(serv, &serv->sv_tempsocks, net);
+ svc_close_list(serv, &serv->sv_permsocks, net);
- svc_clean_up_xprts(serv, net);
- msleep(delay++);
- }
+ svc_clear_pools(serv, net);
+ /*
+ * At this point the sp_sockets lists will stay empty, since
+ * svc_xprt_enqueue will not add new entries without taking the
+ * sp_lock and checking XPT_BUSY.
+ */
+ svc_clear_list(serv, &serv->sv_tempsocks, net);
+ svc_clear_list(serv, &serv->sv_permsocks, net);
}
/*
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index ab02588..33811db 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -485,17 +485,13 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
* xprt_wait_for_buffer_space - wait for transport output buffer to clear
* @task: task to be put to sleep
* @action: function pointer to be executed after wait
- *
- * Note that we only set the timer for the case of RPC_IS_SOFT(), since
- * we don't in general want to force a socket disconnection due to
- * an incomplete RPC call transmission.
*/
void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;
- task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0;
+ task->tk_timeout = req->rq_timeout;
rpc_sleep_on(&xprt->pending, task, action);
}
EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index fc906d9..9b4e483 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -806,7 +806,6 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
if (addr) {
addr->family = AF_TIPC;
addr->addrtype = TIPC_ADDR_ID;
- memset(&addr->addr, 0, sizeof(addr->addr));
addr->addr.id.ref = msg_origport(msg);
addr->addr.id.node = msg_orignode(msg);
addr->addr.name.domain = 0; /* could leave uninitialized */
@@ -921,9 +920,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
goto exit;
}
- /* will be updated in set_orig_addr() if needed */
- m->msg_namelen = 0;
-
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
restart:
@@ -1033,9 +1029,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
goto exit;
}
- /* will be updated in set_orig_addr() if needed */
- m->msg_namelen = 0;
-
target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f347754..5b5c876 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -384,7 +384,7 @@ static void unix_sock_destructor(struct sock *sk)
#endif
}
-static void unix_release_sock(struct sock *sk, int embrion)
+static int unix_release_sock(struct sock *sk, int embrion)
{
struct unix_sock *u = unix_sk(sk);
struct path path;
@@ -453,6 +453,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
if (unix_tot_inflight)
unix_gc(); /* Garbage collect fds */
+
+ return 0;
}
static void init_peercred(struct sock *sk)
@@ -699,10 +701,9 @@ static int unix_release(struct socket *sock)
if (!sk)
return 0;
- unix_release_sock(sk, 0);
sock->sk = NULL;
- return 0;
+ return unix_release_sock(sk, 0);
}
static int unix_autobind(struct socket *sock)
@@ -1995,7 +1996,7 @@ again:
if ((UNIXCB(skb).pid != siocb->scm->pid) ||
(UNIXCB(skb).cred != siocb->scm->cred))
break;
- } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
+ } else {
/* Copy credentials */
scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
check_creds = 1;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 91ef82b..82c4fc7 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -883,7 +883,7 @@ static void handle_channel(struct wiphy *wiphy,
return;
REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq);
- chan->flags |= IEEE80211_CHAN_DISABLED;
+ chan->flags = IEEE80211_CHAN_DISABLED;
return;
}