Skip to content

Commit fb5ff59

Browse files
committed
pinctrl: dns: Ignore additional records.
EDNS is backwards compatible so it's safe to just ignore additional ARs. Reported-at: ovn-org#228 Reported-at: https://issues.redhat.com/browse/FDP-222 Signed-off-by: Dumitru Ceara <dceara@redhat.com> Acked-by: Mark Michelson <mmichels@redhat.com> (cherry picked from commit b7fe2c8)
1 parent cf272b8 commit fb5ff59

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

controller/pinctrl.c

+11-10
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,8 @@ dns_build_ptr_answer(
28822882
free(encoded_answer);
28832883
}
28842884

2885+
#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16))
2886+
28852887
/* Called with in the pinctrl_handler thread context. */
28862888
static void
28872889
pinctrl_handle_dns_lookup(
@@ -2943,18 +2945,13 @@ pinctrl_handle_dns_lookup(
29432945
goto exit;
29442946
}
29452947

2946-
/* Check if there is an additional record present, which is unsupported */
2947-
if (in_dns_header->arcount) {
2948-
VLOG_DBG_RL(&rl, "Received DNS query with additional records, which"
2949-
" is unsupported");
2950-
goto exit;
2951-
}
2952-
29532948
struct udp_header *in_udp = dp_packet_l4(pkt_in);
29542949
size_t udp_len = ntohs(in_udp->udp_len);
29552950
size_t l4_len = dp_packet_l4_size(pkt_in);
2951+
uint8_t *l4_start = (uint8_t *) in_udp;
29562952
uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
29572953
uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1);
2954+
uint8_t *in_dns_data_start = in_dns_data;
29582955
uint8_t *in_queryname = in_dns_data;
29592956
uint16_t idx = 0;
29602957
struct ds query_name;
@@ -2978,7 +2975,7 @@ pinctrl_handle_dns_lookup(
29782975
in_dns_data += idx;
29792976

29802977
/* Query should have TYPE and CLASS fields */
2981-
if (in_dns_data + (2 * sizeof(ovs_be16)) > end) {
2978+
if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) {
29822979
ds_destroy(&query_name);
29832980
goto exit;
29842981
}
@@ -2992,6 +2989,10 @@ pinctrl_handle_dns_lookup(
29922989
goto exit;
29932990
}
29942991

2992+
uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN;
2993+
uint32_t query_size = rest - in_dns_data_start;
2994+
uint32_t query_l4_size = rest - l4_start;
2995+
29952996
uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
29962997
const char *answer_data = NULL;
29972998
struct shash_node *iter;
@@ -3060,7 +3061,7 @@ pinctrl_handle_dns_lookup(
30603061
goto exit;
30613062
}
30623063

3063-
uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size;
3064+
uint16_t new_l4_size = query_l4_size + dns_answer.size;
30643065
size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
30653066
struct dp_packet pkt_out;
30663067
dp_packet_init(&pkt_out, new_packet_size);
@@ -3093,7 +3094,7 @@ pinctrl_handle_dns_lookup(
30933094
out_dns_header->arcount = 0;
30943095

30953096
/* Copy the Query section. */
3096-
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
3097+
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size);
30973098

30983099
/* Copy the answer sections. */
30993100
dp_packet_put(&pkt_out, dns_answer.data, dns_answer.size);

tests/ovn.at

+51
Original file line numberDiff line numberDiff line change
@@ -11023,6 +11023,57 @@ OVN_CLEANUP([hv1])
1102311023
AT_CLEANUP
1102411024
])
1102511025

11026+
OVN_FOR_EACH_NORTHD([
11027+
AT_SETUP([dns lookup : EDNS])
11028+
AT_SKIP_IF([test $HAVE_SCAPY = no])
11029+
ovn_start
11030+
11031+
check ovn-nbctl ls-add ls \
11032+
-- lsp-add ls lsp \
11033+
-- lsp-set-addresses lsp "00:00:00:00:00:01 10.0.0.1"
11034+
11035+
d=$(ovn-nbctl create dns records={})
11036+
11037+
check ovn-nbctl set dns $d records:foo.ovn.org="10.0.0.42"
11038+
check ovn-nbctl set Logical_switch ls dns_records="$d"
11039+
11040+
net_add n1
11041+
sim_add hv1
11042+
11043+
as hv1
11044+
ovs-vsctl add-br br-phys
11045+
ovn_attach n1 br-phys 192.168.0.1
11046+
check ovs-vsctl add-port br-int hv1-vif1 -- \
11047+
set interface hv1-vif1 external-ids:iface-id=lsp \
11048+
options:tx_pcap=hv1/vif1-tx.pcap \
11049+
options:rxq_pcap=hv1/vif1-rx.pcap
11050+
11051+
OVN_POPULATE_ARP
11052+
wait_for_ports_up
11053+
check ovn-nbctl --wait=hv sync
11054+
11055+
dns_req=$(fmt_pkt "Ether(dst='00:00:00:00:00:02', src='00:00:00:00:00:01') / \
11056+
IP(dst='10.0.0.254', src='10.0.0.1') / \
11057+
UDP(sport=42424, dport=53) / \
11058+
DNS(rd=1, qd=DNSQR(qname='foo.ovn.org'), arcount=1, ar=[ \
11059+
DNSRR(type='OPT', rclass=4096, \
11060+
rdata=EDNS0ClientSubnet(source_plen=24, \
11061+
address='10.0.0.1'))])")
11062+
dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01', src='00:00:00:00:00:02') / \
11063+
IP(dst='10.0.0.1', src='10.0.0.254') / \
11064+
UDP(sport=53, dport=42424,chksum=0) / \
11065+
DNS(qr=1, qd=DNSQR(qname='foo.ovn.org'), \
11066+
an=DNSRR(rrname='foo.ovn.org', type='A', ttl=3600, \
11067+
rdata='10.0.0.42'))")
11068+
echo ${dns_reply} > expected
11069+
11070+
as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req}
11071+
OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
11072+
11073+
OVN_CLEANUP([hv1])
11074+
AT_CLEANUP
11075+
])
11076+
1102611077
OVN_FOR_EACH_NORTHD([
1102711078
AT_SETUP([4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1102811079
ovn_start

0 commit comments

Comments
 (0)