aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-05 05:06:47 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-05 05:06:47 -0500
commit508827ff0ac3981d420edac64a70de7f4e304d38 (patch)
treeb0cee8ddef9f0ceab68c388e4ae46b7295eb2cb5 /net/sctp
parent2c3c3d02f28801d7ad2da4952b2c7ca6621ef221 (diff)
parent72e2240f181871675d3a979766330c91d48a1673 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/tokenring/tmspci.c drivers/net/ucc_geth_mii.c
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/protocol.c16
-rw-r--r--net/sctp/sm_sideeffect.c54
-rw-r--r--net/sctp/sm_statefuns.c16
3 files changed, 44 insertions, 42 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index c1e316ee7155..cb198af8887c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -692,15 +692,20 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
692static int sctp_ctl_sock_init(void) 692static int sctp_ctl_sock_init(void)
693{ 693{
694 int err; 694 int err;
695 sa_family_t family; 695 sa_family_t family = PF_INET;
696 696
697 if (sctp_get_pf_specific(PF_INET6)) 697 if (sctp_get_pf_specific(PF_INET6))
698 family = PF_INET6; 698 family = PF_INET6;
699 else
700 family = PF_INET;
701 699
702 err = inet_ctl_sock_create(&sctp_ctl_sock, family, 700 err = inet_ctl_sock_create(&sctp_ctl_sock, family,
703 SOCK_SEQPACKET, IPPROTO_SCTP, &init_net); 701 SOCK_SEQPACKET, IPPROTO_SCTP, &init_net);
702
703 /* If IPv6 socket could not be created, try the IPv4 socket */
704 if (err < 0 && family == PF_INET6)
705 err = inet_ctl_sock_create(&sctp_ctl_sock, AF_INET,
706 SOCK_SEQPACKET, IPPROTO_SCTP,
707 &init_net);
708
704 if (err < 0) { 709 if (err < 0) {
705 printk(KERN_ERR 710 printk(KERN_ERR
706 "SCTP: Failed to create the SCTP control socket.\n"); 711 "SCTP: Failed to create the SCTP control socket.\n");
@@ -1297,9 +1302,8 @@ SCTP_STATIC __init int sctp_init(void)
1297out: 1302out:
1298 return status; 1303 return status;
1299err_v6_add_protocol: 1304err_v6_add_protocol:
1300 sctp_v6_del_protocol();
1301err_add_protocol:
1302 sctp_v4_del_protocol(); 1305 sctp_v4_del_protocol();
1306err_add_protocol:
1303 inet_ctl_sock_destroy(sctp_ctl_sock); 1307 inet_ctl_sock_destroy(sctp_ctl_sock);
1304err_ctl_sock_init: 1308err_ctl_sock_init:
1305 sctp_v6_protosw_exit(); 1309 sctp_v6_protosw_exit();
@@ -1310,7 +1314,6 @@ err_protosw_init:
1310 sctp_v4_pf_exit(); 1314 sctp_v4_pf_exit();
1311 sctp_v6_pf_exit(); 1315 sctp_v6_pf_exit();
1312 sctp_sysctl_unregister(); 1316 sctp_sysctl_unregister();
1313 list_del(&sctp_af_inet.list);
1314 free_pages((unsigned long)sctp_port_hashtable, 1317 free_pages((unsigned long)sctp_port_hashtable,
1315 get_order(sctp_port_hashsize * 1318 get_order(sctp_port_hashsize *
1316 sizeof(struct sctp_bind_hashbucket))); 1319 sizeof(struct sctp_bind_hashbucket)));
@@ -1358,7 +1361,6 @@ SCTP_STATIC __exit void sctp_exit(void)
1358 sctp_v4_pf_exit(); 1361 sctp_v4_pf_exit();
1359 1362
1360 sctp_sysctl_unregister(); 1363 sctp_sysctl_unregister();
1361 list_del(&sctp_af_inet.list);
1362 1364
1363 free_pages((unsigned long)sctp_assoc_hashtable, 1365 free_pages((unsigned long)sctp_assoc_hashtable,
1364 get_order(sctp_assoc_hashsize * 1366 get_order(sctp_assoc_hashsize *
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 5385150df296..e2020eb2c8ca 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -787,36 +787,48 @@ static void sctp_cmd_process_operr(sctp_cmd_seq_t *cmds,
787 struct sctp_association *asoc, 787 struct sctp_association *asoc,
788 struct sctp_chunk *chunk) 788 struct sctp_chunk *chunk)
789{ 789{
790 struct sctp_operr_chunk *operr_chunk;
791 struct sctp_errhdr *err_hdr; 790 struct sctp_errhdr *err_hdr;
791 struct sctp_ulpevent *ev;
792 792
793 operr_chunk = (struct sctp_operr_chunk *)chunk->chunk_hdr; 793 while (chunk->chunk_end > chunk->skb->data) {
794 err_hdr = &operr_chunk->err_hdr; 794 err_hdr = (struct sctp_errhdr *)(chunk->skb->data);
795 795
796 switch (err_hdr->cause) { 796 ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
797 case SCTP_ERROR_UNKNOWN_CHUNK: 797 GFP_ATOMIC);
798 { 798 if (!ev)
799 struct sctp_chunkhdr *unk_chunk_hdr; 799 return;
800 800
801 unk_chunk_hdr = (struct sctp_chunkhdr *)err_hdr->variable; 801 sctp_ulpq_tail_event(&asoc->ulpq, ev);
802 switch (unk_chunk_hdr->type) { 802
803 /* ADDIP 4.1 A9) If the peer responds to an ASCONF with an 803 switch (err_hdr->cause) {
804 * ERROR chunk reporting that it did not recognized the ASCONF 804 case SCTP_ERROR_UNKNOWN_CHUNK:
805 * chunk type, the sender of the ASCONF MUST NOT send any 805 {
806 * further ASCONF chunks and MUST stop its T-4 timer. 806 sctp_chunkhdr_t *unk_chunk_hdr;
807 */ 807
808 case SCTP_CID_ASCONF: 808 unk_chunk_hdr = (sctp_chunkhdr_t *)err_hdr->variable;
809 asoc->peer.asconf_capable = 0; 809 switch (unk_chunk_hdr->type) {
810 sctp_add_cmd_sf(cmds, SCTP_CMD_TIMER_STOP, 810 /* ADDIP 4.1 A9) If the peer responds to an ASCONF with
811 * an ERROR chunk reporting that it did not recognized
812 * the ASCONF chunk type, the sender of the ASCONF MUST
813 * NOT send any further ASCONF chunks and MUST stop its
814 * T-4 timer.
815 */
816 case SCTP_CID_ASCONF:
817 if (asoc->peer.asconf_capable == 0)
818 break;
819
820 asoc->peer.asconf_capable = 0;
821 sctp_add_cmd_sf(cmds, SCTP_CMD_TIMER_STOP,
811 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 822 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
823 break;
824 default:
825 break;
826 }
812 break; 827 break;
828 }
813 default: 829 default:
814 break; 830 break;
815 } 831 }
816 break;
817 }
818 default:
819 break;
820 } 832 }
821} 833}
822 834
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index a907bab0963d..55a61aa69662 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3165,7 +3165,6 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
3165 sctp_cmd_seq_t *commands) 3165 sctp_cmd_seq_t *commands)
3166{ 3166{
3167 struct sctp_chunk *chunk = arg; 3167 struct sctp_chunk *chunk = arg;
3168 struct sctp_ulpevent *ev;
3169 3168
3170 if (!sctp_vtag_verify(chunk, asoc)) 3169 if (!sctp_vtag_verify(chunk, asoc))
3171 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 3170 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -3175,21 +3174,10 @@ sctp_disposition_t sctp_sf_operr_notify(const struct sctp_endpoint *ep,
3175 return sctp_sf_violation_chunklen(ep, asoc, type, arg, 3174 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3176 commands); 3175 commands);
3177 3176
3178 while (chunk->chunk_end > chunk->skb->data) { 3177 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
3179 ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0, 3178 SCTP_CHUNK(chunk));
3180 GFP_ATOMIC);
3181 if (!ev)
3182 goto nomem;
3183 3179
3184 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
3185 SCTP_ULPEVENT(ev));
3186 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_OPERR,
3187 SCTP_CHUNK(chunk));
3188 }
3189 return SCTP_DISPOSITION_CONSUME; 3180 return SCTP_DISPOSITION_CONSUME;
3190
3191nomem:
3192 return SCTP_DISPOSITION_NOMEM;
3193} 3181}
3194 3182
3195/* 3183/*