kern/95031: [patch] routing table doesn't update corectly while
adding new interface address
Bartłomiej Leszak
fixer at 2a.pl
Tue Mar 28 09:20:18 UTC 2006
>Number: 95031
>Category: kern
>Synopsis: [patch] routing table doesn't update corectly while adding new interface address
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Mar 28 09:20:16 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Bartłomiej Leszak
>Release: 6.0
>Organization:
>Environment:
FreeBSD six.2a.pl 6.0-RELEASE-p4 FreeBSD 6.0-RELEASE-p4 #3: Tue Mar 28 08:41:50 CEST 2006 root at six.2a.pl:/usr/obj/usr/src/sys/SIX i386
>Description:
While adding new address to the interface the routing table doesn't update if the network address has the same prefix as the existing route. It's not a problem if it's the same interface, but could be really annoying with machines with many interfaces. Problem occurred in 5.4 and later.
>How-To-Repeat:
Add to rc.conf:
ifconfig_em0="inet 10.0.0.91 netmask 255.255.0.0"
ifconfig_em1="inet 10.1.0.1 netmask 255.0.0.0"
reboot, and look at "netstat -nr"
>Fix:
Down the interface and up it again with: ifconfig em0 down && ifconfig em0 up or change your network configuration in the way, that none of the networks will have the same prefixes in the routing table:
ifconfig_em0="inet 10.2.0.91 netmask 255.255.0.0"
ifconfig_em1="inet 10.1.0.1 netmask 255.0.0.0"
for the above.
The problem is that layout of /usr/src/sys/netinet/in.c changed in 5.4. While adding new address to the interace the in_addprefix() function is invoked to update routing table. This function checks only the prefixes in routing table which is correct in most cases.
The code that does it is like this:
>From line 809 in /usr/src/sys/netinet/in.c:
if (rtinitflags(ia))
p = ia->ia_dstaddr.sin_addr;
else {
p = ia->ia_addr.sin_addr;
p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
}
if (prefix.s_addr != p.s_addr)
continue;
To make it working the check "if (prefix.s_addr != p.s_addr)" needs to be changed to something like this:
"if ((prefix.s_addr != p.s_addr) | (!((prefix.s_addr == p.s_addr) &&(mask.s_addr == ia->ia_sockmask.sin_addr.s_addr))))"
to make sure we really don't have the same route.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list