[ovs-dev] [PATCH v3 2/2] ovn-northd: Add logical flows to support native DNS

Guru Shetty guru at ovn.org
Wed Mar 29 18:17:28 UTC 2017


>
>
>
> Agree. It was in my mind. I somehow missed it out.
>
>
>>
>> The above would mean that for each logical port, we need to create a DNS
>> record in the DNS table. Having the schema like the above has advantages.
>> In the future, if we have to add new options for DNS, then it becomes
>> easier to extend this.  Do you foresee anything?
>>
>
> I don't foresee any new thing to be added.
>
>
>>
>> The disadvantage is that for each logical port (or a VIP), you should now
>> create a new record in DNS table and then link it to all the logical
>> switches in the logical topology.
>>
>>
> Agree. It results in more work for CMS as it has to manage all this.
>
>
>
>> An alternate schema would be to have a single DNS record for the logical
>> topology. i.e have a "record" column which is a map of hostname and
>> addresses. With this, whenever a new logical port (or a VIP in
>> load-balancer) is created, you just add the hostname and addresses to the
>> existing DNS "record" instead of creating a new DNS entry in the table and
>> linking it all the logical switches in the topology.
>>
>> Do you have any opinion? Is one easier than the other for OpenStack?
>>
>>
> The reason I chose to have one DNS record for each logical port as
>  - It almost directly maps to the DNS table in the SB DB (proposed table
> in patch 1)
>  - the code in ovn-northd would be much simpler at the cost of CMS
> managing this. I think with the external_ids column, CMS should be able to
> manage this.
>  - Syncing the NB DNS entries with SB DNS entries would be easier.
>
> I personally prefer this approach as it is easier for ovn-northd. But if
> you think it would be more work for CMS or there are unnecessary ovsdb
> operations/overhead in having one DNS record per port, I am happy to do the
> changes as per your suggestions here:).  Let me know.
>

I had a discussion with Ben talking about pros and cons. We agreed that, we
should have the option of having the single DNS record for the entire
logical topology.

PS: Now, if someone prefers to have multiple DNS entries (i.e one each for
a logical port), they can still do it by simply linking to multiple DNS
records. It is just that with a 'map' in the schema, we can either have
just one or multiple inside the same DNS record.





>
> Thanks
> Numan
>
>
>
>
>>
>>
>>
>>
>>
>>>          "SSL": {
>>>              "columns": {
>>>                  "private_key": {"type": "string"},
>>> diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
>>> index 46a25f6..e17fdf6 100644
>>> --- a/ovn/ovn-nb.xml
>>> +++ b/ovn/ovn-nb.xml
>>> @@ -134,6 +134,11 @@
>>>        QOS marking rules that apply to packets within the logical switch.
>>>      </column>
>>>
>>> +    <column name="dns_lookups">
>>> +      DNS entries to look up for the DNS packets within the logical
>>> switch
>>> +      by the native DNS resolver.
>>> +    </column>
>>> +
>>>      <group title="other_config">
>>>        <p>
>>>          Additional configuration options for the logical switch.
>>> @@ -1888,6 +1893,20 @@
>>>        <column name="other_config"/>
>>>      </group>
>>>    </table>
>>> +  <table name="DNS" title="Native DNS resolution">
>>> +    <p>
>>> +      A DNS look up entry with in a Logical switch.
>>> +    </p>
>>> +
>>> +    <column name="hostname">
>>> +      The host name to be searched.
>>> +    </column>
>>> +
>>> +    <column name="ip_addresses">
>>> +      The IP addresses to include in the DNS answer fields if the
>>> +      <ref column="hostname"/> matches in the DNS query.
>>> +    </column>
>>> +  </table>
>>>    <table name="SSL">
>>>      SSL configuration for ovn-nb database access.
>>>
>>> @@ -1926,5 +1945,4 @@
>>>        <column name="external_ids"/>
>>>      </group>
>>>    </table>
>>> -
>>>  </database>
>>> diff --git a/ovn/utilities/ovn-nbctl.c b/ovn/utilities/ovn-nbctl.c
>>> index 900b088..abdc616 100644
>>> --- a/ovn/utilities/ovn-nbctl.c
>>> +++ b/ovn/utilities/ovn-nbctl.c
>>> @@ -3048,6 +3048,9 @@ static const struct ctl_table_class
>>> tables[NBREC_N_TABLES] = {
>>>
>>>      [NBREC_TABLE_SSL].row_ids[0]
>>>      = {&nbrec_table_nb_global, NULL, &nbrec_nb_global_col_ssl},
>>> +
>>> +    [NBREC_TABLE_DNS].row_ids[0]
>>> +    = {&nbrec_table_dns, NULL, &nbrec_dns_col_hostname},
>>>  };
>>>
>>>  static void
>>> diff --git a/tests/ovn.at b/tests/ovn.at
>>> index 4b4beb0..3df2e51 100644
>>> --- a/tests/ovn.at
>>> +++ b/tests/ovn.at
>>> @@ -6334,6 +6334,359 @@ OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>>
>>>  AT_CLEANUP
>>>
>>> +AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
>>> +AT_SKIP_IF([test $HAVE_PYTHON = no])
>>> +ovn_start
>>> +
>>> +ovn-nbctl ls-add ls1
>>> +
>>> +ovn-nbctl lsp-add ls1 ls1-lp1 \
>>> +-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
>>> +
>>> +ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4
>>> aef0::4"
>>> +
>>> +ovn-nbctl lsp-add ls1 ls1-lp2 \
>>> +-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
>>> +
>>> +ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6
>>> 20.0.0.4"
>>> +
>>> +LP1_DNS=`ovn-nbctl create DNS hostname=vm1.ovn.org \
>>> +ip_addresses="10.0.0.4 aef0\:\:4"`
>>> +
>>> +LP2_DNS=`ovn-nbctl create DNS hostname=vm2.ovn.org \
>>> +ip_addresses="10.0.0.6 20.0.0.4"`
>>> +
>>> +ovn-nbctl add Logical_switch ls1 dns_lookups "$LP1_DNS $LP2_DNS"
>>> +
>>> +net_add n1
>>> +sim_add hv1
>>> +
>>> +as hv1
>>> +ovs-vsctl add-br br-phys
>>> +ovn_attach n1 br-phys 192.168.0.1
>>> +ovs-vsctl -- add-port br-int hv1-vif1 -- \
>>> +    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
>>> +    options:tx_pcap=hv1/vif1-tx.pcap \
>>> +    options:rxq_pcap=hv1/vif1-rx.pcap \
>>> +    ofport-request=1
>>> +
>>> +ovs-vsctl -- add-port br-int hv1-vif2 -- \
>>> +    set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
>>> +    options:tx_pcap=hv1/vif2-tx.pcap \
>>> +    options:rxq_pcap=hv1/vif2-rx.pcap \
>>> +    ofport-request=2
>>> +
>>> +ovn_populate_arp
>>> +sleep 2
>>> +as hv1 ovs-vsctl show
>>> +
>>> +echo "*************************"
>>> +ovn-sbctl list DNS
>>> +echo "*************************"
>>> +
>>> +ip_to_hex() {
>>> +    printf "%02x%02x%02x%02x" "$@"
>>> +}
>>> +
>>> +reset_pcap_file() {
>>> +    local iface=$1
>>> +    local pcap_file=$2
>>> +    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
>>> +options:rxq_pcap=dummy-rx.pcap
>>> +    rm -f ${pcap_file}*.pcap
>>> +    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap
>>> \
>>> +options:rxq_pcap=${pcap_file}-rx.pcap
>>> +}
>>> +
>>> +# set_lsp_dns_params lsp_name
>>> +# Sets the dns_req_data and dns_resp_data
>>> +set_lsp_dns_params() {
>>> +    local lsp_name=$1
>>> +    local ttl=00000e10
>>> +    an_count=0001
>>> +    type=0001
>>> +    case $lsp_name in
>>> +    ls1-lp1)
>>> +        # vm1.ovn.org
>>> +        hostname=03766d31036f766e036f726700
>>> +        # IPv4 address - 10.0.0.4
>>> +        expected_dns_answer=${hostname}00010001${ttl}00040a000004
>>> +        ;;
>>> +    ls1-lp2)
>>> +        # vm2.ovn.org
>>> +        hostname=03766d32036f766e036f726700
>>> +        # IPv4 address - 10.0.0.6
>>> +        expected_dns_answer=${hostname}00010001${ttl}00040a000006
>>> +        # IPv4 address - 20.0.0.4
>>> +        expected_dns_answer=${expected_dns_answer}${hostname}0001000
>>> 1${ttl}000414000004
>>> +        an_count=0002
>>> +        ;;
>>> +    ls1-lp1_ipv6_only)
>>> +        # vm1.ovn.org
>>> +        hostname=03766d31036f766e036f726700
>>> +        # IPv6 address - aef0::4
>>> +        type=001c
>>> +        expected_dns_answer=${hostname}${type}0001${ttl}0010aef00000
>>> 000000000000000000000004
>>> +        ;;
>>> +    ls1-lp1_ipv4_v6)
>>> +        # vm1.ovn.org
>>> +        hostname=03766d31036f766e036f726700
>>> +        type=00ff
>>> +        an_count=0002
>>> +        # IPv4 address - 10.0.0.4
>>> +        # IPv6 address - aef0::4
>>> +        expected_dns_answer=${hostname}00010001${ttl}00040a000004
>>> +        expected_dns_answer=${expected_dns_answer}${hostname}001c000
>>> 1${ttl}0010
>>> +        expected_dns_answer=${expected_dns_answer}aef000000000000000
>>> 00000000000004
>>> +        ;;
>>> +    ls1-lp1_invalid_type)
>>> +        # vm1.ovn.org
>>> +        hostname=03766d31036f766e036f726700
>>> +        # IPv6 address - aef0::4
>>> +        type=0002
>>> +        ;;
>>> +    ls1-lp1_incomplete)
>>> +        # set type to none
>>> +        type=''
>>> +    esac
>>> +    # TTL - 3600
>>> +    local dns_req_header=010201200001000000000000
>>> +    local dns_resp_header=010281200001${an_count}00000000
>>> +    dns_req_data=${dns_req_header}${hostname}${type}0001
>>> +    dns_resp_data=${dns_resp_header}${hostname}${type}0001${expe
>>> cted_dns_answer}
>>> +}
>>> +
>>> +# This shell function sends a DNS request packet
>>> +# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
>>> +test_dns() {
>>> +    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
>>> dns_reply=$6
>>> +    local dns_query_data=$7
>>> +    shift; shift; shift; shift; shift; shift; shift;
>>> +    # Packet size => IPv4 header (20) + UDP header (8) +
>>> +    #                DNS data (header + query)
>>> +    ip_len=`expr 28 + ${#dns_query_data} / 2`
>>> +    udp_len=`expr $ip_len - 20`
>>> +    ip_len=$(printf "%x" $ip_len)
>>> +    udp_len=$(printf "%x" $udp_len)
>>> +    local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110
>>> 000
>>> +    request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
>>> +    # dns data
>>> +    request=${request}${dns_query_data}
>>> +
>>> +    if test $dns_reply != 0; then
>>> +        local dns_reply=$1
>>> +        ip_len=`expr 28 + ${#dns_reply} / 2`
>>> +        udp_len=`expr $ip_len - 20`
>>> +        ip_len=$(printf "%x" $ip_len)
>>> +        udp_len=$(printf "%x" $udp_len)
>>> +        local reply=${src_mac}${dst_mac}0800
>>> 450000${ip_len}0000000080110000
>>> +        reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dn
>>> s_reply}
>>> +        echo $reply >> $inport.expected
>>> +    else
>>> +        for outport; do
>>> +            echo $request >> $outport.expected
>>> +        done
>>> +    fi
>>> +    as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
>>> +}
>>> +
>>> +AT_CAPTURE_FILE([ofctl_monitor0.log])
>>> +as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
>>> +--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
>>> +
>>> +set_lsp_dns_params ls1-lp2
>>> +src_ip=`ip_to_hex 10 0 0 4`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=1
>>> +test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data $dns_resp_data
>>> +
>>> +# NXT_RESUMEs should be 1.
>>> +OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap >
>>> 1.packets
>>> +cat 1.expected | cut -c -48 > expout
>>> +AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
>>> +# Skipping the IPv4 checksum.
>>> +cat 1.expected | cut -c 53- > expout
>>> +AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +set_lsp_dns_params ls1-lp1
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=1
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data $dns_resp_data
>>> +
>>> +# NXT_RESUMEs should be 2.
>>> +OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +cat 2.expected | cut -c -48 > expout
>>> +AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
>>> +# Skipping the IPv4 checksum.
>>> +cat 2.expected | cut -c 53- > expout
>>> +AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Clear the hostname options for ls1-lp2
>>> +ovn-nbctl --wait=hv clear Logical_switch ls1 dns_lookups
>>> +ovn-nbctl --wait=hv add Logical_switch ls1 dns_lookups $LP1_DNS
>>> +
>>> +ovn-nbctl list logical_switch
>>> +echo "****************"
>>> +ovn-nbctl list DNS
>>> +echo "****************"
>>> +ovn-sbctl list DNS
>>> +echo "**********"
>>> +
>>> +set_lsp_dns_params ls1-lp2
>>> +src_ip=`ip_to_hex 10 0 0 4`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=0
>>> +test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply
>>> $dns_req_data
>>> +
>>> +# NXT_RESUMEs should be 3.
>>> +OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap >
>>> 1.packets
>>> +AT_CHECK([cat 1.packets], [0], [])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Clear the hostname for ls1-lp1
>>> +# Since no ports of ls1 has hostname configued,
>>> +# ovn-northd should not add the DNS flows.
>>> +ovn-nbctl clear Logical_switch ls1 dns_lookups
>>> +set_lsp_dns_params ls1-lp1
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=0
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data
>>> +
>>> +# NXT_RESUMEs should be 3 only.
>>> +OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +AT_CHECK([cat 2.packets], [0], [])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Test IPv6 (AAAA records) using IPv4 packet.
>>> +# Add back the DNS options for ls1-lp1.
>>> +ovn-nbctl add Logical_switch ls1 dns_lookups $LP1_DNS
>>> +
>>> +set_lsp_dns_params ls1-lp1_ipv6_only
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=1
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data $dns_resp_data
>>> +
>>> +# NXT_RESUMEs should be 4.
>>> +OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +cat 2.expected | cut -c -48 > expout
>>> +AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
>>> +# Skipping the IPv4 checksum.
>>> +cat 2.expected | cut -c 53- > expout
>>> +AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
>>> +set_lsp_dns_params ls1-lp1_ipv4_v6
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=1
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data $dns_resp_data
>>> +
>>> +# NXT_RESUMEs should be 5.
>>> +OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +cat 2.expected | cut -c -48 > expout
>>> +AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
>>> +# Skipping the IPv4 checksum.
>>> +cat 2.expected | cut -c 53- > expout
>>> +AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Invalid type.
>>> +set_lsp_dns_params ls1-lp1_invalid_type
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=0
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data
>>> +
>>> +# NXT_RESUMEs should be 6.
>>> +OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +AT_CHECK([cat 2.packets], [0], [])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +# Incomplete DNS packet.
>>> +set_lsp_dns_params ls1-lp1_incomplete
>>> +src_ip=`ip_to_hex 10 0 0 6`
>>> +dst_ip=`ip_to_hex 10 0 0 1`
>>> +dns_reply=0
>>> +test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply
>>> $dns_req_data
>>> +
>>> +# NXT_RESUMEs should be 7.
>>> +OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
>>> +
>>> +$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap >
>>> 2.packets
>>> +AT_CHECK([cat 2.packets], [0], [])
>>> +
>>> +reset_pcap_file hv1-vif1 hv1/vif1
>>> +reset_pcap_file hv1-vif2 hv1/vif2
>>> +rm -f 1.expected
>>> +rm -f 2.expected
>>> +
>>> +as hv1
>>> +OVS_APP_EXIT_AND_WAIT([ovn-controller])
>>> +OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +
>>> +as ovn-sb
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +
>>> +as ovn-nb
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +
>>> +as northd
>>> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
>>> +
>>> +as main
>>> +OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
>>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
>>> +AT_CLEANUP
>>> +
>>>  AT_SETUP([ovn -- 1 LR with distributed router gateway port])
>>>  AT_SKIP_IF([test $HAVE_PYTHON = no])
>>>  ovn_start
>>> --
>>> 2.9.3
>>>
>>> _______________________________________________
>>> dev mailing list
>>> dev at openvswitch.org
>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>>
>>
>>
>


More information about the dev mailing list