sctp: add SCTP_AUTH_NO_AUTH type for AUTHENTICATION_EVENT
authorXin Long <lucien.xin@gmail.com>
Wed, 14 Mar 2018 11:05:34 +0000 (19:05 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Mar 2018 17:48:27 +0000 (13:48 -0400)
This patch is to add SCTP_AUTH_NO_AUTH type for AUTHENTICATION_EVENT,
as described in section 6.1.8 of RFC6458.

      SCTP_AUTH_NO_AUTH:  This report indicates that the peer does not
         support SCTP authentication as defined in [RFC4895].

Note that the implementation is quite similar as that of
SCTP_ADAPTATION_INDICATION.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/command.h
include/uapi/linux/sctp.h
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c

index b55c6a48a20696328e918155d310132160f87f64..6640f84fe5368f868e49bfb9ea2c3f94639b4e80 100644 (file)
@@ -100,6 +100,7 @@ enum sctp_verb {
        SCTP_CMD_SET_SK_ERR,     /* Set sk_err */
        SCTP_CMD_ASSOC_CHANGE,   /* generate and send assoc_change event */
        SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
+       SCTP_CMD_PEER_NO_AUTH,   /* generate and send authentication event */
        SCTP_CMD_ASSOC_SHKEY,    /* generate the association shared keys */
        SCTP_CMD_T1_RETRAN,      /* Mark for retransmission after T1 timeout  */
        SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
index 18ebbfeee4af7c5848a679a3e0f6d7a1e4410b56..afd4346386e0ad61df6d22504fd3445290e12c36 100644 (file)
@@ -522,6 +522,7 @@ enum {
        SCTP_AUTH_NEW_KEY,
 #define        SCTP_AUTH_NEWKEY        SCTP_AUTH_NEW_KEY /* compatible with before */
        SCTP_AUTH_FREE_KEY,
+       SCTP_AUTH_NO_AUTH,
 };
 
 /*
index b71e7fb0a20af5f6bb6810e03c44154cd2c2b9f6..298112ca8c069e3bc473e73080c37bbd61253f50 100644 (file)
@@ -1049,6 +1049,16 @@ static void sctp_cmd_assoc_change(struct sctp_cmd_seq *commands,
                asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
 }
 
+static void sctp_cmd_peer_no_auth(struct sctp_cmd_seq *commands,
+                                 struct sctp_association *asoc)
+{
+       struct sctp_ulpevent *ev;
+
+       ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH, GFP_ATOMIC);
+       if (ev)
+               asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
+}
+
 /* Helper function to generate an adaptation indication event */
 static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands,
                                    struct sctp_association *asoc)
@@ -1755,6 +1765,9 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
                case SCTP_CMD_ADAPTATION_IND:
                        sctp_cmd_adaptation_ind(commands, asoc);
                        break;
+               case SCTP_CMD_PEER_NO_AUTH:
+                       sctp_cmd_peer_no_auth(commands, asoc);
+                       break;
 
                case SCTP_CMD_ASSOC_SHKEY:
                        error = sctp_auth_asoc_init_active_key(asoc,
index 1e41dee70b512a9921d504289815af2b2c71cb54..cc56a67dbb4ddf633d2277ca36e8620bf5479fb2 100644 (file)
@@ -659,7 +659,7 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
                                         void *arg,
                                         struct sctp_cmd_seq *commands)
 {
-       struct sctp_ulpevent *ev, *ai_ev = NULL;
+       struct sctp_ulpevent *ev, *ai_ev = NULL, *auth_ev = NULL;
        struct sctp_association *new_asoc;
        struct sctp_init_chunk *peer_init;
        struct sctp_chunk *chunk = arg;
@@ -820,6 +820,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
                        goto nomem_aiev;
        }
 
+       if (!new_asoc->peer.auth_capable) {
+               auth_ev = sctp_ulpevent_make_authkey(new_asoc, 0,
+                                                    SCTP_AUTH_NO_AUTH,
+                                                    GFP_ATOMIC);
+               if (!auth_ev)
+                       goto nomem_authev;
+       }
+
        /* Add all the state machine commands now since we've created
         * everything.  This way we don't introduce memory corruptions
         * during side-effect processing and correclty count established
@@ -847,8 +855,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net,
                sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
                                SCTP_ULPEVENT(ai_ev));
 
+       if (auth_ev)
+               sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
+                               SCTP_ULPEVENT(auth_ev));
+
        return SCTP_DISPOSITION_CONSUME;
 
+nomem_authev:
+       sctp_ulpevent_free(ai_ev);
 nomem_aiev:
        sctp_ulpevent_free(ev);
 nomem_ev:
@@ -953,6 +967,15 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
                                SCTP_ULPEVENT(ev));
        }
 
+       if (!asoc->peer.auth_capable) {
+               ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH,
+                                               GFP_ATOMIC);
+               if (!ev)
+                       goto nomem;
+               sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
+                               SCTP_ULPEVENT(ev));
+       }
+
        return SCTP_DISPOSITION_CONSUME;
 nomem:
        return SCTP_DISPOSITION_NOMEM;
@@ -1908,6 +1931,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_b(
        if (asoc->peer.adaptation_ind)
                sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL());
 
+       if (!asoc->peer.auth_capable)
+               sctp_add_cmd_sf(commands, SCTP_CMD_PEER_NO_AUTH, SCTP_NULL());
+
        return SCTP_DISPOSITION_CONSUME;
 
 nomem:
@@ -1954,7 +1980,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
                                        struct sctp_cmd_seq *commands,
                                        struct sctp_association *new_asoc)
 {
-       struct sctp_ulpevent *ev = NULL, *ai_ev = NULL;
+       struct sctp_ulpevent *ev = NULL, *ai_ev = NULL, *auth_ev = NULL;
        struct sctp_chunk *repl;
 
        /* Clarification from Implementor's Guide:
@@ -2001,6 +2027,14 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
                                goto nomem;
 
                }
+
+               if (!asoc->peer.auth_capable) {
+                       auth_ev = sctp_ulpevent_make_authkey(asoc, 0,
+                                                            SCTP_AUTH_NO_AUTH,
+                                                            GFP_ATOMIC);
+                       if (!auth_ev)
+                               goto nomem;
+               }
        }
 
        repl = sctp_make_cookie_ack(new_asoc, chunk);
@@ -2015,10 +2049,15 @@ static enum sctp_disposition sctp_sf_do_dupcook_d(
        if (ai_ev)
                sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
                                        SCTP_ULPEVENT(ai_ev));
+       if (auth_ev)
+               sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP,
+                               SCTP_ULPEVENT(auth_ev));
 
        return SCTP_DISPOSITION_CONSUME;
 
 nomem:
+       if (auth_ev)
+               sctp_ulpevent_free(auth_ev);
        if (ai_ev)
                sctp_ulpevent_free(ai_ev);
        if (ev)