diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-03-14 07:05:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-14 13:48:27 -0400 |
commit | 30f6ebf65bc46161c5aaff1db2e6e7c76aa4a06b (patch) | |
tree | f5f0ff6a3f3620a169a88efe896a902daea2bb9a | |
parent | ec2e506c680deaa8e1a087986db6d73ba63a04be (diff) |
sctp: add SCTP_AUTH_NO_AUTH type for AUTHENTICATION_EVENT
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>
-rw-r--r-- | include/net/sctp/command.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/sctp.h | 1 | ||||
-rw-r--r-- | net/sctp/sm_sideeffect.c | 13 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 43 |
4 files changed, 56 insertions, 2 deletions
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index b55c6a48a206..6640f84fe536 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -100,6 +100,7 @@ enum sctp_verb { | |||
100 | SCTP_CMD_SET_SK_ERR, /* Set sk_err */ | 100 | SCTP_CMD_SET_SK_ERR, /* Set sk_err */ |
101 | SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ | 101 | SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */ |
102 | SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ | 102 | SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */ |
103 | SCTP_CMD_PEER_NO_AUTH, /* generate and send authentication event */ | ||
103 | SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ | 104 | SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */ |
104 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ | 105 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ |
105 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ | 106 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ |
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h index 18ebbfeee4af..afd4346386e0 100644 --- a/include/uapi/linux/sctp.h +++ b/include/uapi/linux/sctp.h | |||
@@ -522,6 +522,7 @@ enum { | |||
522 | SCTP_AUTH_NEW_KEY, | 522 | SCTP_AUTH_NEW_KEY, |
523 | #define SCTP_AUTH_NEWKEY SCTP_AUTH_NEW_KEY /* compatible with before */ | 523 | #define SCTP_AUTH_NEWKEY SCTP_AUTH_NEW_KEY /* compatible with before */ |
524 | SCTP_AUTH_FREE_KEY, | 524 | SCTP_AUTH_FREE_KEY, |
525 | SCTP_AUTH_NO_AUTH, | ||
525 | }; | 526 | }; |
526 | 527 | ||
527 | /* | 528 | /* |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index b71e7fb0a20a..298112ca8c06 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -1049,6 +1049,16 @@ static void sctp_cmd_assoc_change(struct sctp_cmd_seq *commands, | |||
1049 | asoc->stream.si->enqueue_event(&asoc->ulpq, ev); | 1049 | asoc->stream.si->enqueue_event(&asoc->ulpq, ev); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | static void sctp_cmd_peer_no_auth(struct sctp_cmd_seq *commands, | ||
1053 | struct sctp_association *asoc) | ||
1054 | { | ||
1055 | struct sctp_ulpevent *ev; | ||
1056 | |||
1057 | ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH, GFP_ATOMIC); | ||
1058 | if (ev) | ||
1059 | asoc->stream.si->enqueue_event(&asoc->ulpq, ev); | ||
1060 | } | ||
1061 | |||
1052 | /* Helper function to generate an adaptation indication event */ | 1062 | /* Helper function to generate an adaptation indication event */ |
1053 | static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands, | 1063 | static void sctp_cmd_adaptation_ind(struct sctp_cmd_seq *commands, |
1054 | struct sctp_association *asoc) | 1064 | struct sctp_association *asoc) |
@@ -1755,6 +1765,9 @@ static int sctp_cmd_interpreter(enum sctp_event event_type, | |||
1755 | case SCTP_CMD_ADAPTATION_IND: | 1765 | case SCTP_CMD_ADAPTATION_IND: |
1756 | sctp_cmd_adaptation_ind(commands, asoc); | 1766 | sctp_cmd_adaptation_ind(commands, asoc); |
1757 | break; | 1767 | break; |
1768 | case SCTP_CMD_PEER_NO_AUTH: | ||
1769 | sctp_cmd_peer_no_auth(commands, asoc); | ||
1770 | break; | ||
1758 | 1771 | ||
1759 | case SCTP_CMD_ASSOC_SHKEY: | 1772 | case SCTP_CMD_ASSOC_SHKEY: |
1760 | error = sctp_auth_asoc_init_active_key(asoc, | 1773 | error = sctp_auth_asoc_init_active_key(asoc, |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 1e41dee70b51..cc56a67dbb4d 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -659,7 +659,7 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, | |||
659 | void *arg, | 659 | void *arg, |
660 | struct sctp_cmd_seq *commands) | 660 | struct sctp_cmd_seq *commands) |
661 | { | 661 | { |
662 | struct sctp_ulpevent *ev, *ai_ev = NULL; | 662 | struct sctp_ulpevent *ev, *ai_ev = NULL, *auth_ev = NULL; |
663 | struct sctp_association *new_asoc; | 663 | struct sctp_association *new_asoc; |
664 | struct sctp_init_chunk *peer_init; | 664 | struct sctp_init_chunk *peer_init; |
665 | struct sctp_chunk *chunk = arg; | 665 | struct sctp_chunk *chunk = arg; |
@@ -820,6 +820,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, | |||
820 | goto nomem_aiev; | 820 | goto nomem_aiev; |
821 | } | 821 | } |
822 | 822 | ||
823 | if (!new_asoc->peer.auth_capable) { | ||
824 | auth_ev = sctp_ulpevent_make_authkey(new_asoc, 0, | ||
825 | SCTP_AUTH_NO_AUTH, | ||
826 | GFP_ATOMIC); | ||
827 | if (!auth_ev) | ||
828 | goto nomem_authev; | ||
829 | } | ||
830 | |||
823 | /* Add all the state machine commands now since we've created | 831 | /* Add all the state machine commands now since we've created |
824 | * everything. This way we don't introduce memory corruptions | 832 | * everything. This way we don't introduce memory corruptions |
825 | * during side-effect processing and correclty count established | 833 | * during side-effect processing and correclty count established |
@@ -847,8 +855,14 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, | |||
847 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | 855 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
848 | SCTP_ULPEVENT(ai_ev)); | 856 | SCTP_ULPEVENT(ai_ev)); |
849 | 857 | ||
858 | if (auth_ev) | ||
859 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
860 | SCTP_ULPEVENT(auth_ev)); | ||
861 | |||
850 | return SCTP_DISPOSITION_CONSUME; | 862 | return SCTP_DISPOSITION_CONSUME; |
851 | 863 | ||
864 | nomem_authev: | ||
865 | sctp_ulpevent_free(ai_ev); | ||
852 | nomem_aiev: | 866 | nomem_aiev: |
853 | sctp_ulpevent_free(ev); | 867 | sctp_ulpevent_free(ev); |
854 | nomem_ev: | 868 | nomem_ev: |
@@ -953,6 +967,15 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net, | |||
953 | SCTP_ULPEVENT(ev)); | 967 | SCTP_ULPEVENT(ev)); |
954 | } | 968 | } |
955 | 969 | ||
970 | if (!asoc->peer.auth_capable) { | ||
971 | ev = sctp_ulpevent_make_authkey(asoc, 0, SCTP_AUTH_NO_AUTH, | ||
972 | GFP_ATOMIC); | ||
973 | if (!ev) | ||
974 | goto nomem; | ||
975 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
976 | SCTP_ULPEVENT(ev)); | ||
977 | } | ||
978 | |||
956 | return SCTP_DISPOSITION_CONSUME; | 979 | return SCTP_DISPOSITION_CONSUME; |
957 | nomem: | 980 | nomem: |
958 | return SCTP_DISPOSITION_NOMEM; | 981 | return SCTP_DISPOSITION_NOMEM; |
@@ -1908,6 +1931,9 @@ static enum sctp_disposition sctp_sf_do_dupcook_b( | |||
1908 | if (asoc->peer.adaptation_ind) | 1931 | if (asoc->peer.adaptation_ind) |
1909 | sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL()); | 1932 | sctp_add_cmd_sf(commands, SCTP_CMD_ADAPTATION_IND, SCTP_NULL()); |
1910 | 1933 | ||
1934 | if (!asoc->peer.auth_capable) | ||
1935 | sctp_add_cmd_sf(commands, SCTP_CMD_PEER_NO_AUTH, SCTP_NULL()); | ||
1936 | |||
1911 | return SCTP_DISPOSITION_CONSUME; | 1937 | return SCTP_DISPOSITION_CONSUME; |
1912 | 1938 | ||
1913 | nomem: | 1939 | nomem: |
@@ -1954,7 +1980,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_d( | |||
1954 | struct sctp_cmd_seq *commands, | 1980 | struct sctp_cmd_seq *commands, |
1955 | struct sctp_association *new_asoc) | 1981 | struct sctp_association *new_asoc) |
1956 | { | 1982 | { |
1957 | struct sctp_ulpevent *ev = NULL, *ai_ev = NULL; | 1983 | struct sctp_ulpevent *ev = NULL, *ai_ev = NULL, *auth_ev = NULL; |
1958 | struct sctp_chunk *repl; | 1984 | struct sctp_chunk *repl; |
1959 | 1985 | ||
1960 | /* Clarification from Implementor's Guide: | 1986 | /* Clarification from Implementor's Guide: |
@@ -2001,6 +2027,14 @@ static enum sctp_disposition sctp_sf_do_dupcook_d( | |||
2001 | goto nomem; | 2027 | goto nomem; |
2002 | 2028 | ||
2003 | } | 2029 | } |
2030 | |||
2031 | if (!asoc->peer.auth_capable) { | ||
2032 | auth_ev = sctp_ulpevent_make_authkey(asoc, 0, | ||
2033 | SCTP_AUTH_NO_AUTH, | ||
2034 | GFP_ATOMIC); | ||
2035 | if (!auth_ev) | ||
2036 | goto nomem; | ||
2037 | } | ||
2004 | } | 2038 | } |
2005 | 2039 | ||
2006 | repl = sctp_make_cookie_ack(new_asoc, chunk); | 2040 | repl = sctp_make_cookie_ack(new_asoc, chunk); |
@@ -2015,10 +2049,15 @@ static enum sctp_disposition sctp_sf_do_dupcook_d( | |||
2015 | if (ai_ev) | 2049 | if (ai_ev) |
2016 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | 2050 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, |
2017 | SCTP_ULPEVENT(ai_ev)); | 2051 | SCTP_ULPEVENT(ai_ev)); |
2052 | if (auth_ev) | ||
2053 | sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, | ||
2054 | SCTP_ULPEVENT(auth_ev)); | ||
2018 | 2055 | ||
2019 | return SCTP_DISPOSITION_CONSUME; | 2056 | return SCTP_DISPOSITION_CONSUME; |
2020 | 2057 | ||
2021 | nomem: | 2058 | nomem: |
2059 | if (auth_ev) | ||
2060 | sctp_ulpevent_free(auth_ev); | ||
2022 | if (ai_ev) | 2061 | if (ai_ev) |
2023 | sctp_ulpevent_free(ai_ev); | 2062 | sctp_ulpevent_free(ai_ev); |
2024 | if (ev) | 2063 | if (ev) |