Squid doesn't use SO_BINDTODEVICE on Linux

From: Dave Zarzycki <zarzycki@dont-contact.us>
Date: Tue, 2 Dec 97 17:22:20 -0800

(Sorry for the cross post.)

Well, I have discovered that squid doesn't use SO_BINDTODEVICE. This
feature could prove to be useful for some people, such as the recent
message posted to squid-users by jeff@lys.com. The example code in
/usr/src/linux/Documentation/so_bindtodevice.txt should help, but I don't
know of a system call that can find out what interface an IP address is
attached to. Anybody care to give it a try? I am but a mere programmer of
one semester of C++ so far, so don't expect me to come up with a patch
within the next month or so...


From /usr/src/linux/Documentation/so_bindtodevice.txt :

SO_BINDTODEVICE socket option for Linux 2.0.30+
by Elliot Poger (elliot@poger.com)
of Stanford's MosquitoNet project (http://mosquitonet.stanford.edu)

Using the SO_BINDTODEVICE socket option allows your user-level Berkeley
sockets code to explicitly select which network interface is used for
both input and output on a per-socket basis. I originally wrote it to
allow the Internet Software Consortium DHCP server
(http://www.fugue.com/dhcp/) to run on Linux machines with multiple
interfaces. It has been tested with UDP and TCP sockets.

Usage is as follows:

        int skfd;
        struct ifreq interface;

        skfd = socket(AF_INET, SOCK_DGRAM, 0);
        strncpy(interface.ifr_ifrn.ifrn_name, "eth1", IFNAMSIZ);
        if (setsockopt(skfd, SOL_SOCKET, SO_BINDTODEVICE,
                       (char *)&interface, sizeof(interface)) < 0) {
                perror("sendpacket: setting SO_BINDTODEVICE");

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. If you want to send and receive over multiple
interfaces, keeping them separate, you can open several sockets and bind
each one to a different interface with SO_BINDTODEVICE. (You _can_ call
BINDTODEVICE more than once for a socket to change the interface it's
bound to, but results may be unpredictable because of caching effects
in the kernel...)

Note that the routing table is still consulted when packets are
Basically, routing proceeds as usual, except that any routes which go
through a network interface other than the one specified in the
call are ignored. If you attempt to send a packet to a certain IP address
through an interface which provides no route to that IP address, you'll
a "network unreachable" error. Here is an example of a routing table
will allow you to send packets to any IP address through either eth0 or

Destination Gateway Genmask Flags Metric Ref Use
Iface U 0 0 37
eth0 U 0 0 677
eth1 U 0 0 4 lo UG 0 0 45
eth0 UG 1 0 5

Note that there are actually TWO default routes. The routing table is
searched from top to bottom, so every time you send out a packet, the
(uppermost) matching route which the kernel routing function finds which
matches the destination IP address is used. In this case, packets sent to
the IP address will normally be sent through eth0 and
gateway; if the socket is bound to the eth1 device, the packets will
sent through eth1 and gateway; if the socket is bound to
other device, you will get a "network unreachable" error.

By the way, you can add multiple default routes and set the order of
preference as follows:

route add default gateway
route add default gateway metric 1

Routes with a higher "metric" are put lower in the table and thus have a
lower preference.

Dave Zarzycki Student
Intern San Jose State University
Apple Computer, Inc. dzarzyck@email.sjsu.edu
zarzycki@apple.com zarzycki@ricochet.net
PGP Fingerprints (RSA): 8AF2 1040 8A9C D025 47BE 70DD A51C C887
DSS/Diffie-Hellman: CB9E 2621 B4BA 3F96 3516 B312 15B4 D842 3809 EF99
Contact pgpkeys.mit.edu for my public keys.
Received on Tue Dec 02 1997 - 17:24:37 MST

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:37:49 MST