1f5c39ef3SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0 2f5c39ef3SMauro Carvalho Chehab 3f5c39ef3SMauro Carvalho Chehab================== 4f5c39ef3SMauro Carvalho ChehabOperational States 5f5c39ef3SMauro Carvalho Chehab================== 6f5c39ef3SMauro Carvalho Chehab 7f5c39ef3SMauro Carvalho Chehab 8f5c39ef3SMauro Carvalho Chehab1. Introduction 9f5c39ef3SMauro Carvalho Chehab=============== 10f5c39ef3SMauro Carvalho Chehab 11f5c39ef3SMauro Carvalho ChehabLinux distinguishes between administrative and operational state of an 12f5c39ef3SMauro Carvalho Chehabinterface. Administrative state is the result of "ip link set dev 13f5c39ef3SMauro Carvalho Chehab<dev> up or down" and reflects whether the administrator wants to use 14f5c39ef3SMauro Carvalho Chehabthe device for traffic. 15f5c39ef3SMauro Carvalho Chehab 16f5c39ef3SMauro Carvalho ChehabHowever, an interface is not usable just because the admin enabled it 17f5c39ef3SMauro Carvalho Chehab- ethernet requires to be plugged into the switch and, depending on 18f5c39ef3SMauro Carvalho Chehaba site's networking policy and configuration, an 802.1X authentication 19f5c39ef3SMauro Carvalho Chehabto be performed before user data can be transferred. Operational state 20f5c39ef3SMauro Carvalho Chehabshows the ability of an interface to transmit this user data. 21f5c39ef3SMauro Carvalho Chehab 22f5c39ef3SMauro Carvalho ChehabThanks to 802.1X, userspace must be granted the possibility to 23f5c39ef3SMauro Carvalho Chehabinfluence operational state. To accommodate this, operational state is 24f5c39ef3SMauro Carvalho Chehabsplit into two parts: Two flags that can be set by the driver only, and 25f5c39ef3SMauro Carvalho Chehaba RFC2863 compatible state that is derived from these flags, a policy, 26f5c39ef3SMauro Carvalho Chehaband changeable from userspace under certain rules. 27f5c39ef3SMauro Carvalho Chehab 28f5c39ef3SMauro Carvalho Chehab 29f5c39ef3SMauro Carvalho Chehab2. Querying from userspace 30f5c39ef3SMauro Carvalho Chehab========================== 31f5c39ef3SMauro Carvalho Chehab 32f5c39ef3SMauro Carvalho ChehabBoth admin and operational state can be queried via the netlink 33f5c39ef3SMauro Carvalho Chehaboperation RTM_GETLINK. It is also possible to subscribe to RTNLGRP_LINK 34f5c39ef3SMauro Carvalho Chehabto be notified of updates while the interface is admin up. This is 35f5c39ef3SMauro Carvalho Chehabimportant for setting from userspace. 36f5c39ef3SMauro Carvalho Chehab 37f5c39ef3SMauro Carvalho ChehabThese values contain interface state: 38f5c39ef3SMauro Carvalho Chehab 39f5c39ef3SMauro Carvalho Chehabifinfomsg::if_flags & IFF_UP: 40f5c39ef3SMauro Carvalho Chehab Interface is admin up 41f5c39ef3SMauro Carvalho Chehab 42f5c39ef3SMauro Carvalho Chehabifinfomsg::if_flags & IFF_RUNNING: 43f5c39ef3SMauro Carvalho Chehab Interface is in RFC2863 operational state UP or UNKNOWN. This is for 44f5c39ef3SMauro Carvalho Chehab backward compatibility, routing daemons, dhcp clients can use this 45f5c39ef3SMauro Carvalho Chehab flag to determine whether they should use the interface. 46f5c39ef3SMauro Carvalho Chehab 47f5c39ef3SMauro Carvalho Chehabifinfomsg::if_flags & IFF_LOWER_UP: 48f5c39ef3SMauro Carvalho Chehab Driver has signaled netif_carrier_on() 49f5c39ef3SMauro Carvalho Chehab 50f5c39ef3SMauro Carvalho Chehabifinfomsg::if_flags & IFF_DORMANT: 51f5c39ef3SMauro Carvalho Chehab Driver has signaled netif_dormant_on() 52f5c39ef3SMauro Carvalho Chehab 53f5c39ef3SMauro Carvalho ChehabTLV IFLA_OPERSTATE 54f5c39ef3SMauro Carvalho Chehab------------------ 55f5c39ef3SMauro Carvalho Chehab 56f5c39ef3SMauro Carvalho Chehabcontains RFC2863 state of the interface in numeric representation: 57f5c39ef3SMauro Carvalho Chehab 58f5c39ef3SMauro Carvalho ChehabIF_OPER_UNKNOWN (0): 59f5c39ef3SMauro Carvalho Chehab Interface is in unknown state, neither driver nor userspace has set 60f5c39ef3SMauro Carvalho Chehab operational state. Interface must be considered for user data as 61f5c39ef3SMauro Carvalho Chehab setting operational state has not been implemented in every driver. 62f5c39ef3SMauro Carvalho Chehab 63f5c39ef3SMauro Carvalho ChehabIF_OPER_NOTPRESENT (1): 64f5c39ef3SMauro Carvalho Chehab Unused in current kernel (notpresent interfaces normally disappear), 65f5c39ef3SMauro Carvalho Chehab just a numerical placeholder. 66f5c39ef3SMauro Carvalho Chehab 67f5c39ef3SMauro Carvalho ChehabIF_OPER_DOWN (2): 68f5c39ef3SMauro Carvalho Chehab Interface is unable to transfer data on L1, f.e. ethernet is not 69f5c39ef3SMauro Carvalho Chehab plugged or interface is ADMIN down. 70f5c39ef3SMauro Carvalho Chehab 71f5c39ef3SMauro Carvalho ChehabIF_OPER_LOWERLAYERDOWN (3): 72f5c39ef3SMauro Carvalho Chehab Interfaces stacked on an interface that is IF_OPER_DOWN show this 73f5c39ef3SMauro Carvalho Chehab state (f.e. VLAN). 74f5c39ef3SMauro Carvalho Chehab 75f5c39ef3SMauro Carvalho ChehabIF_OPER_TESTING (4): 76*7a7b8635SJakub Kicinski Interface is in testing mode, for example executing driver self-tests 77*7a7b8635SJakub Kicinski or media (cable) test. It can't be used for normal traffic until tests 78*7a7b8635SJakub Kicinski complete. 79f5c39ef3SMauro Carvalho Chehab 80f5c39ef3SMauro Carvalho ChehabIF_OPER_DORMANT (5): 81f5c39ef3SMauro Carvalho Chehab Interface is L1 up, but waiting for an external event, f.e. for a 82f5c39ef3SMauro Carvalho Chehab protocol to establish. (802.1X) 83f5c39ef3SMauro Carvalho Chehab 84f5c39ef3SMauro Carvalho ChehabIF_OPER_UP (6): 85f5c39ef3SMauro Carvalho Chehab Interface is operational up and can be used. 86f5c39ef3SMauro Carvalho Chehab 87f5c39ef3SMauro Carvalho ChehabThis TLV can also be queried via sysfs. 88f5c39ef3SMauro Carvalho Chehab 89f5c39ef3SMauro Carvalho ChehabTLV IFLA_LINKMODE 90f5c39ef3SMauro Carvalho Chehab----------------- 91f5c39ef3SMauro Carvalho Chehab 92f5c39ef3SMauro Carvalho Chehabcontains link policy. This is needed for userspace interaction 93f5c39ef3SMauro Carvalho Chehabdescribed below. 94f5c39ef3SMauro Carvalho Chehab 95f5c39ef3SMauro Carvalho ChehabThis TLV can also be queried via sysfs. 96f5c39ef3SMauro Carvalho Chehab 97f5c39ef3SMauro Carvalho Chehab 98f5c39ef3SMauro Carvalho Chehab3. Kernel driver API 99f5c39ef3SMauro Carvalho Chehab==================== 100f5c39ef3SMauro Carvalho Chehab 101f5c39ef3SMauro Carvalho ChehabKernel drivers have access to two flags that map to IFF_LOWER_UP and 102f5c39ef3SMauro Carvalho ChehabIFF_DORMANT. These flags can be set from everywhere, even from 103f5c39ef3SMauro Carvalho Chehabinterrupts. It is guaranteed that only the driver has write access, 104f5c39ef3SMauro Carvalho Chehabhowever, if different layers of the driver manipulate the same flag, 105f5c39ef3SMauro Carvalho Chehabthe driver has to provide the synchronisation needed. 106f5c39ef3SMauro Carvalho Chehab 107f5c39ef3SMauro Carvalho Chehab__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP: 108f5c39ef3SMauro Carvalho Chehab 109f5c39ef3SMauro Carvalho ChehabThe driver uses netif_carrier_on() to clear and netif_carrier_off() to 110f5c39ef3SMauro Carvalho Chehabset this flag. On netif_carrier_off(), the scheduler stops sending 111f5c39ef3SMauro Carvalho Chehabpackets. The name 'carrier' and the inversion are historical, think of 112f5c39ef3SMauro Carvalho Chehabit as lower layer. 113f5c39ef3SMauro Carvalho Chehab 114f5c39ef3SMauro Carvalho ChehabNote that for certain kind of soft-devices, which are not managing any 115f5c39ef3SMauro Carvalho Chehabreal hardware, it is possible to set this bit from userspace. One 11666e0da21SJakub Kicinskishould use TLV IFLA_CARRIER to do so. 117f5c39ef3SMauro Carvalho Chehab 118f5c39ef3SMauro Carvalho Chehabnetif_carrier_ok() can be used to query that bit. 119f5c39ef3SMauro Carvalho Chehab 120f5c39ef3SMauro Carvalho Chehab__LINK_STATE_DORMANT, maps to IFF_DORMANT: 121f5c39ef3SMauro Carvalho Chehab 122f5c39ef3SMauro Carvalho ChehabSet by the driver to express that the device cannot yet be used 123f5c39ef3SMauro Carvalho Chehabbecause some driver controlled protocol establishment has to 124f5c39ef3SMauro Carvalho Chehabcomplete. Corresponding functions are netif_dormant_on() to set the 125f5c39ef3SMauro Carvalho Chehabflag, netif_dormant_off() to clear it and netif_dormant() to query. 126f5c39ef3SMauro Carvalho Chehab 127f5c39ef3SMauro Carvalho ChehabOn device allocation, both flags __LINK_STATE_NOCARRIER and 128f5c39ef3SMauro Carvalho Chehab__LINK_STATE_DORMANT are cleared, so the effective state is equivalent 129f5c39ef3SMauro Carvalho Chehabto netif_carrier_ok() and !netif_dormant(). 130f5c39ef3SMauro Carvalho Chehab 131f5c39ef3SMauro Carvalho Chehab 132f5c39ef3SMauro Carvalho ChehabWhenever the driver CHANGES one of these flags, a workqueue event is 133f5c39ef3SMauro Carvalho Chehabscheduled to translate the flag combination to IFLA_OPERSTATE as 134f5c39ef3SMauro Carvalho Chehabfollows: 135f5c39ef3SMauro Carvalho Chehab 136f5c39ef3SMauro Carvalho Chehab!netif_carrier_ok(): 137f5c39ef3SMauro Carvalho Chehab IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN 138f5c39ef3SMauro Carvalho Chehab otherwise. Kernel can recognise stacked interfaces because their 139f5c39ef3SMauro Carvalho Chehab ifindex != iflink. 140f5c39ef3SMauro Carvalho Chehab 141f5c39ef3SMauro Carvalho Chehabnetif_carrier_ok() && netif_dormant(): 142f5c39ef3SMauro Carvalho Chehab IF_OPER_DORMANT 143f5c39ef3SMauro Carvalho Chehab 144f5c39ef3SMauro Carvalho Chehabnetif_carrier_ok() && !netif_dormant(): 145f5c39ef3SMauro Carvalho Chehab IF_OPER_UP if userspace interaction is disabled. Otherwise 146f5c39ef3SMauro Carvalho Chehab IF_OPER_DORMANT with the possibility for userspace to initiate the 147f5c39ef3SMauro Carvalho Chehab IF_OPER_UP transition afterwards. 148f5c39ef3SMauro Carvalho Chehab 149f5c39ef3SMauro Carvalho Chehab 150f5c39ef3SMauro Carvalho Chehab4. Setting from userspace 151f5c39ef3SMauro Carvalho Chehab========================= 152f5c39ef3SMauro Carvalho Chehab 153f5c39ef3SMauro Carvalho ChehabApplications have to use the netlink interface to influence the 154f5c39ef3SMauro Carvalho ChehabRFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1 155f5c39ef3SMauro Carvalho Chehabvia RTM_SETLINK instructs the kernel that an interface should go to 156f5c39ef3SMauro Carvalho ChehabIF_OPER_DORMANT instead of IF_OPER_UP when the combination 157f5c39ef3SMauro Carvalho Chehabnetif_carrier_ok() && !netif_dormant() is set by the 158f5c39ef3SMauro Carvalho Chehabdriver. Afterwards, the userspace application can set IFLA_OPERSTATE 159f5c39ef3SMauro Carvalho Chehabto IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set 160f5c39ef3SMauro Carvalho Chehabnetif_carrier_off() or netif_dormant_on(). Changes made by userspace 161f5c39ef3SMauro Carvalho Chehabare multicasted on the netlink group RTNLGRP_LINK. 162f5c39ef3SMauro Carvalho Chehab 163f5c39ef3SMauro Carvalho ChehabSo basically a 802.1X supplicant interacts with the kernel like this: 164f5c39ef3SMauro Carvalho Chehab 165f5c39ef3SMauro Carvalho Chehab- subscribe to RTNLGRP_LINK 166f5c39ef3SMauro Carvalho Chehab- set IFLA_LINKMODE to 1 via RTM_SETLINK 167f5c39ef3SMauro Carvalho Chehab- query RTM_GETLINK once to get initial state 168f5c39ef3SMauro Carvalho Chehab- if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until 169f5c39ef3SMauro Carvalho Chehab netlink multicast signals this state 170f5c39ef3SMauro Carvalho Chehab- do 802.1X, eventually abort if flags go down again 171f5c39ef3SMauro Carvalho Chehab- send RTM_SETLINK to set operstate to IF_OPER_UP if authentication 172f5c39ef3SMauro Carvalho Chehab succeeds, IF_OPER_DORMANT otherwise 173f5c39ef3SMauro Carvalho Chehab- see how operstate and IFF_RUNNING is echoed via netlink multicast 174f5c39ef3SMauro Carvalho Chehab- set interface back to IF_OPER_DORMANT if 802.1X reauthentication 175f5c39ef3SMauro Carvalho Chehab fails 176f5c39ef3SMauro Carvalho Chehab- restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag 177f5c39ef3SMauro Carvalho Chehab 178f5c39ef3SMauro Carvalho Chehabif supplicant goes down, bring back IFLA_LINKMODE to 0 and 179f5c39ef3SMauro Carvalho ChehabIFLA_OPERSTATE to a sane value. 180f5c39ef3SMauro Carvalho Chehab 181f5c39ef3SMauro Carvalho ChehabA routing daemon or dhcp client just needs to care for IFF_RUNNING or 182f5c39ef3SMauro Carvalho Chehabwaiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before 183f5c39ef3SMauro Carvalho Chehabconsidering the interface / querying a DHCP address. 184f5c39ef3SMauro Carvalho Chehab 185f5c39ef3SMauro Carvalho Chehab 186f5c39ef3SMauro Carvalho ChehabFor technical questions and/or comments please e-mail to Stefan Rompf 187f5c39ef3SMauro Carvalho Chehab(stefan at loplof.de). 188