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
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(external link). 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
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_addr flr_dst;
- 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): Request exclusive access. ?
- flr_expires: Expiration time of the flow. What is the unit?
- flr_linger: Linger period of the flow. What is the unit and the purpose?
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.
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: Tue 14-Nov-06 23:42:23 PST