Subject: possible kernel NAT-T bug
To: None <>
From: Emmanuel Dreyfus <>
List: tech-net
Date: 12/06/2005 09:01:24

When the kernel receive an ESP over UDP packet, here is the code path:
udp_input() -> udp4_realinput() - udp4_espinudp()

Each function sends struct mbuf *m to the next one. But in udp4_espinudp(), 
we have:

        if (m->m_len < minlen) {
                if ((m = m_pullup(m, minlen)) == NULL) {
                        printf("udp4_espinudp: m_pullup failed\n");
                        return 0;

Two problems can arise
1) m_pullup relocates trhe mbuf, which changes m address. When returning in 
udp4_realinput(), the local value of m will be invalid, thus leading to a 

2) m_pullup fails and sets m to NULL. udp4_realinput() idea of m is still non
NULL and it will try to deallocate it, thus getting a panic.

I'm not sure of the right fix. If I have udp4_realinput() giving a 
struct mbuf ** to udp4_espinudp(), it will see the change, but udp_input()
will not. 

If I duplicate the mbuf, I get a performance hit.

What is the proper fix? 

Emmanuel Dreyfus