Skip to content

Commit 3e80bd1

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 f68cb09 commit 3e80bd1

File tree

2 files changed

+61
-10
lines changed

2 files changed

+61
-10
lines changed

controller/pinctrl.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -2887,6 +2887,7 @@ dns_build_ptr_answer(
28872887
}
28882888

28892889
#define DNS_RCODE_SERVER_REFUSE 0x5
2890+
#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16))
28902891

28912892
/* Called with in the pinctrl_handler thread context. */
28922893
static void
@@ -2950,18 +2951,13 @@ pinctrl_handle_dns_lookup(
29502951
goto exit;
29512952
}
29522953

2953-
/* Check if there is an additional record present, which is unsupported */
2954-
if (in_dns_header->arcount) {
2955-
VLOG_DBG_RL(&rl, "Received DNS query with additional records, which"
2956-
" is unsupported");
2957-
goto exit;
2958-
}
2959-
29602954
struct udp_header *in_udp = dp_packet_l4(pkt_in);
29612955
size_t udp_len = ntohs(in_udp->udp_len);
29622956
size_t l4_len = dp_packet_l4_size(pkt_in);
2957+
uint8_t *l4_start = (uint8_t *) in_udp;
29632958
uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
29642959
uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1);
2960+
uint8_t *in_dns_data_start = in_dns_data;
29652961
uint8_t *in_queryname = in_dns_data;
29662962
uint16_t idx = 0;
29672963
struct ds query_name;
@@ -2985,7 +2981,7 @@ pinctrl_handle_dns_lookup(
29852981
in_dns_data += idx;
29862982

29872983
/* Query should have TYPE and CLASS fields */
2988-
if (in_dns_data + (2 * sizeof(ovs_be16)) > end) {
2984+
if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) {
29892985
ds_destroy(&query_name);
29902986
goto exit;
29912987
}
@@ -2999,6 +2995,10 @@ pinctrl_handle_dns_lookup(
29992995
goto exit;
30002996
}
30012997

2998+
uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN;
2999+
uint32_t query_size = rest - in_dns_data_start;
3000+
uint32_t query_l4_size = rest - l4_start;
3001+
30023002
uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
30033003
const char *answer_data = NULL;
30043004
bool ovn_owned = false;
@@ -3081,7 +3081,7 @@ pinctrl_handle_dns_lookup(
30813081
goto exit;
30823082
}
30833083

3084-
uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size;
3084+
uint16_t new_l4_size = query_l4_size + dns_answer.size;
30853085
size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
30863086
struct dp_packet pkt_out;
30873087
dp_packet_init(&pkt_out, new_packet_size);
@@ -3118,7 +3118,7 @@ pinctrl_handle_dns_lookup(
31183118
out_dns_header->arcount = 0;
31193119

31203120
/* Copy the Query section. */
3121-
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
3121+
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size);
31223122

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

tests/ovn.at

+51
Original file line numberDiff line numberDiff line change
@@ -11455,6 +11455,57 @@ OVN_CLEANUP([hv1])
1145511455
AT_CLEANUP
1145611456
])
1145711457

11458+
OVN_FOR_EACH_NORTHD([
11459+
AT_SETUP([dns lookup : EDNS])
11460+
AT_SKIP_IF([test $HAVE_SCAPY = no])
11461+
ovn_start
11462+
11463+
check ovn-nbctl ls-add ls \
11464+
-- lsp-add ls lsp \
11465+
-- lsp-set-addresses lsp "00:00:00:00:00:01 10.0.0.1"
11466+
11467+
d=$(ovn-nbctl create dns records={})
11468+
11469+
check ovn-nbctl set dns $d records:foo.ovn.org="10.0.0.42"
11470+
check ovn-nbctl set Logical_switch ls dns_records="$d"
11471+
11472+
net_add n1
11473+
sim_add hv1
11474+
11475+
as hv1
11476+
ovs-vsctl add-br br-phys
11477+
ovn_attach n1 br-phys 192.168.0.1
11478+
check ovs-vsctl add-port br-int hv1-vif1 -- \
11479+
set interface hv1-vif1 external-ids:iface-id=lsp \
11480+
options:tx_pcap=hv1/vif1-tx.pcap \
11481+
options:rxq_pcap=hv1/vif1-rx.pcap
11482+
11483+
OVN_POPULATE_ARP
11484+
wait_for_ports_up
11485+
check ovn-nbctl --wait=hv sync
11486+
11487+
dns_req=$(fmt_pkt "Ether(dst='00:00:00:00:00:02', src='00:00:00:00:00:01') / \
11488+
IP(dst='10.0.0.254', src='10.0.0.1') / \
11489+
UDP(sport=42424, dport=53) / \
11490+
DNS(rd=1, qd=DNSQR(qname='foo.ovn.org'), arcount=1, ar=[ \
11491+
DNSRR(type='OPT', rclass=4096, \
11492+
rdata=EDNS0ClientSubnet(source_plen=24, \
11493+
address='10.0.0.1'))])")
11494+
dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01', src='00:00:00:00:00:02') / \
11495+
IP(dst='10.0.0.1', src='10.0.0.254') / \
11496+
UDP(sport=53, dport=42424,chksum=0) / \
11497+
DNS(qr=1, qd=DNSQR(qname='foo.ovn.org'), \
11498+
an=DNSRR(rrname='foo.ovn.org', type='A', ttl=3600, \
11499+
rdata='10.0.0.42'))")
11500+
echo ${dns_reply} > expected
11501+
11502+
as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req}
11503+
OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
11504+
11505+
OVN_CLEANUP([hv1])
11506+
AT_CLEANUP
11507+
])
11508+
1145811509
OVN_FOR_EACH_NORTHD([
1145911510
AT_SETUP([4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1146011511
ovn_start

0 commit comments

Comments
 (0)