diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2014-02-18 16:20:42 +0530 |
---|---|---|
committer | Deepak Nibade <dnibade@nvidia.com> | 2014-03-10 20:03:21 +0530 |
commit | 243d4c9490e60a84e3812cad8786f23da374adac (patch) | |
tree | dabe9e60a091b766e6f8b59b1479453999e39098 /net | |
parent | 635837f825386fe490d57c471442c1dcf2d8bdc0 (diff) | |
parent | 43356cafc2d7d49408c8587039660bbcbc521f01 (diff) |
Merge branch 'android-3.10' into dev-kernel-3.10
Bug 1456092
Change-Id: I87b6b883c382000fc0dfee7c8d8f36269f504e46
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/icmp.c | 5 | ||||
-rw-r--r-- | net/ipv4/ip_sockglue.c | 3 | ||||
-rw-r--r-- | net/ipv4/ping.c | 46 | ||||
-rw-r--r-- | net/ipv4/raw.c | 2 | ||||
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 24 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 5 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 7 | ||||
-rw-r--r-- | net/ipv4/udp.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 9 | ||||
-rw-r--r-- | net/netfilter/xt_IDLETIMER.c | 12 |
10 files changed, 67 insertions, 48 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 62f663040d83..562efd91f457 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -939,7 +939,8 @@ error: 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 offset = iph->ihl<<2; + struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); int type = icmp_hdr(skb)->type; int code = icmp_hdr(skb)->code; struct net *net = dev_net(skb->dev); @@ -949,7 +950,7 @@ void icmp_err(struct sk_buff *skb, u32 info) * triggered by ICMP_ECHOREPLY which sent from kernel. */ if (icmph->type != ICMP_ECHOREPLY) { - ping_v4_err(skb, info); + ping_err(skb, offset, info); return; } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 23e6ab0a2dc0..d9c4f113d709 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -368,7 +368,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf /* * Handle MSG_ERRQUEUE */ -int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) +int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) { struct sock_exterr_skb *serr; struct sk_buff *skb, *skb2; @@ -405,7 +405,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) serr->addr_offset); sin->sin_port = serr->port; memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); - *addr_len = sizeof(*sin); } memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 0b26c09e5af7..5bf79864ca66 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -468,8 +468,6 @@ void ping_err(struct sk_buff *skb, int offset, u32 info) int err; if (skb->protocol == htons(ETH_P_IP)) { - struct iphdr *iph = (struct iphdr *)skb->data; - offset = iph->ihl << 2; family = AF_INET; type = icmp_hdr(skb)->type; code = icmp_hdr(skb)->code; @@ -511,7 +509,8 @@ void ping_err(struct sk_buff *skb, int offset, u32 info) break; case ICMP_SOURCE_QUENCH: /* This is not a real error but ping wants to see it. - * Report it with some fake errno. */ + * Report it with some fake errno. + */ err = EREMOTEIO; break; case ICMP_PARAMETERPROB: @@ -557,11 +556,11 @@ void ping_err(struct sk_buff *skb, int offset, u32 info) } else { if (family == AF_INET) { ip_icmp_error(sk, skb, err, 0 /* no remote port */, - info, (u8 *)icmph); + info, (u8 *)icmph); #if IS_ENABLED(CONFIG_IPV6) } else if (family == AF_INET6) { pingv6_ops.ipv6_icmp_error(sk, skb, err, 0, - info, (u8 *)icmph); + info, (u8 *)icmph); #endif } } @@ -572,18 +571,13 @@ out: } EXPORT_SYMBOL_GPL(ping_err); -void ping_v4_err(struct sk_buff *skb, u32 info) -{ - ping_err(skb, 0, info); -} - /* * Copy and checksum an ICMP Echo packet from user space into a buffer * starting from the payload. */ int ping_getfrag(void *from, char *to, - int offset, int fraglen, int odd, struct sk_buff *skb) + int offset, int fraglen, int odd, struct sk_buff *skb) { struct pingfakehdr *pfh = (struct pingfakehdr *)from; @@ -853,7 +847,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (flags & MSG_ERRQUEUE) { if (family == AF_INET) { - return ip_recv_error(sk, msg, len, addr_len); + return ip_recv_error(sk, msg, len); #if IS_ENABLED(CONFIG_IPV6) } else if (family == AF_INET6) { return pingv6_ops.ipv6_recv_error(sk, msg, len); @@ -881,16 +875,11 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* Copy the address and add cmsg data. */ if (family == AF_INET) { sin = (struct sockaddr_in *) msg->msg_name; - - /* Copy the address. */ - if (msg->msg_name) { - struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; - + if (sin) { sin->sin_family = AF_INET; sin->sin_port = 0 /* skb->h.uh->source */; sin->sin_addr.s_addr = ip_hdr(skb)->saddr; memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - *addr_len = sizeof(*sin); } if (isk->cmsg_flags) @@ -901,17 +890,18 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6hdr *ip6 = ipv6_hdr(skb); sin6 = (struct sockaddr_in6 *) msg->msg_name; - sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; - sin6->sin6_addr = ip6->saddr; - sin6->sin6_flowinfo = 0; - if (np->sndflow) - sin6->sin6_flowinfo = - *(__be32 *)ip6 & IPV6_FLOWINFO_MASK; - - sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr, - IP6CB(skb)->iif); + if (sin6) { + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_addr = ip6->saddr; + sin6->sin6_flowinfo = 0; + if (np->sndflow) + sin6->sin6_flowinfo = ip6_flowinfo(ip6); + sin6->sin6_scope_id = + ipv6_iface_scope_id(&sin6->sin6_addr, + IP6CB(skb)->iif); + } if (inet6_sk(sk)->rxopt.all) pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 402870fdfa0e..448e5a77fa88 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -693,7 +693,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto out; if (flags & MSG_ERRQUEUE) { - err = ip_recv_error(sk, msg, len, addr_len); + err = ip_recv_error(sk, msg, len); goto out; } diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 90b26beb84d4..4fca1aa4c505 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -138,6 +138,21 @@ static int ipv4_ping_group_range(ctl_table *table, int write, return ret; } +/* Validate changes from /proc interface. */ +static int proc_tcp_default_init_rwnd(ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + int old_value = *(int *)ctl->data; + int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + int new_value = *(int *)ctl->data; + + if (write && ret == 0 && (new_value < 3 || new_value > 100)) + *(int *)ctl->data = old_value; + + return ret; +} + static int proc_tcp_congestion_control(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -737,7 +752,7 @@ static struct ctl_table ipv4_table[] = { .mode = 0644, .proc_handler = proc_dointvec }, - { + { .procname = "tcp_thin_dupack", .data = &sysctl_tcp_thin_dupack, .maxlen = sizeof(int), @@ -763,6 +778,13 @@ static struct ctl_table ipv4_table[] = { .extra2 = &gso_max_segs, }, { + .procname = "tcp_default_init_rwnd", + .data = &sysctl_tcp_default_init_rwnd, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_tcp_default_init_rwnd + }, + { .procname = "udp_mem", .data = &sysctl_udp_mem, .maxlen = sizeof(sysctl_udp_mem), diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e15d330919af..aa5f3bfebabd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -98,6 +98,7 @@ int sysctl_tcp_thin_dupack __read_mostly; int sysctl_tcp_moderate_rcvbuf __read_mostly = 1; int sysctl_tcp_early_retrans __read_mostly = 3; +int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND; #define FLAG_DATA 0x01 /* Incoming frame contained data. */ #define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ @@ -351,14 +352,14 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) static void tcp_fixup_rcvbuf(struct sock *sk) { u32 mss = tcp_sk(sk)->advmss; - u32 icwnd = TCP_DEFAULT_INIT_RCVWND; + u32 icwnd = sysctl_tcp_default_init_rwnd; int rcvmem; /* Limit to 10 segments if mss <= 1460, * or 14600/mss segments, with a minimum of two segments. */ if (mss > 1460) - icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2); + icwnd = max_t(u32, (1460 * icwnd) / mss, 2); rcvmem = SKB_TRUESIZE(mss + MAX_TCP_HEADER); while (tcp_win_from_space(rcvmem) < mss) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5560abfe6d30..3b113f84a277 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -231,14 +231,13 @@ void tcp_select_initial_window(int __space, __u32 mss, } /* Set initial window to a value enough for senders starting with - * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place + * initial congestion window of sysctl_tcp_default_init_rwnd. Place * a limit on the initial window when mss is larger than 1460. */ if (mss > (1 << *rcv_wscale)) { - int init_cwnd = TCP_DEFAULT_INIT_RCVWND; + int init_cwnd = sysctl_tcp_default_init_rwnd; if (mss > 1460) - init_cwnd = - max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2); + init_cwnd = max_t(u32, (1460 * init_cwnd) / mss, 2); /* when initializing use the value from init_rcv_wnd * rather than the default from above */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5ed9a7a09f04..fe1a3404314d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1216,7 +1216,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, bool slow; if (flags & MSG_ERRQUEUE) - return ip_recv_error(sk, msg, len, addr_len); + return ip_recv_error(sk, msg, len); try_again: skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 50308a8070f8..6128f302f593 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -85,12 +85,18 @@ static inline struct sock *icmpv6_sk(struct net *net) static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { + /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */ + struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset); struct net *net = dev_net(skb->dev); if (type == ICMPV6_PKT_TOOBIG) ip6_update_pmtu(skb, net, info, 0, 0); else if (type == NDISC_REDIRECT) ip6_redirect(skb, net, 0, 0); + + if (!(type & ICMPV6_INFOMSG_MASK)) + if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST) + ping_err(skb, offset, info); } static int icmpv6_rcv(struct sk_buff *skb); @@ -699,7 +705,8 @@ static int icmpv6_rcv(struct sk_buff *skb) skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 0)); if (__skb_checksum_complete(skb)) { - LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", + LIMIT_NETDEBUG(KERN_DEBUG + "ICMPv6 checksum failed [%pI6c > %pI6c]\n", saddr, daddr); goto csum_error; } diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index f4ba86348660..df91e26f55f2 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -68,15 +68,15 @@ static DEFINE_MUTEX(list_mutex); static struct kobject *idletimer_tg_kobj; -static void notify_netlink_uevent(const char *label, struct idletimer_tg *timer) +static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer) { - char label_msg[NLMSG_MAX_SIZE]; + char iface_msg[NLMSG_MAX_SIZE]; char state_msg[NLMSG_MAX_SIZE]; - char *envp[] = { label_msg, state_msg, NULL }; + char *envp[] = { iface_msg, state_msg, NULL }; int res; - res = snprintf(label_msg, NLMSG_MAX_SIZE, "LABEL=%s", - label); + res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s", + iface); if (NLMSG_MAX_SIZE <= res) { pr_err("message too long (%d)", res); return; @@ -87,7 +87,7 @@ static void notify_netlink_uevent(const char *label, struct idletimer_tg *timer) pr_err("message too long (%d)", res); return; } - pr_debug("putting nlmsg: <%s> <%s>\n", label_msg, state_msg); + pr_debug("putting nlmsg: <%s> <%s>\n", iface_msg, state_msg); kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp); return; |