ifdown/ifup and friends

ifdown/ifup and friends

Oleg Goldshmidt pub at goldshmidt.org
Tue Apr 24 17:51:40 IDT 2018


Hi all,

I am trying to get my head around the problem of bringing network
interfaces up and down and checking the state. I googled extensively,
but I have not found an answer to the conundrum, and I am hoping that
someone here may shed some light.

My target platform is Debian wheezy (no, I can't upgrade it), but what I
describe below is very similar on an up-to-date Fedora 27 (that,
obviously, has a very different set of userspace tools and a very
different kernel).

What I am trying to achieve is as follows. Assume that the system in
question gets a command (imagine an API of sorts) to reconfigure one of
its multiple interfaces. Let's say that the control interface is eth0
and the request is to reconfigure eth3. Here, "reconfigure" may mean,
e.g., "change the static IP address and maybe some routing rules" (or
toggle between static and DHCP or whatever - staying static seems
conceptually simpler).

So the is an implementation (bash, run as root, etc.) that goes, in
essence,

* stop interface eth3
* change eth3 configuration
* start interface eth3

which looks natural enough. It is also natural that there are stop() and
start() functions that may include some subtleties such as flushing IP
address, etc. The start() and stop() functions are used in other
workflows and, in general, one would like to check whether the interface
is up or down, at least to avoid superfluous error messages when one
tries to bring up an interface that is already up, etc. (Such messages
may pollute things for the API client, and hiding stderr in general is
not a good idea because real errors may be lost.)

The problem is that whatever I do in stop() (or by hand), e.g.,

* ifconfig eth3 down
* ifdown --force eth3 (and --no-scripts, and whatever - on Debian)
* ip link set eth3 down

etc., etc., with infinite variations, the UP flag remains set (I also
check with ifconfig, ip link show, etc.).

Technically, the UP flag is the IFF_UP bit in the ifr_flags field of
struct ifreq accessible through a ioctl (cf. man 7 netdevice). I went as
far as writing a C program that uses the ioctl(s) (SIOCGIFFLAGS,
SIOCSIFFLAGS) directly. To no avail: right after I toggle IFF_UP I check
it again and it is *always* up... Again, this is on both Debian wheezy
(old, kernel 3.2.0) and Fedora 27 (fully updated, kernel 4.15.17)...

It also does not depend on whether the interface is designated as "auto"
(on Debian) or anything else I could think of.

I straced all kinds of commands and downloaded sources and did all kinds
of things trying to understand what was going on, but so far in vain. By
the way, I pulled the sources of ifupdown from Debian's git, and I
didn't find any ioctl calls there. Could it be because they don't help
(see above)?

The only way (well, I could implement my own state...) I managed to work
around the *original* is-the-interface-up? problem was by doing an
equivalent of

ifdown --force eth3 && sleep 1 && ifconfig eth3 0.0.0.0

for stop() and then testing for the presence of "inet" (rather than
"UP") in the ifconfig's output (on Debian). By the way, the sleep is
essential - without it it won't work, for whatever reason.

The workaround above may or may not prove sufficient for the immediate
purpose, but a) it's ugly, and b) I would like to understand how one can
toggle the IFF_UP flag programmatically. I also have a dim recollection
that ifdown/ifup and/or ifconfig down/up used to work in distant past...

Any ideas?

-- 
Oleg Goldshmidt | pub at goldshmidt.org



More information about the Linux-il mailing list