Bug 235920 - ifconfig: unable to create another interface after renaming the previous one with the same name
Summary: ifconfig: unable to create another interface after renaming the previous one ...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-net (Nobody)
Depends on:
Reported: 2019-02-21 17:18 UTC by olevole
Modified: 2019-02-22 08:28 UTC (History)
1 user (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description olevole 2019-02-21 17:18:07 UTC
Tested on: 12.0-RELEASE, 13-CURRENT (r344398)

When I try to create an interface (via ifconfig), then rename it (via ifconfig name) and create another one with the same name, this causes an error. E.g:

1) Create and rename interface: 
ifconfig tap100 create name xxx
ifconfig tap100 create && ifconfig tap100 name xxx

2) check that the interface original interface is missing now:
ifconfig tap100
ifconfig: interface tap100 does not exist

3) great! we can create another one:
ifconfig tap100 create
ifconfig: SIOCIFCREATE2: File exists

As far as I can see, the problem is in the UNR(9) area (alloc_unr_specific)

The path to the error that I see:

  setifname() -> 
             if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) {
                err(1, "ioctl SIOCSIFNAME (set name)");

  ifioctl() ->
       case SIOCIFCREATE:
        case SIOCIFCREATE2:
                error = priv_check(td, PRIV_NET_IFCREATE);
                if (error == 0)
                        error = if_clone_create(ifr->ifr_name,
                            sizeof(ifr->ifr_name), cmd == SIOCIFCREATE2 ?
                            ifr_data_get_ptr(ifr) : NULL);
                goto out_noref;

  if_clone_create() ->
        return (if_clone_createif(ifc, name, len, params));

  if_clone_createif() ->
       err = ifc_simple_create(ifc, name, len, params);

  ifc_simple_create() ->
      err = ifc_alloc_unit(ifc, &unit);

  ifc_alloc_unit() ->
      if (alloc_unr_specific(ifc->ifc_unrhdr, *unit) == -1) {
                return (EEXIST);

If we create an interface for the first time, this function ends with:

When we create an interface a second time, we get:
return (EEXIST);
Comment 1 olevole 2019-02-21 17:22:21 UTC
We can test that the interface is actually renamed via ioctl() via:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>

int list_devices() {

    char data[4096];
    struct ifconf ifc;
    struct ifreq *ifr;
    int sk,length;
    unsigned int idx;

    sk = socket(AF_INET, SOCK_DGRAM, 0);
    if(sk < 0)
        return 0;

    ifc.ifc_len = sizeof(data);
    ifc.ifc_buf = (caddr_t)data;
    if(ioctl(sk, SIOCGIFCONF, &ifc) < 0)
        return 0;

    ifr = (struct ifreq*)data;
    for(int i=0;i<ifc.ifc_len;)
        length=IFNAMSIZ + ifr->ifr_addr.sa_len;
        printf("Found: %s [index: %d]\n", ifr->ifr_name,idx);
        ifr=(struct ifr*)((char*)ifr+length);

    return 0;

ifr->ifr_name is changing, but the index is the same (and this is normal?).
However, some information remains from the old interface, and this affects http://man.freebsd.org/alloc_unr_specific/9
Comment 2 Andriy Voskoboinyk freebsd_committer 2019-02-21 22:12:33 UTC
That's OK - not sure about ifnet(9) in general, but for ieee80211(9) net.wlan.0.* tunables are created (at least) and their names will not be changed after interface renaming.
Comment 3 Poul-Henning Kamp freebsd_committer 2019-02-22 08:28:20 UTC
I don't think this has anything to do with the UNR(9) code, it seems to be only a matter of how interface names are managed.

I have always assumed myself that naming an interface was an aliasing operation and that the interface retained its underlying "system-given" name - if nothing else in the sense that dev_printf() would still emit that name on the console.

Apart from those observations I have nothing further to add, and will take myself of the cc list.