Merge tag 'v3.10.73' into update
This is the 3.10.73 stable release
This commit is contained in:
@@ -283,7 +283,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||
int copylen;
|
||||
|
||||
ret = -EOPNOTSUPP;
|
||||
if (m->msg_flags&MSG_OOB)
|
||||
if (flags & MSG_OOB)
|
||||
goto read_error;
|
||||
|
||||
skb = skb_recv_datagram(sk, flags, 0 , &ret);
|
||||
|
||||
@@ -262,6 +262,9 @@ int can_send(struct sk_buff *skb, int loop)
|
||||
goto inval_skb;
|
||||
}
|
||||
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
|
||||
|
||||
@@ -71,6 +71,13 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
|
||||
__get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
|
||||
__get_user(kmsg->msg_flags, &umsg->msg_flags))
|
||||
return -EFAULT;
|
||||
|
||||
if (!tmp1)
|
||||
kmsg->msg_namelen = 0;
|
||||
|
||||
if (kmsg->msg_namelen < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
|
||||
kmsg->msg_namelen = sizeof(struct sockaddr_storage);
|
||||
kmsg->msg_name = compat_ptr(tmp1);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
static int zero = 0;
|
||||
static int one = 1;
|
||||
static int ushort_max = USHRT_MAX;
|
||||
static int min_sndbuf = SOCK_MIN_SNDBUF;
|
||||
static int min_rcvbuf = SOCK_MIN_RCVBUF;
|
||||
|
||||
#ifdef CONFIG_RPS
|
||||
static int rps_sock_flow_sysctl(ctl_table *table, int write,
|
||||
@@ -97,7 +99,7 @@ static struct ctl_table net_core_table[] = {
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &one,
|
||||
.extra1 = &min_sndbuf,
|
||||
},
|
||||
{
|
||||
.procname = "rmem_max",
|
||||
@@ -105,7 +107,7 @@ static struct ctl_table net_core_table[] = {
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &one,
|
||||
.extra1 = &min_rcvbuf,
|
||||
},
|
||||
{
|
||||
.procname = "wmem_default",
|
||||
@@ -113,7 +115,7 @@ static struct ctl_table net_core_table[] = {
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &one,
|
||||
.extra1 = &min_sndbuf,
|
||||
},
|
||||
{
|
||||
.procname = "rmem_default",
|
||||
@@ -121,7 +123,7 @@ static struct ctl_table net_core_table[] = {
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &one,
|
||||
.extra1 = &min_rcvbuf,
|
||||
},
|
||||
{
|
||||
.procname = "dev_weight",
|
||||
|
||||
+15
-3
@@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler(
|
||||
mutex_unlock(&inet_diag_table_mutex);
|
||||
}
|
||||
|
||||
static size_t inet_sk_attr_size(void)
|
||||
{
|
||||
return nla_total_size(sizeof(struct tcp_info))
|
||||
+ nla_total_size(1) /* INET_DIAG_SHUTDOWN */
|
||||
+ nla_total_size(1) /* INET_DIAG_TOS */
|
||||
+ nla_total_size(1) /* INET_DIAG_TCLASS */
|
||||
+ nla_total_size(sizeof(struct inet_diag_meminfo))
|
||||
+ nla_total_size(sizeof(struct inet_diag_msg))
|
||||
+ nla_total_size(SK_MEMINFO_VARS * sizeof(u32))
|
||||
+ nla_total_size(TCP_CA_NAME_MAX)
|
||||
+ nla_total_size(sizeof(struct tcpvegas_info))
|
||||
+ 64;
|
||||
}
|
||||
|
||||
int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
|
||||
struct sk_buff *skb, struct inet_diag_req_v2 *req,
|
||||
struct user_namespace *user_ns,
|
||||
@@ -326,9 +340,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
rep = nlmsg_new(sizeof(struct inet_diag_msg) +
|
||||
sizeof(struct inet_diag_meminfo) +
|
||||
sizeof(struct tcp_info) + 64, GFP_KERNEL);
|
||||
rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL);
|
||||
if (!rep) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
|
||||
+29
-41
@@ -2592,15 +2592,11 @@ void tcp_send_fin(struct sock *sk)
|
||||
} else {
|
||||
/* Socket is locked, keep trying until memory is available. */
|
||||
for (;;) {
|
||||
skb = alloc_skb_fclone(MAX_TCP_HEADER,
|
||||
sk->sk_allocation);
|
||||
skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
|
||||
if (skb)
|
||||
break;
|
||||
yield();
|
||||
}
|
||||
|
||||
/* Reserve space for headers and prepare control bits. */
|
||||
skb_reserve(skb, MAX_TCP_HEADER);
|
||||
/* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
|
||||
tcp_init_nondata_skb(skb, tp->write_seq,
|
||||
TCPHDR_ACK | TCPHDR_FIN);
|
||||
@@ -2874,9 +2870,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct tcp_fastopen_request *fo = tp->fastopen_req;
|
||||
int syn_loss = 0, space, i, err = 0, iovlen = fo->data->msg_iovlen;
|
||||
struct sk_buff *syn_data = NULL, *data;
|
||||
int syn_loss = 0, space, err = 0;
|
||||
unsigned long last_syn_loss = 0;
|
||||
struct sk_buff *syn_data;
|
||||
|
||||
tp->rx_opt.mss_clamp = tp->advmss; /* If MSS is not cached */
|
||||
tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie,
|
||||
@@ -2907,42 +2903,38 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
|
||||
/* limit to order-0 allocations */
|
||||
space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER));
|
||||
|
||||
syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space,
|
||||
sk->sk_allocation);
|
||||
if (syn_data == NULL)
|
||||
syn_data = sk_stream_alloc_skb(sk, space, sk->sk_allocation);
|
||||
if (!syn_data)
|
||||
goto fallback;
|
||||
syn_data->ip_summed = CHECKSUM_PARTIAL;
|
||||
memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
|
||||
if (unlikely(memcpy_fromiovecend(skb_put(syn_data, space),
|
||||
fo->data->msg_iov, 0, space))) {
|
||||
kfree_skb(syn_data);
|
||||
goto fallback;
|
||||
|
||||
for (i = 0; i < iovlen && syn_data->len < space; ++i) {
|
||||
struct iovec *iov = &fo->data->msg_iov[i];
|
||||
unsigned char __user *from = iov->iov_base;
|
||||
int len = iov->iov_len;
|
||||
|
||||
if (syn_data->len + len > space)
|
||||
len = space - syn_data->len;
|
||||
else if (i + 1 == iovlen)
|
||||
/* No more data pending in inet_wait_for_connect() */
|
||||
fo->data = NULL;
|
||||
|
||||
if (skb_add_data(syn_data, from, len))
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
/* Queue a data-only packet after the regular SYN for retransmission */
|
||||
data = pskb_copy(syn_data, sk->sk_allocation);
|
||||
if (data == NULL)
|
||||
goto fallback;
|
||||
TCP_SKB_CB(data)->seq++;
|
||||
TCP_SKB_CB(data)->tcp_flags &= ~TCPHDR_SYN;
|
||||
TCP_SKB_CB(data)->tcp_flags = (TCPHDR_ACK|TCPHDR_PSH);
|
||||
tcp_connect_queue_skb(sk, data);
|
||||
fo->copied = data->len;
|
||||
/* No more data pending in inet_wait_for_connect() */
|
||||
if (space == fo->size)
|
||||
fo->data = NULL;
|
||||
fo->copied = space;
|
||||
|
||||
if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) {
|
||||
tcp_connect_queue_skb(sk, syn_data);
|
||||
|
||||
err = tcp_transmit_skb(sk, syn_data, 1, sk->sk_allocation);
|
||||
|
||||
/* Now full SYN+DATA was cloned and sent (or not),
|
||||
* remove the SYN from the original skb (syn_data)
|
||||
* we keep in write queue in case of a retransmit, as we
|
||||
* also have the SYN packet (with no data) in the same queue.
|
||||
*/
|
||||
TCP_SKB_CB(syn_data)->seq++;
|
||||
TCP_SKB_CB(syn_data)->tcp_flags = TCPHDR_ACK | TCPHDR_PSH;
|
||||
if (!err) {
|
||||
tp->syn_data = (fo->copied > 0);
|
||||
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
|
||||
goto done;
|
||||
}
|
||||
syn_data = NULL;
|
||||
|
||||
fallback:
|
||||
/* Send a regular SYN with Fast Open cookie request option */
|
||||
@@ -2951,7 +2943,6 @@ fallback:
|
||||
err = tcp_transmit_skb(sk, syn, 1, sk->sk_allocation);
|
||||
if (err)
|
||||
tp->syn_fastopen = 0;
|
||||
kfree_skb(syn_data);
|
||||
done:
|
||||
fo->cookie.len = -1; /* Exclude Fast Open option for SYN retries */
|
||||
return err;
|
||||
@@ -2971,13 +2962,10 @@ int tcp_connect(struct sock *sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
buff = alloc_skb_fclone(MAX_TCP_HEADER + 15, sk->sk_allocation);
|
||||
if (unlikely(buff == NULL))
|
||||
buff = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
|
||||
if (unlikely(!buff))
|
||||
return -ENOBUFS;
|
||||
|
||||
/* Reserve space for headers. */
|
||||
skb_reserve(buff, MAX_TCP_HEADER);
|
||||
|
||||
tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN);
|
||||
tp->retrans_stamp = TCP_SKB_CB(buff)->when = tcp_time_stamp;
|
||||
tcp_connect_queue_skb(sk, buff);
|
||||
|
||||
@@ -650,16 +650,24 @@ static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ip_vs_route_me_harder(int af, struct sk_buff *skb)
|
||||
static int ip_vs_route_me_harder(int af, struct sk_buff *skb,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
if (!sysctl_snat_reroute(skb))
|
||||
return 0;
|
||||
/* Reroute replies only to remote clients (FORWARD and LOCAL_OUT) */
|
||||
if (NF_INET_LOCAL_IN == hooknum)
|
||||
return 0;
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
if (af == AF_INET6) {
|
||||
if (sysctl_snat_reroute(skb) && ip6_route_me_harder(skb) != 0)
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
|
||||
if (dst->dev && !(dst->dev->flags & IFF_LOOPBACK) &&
|
||||
ip6_route_me_harder(skb) != 0)
|
||||
return 1;
|
||||
} else
|
||||
#endif
|
||||
if ((sysctl_snat_reroute(skb) ||
|
||||
skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
|
||||
if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
|
||||
ip_route_me_harder(skb, RTN_LOCAL) != 0)
|
||||
return 1;
|
||||
|
||||
@@ -782,7 +790,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
|
||||
union nf_inet_addr *snet,
|
||||
__u8 protocol, struct ip_vs_conn *cp,
|
||||
struct ip_vs_protocol *pp,
|
||||
unsigned int offset, unsigned int ihl)
|
||||
unsigned int offset, unsigned int ihl,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
unsigned int verdict = NF_DROP;
|
||||
|
||||
@@ -812,7 +821,7 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
|
||||
#endif
|
||||
ip_vs_nat_icmp(skb, pp, cp, 1);
|
||||
|
||||
if (ip_vs_route_me_harder(af, skb))
|
||||
if (ip_vs_route_me_harder(af, skb, hooknum))
|
||||
goto out;
|
||||
|
||||
/* do the statistics and put it back */
|
||||
@@ -907,7 +916,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related,
|
||||
|
||||
snet.ip = iph->saddr;
|
||||
return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp,
|
||||
pp, ciph.len, ihl);
|
||||
pp, ciph.len, ihl, hooknum);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IP_VS_IPV6
|
||||
@@ -972,7 +981,8 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
|
||||
snet.in6 = ciph.saddr.in6;
|
||||
writable = ciph.len;
|
||||
return handle_response_icmp(AF_INET6, skb, &snet, ciph.protocol, cp,
|
||||
pp, writable, sizeof(struct ipv6hdr));
|
||||
pp, writable, sizeof(struct ipv6hdr),
|
||||
hooknum);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1031,7 +1041,8 @@ static inline bool is_new_conn(const struct sk_buff *skb,
|
||||
*/
|
||||
static unsigned int
|
||||
handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
|
||||
struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
|
||||
struct ip_vs_conn *cp, struct ip_vs_iphdr *iph,
|
||||
unsigned int hooknum)
|
||||
{
|
||||
struct ip_vs_protocol *pp = pd->pp;
|
||||
|
||||
@@ -1069,7 +1080,7 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
|
||||
* if it came from this machine itself. So re-compute
|
||||
* the routing information.
|
||||
*/
|
||||
if (ip_vs_route_me_harder(af, skb))
|
||||
if (ip_vs_route_me_harder(af, skb, hooknum))
|
||||
goto drop;
|
||||
|
||||
IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT");
|
||||
@@ -1172,7 +1183,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
|
||||
cp = pp->conn_out_get(af, skb, &iph, 0);
|
||||
|
||||
if (likely(cp))
|
||||
return handle_response(af, skb, pd, cp, &iph);
|
||||
return handle_response(af, skb, pd, cp, &iph, hooknum);
|
||||
if (sysctl_nat_icmp_send(net) &&
|
||||
(pp->protocol == IPPROTO_TCP ||
|
||||
pp->protocol == IPPROTO_UDP ||
|
||||
|
||||
@@ -878,6 +878,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
|
||||
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
|
||||
return;
|
||||
}
|
||||
if (!(flags & IP_VS_CONN_F_TEMPLATE))
|
||||
kfree(param->pe_data);
|
||||
}
|
||||
|
||||
if (opt)
|
||||
@@ -1151,6 +1153,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end)
|
||||
(opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL)
|
||||
);
|
||||
#endif
|
||||
ip_vs_pe_put(param.pe);
|
||||
return 0;
|
||||
/* Error exit */
|
||||
out:
|
||||
|
||||
+22
-18
@@ -88,7 +88,9 @@ static unsigned int rds_iw_unmap_fastreg_list(struct rds_iw_mr_pool *pool,
|
||||
int *unpinned);
|
||||
static void rds_iw_destroy_fastreg(struct rds_iw_mr_pool *pool, struct rds_iw_mr *ibmr);
|
||||
|
||||
static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwdev, struct rdma_cm_id **cm_id)
|
||||
static int rds_iw_get_device(struct sockaddr_in *src, struct sockaddr_in *dst,
|
||||
struct rds_iw_device **rds_iwdev,
|
||||
struct rdma_cm_id **cm_id)
|
||||
{
|
||||
struct rds_iw_device *iwdev;
|
||||
struct rds_iw_cm_id *i_cm_id;
|
||||
@@ -112,15 +114,15 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd
|
||||
src_addr->sin_port,
|
||||
dst_addr->sin_addr.s_addr,
|
||||
dst_addr->sin_port,
|
||||
rs->rs_bound_addr,
|
||||
rs->rs_bound_port,
|
||||
rs->rs_conn_addr,
|
||||
rs->rs_conn_port);
|
||||
src->sin_addr.s_addr,
|
||||
src->sin_port,
|
||||
dst->sin_addr.s_addr,
|
||||
dst->sin_port);
|
||||
#ifdef WORKING_TUPLE_DETECTION
|
||||
if (src_addr->sin_addr.s_addr == rs->rs_bound_addr &&
|
||||
src_addr->sin_port == rs->rs_bound_port &&
|
||||
dst_addr->sin_addr.s_addr == rs->rs_conn_addr &&
|
||||
dst_addr->sin_port == rs->rs_conn_port) {
|
||||
if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr &&
|
||||
src_addr->sin_port == src->sin_port &&
|
||||
dst_addr->sin_addr.s_addr == dst->sin_addr.s_addr &&
|
||||
dst_addr->sin_port == dst->sin_port) {
|
||||
#else
|
||||
/* FIXME - needs to compare the local and remote
|
||||
* ipaddr/port tuple, but the ipaddr is the only
|
||||
@@ -128,7 +130,7 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd
|
||||
* zero'ed. It doesn't appear to be properly populated
|
||||
* during connection setup...
|
||||
*/
|
||||
if (src_addr->sin_addr.s_addr == rs->rs_bound_addr) {
|
||||
if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr) {
|
||||
#endif
|
||||
spin_unlock_irq(&iwdev->spinlock);
|
||||
*rds_iwdev = iwdev;
|
||||
@@ -180,19 +182,13 @@ int rds_iw_update_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_i
|
||||
{
|
||||
struct sockaddr_in *src_addr, *dst_addr;
|
||||
struct rds_iw_device *rds_iwdev_old;
|
||||
struct rds_sock rs;
|
||||
struct rdma_cm_id *pcm_id;
|
||||
int rc;
|
||||
|
||||
src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr;
|
||||
dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr;
|
||||
|
||||
rs.rs_bound_addr = src_addr->sin_addr.s_addr;
|
||||
rs.rs_bound_port = src_addr->sin_port;
|
||||
rs.rs_conn_addr = dst_addr->sin_addr.s_addr;
|
||||
rs.rs_conn_port = dst_addr->sin_port;
|
||||
|
||||
rc = rds_iw_get_device(&rs, &rds_iwdev_old, &pcm_id);
|
||||
rc = rds_iw_get_device(src_addr, dst_addr, &rds_iwdev_old, &pcm_id);
|
||||
if (rc)
|
||||
rds_iw_remove_cm_id(rds_iwdev, cm_id);
|
||||
|
||||
@@ -598,9 +594,17 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents,
|
||||
struct rds_iw_device *rds_iwdev;
|
||||
struct rds_iw_mr *ibmr = NULL;
|
||||
struct rdma_cm_id *cm_id;
|
||||
struct sockaddr_in src = {
|
||||
.sin_addr.s_addr = rs->rs_bound_addr,
|
||||
.sin_port = rs->rs_bound_port,
|
||||
};
|
||||
struct sockaddr_in dst = {
|
||||
.sin_addr.s_addr = rs->rs_conn_addr,
|
||||
.sin_port = rs->rs_conn_port,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = rds_iw_get_device(rs, &rds_iwdev, &cm_id);
|
||||
ret = rds_iw_get_device(&src, &dst, &rds_iwdev, &cm_id);
|
||||
if (ret || !cm_id) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
|
||||
@@ -87,7 +87,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||
if (!skb) {
|
||||
/* nothing remains on the queue */
|
||||
if (copied &&
|
||||
(msg->msg_flags & MSG_PEEK || timeo == 0))
|
||||
(flags & MSG_PEEK || timeo == 0))
|
||||
goto out;
|
||||
|
||||
/* wait for a message to turn up */
|
||||
|
||||
Reference in New Issue
Block a user