lkml.org 
[lkml]   [2021]   [Jan]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 51/58] udp: mask TOS bits in udp_v4_early_demux()
    Date
    From: Guillaume Nault <gnault@redhat.com>

    commit 8d2b51b008c25240914984208b2ced57d1dd25a5 upstream.

    udp_v4_early_demux() is the only function that calls
    ip_mc_validate_source() with a TOS that hasn't been masked with
    IPTOS_RT_MASK.

    This results in different behaviours for incoming multicast UDPv4
    packets, depending on if ip_mc_validate_source() is called from the
    early-demux path (udp_v4_early_demux) or from the regular input path
    (ip_route_input_noref).

    ECN would normally not be used with UDP multicast packets, so the
    practical consequences should be limited on that side. However,
    IPTOS_RT_MASK is used to also masks the TOS' high order bits, to align
    with the non-early-demux path behaviour.

    Reproducer:

    Setup two netns, connected with veth:
    $ ip netns add ns0
    $ ip netns add ns1
    $ ip -netns ns0 link set dev lo up
    $ ip -netns ns1 link set dev lo up
    $ ip link add name veth01 netns ns0 type veth peer name veth10 netns ns1
    $ ip -netns ns0 link set dev veth01 up
    $ ip -netns ns1 link set dev veth10 up
    $ ip -netns ns0 address add 192.0.2.10 peer 192.0.2.11/32 dev veth01
    $ ip -netns ns1 address add 192.0.2.11 peer 192.0.2.10/32 dev veth10

    In ns0, add route to multicast address 224.0.2.0/24 using source
    address 198.51.100.10:
    $ ip -netns ns0 address add 198.51.100.10/32 dev lo
    $ ip -netns ns0 route add 224.0.2.0/24 dev veth01 src 198.51.100.10

    In ns1, define route to 198.51.100.10, only for packets with TOS 4:
    $ ip -netns ns1 route add 198.51.100.10/32 tos 4 dev veth10

    Also activate rp_filter in ns1, so that incoming packets not matching
    the above route get dropped:
    $ ip netns exec ns1 sysctl -wq net.ipv4.conf.veth10.rp_filter=1

    Now try to receive packets on 224.0.2.11:
    $ ip netns exec ns1 socat UDP-RECVFROM:1111,ip-add-membership=224.0.2.11:veth10,ignoreeof -

    In ns0, send packet to 224.0.2.11 with TOS 4 and ECT(0) (that is,
    tos 6 for socat):
    $ echo test0 | ip netns exec ns0 socat - UDP-DATAGRAM:224.0.2.11:1111,bind=:1111,tos=6

    The "test0" message is properly received by socat in ns1, because
    early-demux has no cached dst to use, so source address validation
    is done by ip_route_input_mc(), which receives a TOS that has the
    ECN bits masked.

    Now send another packet to 224.0.2.11, still with TOS 4 and ECT(0):
    $ echo test1 | ip netns exec ns0 socat - UDP-DATAGRAM:224.0.2.11:1111,bind=:1111,tos=6

    The "test1" message isn't received by socat in ns1, because, now,
    early-demux has a cached dst to use and calls ip_mc_validate_source()
    immediately, without masking the ECN bits.

    Fixes: bc044e8db796 ("udp: perform source validation for mcast early demux")
    Signed-off-by: Guillaume Nault <gnault@redhat.com>
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    net/ipv4/udp.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    --- a/net/ipv4/udp.c
    +++ b/net/ipv4/udp.c
    @@ -2416,7 +2416,8 @@ int udp_v4_early_demux(struct sk_buff *s
    */
    if (!inet_sk(sk)->inet_daddr && in_dev)
    return ip_mc_validate_source(skb, iph->daddr,
    - iph->saddr, iph->tos,
    + iph->saddr,
    + iph->tos & IPTOS_RT_MASK,
    skb->dev, in_dev, &itag);
    }
    return 0;

    \
     
     \ /
      Last update: 2021-01-25 19:50    [W:6.211 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site