Skip to content

Commit f036e68

Browse files
idoschPaolo Abeni
authored andcommitted
ipv4: Fix incorrect TOS in fibmatch route get reply
The TOS value that is returned to user space in the route get reply is the one with which the lookup was performed ('fl4->flowi4_tos'). This is fine when the matched route is configured with a TOS as it would not match if its TOS value did not match the one with which the lookup was performed. However, matching on TOS is only performed when the route's TOS is not zero. It is therefore possible to have the kernel incorrectly return a non-zero TOS: # ip link add name dummy1 up type dummy # ip address add 192.0.2.1/24 dev dummy1 # ip route get fibmatch 192.0.2.2 tos 0xfc 192.0.2.0/24 tos 0x1c dev dummy1 proto kernel scope link src 192.0.2.1 Fix by instead returning the DSCP field from the FIB result structure which was populated during the route lookup. Output after the patch: # ip link add name dummy1 up type dummy # ip address add 192.0.2.1/24 dev dummy1 # ip route get fibmatch 192.0.2.2 tos 0xfc 192.0.2.0/24 dev dummy1 proto kernel scope link src 192.0.2.1 Extend the existing selftests to not only verify that the correct route is returned, but that it is also returned with correct "tos" value (or without it). Fixes: b617981 ("net: ipv4: RTM_GETROUTE: return matched fib result when requested") Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: David Ahern <[email protected]> Reviewed-by: Guillaume Nault <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 338bb57 commit f036e68

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

net/ipv4/route.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3331,7 +3331,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
33313331
fri.tb_id = table_id;
33323332
fri.dst = res.prefix;
33333333
fri.dst_len = res.prefixlen;
3334-
fri.dscp = inet_dsfield_to_dscp(fl4.flowi4_tos);
3334+
fri.dscp = res.dscp;
33353335
fri.type = rt->rt_type;
33363336
fri.offload = 0;
33373337
fri.trap = 0;

tools/testing/selftests/net/fib_tests.sh

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,53 +1737,53 @@ ipv4_rt_dsfield()
17371737

17381738
# DSCP 0x10 should match the specific route, no matter the ECN bits
17391739
$IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
1740-
grep -q "via 172.16.103.2"
1740+
grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
17411741
log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
17421742

17431743
$IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
1744-
grep -q "via 172.16.103.2"
1744+
grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
17451745
log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
17461746

17471747
$IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
1748-
grep -q "via 172.16.103.2"
1748+
grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
17491749
log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
17501750

17511751
$IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
1752-
grep -q "via 172.16.103.2"
1752+
grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
17531753
log_test $? 0 "IPv4 route with DSCP and ECN:CE"
17541754

17551755
# Unknown DSCP should match the generic route, no matter the ECN bits
17561756
$IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
1757-
grep -q "via 172.16.101.2"
1757+
grep -q "172.16.102.0/24 via 172.16.101.2"
17581758
log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
17591759

17601760
$IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
1761-
grep -q "via 172.16.101.2"
1761+
grep -q "172.16.102.0/24 via 172.16.101.2"
17621762
log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
17631763

17641764
$IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
1765-
grep -q "via 172.16.101.2"
1765+
grep -q "172.16.102.0/24 via 172.16.101.2"
17661766
log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
17671767

17681768
$IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
1769-
grep -q "via 172.16.101.2"
1769+
grep -q "172.16.102.0/24 via 172.16.101.2"
17701770
log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
17711771

17721772
# Null DSCP should match the generic route, no matter the ECN bits
17731773
$IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
1774-
grep -q "via 172.16.101.2"
1774+
grep -q "172.16.102.0/24 via 172.16.101.2"
17751775
log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
17761776

17771777
$IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
1778-
grep -q "via 172.16.101.2"
1778+
grep -q "172.16.102.0/24 via 172.16.101.2"
17791779
log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
17801780

17811781
$IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
1782-
grep -q "via 172.16.101.2"
1782+
grep -q "172.16.102.0/24 via 172.16.101.2"
17831783
log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
17841784

17851785
$IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
1786-
grep -q "via 172.16.101.2"
1786+
grep -q "172.16.102.0/24 via 172.16.101.2"
17871787
log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
17881788
}
17891789

0 commit comments

Comments
 (0)