On Dec 18, 1:29*am, Florian Weingarten <f...@go.cc> wrote:
> Hm. Then maybe I misunderstood something. Some manpage I found
> on the web says:
Definitely.
> SO_BINDTODEVICE
> * * Bind this socket to a particular device like "eth0", as specified
> * * in the passed interface name. (...) If a socket is bound to an
> * * interface, only packets received from that particular interface are
> * * processed by the socket. Note that this only works for some socket
> * * types, particularly AF_INET sockets
This is mostly correct. Note that "received from that particular
interface" does not mean what you think it means. Specifically, this
does not mean that if you bind to an Ethernet interface, only packets
received over the wire connected to that physical interface will be
processed by the socket.
> And some really old kernel docu I found says:
>
> *Once the BINDTODEVICE socket option has been set for a socket, as above,
> *any data sent over this socket is guaranteed to go out of the "eth1"
> *interface, and any data received through the socket is guaranteed to
> *have arrived on eth1. (...) Note that the routing table is still
> *consulted when packets are transmitted. Basically, routing proceeds
> *as usual, except that any routes which go through a network interface
> *other than the one specified in the BINDTODEVICE call are ignored.
This is not correct for TCP or UDP. It is correct for raw.
> > If taking the right interface, according to the routing table, doesn't
> > work, then the routing table is wrong. You cannot fake around that
> > with anything but system-level policy routing.
> Well, to be concrete. What I want to do is to write a small tunnel
> software (as a university exercise). I have a default route for some
> network which goes to the tun0 interface, and the userspace program
> which is associated with that tun0 interface (the "daemon") is then
> supposed to send the raw packets, encapsulated as UDP packets, to
> the destination host, but of course I cant just send them, because
> then they would get delivered to the tun interface again (because
> of the route for that net!). So I wanted something like "this
> particular program should NOT use that route, all others should!".
> SO_BINDTODEVICE sounded like a solution :-(
The usual way is to make a more specific route for the other end of
the tunnel. Alternatively, you can use policy routing. As is, your
routing table is simply disastrously wrong, it has an implosion route
for the other end of the tunnel. Nothing you can do to one particular
socket can fix the fact that your routing table is wrong.
> > Depending on your application, the right solution might also be to use
> > raw sockets or bpf.
> Why? Whats the difference? Does SO_BINDTODEVICE does what I want,
> except it does not work with UDP/TCP, but with RAW sockets? Why is
> that?
Because the kernel's implementation of UDP/TCP has to have certain
assumptions for its own sanity. One of them is that the routing table
does not contain fatal defects such as implosion routes. If you want
to use the kernel's UDP/TCP, you must make sure the assumptions it
relies on are in fact correct. One of them is that routing table
doesn't contain routes that fail horribly.
> Does that mean I have to use RAW sockets, then create my own
> UDP packet (create the headers myself and stuff) and then it would
> work?
You could do it that way. The preferred way is either a more-specific
route for the other end of the tunnel or not using UDP as the
encapsulation protocol.
DS
|