0x01
  "   ˆl–ßi~”*j"Tâ€fà¸TÅ£Êƒh¹¿Ç      MAJOR=10
MINOR=123
DEVNAME=kcare
  1   ˆl—ßi~”d
e¶¥8 ¸ÛwyLZ7ÿËƒ} ‡_ŒuÐb&=LyYÿÁÉ $Ã    #!/usr/bin/sh
#
# Supported formats:
# rd.nvmf.hostnqn=<hostnqn>
# rd.nvmf.hostid=<hostid>
# rd.nvmf.discover=<transport>,<traddr>,<host-traddr>,<trsvcid>
#
# Examples:
# rd.nvmf.hostnqn=nqn.2014-08.org.nvmexpress:uuid:37303738-3034-584d-5137-333230423843
# rd.nvmf.discover=rdma,192.168.1.3,,4420
# rd.nvmf.discover=tcp,192.168.1.3,,4420
# rd.nvmf.discover=tcp,192.168.1.3
# rd.nvmf.discover=fc,nn-0x200400a098d85236:pn-0x201400a098d85236,nn-0x200000109b7db455:pn-0x100000109b7db455
# rd.nvmf.discover=fc,auto
#
# Note: FC does autodiscovery, so typically there is no need to
# specify any discover parameters for FC.
#

command -v getarg > /dev/null || . /lib/dracut-lib.sh
command -v is_ip > /dev/null || . /lib/net-lib.sh

## Sample NBFT output from nvme show-nbft -H -s -d -o json
# [
#   {
#     "filename":"/sys/firmware/acpi/tables/NBFT",
#     "host":{
#       "nqn":"nqn.2014-08.org.nvmexpress:uuid:d6f07002-7eb5-4841-a185-400e296afae4",
#       "id":"111919da-21ea-cc4e-bafe-216d8372dd31",
#       "host_id_configured":0,
#       "host_nqn_configured":0,
#       "primary_admin_host_flag":"not indicated"
#     },
#     "subsystem":[
#       {
#         "index":1,
#         "num_hfis":1,
#         "hfis":[
#           1
#         ],
#         "transport":"tcp",
#         "transport_address":"192.168.100.216",
#         "transport_svcid":"4420",
#         "subsys_port_id":0,
#         "nsid":1,
#         "nid_type":"uuid",
#         "nid":"424d1c8a-8ef9-4681-b2fc-8c343bd8fa69",
#         "subsys_nqn":"timberland-01",
#         "controller_id":0,
#         "asqsz":0,
#         "pdu_header_digest_required":0,
#         "data_digest_required":0
#       }
#     ],
#     "hfi":[
#       {
#         "index":1,
#         "transport":"tcp",
#         "pcidev":"0:0:2.0",
#         "mac_addr":"52:54:00:4f:97:e9",
#         "vlan":0,
#         "ip_origin":63,
#         "ipaddr":"192.168.100.217",
#         "subnet_mask_prefix":24,
#         "gateway_ipaddr":"0.0.0.0",
#         "route_metric":0,
#         "primary_dns_ipaddr":"0.0.0.0",
#         "secondary_dns_ipaddr":"0.0.0.0",
#         "dhcp_server_ipaddr":"",
#         "this_hfi_is_default_route":1
#       }
#     ],
#     "discovery":[
#     ]
#   }
# ]
#
# If the IP address is derived from DHCP, it sets the field
# "hfi.dhcp_server_ipaddr" to a non-emtpy value.
#
#

nbft_run_jq() {
    local st
    local opts="-e"

    while [ $# -gt 0 ]; do
        case $1 in
            -*)
                opts="$opts $1"
                ;;
            *)
                break
                ;;
        esac
        shift
    done
    # Not quoting is intentional here. We won't get glob expressions passed.
    # shellcheck disable=SC2086
    jq $opts "$1" << EOF
$2
EOF
    st=$?
    if [ $st -ne 0 ]; then
        warn "NBFT: jq error while processing \"$1\""
        return $st
    else
        return 0
    fi
}

nbft_check_empty_address() {
    # suppress meaningless or empty IP addresses
    # "null" is returned by jq if no match found for expression
    case $1 in
        null | "::" | "0.0.0.0") ;;
        *)
            echo "$1"
            ;;
    esac
}

nbft_parse_hfi() {
    # false positive of shellcheck - no expansion in variable assignments
    # shellcheck disable=2086
    local hfi_json=$1
    local mac iface ipaddr prefix vlan gateway dns1 dns2 hostname adrfam dhcp

    mac=$(nbft_run_jq -r .mac_addr "$hfi_json") || return 1
    iface=$(set_ifname nbft "$mac")

    vlan=$(nbft_run_jq .vlan "$hfi_json") || vlan=0
    # treat VLAN zero as "no vlan"
    [ "$vlan" -ne 0 ] || vlan=

    [ ! -e /tmp/net."${iface}${vlan:+.$vlan}".has_ibft_config ] || return 0

    dhcp=$(nbft_run_jq -r .dhcp_server_ipaddr "$hfi_json")
    # We need to check $? here as the above is an assignment
    # shellcheck disable=2181
    if [ $? -eq 0 ] && [ "$dhcp" ] && [ "$dhcp" != null ]; then
        case $dhcp in
            *:*)
                echo ip="$if