X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fsctp%2Fsm_make_chunk.c;h=e45be4e3f80d733c8f3eb27773651ad1a4d44add;hb=7524d7d6de5d5d3f081de8cf5479819fad339661;hp=7fd6a6b686144c31c7246601906c83845919581b;hpb=a08de64d074b36a56ee3bb985cd171281db78e96;p=linux-2.6 diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 7fd6a6b686..e45be4e3f8 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -1,22 +1,22 @@ -/* SCTP kernel reference Implementation +/* SCTP kernel implementation * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2002 Intel Corp. * - * This file is part of the SCTP kernel reference Implementation + * This file is part of the SCTP kernel implementation * * These functions work with the state functions in sctp_sm_statefuns.c * to implement the state operations. These functions implement the * steps which require modifying existing data structures. * - * The SCTP reference implementation is free software; + * This SCTP implementation is free software; * you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * - * The SCTP reference implementation is distributed in the hope that it + * This SCTP implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -1692,8 +1692,8 @@ no_hmac: /* Also, add the destination address. */ if (list_empty(&retval->base.bind_addr.address_list)) { - sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1, - GFP_ATOMIC); + sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, + SCTP_ADDR_SRC, GFP_ATOMIC); } retval->next_tsn = retval->c.initial_tsn; @@ -1836,6 +1836,39 @@ static int sctp_process_hn_param(const struct sctp_association *asoc, return 0; } +static int sctp_verify_ext_param(union sctp_params param) +{ + __u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t); + int have_auth = 0; + int have_asconf = 0; + int i; + + for (i = 0; i < num_ext; i++) { + switch (param.ext->chunks[i]) { + case SCTP_CID_AUTH: + have_auth = 1; + break; + case SCTP_CID_ASCONF: + case SCTP_CID_ASCONF_ACK: + have_asconf = 1; + break; + } + } + + /* ADD-IP Security: The draft requires us to ABORT or ignore the + * INIT/INIT-ACK if ADD-IP is listed, but AUTH is not. Do this + * only if ADD-IP is turned on and we are not backward-compatible + * mode. + */ + if (sctp_addip_noauth) + return 1; + + if (sctp_addip_enable && !have_auth && have_asconf) + return 0; + + return 1; +} + static void sctp_process_ext_param(struct sctp_association *asoc, union sctp_params param) { @@ -1966,7 +1999,11 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc, case SCTP_PARAM_UNRECOGNIZED_PARAMETERS: case SCTP_PARAM_ECN_CAPABLE: case SCTP_PARAM_ADAPTATION_LAYER_IND: + break; + case SCTP_PARAM_SUPPORTED_EXT: + if (!sctp_verify_ext_param(param)) + return SCTP_IERROR_ABORT; break; case SCTP_PARAM_SET_PRIMARY: @@ -2019,7 +2056,7 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc, break; case SCTP_PARAM_HMAC_ALGO: - if (!sctp_auth_enable) + if (sctp_auth_enable) break; /* Fall Through */ fallthrough: @@ -2139,10 +2176,11 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, !asoc->peer.peer_hmacs)) asoc->peer.auth_capable = 0; - - /* If the peer claims support for ADD-IP without support - * for AUTH, disable support for ADD-IP. - * Do this only if backward compatible mode is turned off. + /* In a non-backward compatible mode, if the peer claims + * support for ADD-IP but not AUTH, the ADD-IP spec states + * that we MUST ABORT the association. Section 6. The section + * also give us an option to silently ignore the packet, which + * is what we'll do here. */ if (!sctp_addip_noauth && (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) { @@ -2150,6 +2188,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, SCTP_PARAM_DEL_IP | SCTP_PARAM_SET_PRIMARY); asoc->peer.asconf_capable = 0; + goto clean_up; } /* Walk list of transports, removing transports in the UNKNOWN state. */ @@ -3016,7 +3055,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, local_bh_disable(); list_for_each_entry(saddr, &bp->address_list, list) { if (sctp_cmp_addr_exact(&saddr->a, &addr)) - saddr->use_as_src = 1; + saddr->state = SCTP_ADDR_SRC; } local_bh_enable(); break; @@ -3185,6 +3224,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, } /* Free the cached last sent asconf chunk. */ + list_del_init(&asconf->transmitted_list); sctp_chunk_free(asconf); asoc->addip_last_asconf = NULL;