aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 47bc20d3a85b..d344dc481ccc 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -56,6 +56,7 @@
56#include <linux/ipv6.h> 56#include <linux/ipv6.h>
57#include <linux/net.h> 57#include <linux/net.h>
58#include <linux/inet.h> 58#include <linux/inet.h>
59#include <linux/slab.h>
59#include <net/sock.h> 60#include <net/sock.h>
60#include <net/inet_ecn.h> 61#include <net/inet_ecn.h>
61#include <linux/skbuff.h> 62#include <linux/skbuff.h>
@@ -1231,6 +1232,18 @@ out:
1231 return 0; 1232 return 0;
1232} 1233}
1233 1234
1235static bool list_has_sctp_addr(const struct list_head *list,
1236 union sctp_addr *ipaddr)
1237{
1238 struct sctp_transport *addr;
1239
1240 list_for_each_entry(addr, list, transports) {
1241 if (sctp_cmp_addr_exact(ipaddr, &addr->ipaddr))
1242 return true;
1243 }
1244
1245 return false;
1246}
1234/* A restart is occurring, check to make sure no new addresses 1247/* A restart is occurring, check to make sure no new addresses
1235 * are being added as we may be under a takeover attack. 1248 * are being added as we may be under a takeover attack.
1236 */ 1249 */
@@ -1239,10 +1252,10 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
1239 struct sctp_chunk *init, 1252 struct sctp_chunk *init,
1240 sctp_cmd_seq_t *commands) 1253 sctp_cmd_seq_t *commands)
1241{ 1254{
1242 struct sctp_transport *new_addr, *addr; 1255 struct sctp_transport *new_addr;
1243 int found; 1256 int ret = 1;
1244 1257
1245 /* Implementor's Guide - Sectin 5.2.2 1258 /* Implementor's Guide - Section 5.2.2
1246 * ... 1259 * ...
1247 * Before responding the endpoint MUST check to see if the 1260 * Before responding the endpoint MUST check to see if the
1248 * unexpected INIT adds new addresses to the association. If new 1261 * unexpected INIT adds new addresses to the association. If new
@@ -1253,31 +1266,19 @@ static int sctp_sf_check_restart_addrs(const struct sctp_association *new_asoc,
1253 /* Search through all current addresses and make sure 1266 /* Search through all current addresses and make sure
1254 * we aren't adding any new ones. 1267 * we aren't adding any new ones.
1255 */ 1268 */
1256 new_addr = NULL;
1257 found = 0;
1258
1259 list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list, 1269 list_for_each_entry(new_addr, &new_asoc->peer.transport_addr_list,
1260 transports) { 1270 transports) {
1261 found = 0; 1271 if (!list_has_sctp_addr(&asoc->peer.transport_addr_list,
1262 list_for_each_entry(addr, &asoc->peer.transport_addr_list, 1272 &new_addr->ipaddr)) {
1263 transports) { 1273 sctp_sf_send_restart_abort(&new_addr->ipaddr, init,
1264 if (sctp_cmp_addr_exact(&new_addr->ipaddr, 1274 commands);
1265 &addr->ipaddr)) { 1275 ret = 0;
1266 found = 1;
1267 break;
1268 }
1269 }
1270 if (!found)
1271 break; 1276 break;
1272 } 1277 }
1273
1274 /* If a new address was added, ABORT the sender. */
1275 if (!found && new_addr) {
1276 sctp_sf_send_restart_abort(&new_addr->ipaddr, init, commands);
1277 } 1278 }
1278 1279
1279 /* Return success if all addresses were found. */ 1280 /* Return success if all addresses were found. */
1280 return found; 1281 return ret;
1281} 1282}
1282 1283
1283/* Populate the verification/tie tags based on overlapping INIT 1284/* Populate the verification/tie tags based on overlapping INIT
@@ -3675,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3675 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 3676 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
3676 3677
3677 if (!sctp_process_asconf_ack((struct sctp_association *)asoc, 3678 if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
3678 asconf_ack)) 3679 asconf_ack)) {
3680 /* Successfully processed ASCONF_ACK. We can
3681 * release the next asconf if we have one.
3682 */
3683 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF,
3684 SCTP_NULL());
3679 return SCTP_DISPOSITION_CONSUME; 3685 return SCTP_DISPOSITION_CONSUME;
3686 }
3680 3687
3681 abort = sctp_make_abort(asoc, asconf_ack, 3688 abort = sctp_make_abort(asoc, asconf_ack,
3682 sizeof(sctp_errhdr_t)); 3689 sizeof(sctp_errhdr_t));