On Wed, Mar 29, 2017 at 11:47 PM, Guru Shetty <g...@ovn.org> wrote: > >> >> 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 Ben and Guru. I will work on the suggested approach.
Numan > > > >> >> 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