2001-07-24 14:48:15

by Andries E. Brouwer

[permalink] [raw]
Subject: ifconfig and SIOCSIFADDR

I just noticed that the command

ifconfig eth1 netmask 255.255.255.0 broadcast 10.0.0.255 10.0.0.150

(with ifconfig from net-tools-1.60)
results in a netmask of 255.0.0.0, which is wrong in my situation.

Why does ifconfig ignore the explicitly given netmask?
Because it does SIOCSIFNETMASK, then SIOCSIFBRDADDR, then SIOCSIFADDR,
and the last ioctl destroys the information set by the previous two.

I consider this a kernel bug, but the code has been in the kernel
for a long time. In 2.2 and 2.4 it is (devinet.c):

case SIOCSIFADDR:
...
if (!(dev->flags&IFF_POINTOPOINT)) {
ifa->ifa_prefixlen = inet_abc_len(ifa->ifa_address);
ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
if ((dev->flags&IFF_BROADCAST) && ifa->ifa_prefixlen < 31)
ifa->ifa_broadcast = ifa->ifa_address|~ifa->ifa_mask;
} else {
ifa->ifa_prefixlen = 32;
ifa->ifa_mask = inet_make_mask(32);
}

and in 2.0 it is (net/core/dev.c):

case SIOCSIFADDR:
...
/* This is naughty. When net-032e comes out It wants moving
into the net032 code not the kernel. Till then it can sit
here (SIGH) */
if (!dev->pa_mask)
dev->pa_mask = ip_get_mask(dev->pa_addr);
if (!dev->pa_brdaddr)
dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;

that is, 2.0 and earlier will only (reluctantly) set netmask and
broadcast address when it was not set already.

Probably things should be corrected both in the kernel and in ifconfig:
SIOCSIFADDR should not change netmask and broadcast address,
and ifconfig should assume that SIOCSIFADDR may be destructive
and hence wait with setting netmask and broadcast address
until after the SIOCSIFADDR.

Andries



2001-07-24 16:05:40

by Ingo Oeser

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

Hi Andries,

On Tue, Jul 24, 2001 at 02:47:56PM +0000, [email protected] wrote:
> I just noticed that the command
>
> ifconfig eth1 netmask 255.255.255.0 broadcast 10.0.0.255 10.0.0.150
>
> (with ifconfig from net-tools-1.60)
> results in a netmask of 255.0.0.0, which is wrong in my situation.

Just change this to

ifconfig eth1 10.0.0.150 netmask 255.255.255.0 broadcast 10.0.0.255

and be happy.

Deciding about bugs vs. "undefined behavior" is not my business,
so I bite my tongue about this topic ;-)

Regards

Ingo Oeser
--
Use ReiserFS to get a faster fsck and Ext2 to fsck slowly and gently.

2001-07-25 16:37:14

by Alexey Kuznetsov

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

Hello!

> and the last ioctl destroys the information set by the previous two.

Exactly.


> I consider this a kernel bug,

No. And even not a feature, but just the only eligible way.
SIOCSIFADDR resets all previously set address information and
changes it to some legal defaults, otherwise you will stay
with illegal netmask/broadcast set for previously
set address on this interface.

BTW, if no address was selected before, setting netmask
and broadcast etc. simply fails.
So that you had some address set on the interface before
you did the operation and that netmask is set for _that_ address_.


> and ifconfig should assume that SIOCSIFADDR may be destructive
> and hence wait with setting netmask and broadcast address
> until after the SIOCSIFADDR.

I think it is even worse idea. ifconfig is low level tool and should
execute ops in the order, which it was asked. Especially, taking into
account that they are not commutative. Leave this logic to config
scripts or to human brains.

Actually, ifconfig does some too "clever" things by hisorical reasons,
sort of automic upping interface, when setting address. This is very
confusing and inconvenint, however, it is impossible to change by the
same (historical) reasons.

Alexey

2001-07-25 19:24:13

by Andries E. Brouwer

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

From [email protected] Wed Jul 25 18:37:10 2001

> and the last ioctl destroys the information set by the previous two.

Exactly.

> I consider this a kernel bug,

No. And even not a feature, but just the only eligible way.
SIOCSIFADDR resets all previously set address information

Yes. It didn't in 2.0. It does in 2.2 and 2.4.

BTW, if no address was selected before, setting netmask
and broadcast etc. simply fails.
So that you had some address set on the interface before
you did the operation and that netmask is set for _that_ address_.

Yes. I liked such logic thirty years ago. That is Unix.
Today I am less sure that it is a good idea to expect users
to read the kernel and ifconfig sources, but I did and know.

Since you don't like changing the current behaviour, we should
probably document it (say, in ifconfig(8)).

Andries


ifconfig(8):
SYNOPSIS
...
ifconfig interface [aftype] [address] options

OPTIONS
Since options are read and transmitted to the kernel
in the order given, and since giving an address parameter
causes resetting address related information (such as
netmask and broadcast address) to a default, any non-default
such address related information should be given after the
address parameter (if any).

2001-07-25 19:41:04

by Alexey Kuznetsov

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

Hello!

> Yes. It didn't in 2.0.

Soooory, it did. This behavior is copied from there. :-)



> Yes. I liked such logic thirty years ago. That is Unix.

:-) Seems, thirty years ago there were not only Internet but Unix too.

BTW I did not hear about any kind of Unix, which forgets
to set a valid mask on newly selected address.

ifconfig eth0 193.233.7.65 works nicely everywhere.
Only on 4.2BSD it creates bad "zero" broadcast.

Alexey

2001-07-25 20:27:24

by Andries E. Brouwer

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

Hello!

And hello again!

> Yes. It didn't in 2.0.

Soooory, it did. This behavior is copied from there. :-)

You are mistaken. I already quoted you the source.
In case you do not believe in source reading I can demo as well.

2.4:
# ifconfig lo netmask 255.254.0.0 10.0.0.150
# ifconfig lo
lo Link encap:Local Loopback
inet addr:10.0.0.150 Mask:255.0.0.0
[2.4.6, net-tools 1.60]


2.0:
# ifconfig lo netmask 255.254.0.0 10.0.0.150
# ifconfig lo
lo Link encap:Local Loopback
inet addr:10.0.0.150 Bcast:127.255.255.255 Mask:255.254.0.0

[2.0.34, net-tools 1.33]


As you see, the behaviour where setting the address kills
the already set netmask is new.



> Yes. I liked such logic thirty years ago. That is Unix.

:-) Seems, thirty years ago there were not only Internet but Unix too.

Yes, rounded to a nice number. I suppose we started using Unix
26 or 27 years ago or so.

BTW I did not hear about any kind of Unix, which forgets
to set a valid mask on newly selected address.

Linux 2.0, when there already is a nonzero mask.
A zero mask is replaced by a default:

2.0:
# ifconfig lo netmask 0.0.0.0 10.0.0.150
# ifconfig lo
lo Link encap:Local Loopback
inet addr:10.0.0.150 Bcast:127.255.255.255 Mask:255.0.0.0
...

Andries


2001-07-26 14:45:49

by Gerhard Mack

[permalink] [raw]
Subject: Re: ifconfig and SIOCSIFADDR

I used to be all for the OS guessing the correct mask. Then I started
work for my latest employer and tried to trace down strange errors that
were reported to me as an attack on our system. What I discovered was
that the last few people to attempt my job had set the IP and let the OS
guess at the mask. The result? Everything had 66.0.0.0 as the mask (and
66.255.255.255 for the broadcast). And not just linux either.. freebsd,
nt 4/windows 2000 and even the cisco catalysts all had the same
default mask set.

Please *don't* guess. If the admin fails to enter it just spit back an
error or something. You have no way to know the layout and that gets even
more annoying in these days of isps handing out blocks of 16 and 32.

Gerhard


On Wed, 25 Jul 2001 [email protected] wrote:

> Hello!
>
> > Yes. It didn't in 2.0.
>
> Soooory, it did. This behavior is copied from there. :-)
>
>
>
> > Yes. I liked such logic thirty years ago. That is Unix.
>
> :-) Seems, thirty years ago there were not only Internet but Unix too.
>
> BTW I did not hear about any kind of Unix, which forgets
> to set a valid mask on newly selected address.
>
> ifconfig eth0 193.233.7.65 works nicely everywhere.
> Only on 4.2BSD it creates bad "zero" broadcast.
>
> Alexey
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

--
Gerhard Mack

[email protected]

<>< As a computer I find your faith in technology amusing.