Re: ifconfig, CIDR and default broadcast address

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 20 Dec 2000, Nicholas Dronen wrote:

[...]
> $ strace -e trace=ioctl ifconfig eth0:1 >/dev/null

More correctly, we need to look at happens when an interface's parameters
are set (the above cause a bunch of SIOG*, i.e. getting parameter values):

-----------------------------------------------------------------------
gull:~# ifconfig dummy0 down
gull:~# strace -e trace=ioctl ifconfig dummy0 10.42.42.0 netmask 255.255.0.0
ioctl(4, SIOCSIFADDR, 0xbffffc6c)       = 0
ioctl(4, SIOCGIFFLAGS, 0xbffffbbc)      = 0
ioctl(4, SIOCSIFFLAGS, 0xbffffbbc)      = 0
ioctl(4, SIOCSIFNETMASK, 0xbffffc6c)    = 0
gull:~# ifconfig dummy0
dummy0    Link encap:Ethernet  HWaddr 00:00:00:00:00:00
          inet addr:10.42.42.0  Bcast:10.255.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING NOARP  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
-----------------------------------------------------------------------

[...]
> I believe the problem is *not* with the kernel, which should
> provide mechanism, not policy.  Rather, ifconfig needs to 
> pass more appropriate values in the struct ifreq when issuing
> the SIOCSIFBRDADDR ioctl.

That argument is not without merit, but I remain unconvinced.

The counter-argument is that currently the kernel is, having been supplied
with an address and mask, conjuring up an incorrect broadcast address
based on a classful view of things.  IMHO, an address and mask are
sufficient data from which to derive the correct broadcast.

> Regarding where in the kernel this is handled, see:
[snip]
> net/ipv4/devinet.c:devinet_ioctl()	# where the real work is done

This is the one that interests me right now.  I was trying to make some
sense of it (on the train home!) and might be getting somewhere.

In devinet_ioctl there is a big "switch(cmd)".  In that we see that
setting the address also causes setting both ifa_prefixlen by classful
logic and ifa_mask from ifa_prefixlen; then the broadcast address is set
as ifa_address|~ifa_mask - i.e. along classful lines.

Mmm... does this imply that changing the IP address of an interface will
reset its mask to the classful default?

This suggests that, except for classful masks, we must always follow any
setting of IP address by a setting of the mask (even if the mask remained
constant when the address was changed).  That being the case, it's not
unreasonable to consider always setting the broadcast address when the
mask is set.

Untested diff attached.  This is from net/ipv4/devinet.c 1.28.2.4 from
kernel 2.2.18.

Regards,
Neale.
--- devinet.c	Mon Dec 11 11:49:44 2000
+++ devinet.c.nb0	Wed Dec 20 22:21:43 2000
@@ -590,6 +590,16 @@
 				inet_del_ifa(in_dev, ifap, 0);
 				ifa->ifa_mask = sin->sin_addr.s_addr;
 				ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
+				/*
+				 * In a CIDR-world, it's probably a Good Idea
+				 * to update the Broadcast address when the
+				 * netmask is changed.  Note that this could
+				 * surprise someone who has set the broadcast
+				 * non-standard and then sets the netmask.
+				 * Neale Banks <neale@lowendale.com.au>
+				 * Wed, 20 Dec 2000 19:56:54 +1100
+				 * /
+				ifa->ifa_broadcast = ifa->ifa_address|~ifa->ifa_mask;
 				inet_set_ifa(dev, ifa);
 			}
 			break;

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux