diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/ipv6.c | 5 | ||||
-rw-r--r-- | net/sctp/outqueue.c | 3 | ||||
-rw-r--r-- | net/sctp/protocol.c | 4 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 29 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 3 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 23 | ||||
-rw-r--r-- | net/sctp/socket.c | 5 | ||||
-rw-r--r-- | net/sctp/ulpevent.c | 2 |
8 files changed, 63 insertions, 11 deletions
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; | ||
2062 | fallthrough: | 2085 | fallthrough: |
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 | } |