This has been around for too long:
[root@scox root]# ifconfig eth0:1 192.168.120.12/22
SIOCSIFNETMASK: Cannot assign requested address
[root@scox root]# ifconfig eth0:1 192.168.120.12/22
[root@scox root]#
First time it fails to assign the specified netmask apparently because
it is attempting to do so _before_ assigning the address. Second time it
succeeds as the interface already has an address.
OTOH:
[root@scox root]# ifconfig eth0:1 192.168.120.12 netmask
255.255.252.0
[root@scox root]#
succeeds the first time since the actions are executed in the right
order: SIOCSIFADDR _then_ SIOCSIFNETMASK.
This patch against net-tools-1.60 defers the netmask ioctl when using
implicit/CIDR notation till after the address has been assigned. IOW, it
makes the 2 commands equivalent (as some of us might expect ;).
--
Florin Malita <florin.malita(a)glenayre.com>
diff -aur net-tools-1.60.orig/ifconfig.c net-tools-1.60.new/ifconfig.c
--- net-tools-1.60.orig/ifconfig.c 2001-04-13 14:25:18.000000000
-0400
+++ net-tools-1.60.new/ifconfig.c 2004-08-31 17:07:38.362758712
-0400
@@ -23,6 +23,7 @@
* 20001008 - Bernd Eckenfels, Patch from RH for setting mtu
* (default AF was wrong)
* 20010404 - Arnaldo Carvalho de Melo, use setlocale
+ * 20040831 - Florin Malita <fmalita(a)glenayre.com> delayed
CIDR netmask
*/
#define DFLT_AF "inet"
@@ -227,13 +228,13 @@
int main(int argc, char **argv)
{
- struct sockaddr sa;
+ struct sockaddr sa, sa_netmask;
struct sockaddr_in sin;
char host[128];
struct aftype *ap;
struct hwtype *hw;
struct ifreq ifr;
- int goterr = 0, didnetmask = 0;
+ int goterr = 0, didnetmask = 0, donetmask = 0;
char **spp;
int fd;
#if HAVE_AFINET6
@@ -903,16 +904,16 @@
/* FIXME: sa is too small for INET6 addresses, inet6 should use
that too,
broadcast is unexpected */
if (ap->getmask) {
- switch (ap->getmask(host, &sa, NULL)) {
+ switch (ap->getmask(host, &sa_netmask, NULL)) {
case -1:
usage();
break;
case 1:
if (didnetmask)
usage();
-
- goterr = set_netmask(skfd, &ifr, &sa);
- didnetmask++;
+
+ /* delay setting the CIDR netmask till after setting the
addr */
+ donetmask = 1;
break;
}
}
@@ -960,6 +961,13 @@
}
}
+ /* set CIDR netmask */
+ if (donetmask){
+ donetmask = 0;
+ goterr = set_netmask(skfd, &ifr, &sa_netmask);
+ didnetmask++;
+ }
+
/*
* Don't do the set_flag() if the address is an alias with a -
at the
* end, since it's deleted already! - Roman