Synopsis:      route(8): add treats 0.0.0.0/ANYTHING as default route
Category:      system
Environment:
        System      : OpenBSD 4.9
Details : OpenBSD 4.9 (GENERIC) #477: Wed Mar 2 06:50:31 MST 2011

[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC

        Architecture: OpenBSD.amd64
        Machine     : amd64
Description:
"route add" understands CIDR prefixes (eg, a.b.c.d/22) for most purposes, and they are used as examples in the man page, so that it is possible to add routes for subnets simply by specifying the CIDR prefix, and without using "-netmask" or "-prefixlen".

However if a.b.c.d is 0.0.0.0, then irrespective of the prefix length specified in the CIDR prefix, "route add" will always (try to) add a default route, even though it will report the whole CIDR prefix (including the specified length) as being processed.

It is possible to add a subnet starting at 0.0.0.0 using "-netmask" or "-prefixlen". But since only 0.0.0.0/0 is equivalent to default in CIDR notation, only 0.0.0.0 or 0.0.0.0/0 should be treated as the default route. The rest should be treated like subnets. (Subnets starting at 0.0.0.0 are useful to add "more specifics" for a default route that will be preferred by the routing engine; in my case to work around ripd limitations.)

How-To-Repeat:
Example session below showing incorrect handling of 0.0.0.0/LEN compared with -prefixlen and -netmask. Plus correct handling of eg, 128.0.0.0/LEN.

ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
ewen@fw-test:~$ sudo route add 0.0.0.0/1 172.20.2.42
add net 0.0.0.0/1: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
default            172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete default
delete net default
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$ sudo route add 0.0.0.0/31 172.20.2.42
add net 0.0.0.0/31: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
default            172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete default
delete net default
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$ sudo route add 0.0.0.0 -prefixlen 31 172.20.2.42
add net 0.0.0.0: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
0.0.0.0/31         172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete 0.0.0.0 -prefixlen 31
delete net 0.0.0.0
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$ sudo route add 0.0.0.0 -prefixlen 1 172.20.2.42
add net 0.0.0.0: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
0/1                172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete 0.0.0.0 -prefixlen 1
delete net 0.0.0.0
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$ sudo route add 0.0.0.0 -netmask 128.0.0.0 172.20.2.42
add net 0.0.0.0: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
0/1                172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete 0.0.0.0 -netmask 128.0.0.0
delete net 0.0.0.0
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$

ewen@fw-test:~$ sudo route add 128.0.0.0/31 172.20.2.42
add net 128.0.0.0/31: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
128.0.0.0/31       172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete 128.0.0.0/31
delete net 128.0.0.0/31
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$ sudo route add 128.0.0.0/1 172.20.2.42
add net 128.0.0.0/1: gateway 172.20.2.42
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
128/1              172.20.2.42        UGS        0        0     -     8 em0
172.20.2.42        link#1             UHLc       1        0     -     4 em0
ewen@fw-test:~$ sudo route delete 128.0.0.0/1
delete net 128.0.0.0/1
ewen@fw-test:~$ netstat -nr -finet | grep 172.20.2.42
172.20.2.42        link#1             UHLc       0        0     -     4 em0
ewen@fw-test:~$

Fix:
"route add" should treat "a.b.c.d/NN" as equivalent to "a.b.c.d -prefixlen NN", and only consider 0.0.0.0 or 0.0.0.0/0 as equivalent to default. Not every possible string starting with 0.0.0.0.

I've not read through the source code, but suspect this is a too-greedy special case handler (for default route) in the route binary.


dmesg:
OpenBSD 4.9 (GENERIC) #477: Wed Mar  2 06:50:31 MST 2011
    [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC
real mem = 535801856 (510MB)
avail mem = 507539456 (484MB)
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.4 @ 0x1ffffef0 (10 entries)
bios0: vendor Bochs version "Bochs" date 01/01/2007
bios0: Bochs Bochs
acpi0 at bios0: rev 0
acpi0: sleep states S3 S4 S5
acpi0: tables DSDT FACP SSDT APIC HPET
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
acpihpet0 at acpi0: 100000000 Hz
acpiprt0 at acpi0: bus 0 (PCI0)
acpicpu0 at acpi0
mpbios0 at bios0: Intel MP Specification 1.4
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Opteron or Athlon 64, 2660.26 MHz
cpu0: FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,PGE,CMOV,PAT,MMX,FXSR,SSE,SSE2,SSE3,POPCNT
cpu0: apic clock running at 1000MHz
mpbios0: bus 0 is type PCI
mpbios0: bus 1 is type ISA
ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 11, 24 pins
ioapic0: misconfigured as apic 0, remapped to apid 1
vmt0 at mainbus0
vmware: open failed, eax=564d5868, ecx=0000001e, edx=00005658
vmt0: failed to open backdoor RPC channel (TCLO protocol)
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371SB IDE" rev 0x00: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <QEMU HARDDISK>
wd0: 16-sector PIO, LBA48, 20480MB, 41943040 sectors
wd0(pciide0:0:0): using PIO mode 0, DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus0 at atapiscsi0: 2 targets
cd0 at scsibus0 targ 0 lun 0: <QEMU, QEMU DVD-ROM, 0.12> ATAPI 5/cdrom removable
cd0(pciide0:1:0): using PIO mode 0
uhci0 at pci0 dev 1 function 2 "Intel 82371SB USB" rev 0x01: apic 1 int 11 (irq 11) piixpm0 at pci0 dev 1 function 3 "Intel 82371AB Power" rev 0x03: apic 1 int 9 (irq 9)
iic0 at piixpm0
iic0: addr 0x4c 48=00 words 00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000 iic0: addr 0x4e 48=00 words 00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000
vga1 at pci0 dev 2 function 0 "Cirrus Logic CL-GD5446" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
em0 at pci0 dev 3 function 0 "Intel PRO/1000MT (82540EM)" rev 0x03: apic 1 int 11 (irq 11), address 00:16:3e:03:48:48
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
fd0 at fdc0 drive 0: density unknown
fd1 at fdc0 drive 1: density unknown
usb0 at uhci0: USB revision 1.0
uhub0 at usb0 "Intel UHCI root hub" rev 1.00/1.00 addr 1
nvram: invalid checksum
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
root on wd0a swap on wd0b dump on wd0b
clock: unknown CMOS layout

usbdevs:
Controller /dev/usb0:
addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), Intel(0x8086), rev 1.00
 port 1 powered
 port 2 powered

Reply via email to