Skip to content

Commit cb0c918

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 6c15e96 commit cb0c918

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
@@ -2949,6 +2949,8 @@ dns_build_ptr_answer(
29492949
free(encoded_answer);
29502950
}
29512951

2952+
#define DNS_QUERY_TYPE_CLASS_LEN (2 * sizeof(ovs_be16))
2953+
29522954
/* Called with in the pinctrl_handler thread context. */
29532955
static void
29542956
pinctrl_handle_dns_lookup(
@@ -3010,18 +3012,13 @@ pinctrl_handle_dns_lookup(
30103012
goto exit;
30113013
}
30123014

3013-
/* Check if there is an additional record present, which is unsupported */
3014-
if (in_dns_header->arcount) {
3015-
VLOG_DBG_RL(&rl, "Received DNS query with additional records, which"
3016-
" is unsupported");
3017-
goto exit;
3018-
}
3019-
30203015
struct udp_header *in_udp = dp_packet_l4(pkt_in);
30213016
size_t udp_len = ntohs(in_udp->udp_len);
30223017
size_t l4_len = dp_packet_l4_size(pkt_in);
3018+
uint8_t *l4_start = (uint8_t *) in_udp;
30233019
uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
30243020
uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1);
3021+
uint8_t *in_dns_data_start = in_dns_data;
30253022
uint8_t *in_queryname = in_dns_data;
30263023
uint16_t idx = 0;
30273024
struct ds query_name;
@@ -3045,7 +3042,7 @@ pinctrl_handle_dns_lookup(
30453042
in_dns_data += idx;
30463043

30473044
/* Query should have TYPE and CLASS fields */
3048-
if (in_dns_data + (2 * sizeof(ovs_be16)) > end) {
3045+
if (in_dns_data + DNS_QUERY_TYPE_CLASS_LEN > end) {
30493046
ds_destroy(&query_name);
30503047
goto exit;
30513048
}
@@ -3059,6 +3056,10 @@ pinctrl_handle_dns_lookup(
30593056
goto exit;
30603057
}
30613058

3059+
uint8_t *rest = in_dns_data + DNS_QUERY_TYPE_CLASS_LEN;
3060+
uint32_t query_size = rest - in_dns_data_start;
3061+
uint32_t query_l4_size = rest - l4_start;
3062+
30623063
uint64_t dp_key = ntohll(pin->flow_metadata.flow.metadata);
30633064
const char *answer_data = NULL;
30643065
struct shash_node *iter;
@@ -3127,7 +3128,7 @@ pinctrl_handle_dns_lookup(
31273128
goto exit;
31283129
}
31293130

3130-
uint16_t new_l4_size = ntohs(in_udp->udp_len) + dns_answer.size;
3131+
uint16_t new_l4_size = query_l4_size + dns_answer.size;
31313132
size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
31323133
struct dp_packet pkt_out;
31333134
dp_packet_init(&pkt_out, new_packet_size);
@@ -3160,7 +3161,7 @@ pinctrl_handle_dns_lookup(
31603161
out_dns_header->arcount = 0;
31613162

31623163
/* Copy the Query section. */
3163-
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), dp_packet_size(pkt_in));
3164+
dp_packet_put(&pkt_out, dp_packet_data(pkt_in), query_size);
31643165

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

tests/ovn.at

+51
Original file line numberDiff line numberDiff line change
@@ -11115,6 +11115,57 @@ OVN_CLEANUP([hv1])
1111511115
AT_CLEANUP
1111611116
])
1111711117

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

0 commit comments

Comments
 (0)