Fix bugs concerning cached route entry in UDP inpcb.
commit2d127eb08adbaaed0131a43e458c3d3de28fe9f0
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 26 Mar 2008 14:44:59 +0000 (26 14:44 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 26 Mar 2008 14:44:59 +0000 (26 14:44 +0000)
tree7b99e687609b4caf10c8be872682c483b2002b32
parentca4e42fb97613e68d67d5e9a387584bd63faeb95
Fix bugs concerning cached route entry in UDP inpcb.

For an unconnected and unbound UDP socket, first sending calls in_pcbladdr()
to fix the local port, which may change the target CPU of the next sending.
in_pcbladdr() has a side effect to allocate the route entry cached in inpcb.
If the target CPU after in_pcbladdr() is no longer the current CPU, then
the route entry will be accessed/freed on non-owner CPU during later sending.
Similarly, connect/disconnect a UDP socket may change the target CPU too; the
target CPU may no longer the owner of the cached route entry.

So, for the first sending happens on an unconnected and unbound UDP socket,
the target CPU of next sending is compared with the current CPU.  If they
are different, then cached route entry will be freed, so next time a packet
sent on this socket, a new route entry owned by the correct CPU will be
cached.  Same target CPU check is applied to UDP socket connect/disconnect.

Originally UDP PRU_CONNECT always happens on CPU0, which will cause problem if
following conditions are met:
- Dst of the cached route entry is different from the dst to be connected
- Cached route entry is not allocated on CPU0
This could happen if two datagram are sent on an unbounded and unconnected UDP
socket, then later connectting this UDP socket will cause cached route entry
being freed on different CPU.  To solve this problem, PRU_CONNECT is dispatched
according to existing [lf]{addr,port} pairs.

If in_pcbladdr() fails after altering the cached route entry, the cached route
entry is freed to make sure that freeing this cached route entry happens on
its owner CPU.

Reported-by: y0netan1@
Tested-by: y0netan1@
sys/netinet/in_pcb.c
sys/netinet/ip_demux.c
sys/netinet/udp_usrreq.c