aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/atm/br2684.c78
-rw-r--r--net/core/dev.c34
-rw-r--r--net/ipv4/inet_connection_sock.c6
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv6/sit.c44
-rw-r--r--net/mac80211/wext.c3
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/sched/sch_htb.c23
-rw-r--r--net/sctp/associola.c13
-rw-r--r--net/sctp/protocol.c19
11 files changed, 143 insertions, 85 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 9d52ebfc1962..05fafdc2eea3 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -188,10 +188,13 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
188 return 0; 188 return 0;
189 } 189 }
190 } 190 }
191 } else { 191 } else { /* e_vc */
192 skb_push(skb, 2); 192 if (brdev->payload == p_bridged) {
193 if (brdev->payload == p_bridged) 193 skb_push(skb, 2);
194 memset(skb->data, 0, 2); 194 memset(skb->data, 0, 2);
195 } else { /* p_routed */
196 skb_pull(skb, ETH_HLEN);
197 }
195 } 198 }
196 skb_debug(skb); 199 skb_debug(skb);
197 200
@@ -377,11 +380,8 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
377 (skb->data + 6, ethertype_ipv4, 380 (skb->data + 6, ethertype_ipv4,
378 sizeof(ethertype_ipv4)) == 0) 381 sizeof(ethertype_ipv4)) == 0)
379 skb->protocol = __constant_htons(ETH_P_IP); 382 skb->protocol = __constant_htons(ETH_P_IP);
380 else { 383 else
381 brdev->stats.rx_errors++; 384 goto error;
382 dev_kfree_skb(skb);
383 return;
384 }
385 skb_pull(skb, sizeof(llc_oui_ipv4)); 385 skb_pull(skb, sizeof(llc_oui_ipv4));
386 skb_reset_network_header(skb); 386 skb_reset_network_header(skb);
387 skb->pkt_type = PACKET_HOST; 387 skb->pkt_type = PACKET_HOST;
@@ -394,44 +394,56 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
394 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { 394 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
395 skb_pull(skb, sizeof(llc_oui_pid_pad)); 395 skb_pull(skb, sizeof(llc_oui_pid_pad));
396 skb->protocol = eth_type_trans(skb, net_dev); 396 skb->protocol = eth_type_trans(skb, net_dev);
397 } else { 397 } else
398 brdev->stats.rx_errors++; 398 goto error;
399 dev_kfree_skb(skb);
400 return;
401 }
402 399
403 } else { 400 } else { /* e_vc */
404 /* first 2 chars should be 0 */ 401 if (brdev->payload == p_routed) {
405 if (*((u16 *) (skb->data)) != 0) { 402 struct iphdr *iph;
406 brdev->stats.rx_errors++; 403
407 dev_kfree_skb(skb); 404 skb_reset_network_header(skb);
408 return; 405 iph = ip_hdr(skb);
406 if (iph->version == 4)
407 skb->protocol = __constant_htons(ETH_P_IP);
408 else if (iph->version == 6)
409 skb->protocol = __constant_htons(ETH_P_IPV6);
410 else
411 goto error;
412 skb->pkt_type = PACKET_HOST;
413 } else { /* p_bridged */
414 /* first 2 chars should be 0 */
415 if (*((u16 *) (skb->data)) != 0)
416 goto error;
417 skb_pull(skb, BR2684_PAD_LEN);
418 skb->protocol = eth_type_trans(skb, net_dev);
409 } 419 }
410 skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN); /* pad, dstmac, srcmac, ethtype */
411 skb->protocol = eth_type_trans(skb, net_dev);
412 } 420 }
413 421
414#ifdef CONFIG_ATM_BR2684_IPFILTER 422#ifdef CONFIG_ATM_BR2684_IPFILTER
415 if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) { 423 if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb)))
416 brdev->stats.rx_dropped++; 424 goto dropped;
417 dev_kfree_skb(skb);
418 return;
419 }
420#endif /* CONFIG_ATM_BR2684_IPFILTER */ 425#endif /* CONFIG_ATM_BR2684_IPFILTER */
421 skb->dev = net_dev; 426 skb->dev = net_dev;
422 ATM_SKB(skb)->vcc = atmvcc; /* needed ? */ 427 ATM_SKB(skb)->vcc = atmvcc; /* needed ? */
423 pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol)); 428 pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol));
424 skb_debug(skb); 429 skb_debug(skb);
425 if (unlikely(!(net_dev->flags & IFF_UP))) { 430 /* sigh, interface is down? */
426 /* sigh, interface is down */ 431 if (unlikely(!(net_dev->flags & IFF_UP)))
427 brdev->stats.rx_dropped++; 432 goto dropped;
428 dev_kfree_skb(skb);
429 return;
430 }
431 brdev->stats.rx_packets++; 433 brdev->stats.rx_packets++;
432 brdev->stats.rx_bytes += skb->len; 434 brdev->stats.rx_bytes += skb->len;
433 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); 435 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
434 netif_rx(skb); 436 netif_rx(skb);
437 return;
438
439dropped:
440 brdev->stats.rx_dropped++;
441 goto free_skb;
442error:
443 brdev->stats.rx_errors++;
444free_skb:
445 dev_kfree_skb(skb);
446 return;
435} 447}
436 448
437/* 449/*
@@ -518,9 +530,9 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
518 struct sk_buff *next = skb->next; 530 struct sk_buff *next = skb->next;
519 531
520 skb->next = skb->prev = NULL; 532 skb->next = skb->prev = NULL;
533 br2684_push(atmvcc, skb);
521 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; 534 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len;
522 BRPRIV(skb->dev)->stats.rx_packets--; 535 BRPRIV(skb->dev)->stats.rx_packets--;
523 br2684_push(atmvcc, skb);
524 536
525 skb = next; 537 skb = next;
526 } 538 }
diff --git a/net/core/dev.c b/net/core/dev.c
index 582963077877..68d8df0992ab 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -119,6 +119,7 @@
119#include <linux/err.h> 119#include <linux/err.h>
120#include <linux/ctype.h> 120#include <linux/ctype.h>
121#include <linux/if_arp.h> 121#include <linux/if_arp.h>
122#include <linux/if_vlan.h>
122 123
123#include "net-sysfs.h" 124#include "net-sysfs.h"
124 125
@@ -1362,6 +1363,29 @@ void netif_device_attach(struct net_device *dev)
1362} 1363}
1363EXPORT_SYMBOL(netif_device_attach); 1364EXPORT_SYMBOL(netif_device_attach);
1364 1365
1366static bool can_checksum_protocol(unsigned long features, __be16 protocol)
1367{
1368 return ((features & NETIF_F_GEN_CSUM) ||
1369 ((features & NETIF_F_IP_CSUM) &&
1370 protocol == htons(ETH_P_IP)) ||
1371 ((features & NETIF_F_IPV6_CSUM) &&
1372 protocol == htons(ETH_P_IPV6)));
1373}
1374
1375static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb)
1376{
1377 if (can_checksum_protocol(dev->features, skb->protocol))
1378 return true;
1379
1380 if (skb->protocol == htons(ETH_P_8021Q)) {
1381 struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
1382 if (can_checksum_protocol(dev->features & dev->vlan_features,
1383 veh->h_vlan_encapsulated_proto))
1384 return true;
1385 }
1386
1387 return false;
1388}
1365 1389
1366/* 1390/*
1367 * Invalidate hardware checksum when packet is to be mangled, and 1391 * Invalidate hardware checksum when packet is to be mangled, and
@@ -1640,14 +1664,8 @@ int dev_queue_xmit(struct sk_buff *skb)
1640 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1664 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1641 skb_set_transport_header(skb, skb->csum_start - 1665 skb_set_transport_header(skb, skb->csum_start -
1642 skb_headroom(skb)); 1666 skb_headroom(skb));
1643 1667 if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb))
1644 if (!(dev->features & NETIF_F_GEN_CSUM) && 1668 goto out_kfree_skb;
1645 !((dev->features & NETIF_F_IP_CSUM) &&
1646 skb->protocol == htons(ETH_P_IP)) &&
1647 !((dev->features & NETIF_F_IPV6_CSUM) &&
1648 skb->protocol == htons(ETH_P_IPV6)))
1649 if (skb_checksum_help(skb))
1650 goto out_kfree_skb;
1651 } 1669 }
1652 1670
1653gso: 1671gso:
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4c804b3c287b..5bbf00051512 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -468,9 +468,9 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
468 reqp=&lopt->syn_table[i]; 468 reqp=&lopt->syn_table[i];
469 while ((req = *reqp) != NULL) { 469 while ((req = *reqp) != NULL) {
470 if (time_after_eq(now, req->expires)) { 470 if (time_after_eq(now, req->expires)) {
471 if ((req->retrans < (inet_rsk(req)->acked ? max_retries : thresh)) && 471 if ((req->retrans < thresh ||
472 (inet_rsk(req)->acked || 472 (inet_rsk(req)->acked && req->retrans < max_retries))
473 !req->rsk_ops->rtx_syn_ack(parent, req))) { 473 && !req->rsk_ops->rtx_syn_ack(parent, req)) {
474 unsigned long timeo; 474 unsigned long timeo;
475 475
476 if (req->retrans++ == 0) 476 if (req->retrans++ == 0)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 36035a0c6dc2..7d449468409e 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -931,7 +931,7 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
931 srcp = inet->num; 931 srcp = inet->num;
932 932
933 seq_printf(seq, "%4d: %08X:%04X %08X:%04X" 933 seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
934 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d", 934 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
935 i, src, srcp, dest, destp, sp->sk_state, 935 i, src, srcp, dest, destp, sp->sk_state,
936 atomic_read(&sp->sk_wmem_alloc), 936 atomic_read(&sp->sk_wmem_alloc),
937 atomic_read(&sp->sk_rmem_alloc), 937 atomic_read(&sp->sk_rmem_alloc),
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 64b385f65930..0db9b75c1fa2 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -83,10 +83,6 @@
83int sysctl_tcp_tw_reuse __read_mostly; 83int sysctl_tcp_tw_reuse __read_mostly;
84int sysctl_tcp_low_latency __read_mostly; 84int sysctl_tcp_low_latency __read_mostly;
85 85
86/* Check TCP sequence numbers in ICMP packets. */
87#define ICMP_MIN_LENGTH 8
88
89void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
90 86
91#ifdef CONFIG_TCP_MD5SIG 87#ifdef CONFIG_TCP_MD5SIG
92static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, 88static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b0c5080420a8..b7a50e968506 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -220,15 +220,18 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
220 220
221} 221}
222 222
223static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) 223static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
224 struct ip_tunnel_prl __user *a)
224{ 225{
225 struct ip_tunnel_prl *kp; 226 struct ip_tunnel_prl kprl, *kp;
226 struct ip_tunnel_prl_entry *prl; 227 struct ip_tunnel_prl_entry *prl;
227 unsigned int cmax, c = 0, ca, len; 228 unsigned int cmax, c = 0, ca, len;
228 int ret = 0; 229 int ret = 0;
229 230
230 cmax = a->datalen / sizeof(*a); 231 if (copy_from_user(&kprl, a, sizeof(kprl)))
231 if (cmax > 1 && a->addr != htonl(INADDR_ANY)) 232 return -EFAULT;
233 cmax = kprl.datalen / sizeof(kprl);
234 if (cmax > 1 && kprl.addr != htonl(INADDR_ANY))
232 cmax = 1; 235 cmax = 1;
233 236
234 /* For simple GET or for root users, 237 /* For simple GET or for root users,
@@ -259,26 +262,25 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
259 for (prl = t->prl; prl; prl = prl->next) { 262 for (prl = t->prl; prl; prl = prl->next) {
260 if (c > cmax) 263 if (c > cmax)
261 break; 264 break;
262 if (a->addr != htonl(INADDR_ANY) && prl->addr != a->addr) 265 if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
263 continue; 266 continue;
264 kp[c].addr = prl->addr; 267 kp[c].addr = prl->addr;
265 kp[c].flags = prl->flags; 268 kp[c].flags = prl->flags;
266 c++; 269 c++;
267 if (a->addr != htonl(INADDR_ANY)) 270 if (kprl.addr != htonl(INADDR_ANY))
268 break; 271 break;
269 } 272 }
270out: 273out:
271 read_unlock(&ipip6_lock); 274 read_unlock(&ipip6_lock);
272 275
273 len = sizeof(*kp) * c; 276 len = sizeof(*kp) * c;
274 ret = len ? copy_to_user(a->data, kp, len) : 0; 277 ret = 0;
278 if ((len && copy_to_user(a + 1, kp, len)) || put_user(len, &a->datalen))
279 ret = -EFAULT;
275 280
276 kfree(kp); 281 kfree(kp);
277 if (ret)
278 return -EFAULT;
279 282
280 a->datalen = len; 283 return ret;
281 return 0;
282} 284}
283 285
284static int 286static int
@@ -871,11 +873,20 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
871 break; 873 break;
872 874
873 case SIOCGETPRL: 875 case SIOCGETPRL:
876 err = -EINVAL;
877 if (dev == sitn->fb_tunnel_dev)
878 goto done;
879 err = -ENOENT;
880 if (!(t = netdev_priv(dev)))
881 goto done;
882 err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data);
883 break;
884
874 case SIOCADDPRL: 885 case SIOCADDPRL:
875 case SIOCDELPRL: 886 case SIOCDELPRL:
876 case SIOCCHGPRL: 887 case SIOCCHGPRL:
877 err = -EPERM; 888 err = -EPERM;
878 if (cmd != SIOCGETPRL && !capable(CAP_NET_ADMIN)) 889 if (!capable(CAP_NET_ADMIN))
879 goto done; 890 goto done;
880 err = -EINVAL; 891 err = -EINVAL;
881 if (dev == sitn->fb_tunnel_dev) 892 if (dev == sitn->fb_tunnel_dev)
@@ -888,12 +899,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
888 goto done; 899 goto done;
889 900
890 switch (cmd) { 901 switch (cmd) {
891 case SIOCGETPRL:
892 err = ipip6_tunnel_get_prl(t, &prl);
893 if (!err && copy_to_user(ifr->ifr_ifru.ifru_data,
894 &prl, sizeof(prl)))
895 err = -EFAULT;
896 break;
897 case SIOCDELPRL: 902 case SIOCDELPRL:
898 err = ipip6_tunnel_del_prl(t, &prl); 903 err = ipip6_tunnel_del_prl(t, &prl);
899 break; 904 break;
@@ -902,8 +907,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
902 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); 907 err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
903 break; 908 break;
904 } 909 }
905 if (cmd != SIOCGETPRL) 910 netdev_state_change(dev);
906 netdev_state_change(dev);
907 break; 911 break;
908 912
909 default: 913 default:
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 4806d96b9877..5af3862e7191 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -508,7 +508,8 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
508 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 508 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
509 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 509 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
510 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 510 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
511 if (sdata->u.sta.state == IEEE80211_ASSOCIATED) { 511 if (sdata->u.sta.state == IEEE80211_ASSOCIATED ||
512 sdata->u.sta.state == IEEE80211_IBSS_JOINED) {
512 ap_addr->sa_family = ARPHRD_ETHER; 513 ap_addr->sa_family = ARPHRD_ETHER;
513 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); 514 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
514 return 0; 515 return 0;
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index d8c2f9688b25..cfa8fbb0736a 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -637,7 +637,7 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
637#ifdef CONFIG_MAC80211_HT_DEBUG 637#ifdef CONFIG_MAC80211_HT_DEBUG
638 if (net_ratelimit()) 638 if (net_ratelimit())
639 printk(KERN_DEBUG "allocated aggregation queue" 639 printk(KERN_DEBUG "allocated aggregation queue"
640 " %d tid %d addr %s pool=0x%lX", 640 " %d tid %d addr %s pool=0x%lX\n",
641 i, tid, print_mac(mac, sta->addr), 641 i, tid, print_mac(mac, sta->addr),
642 q->qdisc_pool[0]); 642 q->qdisc_pool[0]);
643#endif /* CONFIG_MAC80211_HT_DEBUG */ 643#endif /* CONFIG_MAC80211_HT_DEBUG */
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 213071859030..2cef8f34b2cb 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -26,6 +26,7 @@
26 * and many others. thanks. 26 * and many others. thanks.
27 */ 27 */
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/moduleparam.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#include <linux/kernel.h> 31#include <linux/kernel.h>
31#include <linux/string.h> 32#include <linux/string.h>
@@ -51,13 +52,17 @@
51*/ 52*/
52 53
53#define HTB_HSIZE 16 /* classid hash size */ 54#define HTB_HSIZE 16 /* classid hash size */
54#define HTB_HYSTERESIS 1 /* whether to use mode hysteresis for speedup */ 55static int htb_hysteresis __read_mostly = 0; /* whether to use mode hysteresis for speedup */
55#define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */ 56#define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */
56 57
57#if HTB_VER >> 16 != TC_HTB_PROTOVER 58#if HTB_VER >> 16 != TC_HTB_PROTOVER
58#error "Mismatched sch_htb.c and pkt_sch.h" 59#error "Mismatched sch_htb.c and pkt_sch.h"
59#endif 60#endif
60 61
62/* Module parameter and sysfs export */
63module_param (htb_hysteresis, int, 0640);
64MODULE_PARM_DESC(htb_hysteresis, "Hysteresis mode, less CPU load, less accurate");
65
61/* used internaly to keep status of single class */ 66/* used internaly to keep status of single class */
62enum htb_cmode { 67enum htb_cmode {
63 HTB_CANT_SEND, /* class can't send and can't borrow */ 68 HTB_CANT_SEND, /* class can't send and can't borrow */
@@ -460,19 +465,21 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl)
460 htb_remove_class_from_row(q, cl, mask); 465 htb_remove_class_from_row(q, cl, mask);
461} 466}
462 467
463#if HTB_HYSTERESIS
464static inline long htb_lowater(const struct htb_class *cl) 468static inline long htb_lowater(const struct htb_class *cl)
465{ 469{
466 return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0; 470 if (htb_hysteresis)
471 return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0;
472 else
473 return 0;
467} 474}
468static inline long htb_hiwater(const struct htb_class *cl) 475static inline long htb_hiwater(const struct htb_class *cl)
469{ 476{
470 return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0; 477 if (htb_hysteresis)
478 return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0;
479 else
480 return 0;
471} 481}
472#else 482
473#define htb_lowater(cl) (0)
474#define htb_hiwater(cl) (0)
475#endif
476 483
477/** 484/**
478 * htb_class_mode - computes and returns current class mode 485 * htb_class_mode - computes and returns current class mode
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index d5cc731b6798..35b6a023a6d0 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -476,6 +476,15 @@ static void sctp_association_destroy(struct sctp_association *asoc)
476void sctp_assoc_set_primary(struct sctp_association *asoc, 476void sctp_assoc_set_primary(struct sctp_association *asoc,
477 struct sctp_transport *transport) 477 struct sctp_transport *transport)
478{ 478{
479 int changeover = 0;
480
481 /* it's a changeover only if we already have a primary path
482 * that we are changing
483 */
484 if (asoc->peer.primary_path != NULL &&
485 asoc->peer.primary_path != transport)
486 changeover = 1 ;
487
479 asoc->peer.primary_path = transport; 488 asoc->peer.primary_path = transport;
480 489
481 /* Set a default msg_name for events. */ 490 /* Set a default msg_name for events. */
@@ -501,12 +510,12 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
501 * double switch to the same destination address. 510 * double switch to the same destination address.
502 */ 511 */
503 if (transport->cacc.changeover_active) 512 if (transport->cacc.changeover_active)
504 transport->cacc.cycling_changeover = 1; 513 transport->cacc.cycling_changeover = changeover;
505 514
506 /* 2) The sender MUST set CHANGEOVER_ACTIVE to indicate that 515 /* 2) The sender MUST set CHANGEOVER_ACTIVE to indicate that
507 * a changeover has occurred. 516 * a changeover has occurred.
508 */ 517 */
509 transport->cacc.changeover_active = 1; 518 transport->cacc.changeover_active = changeover;
510 519
511 /* 3) The sender MUST store the next TSN to be sent in 520 /* 3) The sender MUST store the next TSN to be sent in
512 * next_tsn_at_change. 521 * next_tsn_at_change.
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index d6af466091d2..23aaffb97ca3 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -108,16 +108,27 @@ static __init int sctp_proc_init(void)
108 } 108 }
109 109
110 if (sctp_snmp_proc_init()) 110 if (sctp_snmp_proc_init())
111 goto out_nomem; 111 goto out_snmp_proc_init;
112 if (sctp_eps_proc_init()) 112 if (sctp_eps_proc_init())
113 goto out_nomem; 113 goto out_eps_proc_init;
114 if (sctp_assocs_proc_init()) 114 if (sctp_assocs_proc_init())
115 goto out_nomem; 115 goto out_assocs_proc_init;
116 if (sctp_remaddr_proc_init()) 116 if (sctp_remaddr_proc_init())
117 goto out_nomem; 117 goto out_remaddr_proc_init;
118 118
119 return 0; 119 return 0;
120 120
121out_remaddr_proc_init:
122 sctp_remaddr_proc_exit();
123out_assocs_proc_init:
124 sctp_eps_proc_exit();
125out_eps_proc_init:
126 sctp_snmp_proc_exit();
127out_snmp_proc_init:
128 if (proc_net_sctp) {
129 proc_net_sctp = NULL;
130 remove_proc_entry("sctp", init_net.proc_net);
131 }
121out_nomem: 132out_nomem:
122 return -ENOMEM; 133 return -ENOMEM;
123} 134}