this has to be a bug...

Dave Johnson dave-gnhlug at davej.org
Sat Mar 25 00:43:01 EST 2006


Paul Lussier writes:
> 
> >From the 'More for your dollar' department:
> 
[snip]
>    $ sudo /sbin/ifconfig eth0:0 del 10.107.33.189
>    $ ifconfig
[snip]
>    eth0:0:1  Link encap:Ethernet  HWaddr 00:0C:F1:E2:A8:6B  
>              inet addr:10.107.33.189  Bcast:0.0.0.0  Mask:0.0.0.0
>              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
>              Base address:0xac00 Memory:ff7e0000-ff800000 
[snip]
> 
> I ask to delete a non-existent interface, and instead, I get a totally
> new one I didn't ask for :)


Ya, a bug in net-tools, but you are using an invalid syntax.  Buggy
software and sudo definately dont mix :(

Calling 'del' with an IPv4 IP on an interface that doesn't exist
causes the call to for_all_interfaces() from set_ifstate() to not find
the interface.  It doesn't handle this case and assumes you want to
add the address as a secondary address on the base interface.


Two bugs here:

1) del with IPv4 actually adds if what you specify doesn't exist.

2) add and del assume you only call it with a parent interface name
   'eth0' not 'eth0:<anything here>' adding a second ':nnn' anyway.

The following actually work:

ifconfig eth0 add 10.107.33.189
ifconfig eth0 del 10.107.33.189

but run 'del' a second time and it adds it back, but with the correct
name (bug)



see below:

(gdb) r
Starting program: /tmp/net-tools-1.60/ifconfig eth0:0 del 10.107.33.189

Breakpoint 1, set_ifstate (parent=0xbf8a1a10 "eth0:0", ip=3173083914, nm=0, 
    bc=0, flag=0) at ifconfig.c:1118
1118        pt.base = parent;
(gdb) n
1119        pt.baselen = strlen(parent);
(gdb) 
1121        pt.flag = flag;
(gdb) 
1120        pt.addr = ip;
(gdb) 
1122        memset(searcher, 0, sizeof(searcher));
(gdb) 
1121        pt.flag = flag;
(gdb) 
1122        memset(searcher, 0, sizeof(searcher));
(gdb) 
1123        i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd, 
(gdb) p pt
$4 = {flag = 0, addr = 3173083914, base = 0xbf8a1a10 "eth0:0", baselen = 6}
(gdb) n
1125        if (i == -1)
(gdb) 
1127        if (i == 1)
(gdb) p i
$5 = 0
(gdb) n
1131        for (i = 0; i < 256; i++)
(gdb) 
1132            if (searcher[i] == 0)
(gdb) 
1131        for (i = 0; i < 256; i++)
(gdb) p searcher
$6 = "\001", '\0' <repeats 254 times>
(gdb) n
1132            if (searcher[i] == 0)
(gdb) 
1135        if (i == 256)
(gdb) 
1138        if (snprintf(buf, IFNAMSIZ, "%s:%d", parent, i) > IFNAMSIZ)
(gdb) p parent
$7 = 0xbf8a1a10 "eth0:0"
(gdb) n
1140        if (set_ip_using(buf, SIOCSIFADDR, ip) == -1)
(gdb) p buf
$8 = "eth0:0:1\000\031\212¿W¹\004\b"
(gdb) p ip
$9 = 3173083914
(gdb) p /x ip
$10 = 0xbd216b0a
(gdb) show endian
The target endianness is set automatically (currently little endian)
(gdb) 


SIOCSIFADDR on 'eth0:0:1' will create the interface.  Kernel is doing
what it's told although with a very non-standard interface name.  As
long as it starts with 'eth0:' it considers it an alias.


-- 
Dave





More information about the gnhlug-discuss mailing list