udev and allow-hotplug on ubuntu and debian

I finally got bothered enough to fix the /etc/network/interfaces problem on my Ubuntu notebook. The problem is that when my neo got connected, I want to do some automatic setup. On Debian lenny, it’s quite easy:

1
2
3
4
5
6
7
8
allow-hotplug usb0
iface usb0 inet static
address 192.168.0.200
netmask 255.255.255.0
post-up iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
pre-down echo 0 > /proc/sys/net/ipv4/ip_forward
pre-down iptables -t nat -D POSTROUTING -s 192.168.0.0/24 -j MASQUERADE

But on Ubuntu gutsy it doesn’t work. I have to replace “allow-hotplug” by “auto”. Even if I changed that, it will only work for the first time you plugged the device. That’s because of a bug listed here. The solution is to remove the DRIVER="?*" in /etc/udev/rules.d/85-ifupdown.rules.

Now, finally, if works even after multiple plug/unplug. However, there is still one problem left: “auto usb0” basically means the system will try to bring up the device during booting. It works for “lo”, the local loopback network interface because it’s always there. But the usb0 won’t be there everytime we boot. That causes some error messages. My solution is to modify /etc/udev/rules.d/85-ifupdown.rules again, replace “auto” by “hotplug”, and use “allow-hotplug usb0” in my /etc/network/interfaces . The final 85-ifupdown.rules looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# This file causes network devices to be brought up or down as a result
# of hardware being added or removed, including that which isn't ordinarily
# removable.
# See udev(7) for syntax.

SUBSYSTEM=="net", GOTO="net_start"
GOTO="net_end"

LABEL="net_start"

# Bring devices up and down only if they're marked auto.
# Use start-stop-daemon so we don't wait on dhcp
ACTION=="add", RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifup -- --allow hotplug $env{INTERFACE}"

ACTION=="remove", RUN+="/sbin/start-stop-daemon --start --background --pidfile /var/run/network/bogus --startas /sbin/ifdown -- --allow hotplug $env{INTERFACE}"

LABEL="net_end"

Some further digging shows the difference between debian lenny and ubuntu gutsy in the handling of the “interfaces” file. On Debian:

1
2
john@buddha:/etc/udev/rules.d$ grep net.agent *
80-drivers.rules:SUBSYSTEM=="net", RUN+="net.agent"

so it runs net.agent, a script under /lib/udev/ to bring up the interfaces. On Ubuntu, this is simply the job of the 85-ifupdown.rules above.