]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
sctp: add pf_expose per netns and sock and asoc
authorXin Long <lucien.xin@gmail.com>
Fri, 8 Nov 2019 05:20:32 +0000 (13:20 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Nov 2019 22:18:32 +0000 (14:18 -0800)
As said in rfc7829, section 3, point 12:

  The SCTP stack SHOULD expose the PF state of its destination
  addresses to the ULP as well as provide the means to notify the
  ULP of state transitions of its destination addresses from
  active to PF, and vice versa.  However, it is recommended that
  an SCTP stack implementing SCTP-PF also allows for the ULP to be
  kept ignorant of the PF state of its destinations and the
  associated state transitions, thus allowing for retention of the
  simpler state transition model of [RFC4960] in the ULP.

Not only does it allow to expose the PF state to ULP, but also
allow to ignore sctp-pf to ULP.

So this patch is to add pf_expose per netns, sock and asoc. And in
sctp_assoc_control_transport(), ulp_notify will be set to false if
asoc->expose is not 'enabled' in next patch.

It also allows a user to change pf_expose per netns by sysctl, and
pf_expose per sock and asoc will be initialized with it.

Note that pf_expose also works for SCTP_GET_PEER_ADDR_INFO sockopt,
to not allow a user to query the state of a sctp-pf peer address
when pf_expose is 'disabled', as said in section 7.3.

v1->v2:
  - Fix a build warning noticed by Nathan Chancellor.
v2->v3:
  - set pf_expose to UNUSED by default to keep compatible with old
    applications.
v3->v4:
  - add a new entry for pf_expose on ip-sysctl.txt, as Marcelo suggested.
  - change this patch to 1/5, and move sctp_assoc_control_transport
    change into 2/5, as Marcelo suggested.
  - use SCTP_PF_EXPOSE_UNSET instead of SCTP_PF_EXPOSE_UNUSED, and
    set SCTP_PF_EXPOSE_UNSET to 0 in enum, as Marcelo suggested.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/ip-sysctl.txt
include/net/netns/sctp.h
include/net/sctp/constants.h
include/net/sctp/structs.h
include/uapi/linux/sctp.h
net/sctp/associola.c
net/sctp/protocol.c
net/sctp/socket.c
net/sctp/sysctl.c

index 8d4ad1d1ae26f11ffe0ff1db61c61f20b573b8b8..0b0feb5b6b0096d1f0d5d8d23a4fbc1f2e3fcae1 100644 (file)
@@ -2091,6 +2091,28 @@ pf_enable - INTEGER
 
        Default: 1
 
+pf_expose - INTEGER
+       Unset or enable/disable pf (pf is short for potentially failed) state
+       exposure.  Applications can control the exposure of the PF path state
+       in the SCTP_PEER_ADDR_CHANGE event and the SCTP_GET_PEER_ADDR_INFO
+       sockopt.   When it's unset, no SCTP_PEER_ADDR_CHANGE event with
+       SCTP_ADDR_PF state will be sent and a SCTP_PF-state transport info
+       can be got via SCTP_GET_PEER_ADDR_INFO sockopt;  When it's enabled,
+       a SCTP_PEER_ADDR_CHANGE event will be sent for a transport becoming
+       SCTP_PF state and a SCTP_PF-state transport info can be got via
+       SCTP_GET_PEER_ADDR_INFO sockopt;  When it's diabled, no
+       SCTP_PEER_ADDR_CHANGE event will be sent and it returns -EACCES when
+       trying to get a SCTP_PF-state transport info via SCTP_GET_PEER_ADDR_INFO
+       sockopt.
+
+       0: Unset pf state exposure, Compatible with old applications.
+
+       1: Disable pf state exposure.
+
+       2: Enable pf state exposure.
+
+       Default: 0
+
 addip_noauth_enable - BOOLEAN
        Dynamic Address Reconfiguration (ADD-IP) requires the use of
        authentication to protect the operations of adding or removing new
index bdc0f27b85140bedade19fe90de20ef203e5f996..18c3ddae77a3b0d9552acea24ca2eba0a7f56a90 100644 (file)
@@ -96,6 +96,14 @@ struct netns_sctp {
         */
        int pf_enable;
 
+       /*
+        * Disable Potentially-Failed state exposure, ignored by default
+        * pf_expose    -  0  : compatible with old applications (by default)
+        *              -  1  : disable pf state exposure
+        *              -  2  : enable  pf state exposure
+        */
+       int pf_expose;
+
        /*
         * Policy for preforming sctp/socket accounting
         * 0   - do socket level accounting, all assocs share sk_sndbuf
index 823afc42a3aa1b8e572664b7feaad43adbb26084..e88b77a34cb1ef73bcd5e23eabcaa5d382300f20 100644 (file)
@@ -286,6 +286,16 @@ enum { SCTP_MAX_GABS = 16 };
                                 * functions simpler to write.
                                 */
 
+/* These are the values for pf exposure, UNUSED is to keep compatible with old
+ * applications by default.
+ */
+enum {
+       SCTP_PF_EXPOSE_UNSET,
+       SCTP_PF_EXPOSE_DISABLE,
+       SCTP_PF_EXPOSE_ENABLE,
+};
+#define SCTP_PF_EXPOSE_MAX     SCTP_PF_EXPOSE_ENABLE
+
 /* These return values describe the success or failure of a number of
  * routines which form the lower interface to SCTP_outqueue.
  */
index 503fbc3cd819948ef516a00297f77016414457c4..9a43738774d739f1b29f083f453342afcfe2320f 100644 (file)
@@ -215,6 +215,7 @@ struct sctp_sock {
        __u32 adaptation_ind;
        __u32 pd_point;
        __u16   nodelay:1,
+               pf_expose:2,
                reuse:1,
                disable_fragments:1,
                v4mapped:1,
@@ -2053,6 +2054,7 @@ struct sctp_association {
 
        __u8 need_ecne:1,       /* Need to send an ECNE Chunk? */
             temp:1,            /* Is it a temporary association? */
+            pf_expose:2,       /* Expose pf state? */
             force_delay:1;
 
        __u8 strreset_enable;
index 6bce7f9837a9a0ac1ee37fffd38c3f0c899f397f..765f41a080b42e78d0c2360a87eb504a9b176705 100644 (file)
@@ -933,6 +933,7 @@ struct sctp_paddrinfo {
 enum sctp_spinfo_state {
        SCTP_INACTIVE,
        SCTP_PF,
+#define        SCTP_POTENTIALLY_FAILED         SCTP_PF
        SCTP_ACTIVE,
        SCTP_UNCONFIRMED,
        SCTP_UNKNOWN = 0xffff  /* Value used for transport state unknown */
index 1b9809ad772528b3596efc9ae96780dbc70f7cc2..3bf3380a552167237c1a7f4d1dc4c00586bc0626 100644 (file)
@@ -86,6 +86,7 @@ static struct sctp_association *sctp_association_init(
         */
        asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt;
        asoc->pf_retrans  = sp->pf_retrans;
+       asoc->pf_expose   = sp->pf_expose;
 
        asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial);
        asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max);
index 08d14d86ecfb0c6c4e1761d1115d1622be02adfe..f86be7bf09725c41abc8580f4604f70f7d51d76b 100644 (file)
@@ -1220,6 +1220,9 @@ static int __net_init sctp_defaults_init(struct net *net)
        /* Enable pf state by default */
        net->sctp.pf_enable = 1;
 
+       /* Ignore pf exposure feature by default */
+       net->sctp.pf_expose = SCTP_PF_EXPOSE_UNSET;
+
        /* Association.Max.Retrans  - 10 attempts
         * Path.Max.Retrans         - 5  attempts (per destination address)
         * Max.Init.Retransmits     - 8  attempts
index 53abb97e0061c14fd4a9c3090a4a5cbe0af9c5a9..318222e9c0a89bd354c6b8e5b5271f0b98143e7a 100644 (file)
@@ -5041,6 +5041,7 @@ static int sctp_init_sock(struct sock *sk)
        sp->hbinterval  = net->sctp.hb_interval;
        sp->pathmaxrxt  = net->sctp.max_retrans_path;
        sp->pf_retrans  = net->sctp.pf_retrans;
+       sp->pf_expose   = net->sctp.pf_expose;
        sp->pathmtu     = 0; /* allow default discovery */
        sp->sackdelay   = net->sctp.sack_timeout;
        sp->sackfreq    = 2;
@@ -5521,8 +5522,16 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
 
        transport = sctp_addr_id2transport(sk, &pinfo.spinfo_address,
                                           pinfo.spinfo_assoc_id);
-       if (!transport)
-               return -EINVAL;
+       if (!transport) {
+               retval = -EINVAL;
+               goto out;
+       }
+
+       if (transport->state == SCTP_PF &&
+           transport->asoc->pf_expose == SCTP_PF_EXPOSE_DISABLE) {
+               retval = -EACCES;
+               goto out;
+       }
 
        pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc);
        pinfo.spinfo_state = transport->state;
index 238cf1737576ae2c9358cf94f0be5ccb23ace73a..5d1ad44a29d1da6143b2b6872cd754de75187eb4 100644 (file)
@@ -34,6 +34,7 @@ static int rto_alpha_min = 0;
 static int rto_beta_min = 0;
 static int rto_alpha_max = 1000;
 static int rto_beta_max = 1000;
+static int pf_expose_max = SCTP_PF_EXPOSE_MAX;
 
 static unsigned long max_autoclose_min = 0;
 static unsigned long max_autoclose_max =
@@ -318,6 +319,15 @@ static struct ctl_table sctp_net_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "pf_expose",
+               .data           = &init_net.sctp.pf_expose,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = &pf_expose_max,
+       },
 
        { /* sentinel */ }
 };