• Heng Guo's avatar
    net: fix IPSTATS_MIB_OUTFORWDATAGRAMS increment after fragment check · cf8b49fb
    Heng Guo authored
    Reproduce environment:
    network with 3 VM linuxs is connected as below:
    VM1<---->VM2(latest kernel 6.5.0-rc7)<---->VM3
    VM1: eth0 ip: 192.168.122.207 MTU 1800
    VM2: eth0 ip: 192.168.122.208, eth1 ip: 192.168.123.224 MTU 1500
    VM3: eth0 ip: 192.168.123.240 MTU 1800
    
    Reproduce:
    VM1 send 1600 bytes UDP data to VM3 using tools scapy with flags='DF'.
    scapy command:
    send(IP(dst="192.168.123.240",flags='DF')/UDP()/str('0'*1600),count=1,
    inter=1.000000)
    
    Result:
    Before IP data is sent.
    ----------------------------------------------------------------------
    root@qemux86-64:~# cat /proc/net/snmp
    Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors
        ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests
        OutDiscards OutNoRoutes ReasmTimeout ReasmReqdss
    Ip: 1 64 6 0 2 2 0 0 2 4 0 0 0 0 0 0 0 0 0
    ......
    root@qemux86-64:~#
    ----------------------------------------------------------------------
    After IP data is sent.
    ----------------------------------------------------------------------
    root@qemux86-64:~# cat /proc/net/snmp
    Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors
        ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests
        OutDiscards OutNoRoutes ReasmTimeout ReasmReqdss
    Ip: 1 64 7 0 2 2 0 0 2 5 0 0 0 0 0 0 0 1 0
    ......
    root@qemux86-64:~#
    ----------------------------------------------------------------------
    ForwDatagrams is always keeping 2 without increment.
    
    Issue description and patch:
    ip_exceeds_mtu() in ip_forward() drops this IP datagram because skb len
    (1600 sending by scapy) is over MTU(1500 in VM2) if "DF" is set.
    According to RFC 4293 "3.2.3. IP Statistics Tables",
      +-------+------>------+----->-----+----->-----+
      | InForwDatagrams (6) | OutForwDatagrams (6)  |
      |                     V                       +->-+ OutFragReqds
      |                 InNoRoutes                  |   | (packets)
      / (local packet (3)                           |   |
      |  IF is that of the address                  |   +--> OutFragFails
      |  and may not be the receiving IF)           |   |    (packets)
    the IPSTATS_MIB_OUTFORWDATAGRAMS should be counted before fragment
    check.
    The existing implementation, instead, would incease the counter after
    fragment check: ip_exceeds_mtu() in ipv4 and ip6_pkt_too_big() in ipv6.
    So do patch to move IPSTATS_MIB_OUTFORWDATAGRAMS counter to ip_forward()
    for ipv4 and ip6_forward() for ipv6.
    
    Test result with patch:
    Before IP data is sent.
    ----------------------------------------------------------------------
    root@qemux86-64:~# cat /proc/net/snmp
    Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors
        ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests
        OutDiscards OutNoRoutes ReasmTimeout ReasmReqdss
    Ip: 1 64 6 0 2 2 0 0 2 4 0 0 0 0 0 0 0 0 0
    ......
    root@qemux86-64:~#
    ----------------------------------------------------------------------
    After IP data is sent.
    ----------------------------------------------------------------------
    root@qemux86-64:~# cat /proc/net/snmp
    Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors
        ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests
        OutDiscards OutNoRoutes ReasmTimeout ReasmReqdss
    Ip: 1 64 7 0 2 3 0 0 2 5 0 0 0 0 0 0 0 1 0
    ......
    root@qemux86-64:~#
    ----------------------------------------------------------------------
    ForwDatagrams is updated from 2 to 3.
    Reviewed-by: default avatarFilip Pudak <filip.pudak@windriver.com>
    Signed-off-by: default avatarHeng Guo <heng.guo@windriver.com>
    Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
    Link: https://lore.kernel.org/r/20231011015137.27262-1-heng.guo@windriver.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    cf8b49fb
ip6_output.c 54 KB