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