MPD drops ip fragments when disordered

Help
valeryprok
2014-02-20
2014-02-21
  • valeryprok
    valeryprok
    2014-02-20

    I have two FreeBSD nodes with external addresses A.B.C.D, E.F.G.H and internal addresses 192.168.0.1, 192.168.1.1, connected via Internet:

      Side 1                       Side 2
    --------------------------------------------------
    (192.168.0.1, A.B.C.D)  <--  (E.F.G.H, 192.168.1.1)
    

    Side 1 is accepting connection from Side 2.
    Side 1 mpd.conf:

    l2tp_server:
            create bundle template B3
            set iface idle 1800
            set iface enable tcpmssfix
            set ipcp yes vjcomp
            set iface up-script /usr/local/etc/mpd5/mpd-up.sh
            set iface down-script /usr/local/etc/mpd5/mpd-down.sh
            set ipcp ranges 192.168.0.1/32 0.0.0.0/0
            set ipcp dns 192.168.0.1
            set bundle enable compression
            set ccp yes mppc
            set mppc yes e40
            set mppc yes e128
            set mppc yes stateless
            create link template L3 l2tp
            set link action bundle B3
            set link yes acfcomp protocomp
            set link no pap chap eap
            set link enable chap
            set link keep-alive 10 60
            set link mtu 1460
            set link enable incoming`
    

    Side 2 mpd.conf:

    client:
            create bundle static B1
            set bundle enable compression
            set bundle enable encryption
            set iface route 192.168.0.0/16
            set iface disable on-demand
            set iface idle 0
            set iface enable tcpmssfix
            set ipcp yes vjcomp
            create link static L1 l2tp
            set link action bundle B1
            set auth authname ub
            set link max-redial 0
            set link mtu 1460
            set link keep-alive 20 75
            set l2tp peer 109.232.187.76
            set link no pap
            set link yes chap
            set link enable no-orig-auth
            set link keep-alive 10 75
            set link disable incoming
            open
    

    Everything works fine, i.e. when I run on Side 2 “ping 192.168.0.1” I’ve got: “64 bytes from 192.168.0.1: icmp_seq=0 ttl=64 time=12.193 ms”.

    But if I run on Side 2 “ping –s 1500 192.168.0.1” there may be packet loss (usually about 50%). So big packets (not only ICMP), that needed to be fragmented SOMETIMES dropped.

    Here is tcpdump output from Side2:

    {PACKET1}

    11:33:43.022127 IP (tos 0x0, ttl 64, id 26332, offset 0, flags [none], proto UDP (17), length 1491)
        E.F.G.H.17866 > A.B.C.D.1701:  l2tp:[S](65444/45127)Ns=2663,Nr=2133 {IP (tos 0x0, ttl 64, id 26331, offset 0, flags [+], proto ICMP (1), length 1452)
        192.168.1.1 > 192.168.0.1: ICMP echo request, id 59412, seq 20, length 1432}

    {PACKET2}

    11:33:43.823293 IP (tos 0x0, ttl 64, id 26340, offset 0, flags [none], proto UDP (17), length 135)
        E.F.G.H.17866 > A.B.C.D.1701:  l2tp:[S](65444/45127)Ns=2666,Nr=2133 {IP (tos 0x0, ttl 64, id 26338, offset 1432, flags [none], proto ICMP (1), length 96)
        192.168.1.1 > 192.168.0.1: icmp}

    As we can see, big ICMP packet fragmented and wrapped in 2 l2tp packets: PACKET1 and PACKET2.
    Everything will be ok, if Side1 will receive these packets in correct order (PACKET1,PACKET2).
    But if for any reason (f.e. provider delays) order is broken, i.e. side1 receives packets in such order: (PACKET2,PACKET1), there is no response to ping. It seems that MPD simply drops PACKET1 in this case.
    This behavior can be simulated by adding following ipfw rules on Side2:
    ipfw pipe 1 config delay 200
    ipfw add XXXX pipe 1 udp from me to any 1701 out iplen 1400-2000

    Such a problem arises when using pptp(gre) tunnels also.
    MPD version 5.7 (also tried on 5.6)
    FreeBSD 9.2 (also tried on 9.1, 8.3)

    So, is there any way to avoid losing fragmented packets if MPD receives fragments disordered?

     
    Last edit: valeryprok 2014-02-20
  • mpd does not receive and send packets. All packets going inside netgraph's nodes. You must enable netgraph debugging and find, what is wrong.

     
  • PPP stack relies on correct packet ordering. That is why PPTP, L2TP and other tunnel transports should have sequence numbers and drop packets received out of order. You can disable L2TP dataseq option in mpd to make it ignore packet order, but that is on your own risk. Especially that is important if you are using any form of stateful traffic compression.

     
    • valeryprok
      valeryprok
      2014-02-21

      Thank you!
      This option made my case work for L2TP.
      But for PPTP there is no such option, isn't it?