> > > > 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 >>> d...@openvswitch.org >>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >>> >> >> > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev