Historically all interfaces have their if_init() method, which initializes
final resources and brings it up. Usually, the driver code calls its
xxx_init() method internally, when being brought IFF_UP via SIOCSIFFLAGS.
However, for IPv4 there historically existed another quite ugly code path:
sys_ioctl(SIOCAIFADDR) -> .. -> in_control(SIOCAIFADDR) ->
-> if_ioctl(SIOCSIFADDR) -> ether_ioctl(SIOCSIFADDR) -> if_init().
Note that a legitimate SIOCAIFADDR is temporarily substituted with
obsoleted SIOCSIFADDR. Moreover, the pointer provided with command
is not ifreq pointer, but ifaddr. Finally, the IFF_UP was set by
ether_ioctl() blindly, without executing if_up().
Unentangle that:
- All xxx_init()s are no longer a driver methods, but a static functions. The only legitimate way of upping an interface is SIOCSIFFLAGS.
- in_control() calls SIOCSIFFLAGS if it sees interface not IFF_UP.
- arp_ifinit() moves to in_control(), out of Ethernet code.
- ether_ioctl() no longer contains #ifdef INET hack.
Sponsored by: Netflix
Sponsored by: Nginx, Inc.