aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-14 10:56:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-14 10:56:24 -0400
commit533bb8a4d7388686243c37a414c4448ba3566f8a (patch)
tree506ef946871e4499862ecc8513f49b69389ae865 /net
parent4f3f8e94b7b079131f0faf641e8afd790a6537d1 (diff)
parent159d83363b629c91d020734207c1bc788b96af5a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (31 commits) [BRIDGE]: Fix crash in __ip_route_output_key with bridge netfilter [NETFILTER]: ipt_CLUSTERIP: fix race between clusterip_config_find_get and _entry_put [IPV6] ADDRCONF: Don't generate temporary address for ip6-ip6 interface. [IPV6] ADDRCONF: Ensure disabling multicast RS even if privacy extensions are disabled. [IPV6]: Use appropriate sock tclass setting for routing lookup. [IPV6]: IPv6 extension header structures need to be packed. [IPV6]: Fix ipv6 address fetching in raw6_icmp_error(). [NET]: Return more appropriate error from eth_validate_addr(). [ISDN]: Do not validate ISDN net device address prior to interface-up [NET]: Fix kernel-doc for skb_segment [SOCK] sk_stamp: should be initialized to ktime_set(-1L, 0) net: check for underlength tap writes net: make struct tun_struct private to tun.c [SCTP]: IPv4 vs IPv6 addresses mess in sctp_inet[6]addr_event. [SCTP]: Fix compiler warning about const qualifiers [SCTP]: Fix protocol violation when receiving an error lenght INIT-ACK [SCTP]: Add check for hmac_algo parameter in sctp_verify_param() [NET_SCHED] cls_u32: refcounting fix for u32_delete() [DCCP]: Fix skb->cb conflicts with IP [AX25]: Potential ax25_uid_assoc-s leaks on module unload. ...
Diffstat (limited to 'net')
-rw-r--r--net/ax25/ax25_uid.c2
-rw-r--r--net/bridge/br_netfilter.c3
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/core/sock.c2
-rw-r--r--net/dccp/dccp.h6
-rw-r--r--net/dccp/ipv4.c1
-rw-r--r--net/dccp/output.c1
-rw-r--r--net/dccp/proto.c3
-rw-r--r--net/ethernet/eth.c2
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c4
-rw-r--r--net/ipv6/addrconf.c19
-rw-r--r--net/ipv6/raw.c6
-rw-r--r--net/sched/cls_u32.c12
-rw-r--r--net/sctp/ipv6.c5
-rw-r--r--net/sctp/outqueue.c3
-rw-r--r--net/sctp/protocol.c4
-rw-r--r--net/sctp/sm_make_chunk.c29
-rw-r--r--net/sctp/sm_sideeffect.c3
-rw-r--r--net/sctp/sm_statefuns.c23
-rw-r--r--net/sctp/socket.c5
-rw-r--r--net/sctp/ulpevent.c2
21 files changed, 106 insertions, 33 deletions
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 5f4eb73fb9d3..57aeba729bae 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -218,9 +218,11 @@ void __exit ax25_uid_free(void)
218 struct hlist_node *node; 218 struct hlist_node *node;
219 219
220 write_lock(&ax25_uid_lock); 220 write_lock(&ax25_uid_lock);
221again:
221 ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { 222 ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
222 hlist_del_init(&ax25_uid->uid_node); 223 hlist_del_init(&ax25_uid->uid_node);
223 ax25_uid_put(ax25_uid); 224 ax25_uid_put(ax25_uid);
225 goto again;
224 } 226 }
225 write_unlock(&ax25_uid_lock); 227 write_unlock(&ax25_uid_lock);
226} 228}
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 1c0efd8ad9f3..af7e8be8d8d2 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -110,7 +110,8 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
110 * ipt_REJECT needs it. Future netfilter modules might 110 * ipt_REJECT needs it. Future netfilter modules might
111 * require us to fill additional fields. */ 111 * require us to fill additional fields. */
112static struct net_device __fake_net_device = { 112static struct net_device __fake_net_device = {
113 .hard_header_len = ETH_HLEN 113 .hard_header_len = ETH_HLEN,
114 .nd_net = &init_net,
114}; 115};
115 116
116static struct rtable __fake_rtable = { 117static struct rtable __fake_rtable = {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 0d0fd28a9041..608701339620 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2131,8 +2131,8 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);
2131 * @features: features for the output path (see dev->features) 2131 * @features: features for the output path (see dev->features)
2132 * 2132 *
2133 * This function performs segmentation on the given skb. It returns 2133 * This function performs segmentation on the given skb. It returns
2134 * the segment at the given position. It returns NULL if there are 2134 * a pointer to the first in a list of new skbs for the segments.
2135 * no more segments to generate, or when an error is encountered. 2135 * In case of error it returns ERR_PTR(err).
2136 */ 2136 */
2137struct sk_buff *skb_segment(struct sk_buff *skb, int features) 2137struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2138{ 2138{
diff --git a/net/core/sock.c b/net/core/sock.c
index 2654c147c004..7a0567b4b2c9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1725,7 +1725,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
1725 sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; 1725 sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
1726 sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; 1726 sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
1727 1727
1728 sk->sk_stamp = ktime_set(-1L, -1L); 1728 sk->sk_stamp = ktime_set(-1L, 0);
1729 1729
1730 atomic_set(&sk->sk_refcnt, 1); 1730 atomic_set(&sk->sk_refcnt, 1);
1731 atomic_set(&sk->sk_drops, 0); 1731 atomic_set(&sk->sk_drops, 0);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 287a62bc2e0f..ba2ef94a2302 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,
325 * This is used for transmission as well as for reception. 325 * This is used for transmission as well as for reception.
326 */ 326 */
327struct dccp_skb_cb { 327struct dccp_skb_cb {
328 union {
329 struct inet_skb_parm h4;
330#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
331 struct inet6_skb_parm h6;
332#endif
333 } header;
328 __u8 dccpd_type:4; 334 __u8 dccpd_type:4;
329 __u8 dccpd_ccval:4; 335 __u8 dccpd_ccval:4;
330 __u8 dccpd_reset_code, 336 __u8 dccpd_reset_code,
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 474075adbde4..b33704415555 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
489 489
490 dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr, 490 dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr,
491 ireq->rmt_addr); 491 ireq->rmt_addr);
492 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
493 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, 492 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
494 ireq->rmt_addr, 493 ireq->rmt_addr,
495 ireq->opt); 494 ireq->opt);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 3b763db3d863..3d7d628d870d 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
126 126
127 DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 127 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
128 128
129 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
130 err = icsk->icsk_af_ops->queue_xmit(skb, 0); 129 err = icsk->icsk_af_ops->queue_xmit(skb, 0);
131 return net_xmit_eval(err); 130 return net_xmit_eval(err);
132 } 131 }
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index e3f5d37b84be..c91d3c1fd30d 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)
1057 int ehash_order, bhash_order, i; 1057 int ehash_order, bhash_order, i;
1058 int rc = -ENOBUFS; 1058 int rc = -ENOBUFS;
1059 1059
1060 BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
1061 FIELD_SIZEOF(struct sk_buff, cb));
1062
1060 dccp_hashinfo.bind_bucket_cachep = 1063 dccp_hashinfo.bind_bucket_cachep =
1061 kmem_cache_create("dccp_bind_bucket", 1064 kmem_cache_create("dccp_bind_bucket",
1062 sizeof(struct inet_bind_bucket), 0, 1065 sizeof(struct inet_bind_bucket), 0,
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a7b417523e9b..a80839b02e3f 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -301,7 +301,7 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu)
301static int eth_validate_addr(struct net_device *dev) 301static int eth_validate_addr(struct net_device *dev)
302{ 302{
303 if (!is_valid_ether_addr(dev->dev_addr)) 303 if (!is_valid_ether_addr(dev->dev_addr))
304 return -EINVAL; 304 return -EADDRNOTAVAIL;
305 305
306 return 0; 306 return 0;
307} 307}
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 52926c8e3cc1..a12dd329e208 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -82,8 +82,8 @@ clusterip_config_put(struct clusterip_config *c)
82static inline void 82static inline void
83clusterip_config_entry_put(struct clusterip_config *c) 83clusterip_config_entry_put(struct clusterip_config *c)
84{ 84{
85 write_lock_bh(&clusterip_lock);
85 if (atomic_dec_and_test(&c->entries)) { 86 if (atomic_dec_and_test(&c->entries)) {
86 write_lock_bh(&clusterip_lock);
87 list_del(&c->list); 87 list_del(&c->list);
88 write_unlock_bh(&clusterip_lock); 88 write_unlock_bh(&clusterip_lock);
89 89
@@ -96,7 +96,9 @@ clusterip_config_entry_put(struct clusterip_config *c)
96#ifdef CONFIG_PROC_FS 96#ifdef CONFIG_PROC_FS
97 remove_proc_entry(c->pde->name, c->pde->parent); 97 remove_proc_entry(c->pde->name, c->pde->parent);
98#endif 98#endif
99 return;
99 } 100 }
101 write_unlock_bh(&clusterip_lock);
100} 102}
101 103
102static struct clusterip_config * 104static struct clusterip_config *
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a65935a9afd9..e08955baedff 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -371,25 +371,26 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
371 */ 371 */
372 in6_dev_hold(ndev); 372 in6_dev_hold(ndev);
373 373
374#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
375 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
376 printk(KERN_INFO
377 "%s: Disabled Multicast RS\n",
378 dev->name);
379 ndev->cnf.rtr_solicits = 0;
380 }
381#endif
382
374#ifdef CONFIG_IPV6_PRIVACY 383#ifdef CONFIG_IPV6_PRIVACY
375 setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); 384 setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
376 if ((dev->flags&IFF_LOOPBACK) || 385 if ((dev->flags&IFF_LOOPBACK) ||
377 dev->type == ARPHRD_TUNNEL || 386 dev->type == ARPHRD_TUNNEL ||
378#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 387 dev->type == ARPHRD_TUNNEL6 ||
379 dev->type == ARPHRD_SIT || 388 dev->type == ARPHRD_SIT ||
380#endif
381 dev->type == ARPHRD_NONE) { 389 dev->type == ARPHRD_NONE) {
382 printk(KERN_INFO 390 printk(KERN_INFO
383 "%s: Disabled Privacy Extensions\n", 391 "%s: Disabled Privacy Extensions\n",
384 dev->name); 392 dev->name);
385 ndev->cnf.use_tempaddr = -1; 393 ndev->cnf.use_tempaddr = -1;
386
387 if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
388 printk(KERN_INFO
389 "%s: Disabled Multicast RS\n",
390 dev->name);
391 ndev->cnf.rtr_solicits = 0;
392 }
393 } else { 394 } else {
394 in6_dev_hold(ndev); 395 in6_dev_hold(ndev);
395 ipv6_regen_rndid((unsigned long) ndev); 396 ipv6_regen_rndid((unsigned long) ndev);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 8897ccf8086a..0a6fbc1d1a50 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -372,8 +372,10 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
372 read_lock(&raw_v6_hashinfo.lock); 372 read_lock(&raw_v6_hashinfo.lock);
373 sk = sk_head(&raw_v6_hashinfo.ht[hash]); 373 sk = sk_head(&raw_v6_hashinfo.ht[hash]);
374 if (sk != NULL) { 374 if (sk != NULL) {
375 saddr = &ipv6_hdr(skb)->saddr; 375 struct ipv6hdr *hdr = (struct ipv6hdr *) skb->data;
376 daddr = &ipv6_hdr(skb)->daddr; 376
377 saddr = &hdr->saddr;
378 daddr = &hdr->daddr;
377 net = skb->dev->nd_net; 379 net = skb->dev->nd_net;
378 380
379 while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, 381 while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index c5c16b4b6e98..4d755444c449 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -411,8 +411,10 @@ static void u32_destroy(struct tcf_proto *tp)
411 } 411 }
412 } 412 }
413 413
414 for (ht=tp_c->hlist; ht; ht = ht->next) 414 for (ht = tp_c->hlist; ht; ht = ht->next) {
415 ht->refcnt--;
415 u32_clear_hnode(tp, ht); 416 u32_clear_hnode(tp, ht);
417 }
416 418
417 while ((ht = tp_c->hlist) != NULL) { 419 while ((ht = tp_c->hlist) != NULL) {
418 tp_c->hlist = ht->next; 420 tp_c->hlist = ht->next;
@@ -441,8 +443,12 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)
441 if (tp->root == ht) 443 if (tp->root == ht)
442 return -EINVAL; 444 return -EINVAL;
443 445
444 if (--ht->refcnt == 0) 446 if (ht->refcnt == 1) {
447 ht->refcnt--;
445 u32_destroy_hnode(tp, ht); 448 u32_destroy_hnode(tp, ht);
449 } else {
450 return -EBUSY;
451 }
446 452
447 return 0; 453 return 0;
448} 454}
@@ -568,7 +574,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
568 if (ht == NULL) 574 if (ht == NULL)
569 return -ENOBUFS; 575 return -ENOBUFS;
570 ht->tp_c = tp_c; 576 ht->tp_c = tp_c;
571 ht->refcnt = 0; 577 ht->refcnt = 1;
572 ht->divisor = divisor; 578 ht->divisor = divisor;
573 ht->handle = handle; 579 ht->handle = handle;
574 ht->prio = tp->prio; 580 ht->prio = tp->prio;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index b1e05d719f9b..85f1495e0edc 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -110,8 +110,9 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
110 spin_lock_bh(&sctp_local_addr_lock); 110 spin_lock_bh(&sctp_local_addr_lock);
111 list_for_each_entry_safe(addr, temp, 111 list_for_each_entry_safe(addr, temp,
112 &sctp_local_addr_list, list) { 112 &sctp_local_addr_list, list) {
113 if (ipv6_addr_equal(&addr->a.v6.sin6_addr, 113 if (addr->a.sa.sa_family == AF_INET6 &&
114 &ifa->addr)) { 114 ipv6_addr_equal(&addr->a.v6.sin6_addr,
115 &ifa->addr)) {
115 found = 1; 116 found = 1;
116 addr->valid = 0; 117 addr->valid = 0;
117 list_del_rcu(&addr->list); 118 list_del_rcu(&addr->list);
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1bb3c5c35d2a..c0714469233c 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -793,6 +793,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
793 break; 793 break;
794 794
795 case SCTP_CID_ABORT: 795 case SCTP_CID_ABORT:
796 if (sctp_test_T_bit(chunk)) {
797 packet->vtag = asoc->c.my_vtag;
798 }
796 case SCTP_CID_SACK: 799 case SCTP_CID_SACK:
797 case SCTP_CID_HEARTBEAT: 800 case SCTP_CID_HEARTBEAT:
798 case SCTP_CID_HEARTBEAT_ACK: 801 case SCTP_CID_HEARTBEAT_ACK:
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f90091a1b9ce..c2dd65d9f38d 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -647,7 +647,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
647 spin_lock_bh(&sctp_local_addr_lock); 647 spin_lock_bh(&sctp_local_addr_lock);
648 list_for_each_entry_safe(addr, temp, 648 list_for_each_entry_safe(addr, temp,
649 &sctp_local_addr_list, list) { 649 &sctp_local_addr_list, list) {
650 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { 650 if (addr->a.sa.sa_family == AF_INET &&
651 addr->a.v4.sin_addr.s_addr ==
652 ifa->ifa_local) {
651 found = 1; 653 found = 1;
652 addr->valid = 0; 654 addr->valid = 0;
653 list_del_rcu(&addr->list); 655 list_del_rcu(&addr->list);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 578630e8e00d..36ebb392472e 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1982,7 +1982,10 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
1982 struct sctp_chunk *chunk, 1982 struct sctp_chunk *chunk,
1983 struct sctp_chunk **err_chunk) 1983 struct sctp_chunk **err_chunk)
1984{ 1984{
1985 struct sctp_hmac_algo_param *hmacs;
1985 int retval = SCTP_IERROR_NO_ERROR; 1986 int retval = SCTP_IERROR_NO_ERROR;
1987 __u16 n_elt, id = 0;
1988 int i;
1986 1989
1987 /* FIXME - This routine is not looking at each parameter per the 1990 /* FIXME - This routine is not looking at each parameter per the
1988 * chunk type, i.e., unrecognized parameters should be further 1991 * chunk type, i.e., unrecognized parameters should be further
@@ -2056,9 +2059,29 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
2056 break; 2059 break;
2057 2060
2058 case SCTP_PARAM_HMAC_ALGO: 2061 case SCTP_PARAM_HMAC_ALGO:
2059 if (sctp_auth_enable) 2062 if (!sctp_auth_enable)
2060 break; 2063 goto fallthrough;
2061 /* Fall Through */ 2064
2065 hmacs = (struct sctp_hmac_algo_param *)param.p;
2066 n_elt = (ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) >> 1;
2067
2068 /* SCTP-AUTH: Section 6.1
2069 * The HMAC algorithm based on SHA-1 MUST be supported and
2070 * included in the HMAC-ALGO parameter.
2071 */
2072 for (i = 0; i < n_elt; i++) {
2073 id = ntohs(hmacs->hmac_ids[i]);
2074
2075 if (id == SCTP_AUTH_HMAC_ID_SHA1)
2076 break;
2077 }
2078
2079 if (id != SCTP_AUTH_HMAC_ID_SHA1) {
2080 sctp_process_inv_paramlength(asoc, param.p, chunk,
2081 err_chunk);
2082 retval = SCTP_IERROR_ABORT;
2083 }
2084 break;
2062fallthrough: 2085fallthrough:
2063 default: 2086 default:
2064 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n", 2087 SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 28eb38eb6083..a4763fd24fd8 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1536,6 +1536,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1536 error = sctp_auth_asoc_init_active_key(asoc, 1536 error = sctp_auth_asoc_init_active_key(asoc,
1537 GFP_ATOMIC); 1537 GFP_ATOMIC);
1538 break; 1538 break;
1539 case SCTP_CMD_UPDATE_INITTAG:
1540 asoc->peer.i.init_tag = cmd->obj.u32;
1541 break;
1539 1542
1540 default: 1543 default:
1541 printk(KERN_WARNING "Impossible command: %u, %p\n", 1544 printk(KERN_WARNING "Impossible command: %u, %p\n",
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index f2ed6473feef..07194c2a32df 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4144,6 +4144,24 @@ static sctp_disposition_t sctp_sf_abort_violation(
4144 goto nomem; 4144 goto nomem;
4145 4145
4146 if (asoc) { 4146 if (asoc) {
4147 /* Treat INIT-ACK as a special case during COOKIE-WAIT. */
4148 if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
4149 !asoc->peer.i.init_tag) {
4150 sctp_initack_chunk_t *initack;
4151
4152 initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
4153 if (!sctp_chunk_length_valid(chunk,
4154 sizeof(sctp_initack_chunk_t)))
4155 abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
4156 else {
4157 unsigned int inittag;
4158
4159 inittag = ntohl(initack->init_hdr.init_tag);
4160 sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
4161 SCTP_U32(inittag));
4162 }
4163 }
4164
4147 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 4165 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4148 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4166 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4149 4167
@@ -4349,6 +4367,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4349 sctp_cmd_seq_t *commands) 4367 sctp_cmd_seq_t *commands)
4350{ 4368{
4351 struct sctp_chunk *repl; 4369 struct sctp_chunk *repl;
4370 struct sctp_association* my_asoc;
4352 4371
4353 /* The comment below says that we enter COOKIE-WAIT AFTER 4372 /* The comment below says that we enter COOKIE-WAIT AFTER
4354 * sending the INIT, but that doesn't actually work in our 4373 * sending the INIT, but that doesn't actually work in our
@@ -4372,8 +4391,8 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
4372 /* Cast away the const modifier, as we want to just 4391 /* Cast away the const modifier, as we want to just
4373 * rerun it through as a sideffect. 4392 * rerun it through as a sideffect.
4374 */ 4393 */
4375 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, 4394 my_asoc = (struct sctp_association *)asoc;
4376 SCTP_ASOC((struct sctp_association *) asoc)); 4395 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
4377 4396
4378 /* Choose transport for INIT. */ 4397 /* Choose transport for INIT. */
4379 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT, 4398 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d994d822900d..998e63a31311 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5868,11 +5868,12 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
5868 sctp_cmsgs_t *cmsgs) 5868 sctp_cmsgs_t *cmsgs)
5869{ 5869{
5870 struct cmsghdr *cmsg; 5870 struct cmsghdr *cmsg;
5871 struct msghdr *my_msg = (struct msghdr *)msg;
5871 5872
5872 for (cmsg = CMSG_FIRSTHDR(msg); 5873 for (cmsg = CMSG_FIRSTHDR(msg);
5873 cmsg != NULL; 5874 cmsg != NULL;
5874 cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) { 5875 cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
5875 if (!CMSG_OK(msg, cmsg)) 5876 if (!CMSG_OK(my_msg, cmsg))
5876 return -EINVAL; 5877 return -EINVAL;
5877 5878
5878 /* Should we parse this header or ignore? */ 5879 /* Should we parse this header or ignore? */
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index b43f1f110f87..ce6cda6b6994 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -859,7 +859,7 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event)
859 union sctp_notification *notification; 859 union sctp_notification *notification;
860 struct sk_buff *skb; 860 struct sk_buff *skb;
861 861
862 skb = sctp_event2skb((struct sctp_ulpevent *)event); 862 skb = sctp_event2skb(event);
863 notification = (union sctp_notification *) skb->data; 863 notification = (union sctp_notification *) skb->data;
864 return notification->sn_header.sn_type; 864 return notification->sn_header.sn_type;
865} 865}