Skip to content

Commit 02bbd6a

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 c07660d commit 02bbd6a

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
@@ -2923,6 +2923,8 @@ dns_build_ptr_answer(
29232923
free(encoded_answer);
29242924
}
29252925

2926+
#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16))
2927+
29262928
/* Called with in the pinctrl_handler thread context. */
29272929
static void
29282930
pinctrl_handle_dns_lookup(
@@ -2984,18 +2986,13 @@ pinctrl_handle_dns_lookup(
29842986
goto exit;
29852987
}
29862988

2987-
/* Check if there is an additional record present, which is unsupported */
2988-
if (in_dns_header->arcount) {
2989-
VLOG_DBG_RL(&rl, "Received DNS query with additional records, which"
2990-
" is unsupported");
2991-
goto exit;
2992-
}
2993-
29942989
struct udp_header *in_udp = dp_packet_l4(pkt_in);
29952990
size_t udp_len = ntohs(in_udp->udp_len);
29962991
size_t l4_len = dp_packet_l4_size(pkt_in);
2992+
uint8_t *l4_start = (uint8_t *) in_udp;
29972993
uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
29982994
uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1);
2995+
uint8_t *in_dns_data_start = in_dns_data;
29992996
uint8_t *in_queryname = in_dns_data;
30002997
uint16_t idx = 0;
30012998
struct ds query_name;
@@ -3019,7 +3016,7 @@ pinctrl_handle_dns_lookup(
30193016
in_dns_data += idx;
30203017

30213018
/* Query should have TYPE and CLASS fields */
3022-
if (in_dns_data + (2 * sizeof(ovs_be16)) > end) {
3019+
if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) {
30233020
ds_destroy(&query_name);
30243021
goto exit;
30253022
}
@@ -3033,6 +3030,10 @@ pinctrl_handle_dns_lookup(
30333030
goto exit;
30343031
}
30353032

3033+
uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN;
3034+
uint32_t query_size = rest - in_dns_data_start;
3035+
uint32_t query_l4_size = rest - l4_start;
3036+
30363037
uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
30373038
const char *answer_data = NULL;
30383039
struct shash_node *iter;
@@ -3101,7 +3102,7 @@ pinctrl_handle_dns_lookup(
31013102
goto exit;
31023103
}
31033104

3104-
uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size;
3105+
uint16_t new_l4_size = query_l4_size + dns_answer.size;
31053106
size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
31063107
struct dp_packet pkt_out;
31073108
dp_packet_init(&pkt_out, new_packet_size);
@@ -3134,7 +3135,7 @@ pinctrl_handle_dns_lookup(
31343135
out_dns_header->arcount = 0;
31353136

31363137
/* Copy the Query section. */
3137-
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
3138+
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size);
31383139

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

tests/ovn.at

+51
Original file line numberDiff line numberDiff line change
@@ -11106,6 +11106,57 @@ OVN_CLEANUP([hv1])
1110611106
AT_CLEANUP
1110711107
])
1110811108

11109+
OVN_FOR_EACH_NORTHD([
11110+
AT_SETUP([dns lookup : EDNS])
11111+
AT_SKIP_IF([test $HAVE_SCAPY = no])
11112+
ovn_start
11113+
11114+
check ovn-nbctl ls-add ls \
11115+
-- lsp-add ls lsp \
11116+
-- lsp-set-addresses lsp "00:00:00:00:00:01 10.0.0.1"
11117+
11118+
d=$(ovn-nbctl create dns records={})
11119+
11120+
check ovn-nbctl set dns $d records:foo.ovn.org="10.0.0.42"
11121+
check ovn-nbctl set Logical_switch ls dns_records="$d"
11122+
11123+
net_add n1
11124+
sim_add hv1
11125+
11126+
as hv1
11127+
ovs-vsctl add-br br-phys
11128+
ovn_attach n1 br-phys 192.168.0.1
11129+
check ovs-vsctl add-port br-int hv1-vif1 -- \
11130+
set interface hv1-vif1 external-ids:iface-id=lsp \
11131+
options:tx_pcap=hv1/vif1-tx.pcap \
11132+
options:rxq_pcap=hv1/vif1-rx.pcap
11133+
11134+
OVN_POPULATE_ARP
11135+
wait_for_ports_up
11136+
check ovn-nbctl --wait=hv sync
11137+
11138+
dns_req=$(fmt_pkt "Ether(dst='00:00:00:00:00:02', src='00:00:00:00:00:01') / \
11139+
IP(dst='10.0.0.254', src='10.0.0.1') / \
11140+
UDP(sport=42424, dport=53) / \
11141+
DNS(rd=1, qd=DNSQR(qname='foo.ovn.org'), arcount=1, ar=[ \
11142+
DNSRR(type='OPT', rclass=4096, \
11143+
rdata=EDNS0ClientSubnet(source_plen=24, \
11144+
address='10.0.0.1'))])")
11145+
dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01', src='00:00:00:00:00:02') / \
11146+
IP(dst='10.0.0.1', src='10.0.0.254') / \
11147+
UDP(sport=53, dport=42424,chksum=0) / \
11148+
DNS(qr=1, qd=DNSQR(qname='foo.ovn.org'), \
11149+
an=DNSRR(rrname='foo.ovn.org', type='A', ttl=3600, \
11150+
rdata='10.0.0.42'))")
11151+
echo ${dns_reply} > expected
11152+
11153+
as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req}
11154+
OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
11155+
11156+
OVN_CLEANUP([hv1])
11157+
AT_CLEANUP
11158+
])
11159+
1110911160
OVN_FOR_EACH_NORTHD([
1111011161
AT_SETUP([4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1111111162
ovn_start

0 commit comments

Comments
 (0)