Thread (13 messages) flat view 13 messages, 5 authors, 2007-03-27

Re: [PATCH 1/5 2.6.21-rc4] l2tp: pppol2tp core

From: Patrick McHardy <hidden>
Date: 2007-03-27 14:38:37

James Chapman wrote:
quoted
quoted
Wouldn't that effectively duplicate the code in udp_sendmsg()? If I
don't use a socket, I'd also have to build an IP header and feed the
frame into the IP stack for outbound routing. It doesn't feel like the
right thing to do.

Thats what other tunnel drivers do. Sending UDP is pretty simple, I'd
expect that it comes down to less code than now.

I'm still not getting this. :( What other tunnel drivers do this?

Building their own IP-header: ipip, ip_gre.
Building their own UDP-header: esp[46].c
I've looked at other socket code examples. I see sendmsg code like pppoe
which builds a skb and does a dev_queue_xmit() or code like cifs that
uses kernel_sendmsg() which does the set_fs hack internally.

I don't think CIFS is an example that should be copied from. PPPoE
is a bit different since it wants to transmit directly to an ethernet
device and takes care of building the ethernet header itself.
ESP does build its own UDP header. But ESP is working at a different
level (IP packet type) rather than L2TP which is really just UDP data.

I don't see the difference. Both receive packets from somewhere,
encapsulate them and send them out.
Most of the stuff done in udp_sendmsg() is relevant for L2TP, i.e.
socket param checks, UDP checksum, flow classification, route lookup, IP
output, MIB counter updates etc. If I do all of this in
pppol2tp_sendmsg() and insert the IP and UDP header, should I also
insert the netdevice's MAC address and then dev_queue_xmit()? I'd just
like to be clear in my own mind what you are recommending before I code
it up. :)

On the send-side you can simply add an UDP- and IP-header, compute the
checksums, route the packet and send it out using dst_output. The MAC
address is automatically inserted by the IP layer. You could also
(internally) use a socket per tunnel and use ip_queue_xmit, which takes
care of building the IP header, routing the packet, so all you need to
do is add the UDP header and compute the checksum. The advantages are:

- no set_fs hacks
- no need for a seperate TX thread
- probably a lot less and cleaner code
My understanding is that encapsulation is used where a header is
inserted _before_ UDP/TCP headers, not after. In the L2TP case, the
kernel has some data that it wants to send over UDP. The UDP socket
doesn't need to be special.

The name encapsulation socket may be misleading since its only
used on the receive side, decapsulation socket might be better
fitting. What it does is allow you to receive packets from a
UDP socket without going through the socket queue and using
recvmsg and to process it immediately while in NET_RX_SOFTIRQ.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help