# Copyright (c) 2021, Dell Inc. or its subsidiaries.  All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# See the LICENSE file for details.
#
# This file is part of NVMe STorage Appliance Services (nvme-stas).

# ==============================================================================
# STorage Appliance Connector Daemon (stacd) - configuration file
#
# In this file, options that are commented represent the default values used.
# Uncommented options override the default value.


[Global]
# tron:        Trace-ON. Enable additional debug info
#              Type:  boolean
#              Range: [false, true]
#tron=false

# hdr-digest:  Protocol Data Unit (PDU) Header Digest. NVMe/TCP facilitates an
#              optional PDU Header digest. Digests are calculated using the
#              CRC32C algorithm.
#              Type:  boolean
#              Range: [false, true]
#hdr-digest=false

# data-digest: Protocol Data Unit (PDU) Data Digest. NVMe/TCP facilitates an
#              optional PDU Data digest. Digests are calculated using the
#              CRC32C algorithm.
#              Type:  boolean
#              Range: [false, true]
#data-digest=false

# kato:        Keep Alive Timeout (KATO): This field specifies the timeout value
#              for the Keep Alive feature in seconds. The default value for this
#              field is 30 seconds (2 minutes).
#              Type:  Unsigned integer
#              Range: 0..N
#              Unit:  Seconds
#kato=30

# ignore-iface: This option controls how connections with I/O Controllers (IOC)
#               are made.
#
#               There is no guarantee that there will be a route to reach that
#               IOC. However, we can use the socket option SO_BINDTODEVICE to
#               force the connection to be made on a specific interface instead
#               of letting the routing tables decide where to make the connection.
#
#               This option determines whether stacd will use SO_BINDTODEVICE to
#               force connections on an interface or just rely on the routing
#               tables. The default is to use SO_BINDTODEVICE, in other words,
#               stacd does not ignore the interface.
#
#               BACKGROUND:
#               By default, stacd will connect to IOCs on the same interface that
#               was used to retrieve the discovery log pages. If stafd discovers
#               a DC on an interface using mDNS, and stafd connects to that DC
#               and retrieves the log pages, it is expected that the storage
#               subsystems listed in the log pages are reachable on the same
#               interface where the DC was discovered.
#
#               For example, let's say a DC is discovered on interface ens102.
#               Then all the subsystems listed in the log pages retrieved from
#               that DC must be reachable on interface ens102. If this doesn't
#               work, for example you cannot "ping -I ens102 [storage-ip]", then
#               the most likely explanation is that arp proxy is not enabled on
#               the switch that the host is connected to on interface ens102.
#               Whatever you do, resist the temptation to manually set up the
#               routing tables or to add alternate routes going over a different
#               interface than the one where the DC is located. That simply
#               won't work. Make sure arp proxy is enabled on the switch first.
#
#               Setting routes won't work because, by default, stacd uses the
#               SO_BINDTODEVICE socket option when it connects to IOCs. This
#               option is used to force a socket connection to be made on a
#               specific interface instead of letting the routing tables decide
#               where to connect the socket. Even if you were to manually
#               configure an alternate route on a different interface, the
#               connections (i.e. host to IOC) will still be made on the
#               interface where the DC was discovered by stafd.
#
#               Type:    boolean
#               Range:   [false, true]
#               Default: true
#ignore-iface=false

# ip-family: With this you can specify whether stacd will support IPv4, IPv6,
#            or both when connecting to I/O Controllers (IOC). stacd will
#            not try to connect to IP addresses (whether they come from the
#            discovery log pages or manually configured with the 'controller'
#            option defined below) if those IP addresses are disabled by this
#            option. stacd will default to "ipv4+ipv6" if an invalid value is
#            specified for this option.
#
#            Type:    String
#            Range:   [ipv4, ipv6, ipv4+ipv6]
#            Default: ipv4+ipv6
#ip-family=ipv4+ipv6

# udev-rule: nvme-cli uses a udev rule to tell udevd to automatically invoke the
#            "nvme connect" command to connect to I/O Controllers (IOC) when an
#            AEN indicating a change of Discovery Log Page Entries (DLPE) is
#            received.
#
#            Using udevd in this way creates a race condition with stafd/stacd
#            that also reacts to AENs by retrieving the DLPEs and connecting to
#            IOCs. This is not a critical issue. It's only annoying because we
#            may get error messages in the syslog as a result of the race
#            condition. However, all connections are successful and stacd will
#            eventually realize that the connections succeeded.
#
#            This parameter allows disabling nvme-cli's udev rule. By doing
#            this, stafd/stacd will now be the only processes responding to AENs
#            indicating a change of DPLEs. Commands such as nvme-cli's
#            "nvme connect-all" will still be functional, but only stafd/stacd
#            (and not udevd) will retrieve the DPLEs and establish IOC
#            connections. The default, enabled, means that nvme-cli's udev rule
#            is enabled and the race condition with stafd/stacd can occur.
#
#            Type:    String
#            Range:   [disabled, enabled]
#            Default: enabled
#udev-rule=enabled

# sticky-connections: Keep existing connections to I/O controllers (IOC).
#
#                     In this text, we use the following definitions:
#                        Manual Config:    Refers to manually adding entries to
#                                          stacd.conf.
#                        Automatic Config: Refers to receiving configuration
#                                          from a Discovery Controller (DC).
#                        External Config:  Refers to configuration done outside
#                                          of the nvme-stas framework, for
#                                          example using nvme-cli commands.
#
#                     There are 3 ways to configure IOC connections on a host:
#
#                     1) Manual Config by adding "controller" entries to the
#                        [Controllers] section (see below).
#
#                     2) Automatic Config received in the form of Discovery Log
#                        Page Entries (DLPE) from a remote DC.
#
#                     3) External Config using nvme-cli (e.g. nvme connect)
#
#                     Zoning and DLPEs:
#                        When retrieving DLPEs from a DC using the Get Log Page
#                        command, the DC will only send DLPEs for IOCs that are
#                        zoned for that host. Changing zoning configuration at a
#                        DC involves adding or removing IOC and/or hosts from a
#                        zone. When zoning configuration is changed, an
#                        Asynchronous Event Notifications (AEN) is sent by the
#                        DC to the host to let it know that the DLPEs have
#                        changed and that the host should retrieve the new DLPEs
#                        with the Get DLP command. The host then uses the DLPEs
#                        to determine which IOC it should connect to.
#
#                     There are 3 ways to remove controller connections to an IOC:
#
#                     1) Manual Config.
#                           A) by adding "blacklist" entries to the
#                              [Controllers] section (see below).
#                           B) by removing "controller" entries from the
#                              [Controllers] section.
#
#                     2) Automatic Config. As explained above, changing zoning
#                        at a DC will result in the host getting a new list of
#                        DLPEs. On DLPE removal, the host should remove the
#                        connection to the IOC matching that DLPE.
#
#                     3) External Config using nvme-cli (e.g. nvme disconnect or
#                        nvme disconnect-all)
#
#                     Some users may prefer for the IOC to be "sticky" and only
#                     be removed manually (nvme-cli or blacklist) or removed by
#                     a system reboot. They don't want for IOCs connection to be
#                     removed unexpectedly on DLPE removal. This is where
#                     sticky-connections comes into play.
#
#                     The configuration parameter "sticky-connections" tells
#                     stacd whether to keep connections to IOC even if their
#                     DPLEs have been removed or a "controller" entry in
#                     stacd.conf has been removed.
#
#                     With sticky-connections=enabled:
#                        IOC connections are not removed automatically with DLPE
#                        or "controller" entry removal. Instead, they can be
#                        removed manually with a nvme-cli command, a blacklist
#                        entry (see below), or a system reboot.
#
#                     With sticky-connections=disabled:
#                        IOC connections are removed automatically with DLPE
#                        or "controller" entry removal.
#
#                        NOTE: This mode implies that nvme-stas will
#                        only allow Manually Configured or Automatically
#                        Configured IOC connections to exist. Externally
#                        Configured connections using nvme-cli that do not match
#                        any Manual Config (stacd.conf) or Automatic Config
#                        (DLPEs) will get deleted immediately by stacd.
#
#                     Type:    String
#                     Range:   [disabled, enabled]
#                     Default: disabled
#sticky-connections=disabled

[Controllers]
# controller: I/O Controllers (IOC) are specified with this keyword.
#
#             Syntax:
#               controller = transport=<trtype>;traddr=<traddr>;trsvcid=<trsvcid>;host-traddr=<traddr>;host-iface=<iface>,nqn=<subnqn>
#
#             transport=<trtype>    [MANDATORY]
#               This field specifies the network fabric being used for a NVMe-over-
#               Fabrics network. Current string values include:
#
#               Value   Definition
#               ------- -----------------------------------------------------------
#               rdma    The network fabric is an rdma network (RoCE, iWARP, Infiniband, basic rdma, etc)
#               fc      The network fabric is a Fibre Channel network.
#               tcp     The network fabric is a TCP/IP network.
#               loop    Connect to a NVMe over Fabrics target on the local host
#
#             traddr=<traddr>       [MANDATORY]
#               This field specifies the network address of the Controller. For
#               transports using IP addressing (e.g. rdma) this should be an IP-
#               based address (ex. IPv4, IPv6). It could also be a resolvable host
#               name (e.g. localhost).
#
#             nqn=<subnqn>          [MANDATORY]
#               This field specifies the Subsystem's NVMe Qualified Name.
#
#             trsvcid=<trsvcid>     [OPTIONAL]
#               This field specifies the transport service id. For transports using
#               IP addressing (e.g. rdma) this field is the port number.
#
#               Depending on the transport type, this field will default to either
#               8009 or 4420 as follows.
#
#               UDP port 4420 and TCP port 4420 have been assigned by IANA
#               for use by NVMe over Fabrics. NVMe/RoCEv2 controllers use UDP port
#               4420 by default. NVMe/iWARP controllers use TCP port 4420 by
#               default.
#
#               TCP port 4420 has been assigned for use by NVMe over Fabrics and TCP
#               port 8009 has been assigned by IANA for use by NVMe over Fabrics
#               discovery. TCP port 8009 is the default TCP port for NVMe/TCP
#               discovery controllers. There is no default TCP port for NVMe/TCP I/O
#               controllers, the Transport Service Identifier (TRSVCID) field in the
#               Discovery Log Entry indicates the TCP port to use.
#
#               The TCP ports that may be used for NVMe/TCP I/O controllers include
#               TCP port 4420, and the Dynamic and/or Private TCP ports (i.e., ports
#               in the TCP port number range from 49152 to 65535). NVMe/TCP I/O
#               controllers should not use TCP port 8009. TCP port 4420 shall not be
#               used for both NVMe/iWARP and NVMe/TCP at the same IP address on the
#               same network.
#
#             host-traddr=<traddr>  [OPTIONAL]
#               This field specifies the network address used on the host to connect
#               to the Controller. For TCP, this sets the source address on the
#               socket.
#
#             host-iface=<iface>    [OPTIONAL]
#               This field specifies the network interface used on the host to
#               connect to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da).
#               This forces the connection to be made on a specific interface
#               instead of letting the system decide.
#
#             Multiple DCs may be specified on separate lines like this (this is
#             just an example and does not represent default values):
#
#             controller = transport=tcp;traddr=localhost;nqn=nqn.1988-11.com.dell:PowerSANxxx:01:20210225100113-454f73093ceb4847a7bdfc6e34ae8e28
#             controller = transport=tcp;traddr=[2001:db8:::370:7334];host-iface=enp0s8;nqn=nqn.starship-enterprise
#             controller = transport=fc;traddr=nn-0x204600a098cbcac6:pn-0x204700a098cbcac6;nqn=nqn.romulan-empire
#                 ...
#             Type: String
#
#             Default: There is no default controller. STAC will not try to
#                      connect to a default I/O Controller.
#controller=


# blacklist: Blacklisted controllers. This keyword allows configuring I/O
#            controllers that should not be connected to (whatever the
#            reason may be).
#
#            The syntax is the same as for "controller", except that the key
#            host-traddr does not apply. Multiple "blacklist" keywords may
#            appear in the config file to specify more than 1 blacklisted
#            controller.
#
#            Note 1: A minimal match approach is used to eliminate unwanted
#            controllers. That is, you do not need to specify all the
#            parameters to identify a controller. Just specifying the
#            host-iface, for example, can be used to blacklist all controllers
#            on an interface.
#
#            Note 2: "blacklist" takes precedence over "controller". A
#            controller specified by the "controller" keyword, can be
#            eliminated by the "blacklist" keyword.
#
#            Syntax: Same as "controller" above.
#            Type:   String
#
#            Example:
#             blacklist = transport=tcp;traddr=fe80::2c6e:dee7:857:26bb # Eliminate a specific address
#             blacklist = host-iface=enp0s8                             # Eliminate everything on this interface
#blacklist=
