From f5c39ef3299f4efaab4d1bb410406de5909c1687 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 30 Apr 2020 18:04:10 +0200 Subject: docs: networking: convert operstates.txt to ReST - add SPDX header; - add a document title; - adjust chapters, adding proper markups; - mark lists as such; - adjust identation, whitespaces and blank lines where needed; - add to networking/index.rst. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: David S. Miller --- Documentation/networking/index.rst | 1 + Documentation/networking/operstates.rst | 185 ++++++++++++++++++++++++++++++++ Documentation/networking/operstates.txt | 164 ---------------------------- 3 files changed, 186 insertions(+), 164 deletions(-) create mode 100644 Documentation/networking/operstates.rst delete mode 100644 Documentation/networking/operstates.txt (limited to 'Documentation') diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst index b7f558480aca..028a36821b9a 100644 --- a/Documentation/networking/index.rst +++ b/Documentation/networking/index.rst @@ -88,6 +88,7 @@ Contents: nf_conntrack-sysctl nf_flowtable openvswitch + operstates .. only:: subproject and html diff --git a/Documentation/networking/operstates.rst b/Documentation/networking/operstates.rst new file mode 100644 index 000000000000..9c918f7cb0e8 --- /dev/null +++ b/Documentation/networking/operstates.rst @@ -0,0 +1,185 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================== +Operational States +================== + + +1. Introduction +=============== + +Linux distinguishes between administrative and operational state of an +interface. Administrative state is the result of "ip link set dev + up or down" and reflects whether the administrator wants to use +the device for traffic. + +However, an interface is not usable just because the admin enabled it +- ethernet requires to be plugged into the switch and, depending on +a site's networking policy and configuration, an 802.1X authentication +to be performed before user data can be transferred. Operational state +shows the ability of an interface to transmit this user data. + +Thanks to 802.1X, userspace must be granted the possibility to +influence operational state. To accommodate this, operational state is +split into two parts: Two flags that can be set by the driver only, and +a RFC2863 compatible state that is derived from these flags, a policy, +and changeable from userspace under certain rules. + + +2. Querying from userspace +========================== + +Both admin and operational state can be queried via the netlink +operation RTM_GETLINK. It is also possible to subscribe to RTNLGRP_LINK +to be notified of updates while the interface is admin up. This is +important for setting from userspace. + +These values contain interface state: + +ifinfomsg::if_flags & IFF_UP: + Interface is admin up + +ifinfomsg::if_flags & IFF_RUNNING: + Interface is in RFC2863 operational state UP or UNKNOWN. This is for + backward compatibility, routing daemons, dhcp clients can use this + flag to determine whether they should use the interface. + +ifinfomsg::if_flags & IFF_LOWER_UP: + Driver has signaled netif_carrier_on() + +ifinfomsg::if_flags & IFF_DORMANT: + Driver has signaled netif_dormant_on() + +TLV IFLA_OPERSTATE +------------------ + +contains RFC2863 state of the interface in numeric representation: + +IF_OPER_UNKNOWN (0): + Interface is in unknown state, neither driver nor userspace has set + operational state. Interface must be considered for user data as + setting operational state has not been implemented in every driver. + +IF_OPER_NOTPRESENT (1): + Unused in current kernel (notpresent interfaces normally disappear), + just a numerical placeholder. + +IF_OPER_DOWN (2): + Interface is unable to transfer data on L1, f.e. ethernet is not + plugged or interface is ADMIN down. + +IF_OPER_LOWERLAYERDOWN (3): + Interfaces stacked on an interface that is IF_OPER_DOWN show this + state (f.e. VLAN). + +IF_OPER_TESTING (4): + Unused in current kernel. + +IF_OPER_DORMANT (5): + Interface is L1 up, but waiting for an external event, f.e. for a + protocol to establish. (802.1X) + +IF_OPER_UP (6): + Interface is operational up and can be used. + +This TLV can also be queried via sysfs. + +TLV IFLA_LINKMODE +----------------- + +contains link policy. This is needed for userspace interaction +described below. + +This TLV can also be queried via sysfs. + + +3. Kernel driver API +==================== + +Kernel drivers have access to two flags that map to IFF_LOWER_UP and +IFF_DORMANT. These flags can be set from everywhere, even from +interrupts. It is guaranteed that only the driver has write access, +however, if different layers of the driver manipulate the same flag, +the driver has to provide the synchronisation needed. + +__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP: + +The driver uses netif_carrier_on() to clear and netif_carrier_off() to +set this flag. On netif_carrier_off(), the scheduler stops sending +packets. The name 'carrier' and the inversion are historical, think of +it as lower layer. + +Note that for certain kind of soft-devices, which are not managing any +real hardware, it is possible to set this bit from userspace. One +should use TVL IFLA_CARRIER to do so. + +netif_carrier_ok() can be used to query that bit. + +__LINK_STATE_DORMANT, maps to IFF_DORMANT: + +Set by the driver to express that the device cannot yet be used +because some driver controlled protocol establishment has to +complete. Corresponding functions are netif_dormant_on() to set the +flag, netif_dormant_off() to clear it and netif_dormant() to query. + +On device allocation, both flags __LINK_STATE_NOCARRIER and +__LINK_STATE_DORMANT are cleared, so the effective state is equivalent +to netif_carrier_ok() and !netif_dormant(). + + +Whenever the driver CHANGES one of these flags, a workqueue event is +scheduled to translate the flag combination to IFLA_OPERSTATE as +follows: + +!netif_carrier_ok(): + IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN + otherwise. Kernel can recognise stacked interfaces because their + ifindex != iflink. + +netif_carrier_ok() && netif_dormant(): + IF_OPER_DORMANT + +netif_carrier_ok() && !netif_dormant(): + IF_OPER_UP if userspace interaction is disabled. Otherwise + IF_OPER_DORMANT with the possibility for userspace to initiate the + IF_OPER_UP transition afterwards. + + +4. Setting from userspace +========================= + +Applications have to use the netlink interface to influence the +RFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1 +via RTM_SETLINK instructs the kernel that an interface should go to +IF_OPER_DORMANT instead of IF_OPER_UP when the combination +netif_carrier_ok() && !netif_dormant() is set by the +driver. Afterwards, the userspace application can set IFLA_OPERSTATE +to IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set +netif_carrier_off() or netif_dormant_on(). Changes made by userspace +are multicasted on the netlink group RTNLGRP_LINK. + +So basically a 802.1X supplicant interacts with the kernel like this: + +- subscribe to RTNLGRP_LINK +- set IFLA_LINKMODE to 1 via RTM_SETLINK +- query RTM_GETLINK once to get initial state +- if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until + netlink multicast signals this state +- do 802.1X, eventually abort if flags go down again +- send RTM_SETLINK to set operstate to IF_OPER_UP if authentication + succeeds, IF_OPER_DORMANT otherwise +- see how operstate and IFF_RUNNING is echoed via netlink multicast +- set interface back to IF_OPER_DORMANT if 802.1X reauthentication + fails +- restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag + +if supplicant goes down, bring back IFLA_LINKMODE to 0 and +IFLA_OPERSTATE to a sane value. + +A routing daemon or dhcp client just needs to care for IFF_RUNNING or +waiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before +considering the interface / querying a DHCP address. + + +For technical questions and/or comments please e-mail to Stefan Rompf +(stefan at loplof.de). diff --git a/Documentation/networking/operstates.txt b/Documentation/networking/operstates.txt deleted file mode 100644 index b203d1334822..000000000000 --- a/Documentation/networking/operstates.txt +++ /dev/null @@ -1,164 +0,0 @@ - -1. Introduction - -Linux distinguishes between administrative and operational state of an -interface. Administrative state is the result of "ip link set dev - up or down" and reflects whether the administrator wants to use -the device for traffic. - -However, an interface is not usable just because the admin enabled it -- ethernet requires to be plugged into the switch and, depending on -a site's networking policy and configuration, an 802.1X authentication -to be performed before user data can be transferred. Operational state -shows the ability of an interface to transmit this user data. - -Thanks to 802.1X, userspace must be granted the possibility to -influence operational state. To accommodate this, operational state is -split into two parts: Two flags that can be set by the driver only, and -a RFC2863 compatible state that is derived from these flags, a policy, -and changeable from userspace under certain rules. - - -2. Querying from userspace - -Both admin and operational state can be queried via the netlink -operation RTM_GETLINK. It is also possible to subscribe to RTNLGRP_LINK -to be notified of updates while the interface is admin up. This is -important for setting from userspace. - -These values contain interface state: - -ifinfomsg::if_flags & IFF_UP: - Interface is admin up -ifinfomsg::if_flags & IFF_RUNNING: - Interface is in RFC2863 operational state UP or UNKNOWN. This is for - backward compatibility, routing daemons, dhcp clients can use this - flag to determine whether they should use the interface. -ifinfomsg::if_flags & IFF_LOWER_UP: - Driver has signaled netif_carrier_on() -ifinfomsg::if_flags & IFF_DORMANT: - Driver has signaled netif_dormant_on() - -TLV IFLA_OPERSTATE - -contains RFC2863 state of the interface in numeric representation: - -IF_OPER_UNKNOWN (0): - Interface is in unknown state, neither driver nor userspace has set - operational state. Interface must be considered for user data as - setting operational state has not been implemented in every driver. -IF_OPER_NOTPRESENT (1): - Unused in current kernel (notpresent interfaces normally disappear), - just a numerical placeholder. -IF_OPER_DOWN (2): - Interface is unable to transfer data on L1, f.e. ethernet is not - plugged or interface is ADMIN down. -IF_OPER_LOWERLAYERDOWN (3): - Interfaces stacked on an interface that is IF_OPER_DOWN show this - state (f.e. VLAN). -IF_OPER_TESTING (4): - Unused in current kernel. -IF_OPER_DORMANT (5): - Interface is L1 up, but waiting for an external event, f.e. for a - protocol to establish. (802.1X) -IF_OPER_UP (6): - Interface is operational up and can be used. - -This TLV can also be queried via sysfs. - -TLV IFLA_LINKMODE - -contains link policy. This is needed for userspace interaction -described below. - -This TLV can also be queried via sysfs. - - -3. Kernel driver API - -Kernel drivers have access to two flags that map to IFF_LOWER_UP and -IFF_DORMANT. These flags can be set from everywhere, even from -interrupts. It is guaranteed that only the driver has write access, -however, if different layers of the driver manipulate the same flag, -the driver has to provide the synchronisation needed. - -__LINK_STATE_NOCARRIER, maps to !IFF_LOWER_UP: - -The driver uses netif_carrier_on() to clear and netif_carrier_off() to -set this flag. On netif_carrier_off(), the scheduler stops sending -packets. The name 'carrier' and the inversion are historical, think of -it as lower layer. - -Note that for certain kind of soft-devices, which are not managing any -real hardware, it is possible to set this bit from userspace. One -should use TVL IFLA_CARRIER to do so. - -netif_carrier_ok() can be used to query that bit. - -__LINK_STATE_DORMANT, maps to IFF_DORMANT: - -Set by the driver to express that the device cannot yet be used -because some driver controlled protocol establishment has to -complete. Corresponding functions are netif_dormant_on() to set the -flag, netif_dormant_off() to clear it and netif_dormant() to query. - -On device allocation, both flags __LINK_STATE_NOCARRIER and -__LINK_STATE_DORMANT are cleared, so the effective state is equivalent -to netif_carrier_ok() and !netif_dormant(). - - -Whenever the driver CHANGES one of these flags, a workqueue event is -scheduled to translate the flag combination to IFLA_OPERSTATE as -follows: - -!netif_carrier_ok(): - IF_OPER_LOWERLAYERDOWN if the interface is stacked, IF_OPER_DOWN - otherwise. Kernel can recognise stacked interfaces because their - ifindex != iflink. - -netif_carrier_ok() && netif_dormant(): - IF_OPER_DORMANT - -netif_carrier_ok() && !netif_dormant(): - IF_OPER_UP if userspace interaction is disabled. Otherwise - IF_OPER_DORMANT with the possibility for userspace to initiate the - IF_OPER_UP transition afterwards. - - -4. Setting from userspace - -Applications have to use the netlink interface to influence the -RFC2863 operational state of an interface. Setting IFLA_LINKMODE to 1 -via RTM_SETLINK instructs the kernel that an interface should go to -IF_OPER_DORMANT instead of IF_OPER_UP when the combination -netif_carrier_ok() && !netif_dormant() is set by the -driver. Afterwards, the userspace application can set IFLA_OPERSTATE -to IF_OPER_DORMANT or IF_OPER_UP as long as the driver does not set -netif_carrier_off() or netif_dormant_on(). Changes made by userspace -are multicasted on the netlink group RTNLGRP_LINK. - -So basically a 802.1X supplicant interacts with the kernel like this: - --subscribe to RTNLGRP_LINK --set IFLA_LINKMODE to 1 via RTM_SETLINK --query RTM_GETLINK once to get initial state --if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until - netlink multicast signals this state --do 802.1X, eventually abort if flags go down again --send RTM_SETLINK to set operstate to IF_OPER_UP if authentication - succeeds, IF_OPER_DORMANT otherwise --see how operstate and IFF_RUNNING is echoed via netlink multicast --set interface back to IF_OPER_DORMANT if 802.1X reauthentication - fails --restart if kernel changes IFF_LOWER_UP or IFF_DORMANT flag - -if supplicant goes down, bring back IFLA_LINKMODE to 0 and -IFLA_OPERSTATE to a sane value. - -A routing daemon or dhcp client just needs to care for IFF_RUNNING or -waiting for operstate to go IF_OPER_UP/IF_OPER_UNKNOWN before -considering the interface / querying a DHCP address. - - -For technical questions and/or comments please e-mail to Stefan Rompf -(stefan at loplof.de). -- cgit v1.2.3