Skip to contentSkip to conversation

New: tun device without protocol info header fails under IPv6

Bugme-new Andrew Morton 2 participants 2 messages Feb 4, 2008 – Feb 8, 2008 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]/

#1 lore raw
Quoted 62 lines · On Mon, 4 Feb 2008 13:46:13 -0800 (PST) [email protected] wrote:

http://bugzilla.kernel.org/show_bug.cgi?id=9888

           Summary: tun device without protocol info header fails under IPv6
           Product: Networking
           Version: 2.5
     KernelVersion: >=2.6.23
          Platform: All
        OS/Version: Linux
              Tree: Mainline
            Status: NEW
          Severity: low
          Priority: P1
         Component: IPV6
        AssignedTo: [email protected]
        ReportedBy: [email protected]

Latest working kernel version: None known -- appears to be a historic bug Earliest failing kernel version: All
Distribution:
Hardware Environment:
Software Environment:
Problem Description:

Steps to reproduce:

Open a tun device as type TUN, set the TUN_NO_PI flag, and try sending an IPv6 packet. The packet appears at the interface under tcpdumps, but propagates no further. This is because the default protocol info used for tun devices where the TUN_NO_PI flag is set assumes IPv4 as can be seen by the initialization at the top of the tun_get_user function in drivers/net/tun.c file given by

        struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };

This can easily be fixed by adding a quick check at the top of tun_get_user. Basically the code that used to read

        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > count)
                        return -EINVAL;

                if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
                        return -EFAULT;
        }

when changed to read

        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > count)
                        return -EINVAL;

                if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
                        return -EFAULT;
        }
        else {
          /* Fixup default pi if IPv6 rather than IPv4 */
          if (((tun->flags & TUN_TYPE_MASK) == TUN_TUN_DEV) &&
              (*(char *)(iv->iov_base)      == 0x60)) {
            pi.proto = __constant_htons(ETH_P_IPV6);
          }
        }
Quoted 4 lines

fixes the problem.

How do we get this in as part of the maintained codebase??

Please email a tested patch prepared as described in

Documentation/SubmittingPatches
Documentation/SubmitChecklist
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

to

Maxim Krasnyansky <[email protected]>
"David S. Miller" <[email protected]>
Andrew Morton <[email protected]>
[email protected]

thanks.

#2 lore raw
Quoted 50 lines · Andrew Morton
Quoted 37 lines · On Mon, 4 Feb 2008 13:46:13 -0800 (PST) [email protected] wrote:

Open a tun device as type TUN, set the TUN_NO_PI flag, and try sending an IPv6 packet. The packet appears at the interface under tcpdumps, but propagates no further. This is because the default protocol info used for tun devices where the TUN_NO_PI flag is set assumes IPv4 as can be seen by the initialization at the top of the tun_get_user function in drivers/net/tun.c file given by

        struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };

This can easily be fixed by adding a quick check at the top of tun_get_user. Basically the code that used to read

        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > count)
                        return -EINVAL;

                if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
                        return -EFAULT;
        }

when changed to read

        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > count)
                        return -EINVAL;

                if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
                        return -EFAULT;
        }
        else {
          /* Fixup default pi if IPv6 rather than IPv4 */
          if (((tun->flags & TUN_TYPE_MASK) == TUN_TUN_DEV) &&
              (*(char *)(iv->iov_base)      == 0x60)) {
            pi.proto = __constant_htons(ETH_P_IPV6);
          }
        }
Quoted 4 lines

fixes the problem.

How do we get this in as part of the maintained codebase??

Please email a tested patch prepared as described in

Documentation/SubmittingPatches
Documentation/SubmitChecklist
http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt

Quoted 6 lines

to

Maxim Krasnyansky <[email protected]>
"David S. Miller" <[email protected]>
Andrew Morton <[email protected]>
[email protected]

btw I'd be ok with this fix. But I guess the questions is why not use struct tun_pi in the apps instead ?

Max