1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun================== 4*4882a593SmuzhiyunOperational States 5*4882a593Smuzhiyun================== 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun1. Introduction 9*4882a593Smuzhiyun=============== 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunLinux distinguishes between administrative and operational state of an 12*4882a593Smuzhiyuninterface. Administrative state is the result of "ip link set dev 13*4882a593Smuzhiyun<dev> up or down" and reflects whether the administrator wants to use 14*4882a593Smuzhiyunthe device for traffic. 15*4882a593Smuzhiyun 16*4882a593SmuzhiyunHowever, an interface is not usable just because the admin enabled it 17*4882a593Smuzhiyun- ethernet requires to be plugged into the switch and, depending on 18*4882a593Smuzhiyuna site's networking policy and configuration, an 802.1X authentication 19*4882a593Smuzhiyunto be performed before user data can be transferred. Operational state 20*4882a593Smuzhiyunshows the ability of an interface to transmit this user data. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunThanks to 802.1X, userspace must be granted the possibility to 23*4882a593Smuzhiyuninfluence operational state. To accommodate this, operational state is 24*4882a593Smuzhiyunsplit into two parts: Two flags that can be set by the driver only, and 25*4882a593Smuzhiyuna RFC2863 compatible state that is derived from these flags, a policy, 26*4882a593Smuzhiyunand changeable from userspace under certain rules. 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun2. Querying from userspace 30*4882a593Smuzhiyun========================== 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunBoth admin and operational state can be queried via the netlink 33*4882a593Smuzhiyunoperation RTM_GETLINK. It is also possible to subscribe to RTNLGRP_LINK 34*4882a593Smuzhiyunto be notified of updates while the interface is admin up. This is 35*4882a593Smuzhiyunimportant for setting from userspace. 36*4882a593Smuzhiyun 37*4882a593SmuzhiyunThese values contain interface state: 38*4882a593Smuzhiyun 39*4882a593Smuzhiyunifinfomsg::if_flags & IFF_UP: 40*4882a593Smuzhiyun Interface is admin up 41*4882a593Smuzhiyun 42*4882a593Smuzhiyunifinfomsg::if_flags & IFF_RUNNING: 43*4882a593Smuzhiyun Interface is in RFC2863 operational state UP or UNKNOWN. This is for 44*4882a593Smuzhiyun backward compatibility, routing daemons, dhcp clients can use this 45*4882a593Smuzhiyun flag to determine whether they should use the interface. 46*4882a593Smuzhiyun 47*4882a593Smuzhiyunifinfomsg::if_flags & IFF_LOWER_UP: 48*4882a593Smuzhiyun Driver has signaled netif_carrier_on() 49*4882a593Smuzhiyun 50*4882a593Smuzhiyunifinfomsg::if_flags & IFF_DORMANT: 51*4882a593Smuzhiyun Driver has signaled netif_dormant_on() 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunTLV IFLA_OPERSTATE 54*4882a593Smuzhiyun------------------ 55*4882a593Smuzhiyun 56*4882a593Smuzhiyuncontains RFC2863 state of the interface in numeric representation: 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunIF_OPER_UNKNOWN (0): 59*4882a593Smuzhiyun Interface is in unknown state, neither driver nor userspace has set 60*4882a593Smuzhiyun operational state. Interface must be considered for user data as 61*4882a593Smuzhiyun setting operational state has not been implemented in every driver. 62*4882a593Smuzhiyun 63*4882a593SmuzhiyunIF_OPER_NOTPRESENT (1): 64*4882a593Smuzhiyun Unused in current kernel (notpresent interfaces normally disappear), 65*4882a593Smuzhiyun just a numerical placeholder. 66*4882a593Smuzhiyun 67*4882a593SmuzhiyunIF_OPER_DOWN (2): 68*4882a593Smuzhiyun Interface is unable to transfer data on L1, f.e. ethernet is not 69*4882a593Smuzhiyun plugged or interface is ADMIN down. 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunIF_OPER_LOWERLAYERDOWN (3): 72*4882a593Smuzhiyun Interfaces stacked on an interface that is IF_OPER_DOWN show this 73*4882a593Smuzhiyun state (f.e. VLAN). 74*4882a593Smuzhiyun 75*4882a593SmuzhiyunIF_OPER_TESTING (4): 76*4882a593Smuzhiyun Unused in current kernel. 77*4882a593Smuzhiyun 78*4882a593SmuzhiyunIF_OPER_DORMANT (5): 79*4882a593Smuzhiyun Interface is L1 up, but waiting for an external event, f.e. for a 80*4882a593Smuzhiyun protocol to establish. (802.1X) 81*4882a593Smuzhiyun 82*4882a593SmuzhiyunIF_OPER_UP (6): 83*4882a593Smuzhiyun Interface is operational up and can be used. 84*4882a593Smuzhiyun 85*4882a593SmuzhiyunThis TLV can also be queried via sysfs. 86*4882a593Smuzhiyun 87*4882a593SmuzhiyunTLV IFLA_LINKMODE 88*4882a593Smuzhiyun----------------- 89*4882a593Smuzhiyun 90*4882a593Smuzhiyuncontains link policy. This is needed for userspace interaction 91*4882a593Smuzhiyundescribed below. 92*4882a593Smuzhiyun 93*4882a593SmuzhiyunThis TLV can also be queried via sysfs. 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun3. Kernel driver API 97*4882a593Smuzhiyun==================== 98*4882a593Smuzhiyun 99*4882a593SmuzhiyunKernel drivers have access to two flags that map to IFF_LOWER_UP and 100*4882a593SmuzhiyunIFF_DORMANT. These flags can be set from everywhere, even from 101*4882a593Smuzhiyuninterrupts. It is guaranteed that only the driver has write access, 102*4882a593Smuzhiyunhowever, if different layers of the driver manipulate the same flag, 103*4882a593Smuzhiyunthe driver has to provide the synchronisation needed. 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP: 106*4882a593Smuzhiyun 107*4882a593SmuzhiyunThe driver uses netif_carrier_on() to clear and netif_carrier_off() to 108*4882a593Smuzhiyunset this flag. On netif_carrier_off(), the scheduler stops sending 109*4882a593Smuzhiyunpackets. The name 'carrier' and the inversion are historical, think of 110*4882a593Smuzhiyunit as lower layer. 111*4882a593Smuzhiyun 112*4882a593SmuzhiyunNote that for certain kind of soft-devices, which are not managing any 113*4882a593Smuzhiyunreal hardware, it is possible to set this bit from userspace. One 114*4882a593Smuzhiyunshould use TVL IFLA_CARRIER to do so. 115*4882a593Smuzhiyun 116*4882a593Smuzhiyunnetif_carrier_ok() can be used to query that bit. 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun__LINK_STATE_DORMANT, maps to IFF_DORMANT: 119*4882a593Smuzhiyun 120*4882a593SmuzhiyunSet by the driver to express that the device cannot yet be used 121*4882a593Smuzhiyunbecause some driver controlled protocol establishment has to 122*4882a593Smuzhiyuncomplete. Corresponding functions are netif_dormant_on() to set the 123*4882a593Smuzhiyunflag, netif_dormant_off() to clear it and netif_dormant() to query. 124*4882a593Smuzhiyun 125*4882a593SmuzhiyunOn device allocation, both flags __LINK_STATE_NOCARRIER and 126*4882a593Smuzhiyun__LINK_STATE_DORMANT are cleared, so the effective state is equivalent 127*4882a593Smuzhiyunto netif_carrier_ok() and !netif_dormant(). 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun 130*4882a593SmuzhiyunWhenever the driver CHANGES one of these flags, a workqueue event is 131*4882a593Smuzhiyunscheduled to translate the flag combination to IFLA_OPERSTATE as 132*4882a593Smuzhiyunfollows: 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun!netif_carrier_ok(): 135*4882a593Smuzhiyun IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN 136*4882a593Smuzhiyun otherwise. Kernel can recognise stacked interfaces because their 137*4882a593Smuzhiyun ifindex != iflink. 138*4882a593Smuzhiyun 139*4882a593Smuzhiyunnetif_carrier_ok() && netif_dormant(): 140*4882a593Smuzhiyun IF_OPER_DORMANT 141*4882a593Smuzhiyun 142*4882a593Smuzhiyunnetif_carrier_ok() && !netif_dormant(): 143*4882a593Smuzhiyun IF_OPER_UP if userspace interaction is disabled. Otherwise 144*4882a593Smuzhiyun IF_OPER_DORMANT with the possibility for userspace to initiate the 145*4882a593Smuzhiyun IF_OPER_UP transition afterwards. 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun4. Setting from userspace 149*4882a593Smuzhiyun========================= 150*4882a593Smuzhiyun 151*4882a593SmuzhiyunApplications have to use the netlink interface to influence the 152*4882a593SmuzhiyunRFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1 153*4882a593Smuzhiyunvia RTM_SETLINK instructs the kernel that an interface should go to 154*4882a593SmuzhiyunIF_OPER_DORMANT instead of IF_OPER_UP when the combination 155*4882a593Smuzhiyunnetif_carrier_ok() && !netif_dormant() is set by the 156*4882a593Smuzhiyundriver. Afterwards, the userspace application can set IFLA_OPERSTATE 157*4882a593Smuzhiyunto IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set 158*4882a593Smuzhiyunnetif_carrier_off() or netif_dormant_on(). Changes made by userspace 159*4882a593Smuzhiyunare multicasted on the netlink group RTNLGRP_LINK. 160*4882a593Smuzhiyun 161*4882a593SmuzhiyunSo basically a 802.1X supplicant interacts with the kernel like this: 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun- subscribe to RTNLGRP_LINK 164*4882a593Smuzhiyun- set IFLA_LINKMODE to 1 via RTM_SETLINK 165*4882a593Smuzhiyun- query RTM_GETLINK once to get initial state 166*4882a593Smuzhiyun- if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until 167*4882a593Smuzhiyun netlink multicast signals this state 168*4882a593Smuzhiyun- do 802.1X, eventually abort if flags go down again 169*4882a593Smuzhiyun- send RTM_SETLINK to set operstate to IF_OPER_UP if authentication 170*4882a593Smuzhiyun succeeds, IF_OPER_DORMANT otherwise 171*4882a593Smuzhiyun- see how operstate and IFF_RUNNING is echoed via netlink multicast 172*4882a593Smuzhiyun- set interface back to IF_OPER_DORMANT if 802.1X reauthentication 173*4882a593Smuzhiyun fails 174*4882a593Smuzhiyun- restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag 175*4882a593Smuzhiyun 176*4882a593Smuzhiyunif supplicant goes down, bring back IFLA_LINKMODE to 0 and 177*4882a593SmuzhiyunIFLA_OPERSTATE to a sane value. 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunA routing daemon or dhcp client just needs to care for IFF_RUNNING or 180*4882a593Smuzhiyunwaiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before 181*4882a593Smuzhiyunconsidering the interface / querying a DHCP address. 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun 184*4882a593SmuzhiyunFor technical questions and/or comments please e-mail to Stefan Rompf 185*4882a593Smuzhiyun(stefan at loplof.de). 186