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)
 {
        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:
                                        !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)) {
                                                  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. */
 
                              &err_chunk)) {
 
                /* This chunk contains fatal error. It is to be discarded.
-                * Send an ABORT, with causes if there is any.
+                * Send an ABORT, with causes.  If there are no causes,
+                * then there wasn't enough memory.  Just terminate
+                * the association.
                 */
                if (err_chunk) {
                        packet = sctp_abort_pkt_new(ep, asoc, arg,
                        } else {
                                error = SCTP_ERROR_NO_RESOURCE;
                        }
-               } else {
-                       sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
-                       error = SCTP_ERROR_INV_PARAM;
                }
 
                /* SCTP-AUTH, Section 6.3: