aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-10-04 14:56:38 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-04 14:56:38 -0400
commit21a180cda012e1f93e362dd4a9b0bfd3d8c92940 (patch)
tree0e0d10baa3fdcd8ffbc6881076ff1695808dad9d /net
parentc7d4426a98a5f6654cd0b4b33d9dab2e77192c18 (diff)
parent51e97a12bef19b7e43199fc153cf9bd5f2140362 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: net/ipv4/Kconfig net/ipv4/tcp_timer.c
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan_core.c14
-rw-r--r--net/9p/trans_virtio.c3
-rw-r--r--net/core/iovec.c5
-rw-r--r--net/core/stream.c8
-rw-r--r--net/ipv4/Kconfig4
-rw-r--r--net/ipv4/igmp.c14
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_timer.c25
-rw-r--r--net/ipv6/route.c30
-rw-r--r--net/phonet/pep.c3
-rw-r--r--net/sctp/auth.c8
-rw-r--r--net/sctp/socket.c13
14 files changed, 97 insertions, 37 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 0eb486d342dc..b6d55a9304f2 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -24,8 +24,11 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
24 24
25 if (vlan_dev) 25 if (vlan_dev)
26 skb->dev = vlan_dev; 26 skb->dev = vlan_dev;
27 else if (vlan_id) 27 else if (vlan_id) {
28 goto drop; 28 if (!(skb->dev->flags & IFF_PROMISC))
29 goto drop;
30 skb->pkt_type = PACKET_OTHERHOST;
31 }
29 32
30 return polling ? netif_receive_skb(skb) : netif_rx(skb); 33 return polling ? netif_receive_skb(skb) : netif_rx(skb);
31 34
@@ -101,8 +104,11 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
101 104
102 if (vlan_dev) 105 if (vlan_dev)
103 skb->dev = vlan_dev; 106 skb->dev = vlan_dev;
104 else if (vlan_id) 107 else if (vlan_id) {
105 goto drop; 108 if (!(skb->dev->flags & IFF_PROMISC))
109 goto drop;
110 skb->pkt_type = PACKET_OTHERHOST;
111 }
106 112
107 for (p = napi->gro_list; p; p = p->next) { 113 for (p = napi->gro_list; p; p = p->next) {
108 unsigned long diffs; 114 unsigned long diffs;
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index dcfbe99ff81c..b88515936e4b 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -329,7 +329,8 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
329 329
330 mutex_lock(&virtio_9p_lock); 330 mutex_lock(&virtio_9p_lock);
331 list_for_each_entry(chan, &virtio_chan_list, chan_list) { 331 list_for_each_entry(chan, &virtio_chan_list, chan_list) {
332 if (!strncmp(devname, chan->tag, chan->tag_len)) { 332 if (!strncmp(devname, chan->tag, chan->tag_len) &&
333 strlen(devname) == chan->tag_len) {
333 if (!chan->inuse) { 334 if (!chan->inuse) {
334 chan->inuse = true; 335 chan->inuse = true;
335 found = 1; 336 found = 1;
diff --git a/net/core/iovec.c b/net/core/iovec.c
index f4657c2127b4..72aceb1fe4fa 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -35,9 +35,10 @@
35 * in any case. 35 * in any case.
36 */ 36 */
37 37
38int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode) 38long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode)
39{ 39{
40 int size, err, ct; 40 int size, ct;
41 long err;
41 42
42 if (m->msg_namelen) { 43 if (m->msg_namelen) {
43 if (mode == VERIFY_READ) { 44 if (mode == VERIFY_READ) {
diff --git a/net/core/stream.c b/net/core/stream.c
index d959e0f41528..f5df85dcd20b 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
141 141
142 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 142 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
143 sk->sk_write_pending++; 143 sk->sk_write_pending++;
144 sk_wait_event(sk, &current_timeo, !sk->sk_err && 144 sk_wait_event(sk, &current_timeo, sk->sk_err ||
145 !(sk->sk_shutdown & SEND_SHUTDOWN) && 145 (sk->sk_shutdown & SEND_SHUTDOWN) ||
146 sk_stream_memory_free(sk) && 146 (sk_stream_memory_free(sk) &&
147 vm_wait); 147 !vm_wait));
148 sk->sk_write_pending--; 148 sk->sk_write_pending--;
149 149
150 if (vm_wait) { 150 if (vm_wait) {
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 5462e2d147a6..e848e6c062cd 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -223,7 +223,7 @@ config NET_IPGRE_DEMUX
223 223
224config NET_IPGRE 224config NET_IPGRE
225 tristate "IP: GRE tunnels over IP" 225 tristate "IP: GRE tunnels over IP"
226 depends on NET_IPGRE_DEMUX 226 depends on (IPV6 || IPV6=n) && NET_IPGRE_DEMUX
227 help 227 help
228 Tunneling means encapsulating data of one protocol type within 228 Tunneling means encapsulating data of one protocol type within
229 another protocol and sending it over a channel that understands the 229 another protocol and sending it over a channel that understands the
@@ -419,7 +419,7 @@ config INET_XFRM_MODE_BEET
419 If unsure, say Y. 419 If unsure, say Y.
420 420
421config INET_LRO 421config INET_LRO
422 bool "Large Receive Offload (ipv4/tcp)" 422 tristate "Large Receive Offload (ipv4/tcp)"
423 default y 423 default y
424 ---help--- 424 ---help---
425 Support for Large Receive Offload (ipv4/tcp). 425 Support for Large Receive Offload (ipv4/tcp).
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 1fdcacd36ce7..2a4bb76f2132 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -834,7 +834,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
834 int mark = 0; 834 int mark = 0;
835 835
836 836
837 if (len == 8 || IGMP_V2_SEEN(in_dev)) { 837 if (len == 8) {
838 if (ih->code == 0) { 838 if (ih->code == 0) {
839 /* Alas, old v1 router presents here. */ 839 /* Alas, old v1 router presents here. */
840 840
@@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
856 igmpv3_clear_delrec(in_dev); 856 igmpv3_clear_delrec(in_dev);
857 } else if (len < 12) { 857 } else if (len < 12) {
858 return; /* ignore bogus packet; freed by caller */ 858 return; /* ignore bogus packet; freed by caller */
859 } else if (IGMP_V1_SEEN(in_dev)) {
860 /* This is a v3 query with v1 queriers present */
861 max_delay = IGMP_Query_Response_Interval;
862 group = 0;
863 } else if (IGMP_V2_SEEN(in_dev)) {
864 /* this is a v3 query with v2 queriers present;
865 * Interpretation of the max_delay code is problematic here.
866 * A real v2 host would use ih_code directly, while v3 has a
867 * different encoding. We use the v3 encoding as more likely
868 * to be intended in a v3 query.
869 */
870 max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
859 } else { /* v3 */ 871 } else { /* v3 */
860 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) 872 if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
861 return; 873 return;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index c3cb8bd23638..04e0df82b88c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1232,7 +1232,7 @@ restart:
1232 } 1232 }
1233 1233
1234 if (net_ratelimit()) 1234 if (net_ratelimit())
1235 printk(KERN_WARNING "Neighbour table overflow.\n"); 1235 printk(KERN_WARNING "ipv4: Neighbour table overflow.\n");
1236 rt_drop(rt); 1236 rt_drop(rt);
1237 return -ENOBUFS; 1237 return -ENOBUFS;
1238 } 1238 }
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 19192c5fe67a..1664a0590bb8 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -943,7 +943,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
943 sg = sk->sk_route_caps & NETIF_F_SG; 943 sg = sk->sk_route_caps & NETIF_F_SG;
944 944
945 while (--iovlen >= 0) { 945 while (--iovlen >= 0) {
946 int seglen = iov->iov_len; 946 size_t seglen = iov->iov_len;
947 unsigned char __user *from = iov->iov_base; 947 unsigned char __user *from = iov->iov_base;
948 948
949 iov++; 949 iov++;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index eaf20e7e61da..f6fdd727a23d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2532,7 +2532,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2532 cnt += tcp_skb_pcount(skb); 2532 cnt += tcp_skb_pcount(skb);
2533 2533
2534 if (cnt > packets) { 2534 if (cnt > packets) {
2535 if (tcp_is_sack(tp) || (oldcnt >= packets)) 2535 if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) ||
2536 (oldcnt >= packets))
2536 break; 2537 break;
2537 2538
2538 mss = skb_shinfo(skb)->gso_size; 2539 mss = skb_shinfo(skb)->gso_size;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index baea4a129022..f3c8c6c019ae 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -135,13 +135,16 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
135 135
136/* This function calculates a "timeout" which is equivalent to the timeout of a 136/* This function calculates a "timeout" which is equivalent to the timeout of a
137 * TCP connection after "boundary" unsuccessful, exponentially backed-off 137 * TCP connection after "boundary" unsuccessful, exponentially backed-off
138 * retransmissions with an initial RTO of TCP_RTO_MIN. 138 * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if
139 * syn_set flag is set.
139 */ 140 */
140static bool retransmits_timed_out(struct sock *sk, 141static bool retransmits_timed_out(struct sock *sk,
141 unsigned int boundary, 142 unsigned int boundary,
142 unsigned int timeout) 143 unsigned int timeout,
144 bool syn_set)
143{ 145{
144 unsigned int linear_backoff_thresh, start_ts; 146 unsigned int linear_backoff_thresh, start_ts;
147 unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN;
145 148
146 if (!inet_csk(sk)->icsk_retransmits) 149 if (!inet_csk(sk)->icsk_retransmits)
147 return false; 150 return false;
@@ -152,12 +155,12 @@ static bool retransmits_timed_out(struct sock *sk,
152 start_ts = tcp_sk(sk)->retrans_stamp; 155 start_ts = tcp_sk(sk)->retrans_stamp;
153 156
154 if (likely(timeout == 0)) { 157 if (likely(timeout == 0)) {
155 linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); 158 linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base);
156 159
157 if (boundary <= linear_backoff_thresh) 160 if (boundary <= linear_backoff_thresh)
158 timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; 161 timeout = ((2 << boundary) - 1) * rto_base;
159 else 162 else
160 timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + 163 timeout = ((2 << linear_backoff_thresh) - 1) * rto_base +
161 (boundary - linear_backoff_thresh) * TCP_RTO_MAX; 164 (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
162 } 165 }
163 return (tcp_time_stamp - start_ts) >= timeout; 166 return (tcp_time_stamp - start_ts) >= timeout;
@@ -168,14 +171,15 @@ static int tcp_write_timeout(struct sock *sk)
168{ 171{
169 struct inet_connection_sock *icsk = inet_csk(sk); 172 struct inet_connection_sock *icsk = inet_csk(sk);
170 int retry_until; 173 int retry_until;
171 bool do_reset; 174 bool do_reset, syn_set = 0;
172 175
173 if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { 176 if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
174 if (icsk->icsk_retransmits) 177 if (icsk->icsk_retransmits)
175 dst_negative_advice(sk); 178 dst_negative_advice(sk);
176 retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; 179 retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
180 syn_set = 1;
177 } else { 181 } else {
178 if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { 182 if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
179 /* Black hole detection */ 183 /* Black hole detection */
180 tcp_mtu_probing(icsk, sk); 184 tcp_mtu_probing(icsk, sk);
181 185
@@ -188,7 +192,7 @@ static int tcp_write_timeout(struct sock *sk)
188 192
189 retry_until = tcp_orphan_retries(sk, alive); 193 retry_until = tcp_orphan_retries(sk, alive);
190 do_reset = alive || 194 do_reset = alive ||
191 !retransmits_timed_out(sk, retry_until, 0); 195 !retransmits_timed_out(sk, retry_until, 0, 0);
192 196
193 if (tcp_out_of_resources(sk, do_reset)) 197 if (tcp_out_of_resources(sk, do_reset))
194 return 1; 198 return 1;
@@ -196,8 +200,7 @@ static int tcp_write_timeout(struct sock *sk)
196 } 200 }
197 201
198 if (retransmits_timed_out(sk, retry_until, 202 if (retransmits_timed_out(sk, retry_until,
199 (1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) ? 0 : 203 syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) {
200 icsk->icsk_user_timeout)) {
201 /* Has it gone just too far? */ 204 /* Has it gone just too far? */
202 tcp_write_err(sk); 205 tcp_write_err(sk);
203 return 1; 206 return 1;
@@ -439,7 +442,7 @@ out_reset_timer:
439 icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); 442 icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
440 } 443 }
441 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); 444 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
442 if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) 445 if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0))
443 __sk_dst_reset(sk); 446 __sk_dst_reset(sk);
444 447
445out:; 448out:;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 25476e7e708b..17e217933885 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
670 670
671 if (net_ratelimit()) 671 if (net_ratelimit())
672 printk(KERN_WARNING 672 printk(KERN_WARNING
673 "Neighbour table overflow.\n"); 673 "ipv6: Neighbour table overflow.\n");
674 dst_free(&rt->dst); 674 dst_free(&rt->dst);
675 return NULL; 675 return NULL;
676 } 676 }
@@ -1559,14 +1559,13 @@ out:
1559 * i.e. Path MTU discovery 1559 * i.e. Path MTU discovery
1560 */ 1560 */
1561 1561
1562void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, 1562static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
1563 struct net_device *dev, u32 pmtu) 1563 struct net *net, u32 pmtu, int ifindex)
1564{ 1564{
1565 struct rt6_info *rt, *nrt; 1565 struct rt6_info *rt, *nrt;
1566 struct net *net = dev_net(dev);
1567 int allfrag = 0; 1566 int allfrag = 0;
1568 1567
1569 rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); 1568 rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
1570 if (rt == NULL) 1569 if (rt == NULL)
1571 return; 1570 return;
1572 1571
@@ -1634,6 +1633,27 @@ out:
1634 dst_release(&rt->dst); 1633 dst_release(&rt->dst);
1635} 1634}
1636 1635
1636void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1637 struct net_device *dev, u32 pmtu)
1638{
1639 struct net *net = dev_net(dev);
1640
1641 /*
1642 * RFC 1981 states that a node "MUST reduce the size of the packets it
1643 * is sending along the path" that caused the Packet Too Big message.
1644 * Since it's not possible in the general case to determine which
1645 * interface was used to send the original packet, we update the MTU
1646 * on the interface that will be used to send future packets. We also
1647 * update the MTU on the interface that received the Packet Too Big in
1648 * case the original packet was forced out that interface with
1649 * SO_BINDTODEVICE or similar. This is the next best thing to the
1650 * correct behaviour, which would be to update the MTU on all
1651 * interfaces.
1652 */
1653 rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
1654 rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
1655}
1656
1637/* 1657/*
1638 * Misc support functions 1658 * Misc support functions
1639 */ 1659 */
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 552fb665645f..aa3d8700d213 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -507,12 +507,13 @@ static void pipe_grant_credits(struct sock *sk)
507static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) 507static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
508{ 508{
509 struct pep_sock *pn = pep_sk(sk); 509 struct pep_sock *pn = pep_sk(sk);
510 struct pnpipehdr *hdr = pnp_hdr(skb); 510 struct pnpipehdr *hdr;
511 int wake = 0; 511 int wake = 0;
512 512
513 if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) 513 if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
514 return -EINVAL; 514 return -EINVAL;
515 515
516 hdr = pnp_hdr(skb);
516 if (hdr->data[0] != PN_PEP_TYPE_COMMON) { 517 if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
517 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", 518 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
518 (unsigned)hdr->data[0]); 519 (unsigned)hdr->data[0]);
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 86366390038a..ddbbf7c81fa1 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
543 id = ntohs(hmacs->hmac_ids[i]); 543 id = ntohs(hmacs->hmac_ids[i]);
544 544
545 /* Check the id is in the supported range */ 545 /* Check the id is in the supported range */
546 if (id > SCTP_AUTH_HMAC_ID_MAX) 546 if (id > SCTP_AUTH_HMAC_ID_MAX) {
547 id = 0;
547 continue; 548 continue;
549 }
548 550
549 /* See is we support the id. Supported IDs have name and 551 /* See is we support the id. Supported IDs have name and
550 * length fields set, so that we can allocated and use 552 * length fields set, so that we can allocated and use
551 * them. We can safely just check for name, for without the 553 * them. We can safely just check for name, for without the
552 * name, we can't allocate the TFM. 554 * name, we can't allocate the TFM.
553 */ 555 */
554 if (!sctp_hmac_list[id].hmac_name) 556 if (!sctp_hmac_list[id].hmac_name) {
557 id = 0;
555 continue; 558 continue;
559 }
556 560
557 break; 561 break;
558 } 562 }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d4bf2a78cb8a..e34ca9cc1167 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -918,6 +918,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
918 /* Walk through the addrs buffer and count the number of addresses. */ 918 /* Walk through the addrs buffer and count the number of addresses. */
919 addr_buf = kaddrs; 919 addr_buf = kaddrs;
920 while (walk_size < addrs_size) { 920 while (walk_size < addrs_size) {
921 if (walk_size + sizeof(sa_family_t) > addrs_size) {
922 kfree(kaddrs);
923 return -EINVAL;
924 }
925
921 sa_addr = (struct sockaddr *)addr_buf; 926 sa_addr = (struct sockaddr *)addr_buf;
922 af = sctp_get_af_specific(sa_addr->sa_family); 927 af = sctp_get_af_specific(sa_addr->sa_family);
923 928
@@ -1004,9 +1009,13 @@ static int __sctp_connect(struct sock* sk,
1004 /* Walk through the addrs buffer and count the number of addresses. */ 1009 /* Walk through the addrs buffer and count the number of addresses. */
1005 addr_buf = kaddrs; 1010 addr_buf = kaddrs;
1006 while (walk_size < addrs_size) { 1011 while (walk_size < addrs_size) {
1012 if (walk_size + sizeof(sa_family_t) > addrs_size) {
1013 err = -EINVAL;
1014 goto out_free;
1015 }
1016
1007 sa_addr = (union sctp_addr *)addr_buf; 1017 sa_addr = (union sctp_addr *)addr_buf;
1008 af = sctp_get_af_specific(sa_addr->sa.sa_family); 1018 af = sctp_get_af_specific(sa_addr->sa.sa_family);
1009 port = ntohs(sa_addr->v4.sin_port);
1010 1019
1011 /* If the address family is not supported or if this address 1020 /* If the address family is not supported or if this address
1012 * causes the address buffer to overflow return EINVAL. 1021 * causes the address buffer to overflow return EINVAL.
@@ -1016,6 +1025,8 @@ static int __sctp_connect(struct sock* sk,
1016 goto out_free; 1025 goto out_free;
1017 } 1026 }
1018 1027
1028 port = ntohs(sa_addr->v4.sin_port);
1029
1019 /* Save current address so we can work with it */ 1030 /* Save current address so we can work with it */
1020 memcpy(&to, sa_addr, af->sockaddr_len); 1031 memcpy(&to, sa_addr, af->sockaddr_len);
1021 1032