Print this page

Documenting Linux IPv6 Flow Label Mangement API

As I was not able to find any documentation on how IPv6 flowlabels are to be used under Linux, I have chosen to publish my findings here. Comments are more than welcome 

I would like to thank Martin Jaros for the clarifications he has made regarding flr_flags, flr_expires, and flr_linger.

In order to be able to set the flowlabel header field of IPv6 packets under Linux, a flowlabel has to be allocated by the kernel. The Linux kernel manages flowlabels in order to adhere to IPv6 RFC that states that flowlabels should be unique for a certain period of time.
How flowlabels are set, once they are allocated, is documented in by man ipv6. However, the man pages has no mention of the fact that the flowlabel has to be allocated, and that flowlabels have to be enabled on the socket. I will here describe how flowlabels are allocated and how they are enabled for a socket. Both is done using socket options. Most of the constants and structs required do not exist in any header files outside the kernel. All constants here will be given with both their symbolic name and numerical value.

I have many question marks scattered around this document. If you know the answers to any of these question do please tell me and I’ll fill in the blanks. This also goes for errors. I probably have quite a few.

Managing Flowlabels
The structure in6_flowlabel_req is passed between applications and the kernel using setsockopts and is used to allocate (GET), free (PUT) and refresh (RENEW) flowlabels.
struct in6_flowlabel_req
struct in6_addr flr_dst;
__u32 flr_label;
__u8 flr_action;
__u8 flr_share;
__u16 flr_flags;
__u16 flr_expires;
__u16 flr_linger;
__u32 __flr_pad;

  • flr_dst: IPv6 address of the destination for this flow.
  • flr_label: The 20bit flowlabel, in network byte order.
  • flr_action: The action requested:
    • IPV6_FL_A_GET (0): Retrieves a flowlabel. If the flr_label field is non-zero, the specified flowlabel is retrieved (and locked if it has exclusive sharing). If flr_label is zero and IPV6_F_F_CREATE is used, a new flowlabel will be allocated and returned in the flr_label field.
    • IPV6_FL_A_PUT (1): Releases a flowlabel.
    • IPV6_FL_A_RENEW (2): Renews a flowlabel, avoiding it to be reused.
  • flr_share: How is this flowlabel shared:
    • IPV6_FL_S_NONE (0): No sharing between any other sockets.
    • IPV6_FL_S_EXCL (1): Only one socket is allowed to use this flowlabel at a given point in time. Others can use it as soon as it has been released using IPV6_FL_A_PUT.
    • IPV6_FL_S_PROCESS (2): Shared between socket in the same process.
    • IPV6_FL_S_USER (3): Shared between sockets belonging to the same user.
    • IPV6_FL_S_ANY (255): Shared freely between any sockets.
  • flr_flags: Possible flags:
    • IPV6_FL_F_CREATE (1): Used with IPV6_FL_A_GET action to allocate a new flowlabel. If not used, only existing flowlabels will be retrieved.
    • IPV6_FL_F_EXCL (2): Forces exclusive to the label just for a single call, subsequent calls will honor the flr_share setting. Also if the label already exists -EEXIST is returned, instead of -EPERM in case of sharing violation. It makes sense to use this flag only with nonzero flr_label and nonexclusive flr_share.
  • flr_expires: Expiration time (in seconds) after which the flow label expires and is destroyed (internally extended by linger times)
  • flr_linger: Linger period of the flow (in seconds). After a packet has been sent in the flow, the flow is prevented from experiation for the linger period.

The socket option used to gain access to the flowlabel mangement API is IPV6_FLOWLABEL_MGR (32), and the level is IPPROTO_IPV6. Any options headers to be set for packets belonging to this flow, should follow the in6_flowlabel_req structure. Keep in mind that Linux enforces the requirement that all packets belonging to the same flow should have the same options headers, so you will have to set these using the flowlabel mangement API.

Enabling Flowlabels
Once you have retrieved a flow label by using the method described above, it is necesarry to tell the kernel that flow labels should be enabled on a socket. This is done by using the boolean socket option IPV6_FLOWINFO_SEND (33). The level is again IPPROTO_IPV6. Now all you have to do is, to set the sin6_flowinfo field of the sockaddr_in6 structure to the flow label retrieved and voilá, send packets now contain the flow label.

Modified: Thu 08-Oct-15 06:27:29 PDT