Skip to content

Commit 041891e

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 5e892cc commit 041891e

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
@@ -2828,6 +2828,8 @@ dns_build_ptr_answer(
28282828
free(encoded_answer);
28292829
}
28302830

2831+
#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16))
2832+
28312833
/* Called with in the pinctrl_handler thread context. */
28322834
static void
28332835
pinctrl_handle_dns_lookup(
@@ -2889,18 +2891,13 @@ pinctrl_handle_dns_lookup(
28892891
goto exit;
28902892
}
28912893

2892-
/* Check if there is an additional record present, which is unsupported */
2893-
if (in_dns_header->arcount) {
2894-
VLOG_DBG_RL(&rl, "Received DNS query with additional records, which"
2895-
" is unsupported");
2896-
goto exit;
2897-
}
2898-
28992894
struct udp_header *in_udp = dp_packet_l4(pkt_in);
29002895
size_t udp_len = ntohs(in_udp->udp_len);
29012896
size_t l4_len = dp_packet_l4_size(pkt_in);
2897+
uint8_t *l4_start = (uint8_t *) in_udp;
29022898
uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
29032899
uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1);
2900+
uint8_t *in_dns_data_start = in_dns_data;
29042901
uint8_t *in_queryname = in_dns_data;
29052902
uint16_t idx = 0;
29062903
struct ds query_name;
@@ -2924,7 +2921,7 @@ pinctrl_handle_dns_lookup(
29242921
in_dns_data += idx;
29252922

29262923
/* Query should have TYPE and CLASS fields */
2927-
if (in_dns_data + (2 * sizeof(ovs_be16)) > end) {
2924+
if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) {
29282925
ds_destroy(&query_name);
29292926
goto exit;
29302927
}
@@ -2938,6 +2935,10 @@ pinctrl_handle_dns_lookup(
29382935
goto exit;
29392936
}
29402937

2938+
uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN;
2939+
uint32_t query_size = rest - in_dns_data_start;
2940+
uint32_t query_l4_size = rest - l4_start;
2941+
29412942
uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
29422943
const char *answer_data = NULL;
29432944
struct shash_node *iter;
@@ -3006,7 +3007,7 @@ pinctrl_handle_dns_lookup(
30063007
goto exit;
30073008
}
30083009

3009-
uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size;
3010+
uint16_t new_l4_size = query_l4_size + dns_answer.size;
30103011
size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
30113012
struct dp_packet pkt_out;
30123013
dp_packet_init(&pkt_out, new_packet_size);
@@ -3039,7 +3040,7 @@ pinctrl_handle_dns_lookup(
30393040
out_dns_header->arcount = 0;
30403041

30413042
/* Copy the Query section. */
3042-
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
3043+
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size);
30433044

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

tests/ovn.at

+51
Original file line numberDiff line numberDiff line change
@@ -11183,6 +11183,57 @@ OVN_CLEANUP([hv1])
1118311183
AT_CLEANUP
1118411184
])
1118511185

11186+
OVN_FOR_EACH_NORTHD([
11187+
AT_SETUP([dns lookup : EDNS])
11188+
AT_SKIP_IF([test $HAVE_SCAPY = no])
11189+
ovn_start
11190+
11191+
check ovn-nbctl ls-add ls \
11192+
-- lsp-add ls lsp \
11193+
-- lsp-set-addresses lsp "00:00:00:00:00:01 10.0.0.1"
11194+
11195+
d=$(ovn-nbctl create dns records={})
11196+
11197+
check ovn-nbctl set dns $d records:foo.ovn.org="10.0.0.42"
11198+
check ovn-nbctl set Logical_switch ls dns_records="$d"
11199+
11200+
net_add n1
11201+
sim_add hv1
11202+
11203+
as hv1
11204+
ovs-vsctl add-br br-phys
11205+
ovn_attach n1 br-phys 192.168.0.1
11206+
check ovs-vsctl add-port br-int hv1-vif1 -- \
11207+
set interface hv1-vif1 external-ids:iface-id=lsp \
11208+
options:tx_pcap=hv1/vif1-tx.pcap \
11209+
options:rxq_pcap=hv1/vif1-rx.pcap
11210+
11211+
OVN_POPULATE_ARP
11212+
wait_for_ports_up
11213+
check ovn-nbctl --wait=hv sync
11214+
11215+
dns_req=$(fmt_pkt "Ether(dst='00:00:00:00:00:02', src='00:00:00:00:00:01') / \
11216+
IP(dst='10.0.0.254', src='10.0.0.1') / \
11217+
UDP(sport=42424, dport=53) / \
11218+
DNS(rd=1, qd=DNSQR(qname='foo.ovn.org'), arcount=1, ar=[ \
11219+
DNSRR(type='OPT', rclass=4096, \
11220+
rdata=EDNS0ClientSubnet(source_plen=24, \
11221+
address='10.0.0.1'))])")
11222+
dns_reply=$(fmt_pkt "Ether(dst='00:00:00:00:00:01', src='00:00:00:00:00:02') / \
11223+
IP(dst='10.0.0.1', src='10.0.0.254') / \
11224+
UDP(sport=53, dport=42424,chksum=0) / \
11225+
DNS(qr=1, qd=DNSQR(qname='foo.ovn.org'), \
11226+
an=DNSRR(rrname='foo.ovn.org', type='A', ttl=3600, \
11227+
rdata='10.0.0.42'))")
11228+
echo ${dns_reply} > expected
11229+
11230+
as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 ${dns_req}
11231+
OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv1/vif1-tx.pcap], [expected])
11232+
11233+
OVN_CLEANUP([hv1])
11234+
AT_CLEANUP
11235+
])
11236+
1118611237
OVN_FOR_EACH_NORTHD([
1118711238
AT_SETUP([4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1118811239
ovn_start

0 commit comments

Comments
 (0)