aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/ipv6.c35
-rw-r--r--net/sctp/protocol.c29
-rw-r--r--net/sctp/sm_statefuns.c24
-rw-r--r--net/sctp/socket.c206
-rw-r--r--net/sctp/sysctl.c82
5 files changed, 262 insertions, 114 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 4124bbb99947..ceaa4aa066ea 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -223,10 +223,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
223 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); 223 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
224 } 224 }
225 225
226 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " 226 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n",
227 "src:" NIP6_FMT " dst:" NIP6_FMT "\n",
228 __func__, skb, skb->len, 227 __func__, skb, skb->len,
229 NIP6(fl.fl6_src), NIP6(fl.fl6_dst)); 228 &fl.fl6_src, &fl.fl6_dst);
230 229
231 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); 230 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
232 231
@@ -252,23 +251,19 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
252 fl.oif = daddr->v6.sin6_scope_id; 251 fl.oif = daddr->v6.sin6_scope_id;
253 252
254 253
255 SCTP_DEBUG_PRINTK("%s: DST=" NIP6_FMT " ", 254 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst);
256 __func__, NIP6(fl.fl6_dst));
257 255
258 if (saddr) { 256 if (saddr) {
259 ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); 257 ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr);
260 SCTP_DEBUG_PRINTK( 258 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src);
261 "SRC=" NIP6_FMT " - ",
262 NIP6(fl.fl6_src));
263 } 259 }
264 260
265 dst = ip6_route_output(&init_net, NULL, &fl); 261 dst = ip6_route_output(&init_net, NULL, &fl);
266 if (!dst->error) { 262 if (!dst->error) {
267 struct rt6_info *rt; 263 struct rt6_info *rt;
268 rt = (struct rt6_info *)dst; 264 rt = (struct rt6_info *)dst;
269 SCTP_DEBUG_PRINTK( 265 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",
270 "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", 266 &rt->rt6i_dst.addr, &rt->rt6i_src.addr);
271 NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr));
272 return dst; 267 return dst;
273 } 268 }
274 SCTP_DEBUG_PRINTK("NO ROUTE\n"); 269 SCTP_DEBUG_PRINTK("NO ROUTE\n");
@@ -314,9 +309,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
314 __u8 matchlen = 0; 309 __u8 matchlen = 0;
315 __u8 bmatchlen; 310 __u8 bmatchlen;
316 311
317 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p " 312 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ",
318 "daddr:" NIP6_FMT " ", 313 __func__, asoc, dst, &daddr->v6.sin6_addr);
319 __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
320 314
321 if (!asoc) { 315 if (!asoc) {
322 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)), 316 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
@@ -324,8 +318,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
324 &daddr->v6.sin6_addr, 318 &daddr->v6.sin6_addr,
325 inet6_sk(&sk->inet.sk)->srcprefs, 319 inet6_sk(&sk->inet.sk)->srcprefs,
326 &saddr->v6.sin6_addr); 320 &saddr->v6.sin6_addr);
327 SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n", 321 SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n",
328 NIP6(saddr->v6.sin6_addr)); 322 &saddr->v6.sin6_addr);
329 return; 323 return;
330 } 324 }
331 325
@@ -353,12 +347,11 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
353 347
354 if (baddr) { 348 if (baddr) {
355 memcpy(saddr, baddr, sizeof(union sctp_addr)); 349 memcpy(saddr, baddr, sizeof(union sctp_addr));
356 SCTP_DEBUG_PRINTK("saddr: " NIP6_FMT "\n", 350 SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr);
357 NIP6(saddr->v6.sin6_addr));
358 } else { 351 } else {
359 printk(KERN_ERR "%s: asoc:%p Could not find a valid source " 352 printk(KERN_ERR "%s: asoc:%p Could not find a valid source "
360 "address for the dest:" NIP6_FMT "\n", 353 "address for the dest:%pI6\n",
361 __func__, asoc, NIP6(daddr->v6.sin6_addr)); 354 __func__, asoc, &daddr->v6.sin6_addr);
362 } 355 }
363 356
364 rcu_read_unlock(); 357 rcu_read_unlock();
@@ -727,7 +720,7 @@ static int sctp_v6_is_ce(const struct sk_buff *skb)
727/* Dump the v6 addr to the seq file. */ 720/* Dump the v6 addr to the seq file. */
728static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr) 721static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
729{ 722{
730 seq_printf(seq, NIP6_FMT " ", NIP6(addr->v6.sin6_addr)); 723 seq_printf(seq, "%pI6 ", &addr->v6.sin6_addr);
731} 724}
732 725
733static void sctp_v6_ecn_capable(struct sock *sk) 726static void sctp_v6_ecn_capable(struct sock *sk)
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 0b65354aaf64..b78e3be69013 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -102,6 +102,8 @@ struct sock *sctp_get_ctl_sock(void)
102/* Set up the proc fs entry for the SCTP protocol. */ 102/* Set up the proc fs entry for the SCTP protocol. */
103static __init int sctp_proc_init(void) 103static __init int sctp_proc_init(void)
104{ 104{
105 if (percpu_counter_init(&sctp_sockets_allocated, 0))
106 goto out_nomem;
105#ifdef CONFIG_PROC_FS 107#ifdef CONFIG_PROC_FS
106 if (!proc_net_sctp) { 108 if (!proc_net_sctp) {
107 struct proc_dir_entry *ent; 109 struct proc_dir_entry *ent;
@@ -110,7 +112,7 @@ static __init int sctp_proc_init(void)
110 ent->owner = THIS_MODULE; 112 ent->owner = THIS_MODULE;
111 proc_net_sctp = ent; 113 proc_net_sctp = ent;
112 } else 114 } else
113 goto out_nomem; 115 goto out_free_percpu;
114 } 116 }
115 117
116 if (sctp_snmp_proc_init()) 118 if (sctp_snmp_proc_init())
@@ -135,11 +137,14 @@ out_snmp_proc_init:
135 proc_net_sctp = NULL; 137 proc_net_sctp = NULL;
136 remove_proc_entry("sctp", init_net.proc_net); 138 remove_proc_entry("sctp", init_net.proc_net);
137 } 139 }
138out_nomem: 140out_free_percpu:
139 return -ENOMEM; 141 percpu_counter_destroy(&sctp_sockets_allocated);
140#else 142#else
141 return 0; 143 return 0;
142#endif /* CONFIG_PROC_FS */ 144#endif /* CONFIG_PROC_FS */
145
146out_nomem:
147 return -ENOMEM;
143} 148}
144 149
145/* Clean up the proc fs entry for the SCTP protocol. 150/* Clean up the proc fs entry for the SCTP protocol.
@@ -482,9 +487,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
482 if (saddr) 487 if (saddr)
483 fl.fl4_src = saddr->v4.sin_addr.s_addr; 488 fl.fl4_src = saddr->v4.sin_addr.s_addr;
484 489
485 SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ", 490 SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
486 __func__, NIPQUAD(fl.fl4_dst), 491 __func__, &fl.fl4_dst, &fl.fl4_src);
487 NIPQUAD(fl.fl4_src));
488 492
489 if (!ip_route_output_key(&init_net, &rt, &fl)) { 493 if (!ip_route_output_key(&init_net, &rt, &fl)) {
490 dst = &rt->u.dst; 494 dst = &rt->u.dst;
@@ -540,8 +544,8 @@ out_unlock:
540 rcu_read_unlock(); 544 rcu_read_unlock();
541out: 545out:
542 if (dst) 546 if (dst)
543 SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n", 547 SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n",
544 NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_src)); 548 &rt->rt_dst, &rt->rt_src);
545 else 549 else
546 SCTP_DEBUG_PRINTK("NO ROUTE\n"); 550 SCTP_DEBUG_PRINTK("NO ROUTE\n");
547 551
@@ -646,7 +650,7 @@ static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
646/* Dump the v4 addr to the seq file. */ 650/* Dump the v4 addr to the seq file. */
647static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr) 651static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
648{ 652{
649 seq_printf(seq, "%d.%d.%d.%d ", NIPQUAD(addr->v4.sin_addr)); 653 seq_printf(seq, "%pI4 ", &addr->v4.sin_addr);
650} 654}
651 655
652static void sctp_v4_ecn_capable(struct sock *sk) 656static void sctp_v4_ecn_capable(struct sock *sk)
@@ -866,11 +870,10 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
866{ 870{
867 struct inet_sock *inet = inet_sk(skb->sk); 871 struct inet_sock *inet = inet_sk(skb->sk);
868 872
869 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " 873 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
870 "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
871 __func__, skb, skb->len, 874 __func__, skb, skb->len,
872 NIPQUAD(skb->rtable->rt_src), 875 &skb->rtable->rt_src,
873 NIPQUAD(skb->rtable->rt_dst)); 876 &skb->rtable->rt_dst);
874 877
875 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? 878 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
876 IP_PMTUDISC_DO : IP_PMTUDISC_DONT; 879 IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index a6a0ea71ae93..1c4e5d6c29c0 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -1123,19 +1123,17 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
1123 if (from_addr.sa.sa_family == AF_INET6) { 1123 if (from_addr.sa.sa_family == AF_INET6) {
1124 if (net_ratelimit()) 1124 if (net_ratelimit())
1125 printk(KERN_WARNING 1125 printk(KERN_WARNING
1126 "%s association %p could not find address " 1126 "%s association %p could not find address %pI6\n",
1127 NIP6_FMT "\n",
1128 __func__, 1127 __func__,
1129 asoc, 1128 asoc,
1130 NIP6(from_addr.v6.sin6_addr)); 1129 &from_addr.v6.sin6_addr);
1131 } else { 1130 } else {
1132 if (net_ratelimit()) 1131 if (net_ratelimit())
1133 printk(KERN_WARNING 1132 printk(KERN_WARNING
1134 "%s association %p could not find address " 1133 "%s association %p could not find address %pI4\n",
1135 NIPQUAD_FMT "\n",
1136 __func__, 1134 __func__,
1137 asoc, 1135 asoc,
1138 NIPQUAD(from_addr.v4.sin_addr.s_addr)); 1136 &from_addr.v4.sin_addr.s_addr);
1139 } 1137 }
1140 return SCTP_DISPOSITION_DISCARD; 1138 return SCTP_DISPOSITION_DISCARD;
1141 } 1139 }
@@ -3691,6 +3689,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3691{ 3689{
3692 struct sctp_chunk *chunk = arg; 3690 struct sctp_chunk *chunk = arg;
3693 struct sctp_fwdtsn_hdr *fwdtsn_hdr; 3691 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3692 struct sctp_fwdtsn_skip *skip;
3694 __u16 len; 3693 __u16 len;
3695 __u32 tsn; 3694 __u32 tsn;
3696 3695
@@ -3720,6 +3719,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3720 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) 3719 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3721 goto discard_noforce; 3720 goto discard_noforce;
3722 3721
3722 /* Silently discard the chunk if stream-id is not valid */
3723 sctp_walk_fwdtsn(skip, chunk) {
3724 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
3725 goto discard_noforce;
3726 }
3727
3723 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); 3728 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3724 if (len > sizeof(struct sctp_fwdtsn_hdr)) 3729 if (len > sizeof(struct sctp_fwdtsn_hdr))
3725 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, 3730 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
@@ -3751,6 +3756,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3751{ 3756{
3752 struct sctp_chunk *chunk = arg; 3757 struct sctp_chunk *chunk = arg;
3753 struct sctp_fwdtsn_hdr *fwdtsn_hdr; 3758 struct sctp_fwdtsn_hdr *fwdtsn_hdr;
3759 struct sctp_fwdtsn_skip *skip;
3754 __u16 len; 3760 __u16 len;
3755 __u32 tsn; 3761 __u32 tsn;
3756 3762
@@ -3780,6 +3786,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3780 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) 3786 if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
3781 goto gen_shutdown; 3787 goto gen_shutdown;
3782 3788
3789 /* Silently discard the chunk if stream-id is not valid */
3790 sctp_walk_fwdtsn(skip, chunk) {
3791 if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
3792 goto gen_shutdown;
3793 }
3794
3783 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); 3795 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
3784 if (len > sizeof(struct sctp_fwdtsn_hdr)) 3796 if (len > sizeof(struct sctp_fwdtsn_hdr))
3785 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, 3797 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index a1b904529d5e..b14a8f33e42d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -114,7 +114,7 @@ extern int sysctl_sctp_wmem[3];
114 114
115static int sctp_memory_pressure; 115static int sctp_memory_pressure;
116static atomic_t sctp_memory_allocated; 116static atomic_t sctp_memory_allocated;
117static atomic_t sctp_sockets_allocated; 117struct percpu_counter sctp_sockets_allocated;
118 118
119static void sctp_enter_memory_pressure(struct sock *sk) 119static void sctp_enter_memory_pressure(struct sock *sk)
120{ 120{
@@ -2404,9 +2404,9 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
2404 if (params.sack_delay == 0 && params.sack_freq == 0) 2404 if (params.sack_delay == 0 && params.sack_freq == 0)
2405 return 0; 2405 return 0;
2406 } else if (optlen == sizeof(struct sctp_assoc_value)) { 2406 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2407 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info " 2407 printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
2408 "in delayed_ack socket option deprecated\n"); 2408 "in delayed_ack socket option deprecated\n");
2409 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n"); 2409 printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
2410 if (copy_from_user(&params, optval, optlen)) 2410 if (copy_from_user(&params, optval, optlen))
2411 return -EFAULT; 2411 return -EFAULT;
2412 2412
@@ -2778,32 +2778,77 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
2778} 2778}
2779 2779
2780/* 2780/*
2781 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) 2781 * 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
2782 * 2782 * This option will get or set the maximum size to put in any outgoing
2783 * This socket option specifies the maximum size to put in any outgoing 2783 * SCTP DATA chunk. If a message is larger than this size it will be
2784 * SCTP chunk. If a message is larger than this size it will be
2785 * fragmented by SCTP into the specified size. Note that the underlying 2784 * fragmented by SCTP into the specified size. Note that the underlying
2786 * SCTP implementation may fragment into smaller sized chunks when the 2785 * SCTP implementation may fragment into smaller sized chunks when the
2787 * PMTU of the underlying association is smaller than the value set by 2786 * PMTU of the underlying association is smaller than the value set by
2788 * the user. 2787 * the user. The default value for this option is '0' which indicates
2788 * the user is NOT limiting fragmentation and only the PMTU will effect
2789 * SCTP's choice of DATA chunk size. Note also that values set larger
2790 * than the maximum size of an IP datagram will effectively let SCTP
2791 * control fragmentation (i.e. the same as setting this option to 0).
2792 *
2793 * The following structure is used to access and modify this parameter:
2794 *
2795 * struct sctp_assoc_value {
2796 * sctp_assoc_t assoc_id;
2797 * uint32_t assoc_value;
2798 * };
2799 *
2800 * assoc_id: This parameter is ignored for one-to-one style sockets.
2801 * For one-to-many style sockets this parameter indicates which
2802 * association the user is performing an action upon. Note that if
2803 * this field's value is zero then the endpoints default value is
2804 * changed (effecting future associations only).
2805 * assoc_value: This parameter specifies the maximum size in bytes.
2789 */ 2806 */
2790static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen) 2807static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen)
2791{ 2808{
2809 struct sctp_assoc_value params;
2792 struct sctp_association *asoc; 2810 struct sctp_association *asoc;
2793 struct sctp_sock *sp = sctp_sk(sk); 2811 struct sctp_sock *sp = sctp_sk(sk);
2794 int val; 2812 int val;
2795 2813
2796 if (optlen < sizeof(int)) 2814 if (optlen == sizeof(int)) {
2815 printk(KERN_WARNING
2816 "SCTP: Use of int in maxseg socket option deprecated\n");
2817 printk(KERN_WARNING
2818 "SCTP: Use struct sctp_assoc_value instead\n");
2819 if (copy_from_user(&val, optval, optlen))
2820 return -EFAULT;
2821 params.assoc_id = 0;
2822 } else if (optlen == sizeof(struct sctp_assoc_value)) {
2823 if (copy_from_user(&params, optval, optlen))
2824 return -EFAULT;
2825 val = params.assoc_value;
2826 } else
2797 return -EINVAL; 2827 return -EINVAL;
2798 if (get_user(val, (int __user *)optval)) 2828
2799 return -EFAULT;
2800 if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))) 2829 if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN)))
2801 return -EINVAL; 2830 return -EINVAL;
2802 sp->user_frag = val;
2803 2831
2804 /* Update the frag_point of the existing associations. */ 2832 asoc = sctp_id2assoc(sk, params.assoc_id);
2805 list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { 2833 if (!asoc && params.assoc_id && sctp_style(sk, UDP))
2806 asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); 2834 return -EINVAL;
2835
2836 if (asoc) {
2837 if (val == 0) {
2838 val = asoc->pathmtu;
2839 val -= sp->pf->af->net_header_len;
2840 val -= sizeof(struct sctphdr) +
2841 sizeof(struct sctp_data_chunk);
2842 }
2843
2844 asoc->frag_point = val;
2845 } else {
2846 sp->user_frag = val;
2847
2848 /* Update the frag_point of the existing associations. */
2849 list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
2850 asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
2851 }
2807 } 2852 }
2808 2853
2809 return 0; 2854 return 0;
@@ -2965,14 +3010,21 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
2965} 3010}
2966 3011
2967/* 3012/*
2968 * 7.1.25. Set or Get the sctp partial delivery point 3013 * 8.1.21. Set or Get the SCTP Partial Delivery Point
2969 * (SCTP_PARTIAL_DELIVERY_POINT) 3014 * (SCTP_PARTIAL_DELIVERY_POINT)
3015 *
2970 * This option will set or get the SCTP partial delivery point. This 3016 * This option will set or get the SCTP partial delivery point. This
2971 * point is the size of a message where the partial delivery API will be 3017 * point is the size of a message where the partial delivery API will be
2972 * invoked to help free up rwnd space for the peer. Setting this to a 3018 * invoked to help free up rwnd space for the peer. Setting this to a
2973 * lower value will cause partial delivery's to happen more often. The 3019 * lower value will cause partial deliveries to happen more often. The
2974 * calls argument is an integer that sets or gets the partial delivery 3020 * calls argument is an integer that sets or gets the partial delivery
2975 * point. 3021 * point. Note also that the call will fail if the user attempts to set
3022 * this value larger than the socket receive buffer size.
3023 *
3024 * Note that any single message having a length smaller than or equal to
3025 * the SCTP partial delivery point will be delivered in one single read
3026 * call as long as the user provided buffer is large enough to hold the
3027 * message.
2976 */ 3028 */
2977static int sctp_setsockopt_partial_delivery_point(struct sock *sk, 3029static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
2978 char __user *optval, 3030 char __user *optval,
@@ -2985,6 +3037,12 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
2985 if (get_user(val, (int __user *)optval)) 3037 if (get_user(val, (int __user *)optval))
2986 return -EFAULT; 3038 return -EFAULT;
2987 3039
3040 /* Note: We double the receive buffer from what the user sets
3041 * it to be, also initial rwnd is based on rcvbuf/2.
3042 */
3043 if (val > (sk->sk_rcvbuf >> 1))
3044 return -EINVAL;
3045
2988 sctp_sk(sk)->pd_point = val; 3046 sctp_sk(sk)->pd_point = val;
2989 3047
2990 return 0; /* is this the right error code? */ 3048 return 0; /* is this the right error code? */
@@ -3613,7 +3671,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3613 sp->hmac = NULL; 3671 sp->hmac = NULL;
3614 3672
3615 SCTP_DBG_OBJCNT_INC(sock); 3673 SCTP_DBG_OBJCNT_INC(sock);
3616 atomic_inc(&sctp_sockets_allocated); 3674 percpu_counter_inc(&sctp_sockets_allocated);
3675
3676 local_bh_disable();
3677 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
3678 local_bh_enable();
3679
3617 return 0; 3680 return 0;
3618} 3681}
3619 3682
@@ -3627,7 +3690,10 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
3627 /* Release our hold on the endpoint. */ 3690 /* Release our hold on the endpoint. */
3628 ep = sctp_sk(sk)->ep; 3691 ep = sctp_sk(sk)->ep;
3629 sctp_endpoint_free(ep); 3692 sctp_endpoint_free(ep);
3630 atomic_dec(&sctp_sockets_allocated); 3693 percpu_counter_dec(&sctp_sockets_allocated);
3694 local_bh_disable();
3695 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
3696 local_bh_enable();
3631} 3697}
3632 3698
3633/* API 4.1.7 shutdown() - TCP Style Syntax 3699/* API 4.1.7 shutdown() - TCP Style Syntax
@@ -4168,9 +4234,9 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
4168 if (copy_from_user(&params, optval, len)) 4234 if (copy_from_user(&params, optval, len))
4169 return -EFAULT; 4235 return -EFAULT;
4170 } else if (len == sizeof(struct sctp_assoc_value)) { 4236 } else if (len == sizeof(struct sctp_assoc_value)) {
4171 printk(KERN_WARNING "SCTP: Use of struct sctp_sack_info " 4237 printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
4172 "in delayed_ack socket option deprecated\n"); 4238 "in delayed_ack socket option deprecated\n");
4173 printk(KERN_WARNING "SCTP: struct sctp_sack_info instead\n"); 4239 printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
4174 if (copy_from_user(&params, optval, len)) 4240 if (copy_from_user(&params, optval, len))
4175 return -EFAULT; 4241 return -EFAULT;
4176 } else 4242 } else
@@ -5092,30 +5158,69 @@ static int sctp_getsockopt_context(struct sock *sk, int len,
5092} 5158}
5093 5159
5094/* 5160/*
5095 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) 5161 * 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG)
5096 * 5162 * This option will get or set the maximum size to put in any outgoing
5097 * This socket option specifies the maximum size to put in any outgoing 5163 * SCTP DATA chunk. If a message is larger than this size it will be
5098 * SCTP chunk. If a message is larger than this size it will be
5099 * fragmented by SCTP into the specified size. Note that the underlying 5164 * fragmented by SCTP into the specified size. Note that the underlying
5100 * SCTP implementation may fragment into smaller sized chunks when the 5165 * SCTP implementation may fragment into smaller sized chunks when the
5101 * PMTU of the underlying association is smaller than the value set by 5166 * PMTU of the underlying association is smaller than the value set by
5102 * the user. 5167 * the user. The default value for this option is '0' which indicates
5168 * the user is NOT limiting fragmentation and only the PMTU will effect
5169 * SCTP's choice of DATA chunk size. Note also that values set larger
5170 * than the maximum size of an IP datagram will effectively let SCTP
5171 * control fragmentation (i.e. the same as setting this option to 0).
5172 *
5173 * The following structure is used to access and modify this parameter:
5174 *
5175 * struct sctp_assoc_value {
5176 * sctp_assoc_t assoc_id;
5177 * uint32_t assoc_value;
5178 * };
5179 *
5180 * assoc_id: This parameter is ignored for one-to-one style sockets.
5181 * For one-to-many style sockets this parameter indicates which
5182 * association the user is performing an action upon. Note that if
5183 * this field's value is zero then the endpoints default value is
5184 * changed (effecting future associations only).
5185 * assoc_value: This parameter specifies the maximum size in bytes.
5103 */ 5186 */
5104static int sctp_getsockopt_maxseg(struct sock *sk, int len, 5187static int sctp_getsockopt_maxseg(struct sock *sk, int len,
5105 char __user *optval, int __user *optlen) 5188 char __user *optval, int __user *optlen)
5106{ 5189{
5107 int val; 5190 struct sctp_assoc_value params;
5191 struct sctp_association *asoc;
5108 5192
5109 if (len < sizeof(int)) 5193 if (len == sizeof(int)) {
5194 printk(KERN_WARNING
5195 "SCTP: Use of int in maxseg socket option deprecated\n");
5196 printk(KERN_WARNING
5197 "SCTP: Use struct sctp_assoc_value instead\n");
5198 params.assoc_id = 0;
5199 } else if (len >= sizeof(struct sctp_assoc_value)) {
5200 len = sizeof(struct sctp_assoc_value);
5201 if (copy_from_user(&params, optval, sizeof(params)))
5202 return -EFAULT;
5203 } else
5110 return -EINVAL; 5204 return -EINVAL;
5111 5205
5112 len = sizeof(int); 5206 asoc = sctp_id2assoc(sk, params.assoc_id);
5207 if (!asoc && params.assoc_id && sctp_style(sk, UDP))
5208 return -EINVAL;
5209
5210 if (asoc)
5211 params.assoc_value = asoc->frag_point;
5212 else
5213 params.assoc_value = sctp_sk(sk)->user_frag;
5113 5214
5114 val = sctp_sk(sk)->user_frag;
5115 if (put_user(len, optlen)) 5215 if (put_user(len, optlen))
5116 return -EFAULT; 5216 return -EFAULT;
5117 if (copy_to_user(optval, &val, len)) 5217 if (len == sizeof(int)) {
5118 return -EFAULT; 5218 if (copy_to_user(optval, &params.assoc_value, len))
5219 return -EFAULT;
5220 } else {
5221 if (copy_to_user(optval, &params, len))
5222 return -EFAULT;
5223 }
5119 5224
5120 return 0; 5225 return 0;
5121} 5226}
@@ -5368,6 +5473,38 @@ num:
5368 return 0; 5473 return 0;
5369} 5474}
5370 5475
5476/*
5477 * 8.2.5. Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)
5478 * This option gets the current number of associations that are attached
5479 * to a one-to-many style socket. The option value is an uint32_t.
5480 */
5481static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
5482 char __user *optval, int __user *optlen)
5483{
5484 struct sctp_sock *sp = sctp_sk(sk);
5485 struct sctp_association *asoc;
5486 u32 val = 0;
5487
5488 if (sctp_style(sk, TCP))
5489 return -EOPNOTSUPP;
5490
5491 if (len < sizeof(u32))
5492 return -EINVAL;
5493
5494 len = sizeof(u32);
5495
5496 list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
5497 val++;
5498 }
5499
5500 if (put_user(len, optlen))
5501 return -EFAULT;
5502 if (copy_to_user(optval, &val, len))
5503 return -EFAULT;
5504
5505 return 0;
5506}
5507
5371SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, 5508SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5372 char __user *optval, int __user *optlen) 5509 char __user *optval, int __user *optlen)
5373{ 5510{
@@ -5510,6 +5647,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5510 retval = sctp_getsockopt_local_auth_chunks(sk, len, optval, 5647 retval = sctp_getsockopt_local_auth_chunks(sk, len, optval,
5511 optlen); 5648 optlen);
5512 break; 5649 break;
5650 case SCTP_GET_ASSOC_NUMBER:
5651 retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
5652 break;
5513 default: 5653 default:
5514 retval = -ENOPROTOOPT; 5654 retval = -ENOPROTOOPT;
5515 break; 5655 break;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 52910697e104..f58e994e6852 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -63,8 +63,8 @@ static ctl_table sctp_table[] = {
63 .data = &sctp_rto_initial, 63 .data = &sctp_rto_initial,
64 .maxlen = sizeof(unsigned int), 64 .maxlen = sizeof(unsigned int),
65 .mode = 0644, 65 .mode = 0644,
66 .proc_handler = &proc_dointvec_minmax, 66 .proc_handler = proc_dointvec_minmax,
67 .strategy = &sysctl_intvec, 67 .strategy = sysctl_intvec,
68 .extra1 = &one, 68 .extra1 = &one,
69 .extra2 = &timer_max 69 .extra2 = &timer_max
70 }, 70 },
@@ -74,8 +74,8 @@ static ctl_table sctp_table[] = {
74 .data = &sctp_rto_min, 74 .data = &sctp_rto_min,
75 .maxlen = sizeof(unsigned int), 75 .maxlen = sizeof(unsigned int),
76 .mode = 0644, 76 .mode = 0644,
77 .proc_handler = &proc_dointvec_minmax, 77 .proc_handler = proc_dointvec_minmax,
78 .strategy = &sysctl_intvec, 78 .strategy = sysctl_intvec,
79 .extra1 = &one, 79 .extra1 = &one,
80 .extra2 = &timer_max 80 .extra2 = &timer_max
81 }, 81 },
@@ -85,8 +85,8 @@ static ctl_table sctp_table[] = {
85 .data = &sctp_rto_max, 85 .data = &sctp_rto_max,
86 .maxlen = sizeof(unsigned int), 86 .maxlen = sizeof(unsigned int),
87 .mode = 0644, 87 .mode = 0644,
88 .proc_handler = &proc_dointvec_minmax, 88 .proc_handler = proc_dointvec_minmax,
89 .strategy = &sysctl_intvec, 89 .strategy = sysctl_intvec,
90 .extra1 = &one, 90 .extra1 = &one,
91 .extra2 = &timer_max 91 .extra2 = &timer_max
92 }, 92 },
@@ -96,8 +96,8 @@ static ctl_table sctp_table[] = {
96 .data = &sctp_valid_cookie_life, 96 .data = &sctp_valid_cookie_life,
97 .maxlen = sizeof(unsigned int), 97 .maxlen = sizeof(unsigned int),
98 .mode = 0644, 98 .mode = 0644,
99 .proc_handler = &proc_dointvec_minmax, 99 .proc_handler = proc_dointvec_minmax,
100 .strategy = &sysctl_intvec, 100 .strategy = sysctl_intvec,
101 .extra1 = &one, 101 .extra1 = &one,
102 .extra2 = &timer_max 102 .extra2 = &timer_max
103 }, 103 },
@@ -107,8 +107,8 @@ static ctl_table sctp_table[] = {
107 .data = &sctp_max_burst, 107 .data = &sctp_max_burst,
108 .maxlen = sizeof(int), 108 .maxlen = sizeof(int),
109 .mode = 0644, 109 .mode = 0644,
110 .proc_handler = &proc_dointvec_minmax, 110 .proc_handler = proc_dointvec_minmax,
111 .strategy = &sysctl_intvec, 111 .strategy = sysctl_intvec,
112 .extra1 = &zero, 112 .extra1 = &zero,
113 .extra2 = &int_max 113 .extra2 = &int_max
114 }, 114 },
@@ -118,8 +118,8 @@ static ctl_table sctp_table[] = {
118 .data = &sctp_max_retrans_association, 118 .data = &sctp_max_retrans_association,
119 .maxlen = sizeof(int), 119 .maxlen = sizeof(int),
120 .mode = 0644, 120 .mode = 0644,
121 .proc_handler = &proc_dointvec_minmax, 121 .proc_handler = proc_dointvec_minmax,
122 .strategy = &sysctl_intvec, 122 .strategy = sysctl_intvec,
123 .extra1 = &one, 123 .extra1 = &one,
124 .extra2 = &int_max 124 .extra2 = &int_max
125 }, 125 },
@@ -129,8 +129,8 @@ static ctl_table sctp_table[] = {
129 .data = &sctp_sndbuf_policy, 129 .data = &sctp_sndbuf_policy,
130 .maxlen = sizeof(int), 130 .maxlen = sizeof(int),
131 .mode = 0644, 131 .mode = 0644,
132 .proc_handler = &proc_dointvec, 132 .proc_handler = proc_dointvec,
133 .strategy = &sysctl_intvec 133 .strategy = sysctl_intvec
134 }, 134 },
135 { 135 {
136 .ctl_name = NET_SCTP_RCVBUF_POLICY, 136 .ctl_name = NET_SCTP_RCVBUF_POLICY,
@@ -138,8 +138,8 @@ static ctl_table sctp_table[] = {
138 .data = &sctp_rcvbuf_policy, 138 .data = &sctp_rcvbuf_policy,
139 .maxlen = sizeof(int), 139 .maxlen = sizeof(int),
140 .mode = 0644, 140 .mode = 0644,
141 .proc_handler = &proc_dointvec, 141 .proc_handler = proc_dointvec,
142 .strategy = &sysctl_intvec 142 .strategy = sysctl_intvec
143 }, 143 },
144 { 144 {
145 .ctl_name = NET_SCTP_PATH_MAX_RETRANS, 145 .ctl_name = NET_SCTP_PATH_MAX_RETRANS,
@@ -147,8 +147,8 @@ static ctl_table sctp_table[] = {
147 .data = &sctp_max_retrans_path, 147 .data = &sctp_max_retrans_path,
148 .maxlen = sizeof(int), 148 .maxlen = sizeof(int),
149 .mode = 0644, 149 .mode = 0644,
150 .proc_handler = &proc_dointvec_minmax, 150 .proc_handler = proc_dointvec_minmax,
151 .strategy = &sysctl_intvec, 151 .strategy = sysctl_intvec,
152 .extra1 = &one, 152 .extra1 = &one,
153 .extra2 = &int_max 153 .extra2 = &int_max
154 }, 154 },
@@ -158,8 +158,8 @@ static ctl_table sctp_table[] = {
158 .data = &sctp_max_retrans_init, 158 .data = &sctp_max_retrans_init,
159 .maxlen = sizeof(int), 159 .maxlen = sizeof(int),
160 .mode = 0644, 160 .mode = 0644,
161 .proc_handler = &proc_dointvec_minmax, 161 .proc_handler = proc_dointvec_minmax,
162 .strategy = &sysctl_intvec, 162 .strategy = sysctl_intvec,
163 .extra1 = &one, 163 .extra1 = &one,
164 .extra2 = &int_max 164 .extra2 = &int_max
165 }, 165 },
@@ -169,8 +169,8 @@ static ctl_table sctp_table[] = {
169 .data = &sctp_hb_interval, 169 .data = &sctp_hb_interval,
170 .maxlen = sizeof(unsigned int), 170 .maxlen = sizeof(unsigned int),
171 .mode = 0644, 171 .mode = 0644,
172 .proc_handler = &proc_dointvec_minmax, 172 .proc_handler = proc_dointvec_minmax,
173 .strategy = &sysctl_intvec, 173 .strategy = sysctl_intvec,
174 .extra1 = &one, 174 .extra1 = &one,
175 .extra2 = &timer_max 175 .extra2 = &timer_max
176 }, 176 },
@@ -180,8 +180,8 @@ static ctl_table sctp_table[] = {
180 .data = &sctp_cookie_preserve_enable, 180 .data = &sctp_cookie_preserve_enable,
181 .maxlen = sizeof(int), 181 .maxlen = sizeof(int),
182 .mode = 0644, 182 .mode = 0644,
183 .proc_handler = &proc_dointvec, 183 .proc_handler = proc_dointvec,
184 .strategy = &sysctl_intvec 184 .strategy = sysctl_intvec
185 }, 185 },
186 { 186 {
187 .ctl_name = NET_SCTP_RTO_ALPHA, 187 .ctl_name = NET_SCTP_RTO_ALPHA,
@@ -189,8 +189,8 @@ static ctl_table sctp_table[] = {
189 .data = &sctp_rto_alpha, 189 .data = &sctp_rto_alpha,
190 .maxlen = sizeof(int), 190 .maxlen = sizeof(int),
191 .mode = 0444, 191 .mode = 0444,
192 .proc_handler = &proc_dointvec, 192 .proc_handler = proc_dointvec,
193 .strategy = &sysctl_intvec 193 .strategy = sysctl_intvec
194 }, 194 },
195 { 195 {
196 .ctl_name = NET_SCTP_RTO_BETA, 196 .ctl_name = NET_SCTP_RTO_BETA,
@@ -198,8 +198,8 @@ static ctl_table sctp_table[] = {
198 .data = &sctp_rto_beta, 198 .data = &sctp_rto_beta,
199 .maxlen = sizeof(int), 199 .maxlen = sizeof(int),
200 .mode = 0444, 200 .mode = 0444,
201 .proc_handler = &proc_dointvec, 201 .proc_handler = proc_dointvec,
202 .strategy = &sysctl_intvec 202 .strategy = sysctl_intvec
203 }, 203 },
204 { 204 {
205 .ctl_name = NET_SCTP_ADDIP_ENABLE, 205 .ctl_name = NET_SCTP_ADDIP_ENABLE,
@@ -207,8 +207,8 @@ static ctl_table sctp_table[] = {
207 .data = &sctp_addip_enable, 207 .data = &sctp_addip_enable,
208 .maxlen = sizeof(int), 208 .maxlen = sizeof(int),
209 .mode = 0644, 209 .mode = 0644,
210 .proc_handler = &proc_dointvec, 210 .proc_handler = proc_dointvec,
211 .strategy = &sysctl_intvec 211 .strategy = sysctl_intvec
212 }, 212 },
213 { 213 {
214 .ctl_name = NET_SCTP_PRSCTP_ENABLE, 214 .ctl_name = NET_SCTP_PRSCTP_ENABLE,
@@ -216,8 +216,8 @@ static ctl_table sctp_table[] = {
216 .data = &sctp_prsctp_enable, 216 .data = &sctp_prsctp_enable,
217 .maxlen = sizeof(int), 217 .maxlen = sizeof(int),
218 .mode = 0644, 218 .mode = 0644,
219 .proc_handler = &proc_dointvec, 219 .proc_handler = proc_dointvec,
220 .strategy = &sysctl_intvec 220 .strategy = sysctl_intvec
221 }, 221 },
222 { 222 {
223 .ctl_name = NET_SCTP_SACK_TIMEOUT, 223 .ctl_name = NET_SCTP_SACK_TIMEOUT,
@@ -225,8 +225,8 @@ static ctl_table sctp_table[] = {
225 .data = &sctp_sack_timeout, 225 .data = &sctp_sack_timeout,
226 .maxlen = sizeof(long), 226 .maxlen = sizeof(long),
227 .mode = 0644, 227 .mode = 0644,
228 .proc_handler = &proc_dointvec_minmax, 228 .proc_handler = proc_dointvec_minmax,
229 .strategy = &sysctl_intvec, 229 .strategy = sysctl_intvec,
230 .extra1 = &sack_timer_min, 230 .extra1 = &sack_timer_min,
231 .extra2 = &sack_timer_max, 231 .extra2 = &sack_timer_max,
232 }, 232 },
@@ -236,7 +236,7 @@ static ctl_table sctp_table[] = {
236 .data = &sysctl_sctp_mem, 236 .data = &sysctl_sctp_mem,
237 .maxlen = sizeof(sysctl_sctp_mem), 237 .maxlen = sizeof(sysctl_sctp_mem),
238 .mode = 0644, 238 .mode = 0644,
239 .proc_handler = &proc_dointvec, 239 .proc_handler = proc_dointvec,
240 }, 240 },
241 { 241 {
242 .ctl_name = CTL_UNNUMBERED, 242 .ctl_name = CTL_UNNUMBERED,
@@ -244,7 +244,7 @@ static ctl_table sctp_table[] = {
244 .data = &sysctl_sctp_rmem, 244 .data = &sysctl_sctp_rmem,
245 .maxlen = sizeof(sysctl_sctp_rmem), 245 .maxlen = sizeof(sysctl_sctp_rmem),
246 .mode = 0644, 246 .mode = 0644,
247 .proc_handler = &proc_dointvec, 247 .proc_handler = proc_dointvec,
248 }, 248 },
249 { 249 {
250 .ctl_name = CTL_UNNUMBERED, 250 .ctl_name = CTL_UNNUMBERED,
@@ -252,7 +252,7 @@ static ctl_table sctp_table[] = {
252 .data = &sysctl_sctp_wmem, 252 .data = &sysctl_sctp_wmem,
253 .maxlen = sizeof(sysctl_sctp_wmem), 253 .maxlen = sizeof(sysctl_sctp_wmem),
254 .mode = 0644, 254 .mode = 0644,
255 .proc_handler = &proc_dointvec, 255 .proc_handler = proc_dointvec,
256 }, 256 },
257 { 257 {
258 .ctl_name = CTL_UNNUMBERED, 258 .ctl_name = CTL_UNNUMBERED,
@@ -260,8 +260,8 @@ static ctl_table sctp_table[] = {
260 .data = &sctp_auth_enable, 260 .data = &sctp_auth_enable,
261 .maxlen = sizeof(int), 261 .maxlen = sizeof(int),
262 .mode = 0644, 262 .mode = 0644,
263 .proc_handler = &proc_dointvec, 263 .proc_handler = proc_dointvec,
264 .strategy = &sysctl_intvec 264 .strategy = sysctl_intvec
265 }, 265 },
266 { 266 {
267 .ctl_name = CTL_UNNUMBERED, 267 .ctl_name = CTL_UNNUMBERED,
@@ -269,8 +269,8 @@ static ctl_table sctp_table[] = {
269 .data = &sctp_addip_noauth, 269 .data = &sctp_addip_noauth,
270 .maxlen = sizeof(int), 270 .maxlen = sizeof(int),
271 .mode = 0644, 271 .mode = 0644,
272 .proc_handler = &proc_dointvec, 272 .proc_handler = proc_dointvec,
273 .strategy = &sysctl_intvec 273 .strategy = sysctl_intvec
274 }, 274 },
275 { .ctl_name = 0 } 275 { .ctl_name = 0 }
276}; 276};