Home | History | Annotate | Download | only in doc
      1 ////
      2 	vim.syntax: asciidoc
      3 
      4 	Copyright (c) 2011 Thomas Graf <tgraf (a] suug.ch>
      5 ////
      6 
      7 Routing Family Netlink Library (libnl-route)
      8 ============================================
      9 Thomas Graf <tgraf (a] suug.ch>
     10 3.1, Aug 11 2011:
     11 
     12 == Introduction
     13 
     14 This library provides APIs to the kernel interfaces of the routing family.
     15 
     16 
     17 NOTE: Work in progress.
     18 
     19 == Addresses
     20 
     21 [[route_link]]
     22 == Links (Network Devices)
     23 
     24 The link configuration interface is part of the +NETLINK_ROUTE+ protocol
     25 family and implements the following netlink message types:
     26 
     27 - View and modify the configuration of physical and virtual network devices.
     28 - Create and delete virtual network devices (e.g. dummy devices, VLAN devices,
     29   tun devices, bridging devices, ...)
     30 - View and modify per link network configuration settings (e.g.
     31   +net.ipv6.conf.eth0.accept_ra+, +net.ipv4.conf.eth1.forwarding+, ...)
     32 
     33 .Naming Convention (network device, link, interface)
     34 
     35 In networking several terms are commonly used to refer to network devices.
     36 While they have distinct meanings they have been used interchangeably in
     37 the past. Within the Linux kernel, the term _network device_ or _netdev_ is
     38 commonly used In user space the term _network interface_ is very common.
     39 The routing netlink protocol uses the term _link_ and so does the _iproute2_
     40 utility and most routing daemons.
     41 
     42 === Netlink Protocol
     43 
     44 This section describes the protocol semantics of the netlink based link
     45 configuration interface. The following messages are defined:
     46 
     47 [options="header", cols="1,2,2"]
     48 |==============================================================================
     49 | Message Type   | User -> Kernel                    | Kernel -> User
     50 | +RTM_NEWLINK+  | Create or update virtual network device
     51 | Reply to +RTM_GETLINK+ request or notification of link added or updated
     52 | +RTM_DELLINK+  | Delete virtual network device
     53 | Notification of link deleted or disappeared
     54 | +RTM_GETLINK+  | Retrieve link configuration and statistics | 
     55 | +RTM_SETLINK+  | Modify link configuration | 
     56 |==============================================================================
     57 
     58 See link:core.html#core_msg_types[Netlink Library - Message Types] for more
     59 information on common semantics of these message types.
     60 
     61 ==== Link Message Format
     62 
     63 All netlink link messages share a common header (+struct ifinfomsg+) which
     64 is appended after the netlink header (+struct nlmsghdr+).
     65 
     66 image:ifinfomsg.png["Link Message Header"]
     67 
     68 The meaning of each field may differ depending on the message type. A
     69 +struct ifinfomsg+ is defined in +<linux/rtnetlink.h>+ to represent the
     70 header.
     71 
     72 Address Family (8bit)::
     73 The address family is usually set to +AF_UNSPEC+ but may be specified in
     74 +RTM_GETLINK+ requests to limit the returned links to a specific address
     75 family.
     76 
     77 Link Layer Type (16bit)::
     78 Currently only used in kernel->user messages to report the link layer type
     79 of a link. The value corresponds to the +ARPHRD_*+ defines found in
     80 +<linux/if_arp.h>+. Translation from/to strings can be done using the
     81 functions nl_llproto2str()/nl_str2llproto().
     82 
     83 Link Index (32bit)::
     84 Carries the interface index and is used to identify existing links.
     85 
     86 Flags (32bit)::
     87 In kernel->user messages the value of this field represents the current
     88 state of the link flags. In user->kernel messages this field is used to
     89 change flags or set the initial flag state of new links. Note that in order
     90 to change a flag, the flag must also be set in the _Flags Change Mask_ field.
     91 
     92 Flags Change Mask (32bit)::
     93 The primary use of this field is to specify a mask of flags that should be
     94 changed based on the value of the _Flags_ field. A special meaning is given
     95 to this field when present in link notifications, see TODO.
     96 
     97 Attributes (variable)::
     98 All link message types may carry netlink attributes. They are defined in the
     99 header file <linux/if_link.h> and share the prefix +IFLA_+.
    100 
    101 ==== Link Message Types
    102 
    103 .RTM_GETLINK (user->kernel)
    104 
    105 Lookup link by 1. interface index or 2. link name (+IFLA_IFNAME+) and return
    106 a single +RTM_NEWLINK+ message containing the link configuration and statistics
    107 or a netlink error message if no such link was found.
    108 
    109 *Parameters:*
    110 
    111 * *Address family*
    112 ** If the address family is set to +PF_BRIDGE+, only bridging devices will be
    113    returned.
    114 ** If the address family is set to +PF_INET6+, only ipv6 enabled devices will
    115    be returned.
    116 
    117 *Flags:*
    118 
    119 * +NLM_F_DUMP+ If set, all links will be returned in form of a multipart
    120   message.
    121 
    122 *Returns:*
    123 
    124 * +EINVAL+ if neither interface nor link name are set
    125 * +ENODEV+ if no link was found
    126 * +ENOBUFS+ if allocation failed
    127 
    128 .RTM_NEWLINK (user->kernel)
    129 
    130 Creates a new or updates an existing link. Only virtual links may be created
    131 but all links may be updated.
    132 
    133 *Flags:*
    134 
    135 - +NLM_F_CREATE+ Create link if it does not exist
    136 - +NLM_F_EXCL+ Return +EEXIST+ if link already exists
    137 
    138 *Returns:*
    139 
    140 - +EINVAL+ malformed message or invalid configuration parameters
    141 - +EAFNOSUPPORT+ if a address family specific configuration (+IFLA_AF_SPEC+)
    142   is not supported.
    143 - +EOPNOTSUPP+ if the link does not support modification of parameters
    144 - +EEXIST+ if +NLM_F_EXCL+ was set and the link exists alraedy
    145 - +ENODEV+ if the link does not exist and +NLM_F_CREATE+ is not set
    146 
    147 .RTM_NEWLINK (kernel->user)
    148 
    149 This message type is used in reply to a +RTM_GETLINK+ request and carries
    150 the configuration and statistics of a link. If multiple links need to
    151 be sent, the messages will be sent in form of a multipart message.
    152 
    153 The message type is also used for notifications sent by the kernel to the
    154 multicast group +RTNLGRP_LINK+ to inform about various link events. It is
    155 therefore recommended to always use a separate link socket for link
    156 notifications in order to separate between the two message types.
    157 
    158 TODO: document how to detect different notifications
    159 
    160 .RTM_DELLINK (user->kernel)
    161 
    162 Lookup link by 1. interface index or 2. link name (+IFLA_IFNAME+) and delete
    163 the virtual link.
    164 
    165 *Returns:*
    166 
    167 * +EINVAL+ if neither interface nor link name are set
    168 * +ENODEV+ if no link was found
    169 * +ENOTSUPP+ if the operation is not supported (not a virtual link)
    170 
    171 .RTM_DELLINK (kernel->user)
    172 
    173 Notification sent by the kernel to the multicast group +RTNLGRP_LINK+ when
    174 
    175 a. a network device was unregistered (change == ~0)
    176 b. a bridging device was deleted (address family will be +PF_BRIDGE+)
    177 
    178 === Get / List
    179 
    180 [[link_list]]
    181 ==== Get list of links
    182 
    183 To retrieve the list of links in the kernel, allocate a new link cache
    184 using +rtnl_link_alloc_cache()+ to hold the links. It will automatically
    185 construct and send a +RTM_GETLINK+ message requesting a dump of all links
    186 from the kernel and feed the returned +RTM_NEWLINK+ to the internal link
    187 message parser which adds the returned links to the cache.
    188 
    189 [source,c]
    190 -----
    191 #include <netlink/route/link.h>
    192 
    193 int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
    194 -----
    195 
    196 The cache will contain link objects (+struct rtnl_link+, see <<link_object>>)
    197 and can be accessed using the standard cache functions. By setting the
    198 +family+ parameter to an address familly other than +AF_UNSPEC+, the resulting
    199 cache will only contain links supporting the specified address family.
    200 
    201 The following direct search functions are provided to search by interface
    202 index and by link name:
    203 
    204 [source,c]
    205 -----
    206 #include <netlink/route/link.h>
    207 
    208 struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex);
    209 struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, const char *name);
    210 -----
    211 
    212 .Example: Link Cache
    213 
    214 [source,c]
    215 -----
    216 struct nl_cache *cache;
    217 struct rtnl_link *link;
    218 
    219 if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache)) < 0)
    220 	/* error */
    221 
    222 if (!(link = rtnl_link_get_by_name(cache, "eth1")))
    223 	/* link does not exist */
    224 
    225 /* do something with link */
    226 
    227 rtnl_link_put(link);
    228 nl_cache_put(cache);
    229 -----
    230 
    231 [[link_direct_lookup]]
    232 ==== Lookup Single Link (Direct Lookup)
    233 
    234 If only a single link is of interest, the link can be looked up directly
    235 without the use of a link cache using the function +rtnl_link_get_kernel()+.
    236 
    237 [source,c]
    238 -----
    239 #include <netlink/route/link.h>
    240 
    241 int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result);
    242 -----
    243 
    244 It will construct and send a +RTM_GETLINK+ request using the parameters
    245 provided and wait for a +RTM_NEWLINK+ or netlink error message sent in
    246 return. If the link exists, the link is returned as link object
    247 (see <<link_object>>).
    248 
    249 .Example: Direct link lookup
    250 [source,c]
    251 -----
    252 struct rtnl_link *link;
    253 
    254 if (rtnl_link_get_kernel(sock, 0, "eth1", &link) < 0)
    255 	/* error */
    256 
    257 /* do something with link */
    258 
    259 rtnl_link_put(link);
    260 -----
    261 
    262 NOTE: While using this function can save a substantial amount of bandwidth
    263       on the netlink socket, the result will not be cached, subsequent calls
    264       to rtnl_link_get_kernel() will always trigger sending a +RTM_GETLINK+
    265       request.
    266 
    267 [[link_translate_ifindex]]
    268 ==== Translating interface index to link name
    269 
    270 Applications which require to translate interface index to a link name or
    271 vice verase may use the following functions to do so. Both functions require
    272 a filled link cache to work with.
    273 
    274 [source,c]
    275 -----
    276 char *rtnl_link_i2name (struct nl_cache *cache, int ifindex, char *dst, size_t len);
    277 int rtnl_link_name2i (struct nl_cache *cache, const char *name);
    278 -----
    279 
    280 === Add / Modify
    281 
    282 Several types of virtual link can be added on the fly using the function
    283 +rtnl_link_add()+.
    284 
    285 [source,c]
    286 -----
    287 #include <netlink/route/link.h>
    288 
    289 int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags);
    290 -----
    291 
    292 === Delete
    293 
    294 The deletion of virtual links such as VLAN devices or dummy devices is done
    295 using the function +rtnl_link_delete()+. The link passed on to the function
    296 can be a link from a link cache or it can be construct with the minimal
    297 attributes needed to identify the link.
    298 
    299 [source,c]
    300 -----
    301 #include <netlink/route/link.h>
    302 
    303 int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link);
    304 -----
    305 
    306 The function will construct and send a +RTM_DELLINK+ request message and
    307 returns any errors returned by the kernel.
    308 
    309 .Example: Delete link by name
    310 [source,c]
    311 -----
    312 struct rtnl_link *link;
    313 
    314 if (!(link = rtnl_link_alloc()))
    315 	/* error */
    316 
    317 rtnl_link_set_name(link, "my_vlan");
    318 
    319 if (rtnl_link_delete(sock, link) < 0)
    320 	/* error */
    321 
    322 rtnl_link_put(link);
    323 -----
    324 
    325 [[link_object]]
    326 === Link Object
    327 
    328 A link is represented by the structure +struct rtnl_link+. Instances may be
    329 created with the function +rtnl_link_alloc()+ or via a link cache (see
    330 <<link_list>>) and are freed again using the function +rtnl_link_put()+.
    331 
    332 [source,c]
    333 -----
    334 #include <netlink/route/link.h>
    335 
    336 struct rtnl_link *rtnl_link_alloc(void);
    337 void rtnl_link_put(struct rtnl_link *link);
    338 -----
    339 
    340 [[link_attr_name]]
    341 ==== Name
    342 The name serves as unique, human readable description of the link. By
    343 default, links are named based on their type and then enumerated, e.g.
    344 eth0, eth1, ethn but they may be renamed at any time.
    345 
    346 Kernels >= 2.6.11 support identification by link name.
    347 
    348 [source,c]
    349 -----
    350 #include <netlink/route/link.h>
    351 
    352 void rtnl_link_set_name(struct rtnl_link *link, const char *name);
    353 char *rtnl_link_get_name(struct rtnl_link *link);
    354 -----
    355 
    356 *Accepted link name format:* +[^ /]*+ (maximum length: 15 characters)
    357 
    358 [[link_attr_ifindex]]
    359 ==== Interface Index (Identifier)
    360 The interface index is an integer uniquely identifying a link. If present
    361 in any link message, it will be used to identify an existing link.
    362 
    363 [source,c]
    364 -----
    365 #include <netlink/route/link.h>
    366 
    367 void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex);
    368 int rtnl_link_get_ifindex(struct rtnl_link *link);
    369 -----
    370 
    371 [[link_attr_group]]
    372 ==== Group
    373 Each link can be assigned a numeric group identifier to group a bunch of links
    374 together and apply a set of changes to a group instead of just a single link.
    375 
    376 
    377 [source,c]
    378 -----
    379 #include <netlink/route/link.h>
    380 
    381 void rtnl_link_set_group(struct rtnl_link *link, uint32_t group);
    382 uint32_t rtnl_link_get_group(struct rtnl_link *link);
    383 -----
    384 
    385 [[link_attr_address]]
    386 ==== Link Layer Address
    387 The link layer address (e.g. MAC address).
    388 
    389 [source,c]
    390 -----
    391 #include <netlink/route/link.h>
    392 
    393 void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr);
    394 struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link);
    395 -----
    396 
    397 [[link_attr_broadcast]]
    398 ==== Broadcast Address
    399 The link layer broadcast address
    400 
    401 [source,c]
    402 -----
    403 #include <netlink/route/link.h>
    404 
    405 void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr);
    406 struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link);
    407 -----
    408 
    409 [[link_attr_mtu]]
    410 ==== MTU (Maximum Transmission Unit)
    411 The maximum transmission unit specifies the maximum packet size a network
    412 device can transmit or receive. This value may be lower than the capability
    413 of the physical network device.
    414 
    415 [source,c]
    416 -----
    417 #include <netlink/route/link.h>
    418 
    419 void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu);
    420 unsigned int rtnl_link_get_mtu(struct rtnl_link *link);
    421 -----
    422 
    423 [[link_attr_flags]]
    424 ==== Flags
    425 The flags of a link enable or disable various link features or inform about
    426 the state of the link.
    427 
    428 [source,c]
    429 -----
    430 #include <netlink/route/link.h>
    431 
    432 void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags);
    433 void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags);
    434 unsigned int rtnl_link_get_flags(struct rtnl_link *link);
    435 -----
    436 
    437 [options="compact"]
    438 [horizontal]
    439 IFF_UP::           Link is up (administratively)
    440 IFF_RUNNING::      Link is up and carrier is OK (RFC2863 OPER_UP)
    441 IFF_LOWER_UP::     Link layer is operational
    442 IFF_DORMANT::      Driver signals dormant
    443 IFF_BROADCAST::    Link supports broadcasting
    444 IFF_MULTICAST::    Link supports multicasting
    445 IFF_ALLMULTI::     Link supports multicast routing
    446 IFF_DEBUG::        Tell driver to do debugging (currently unused)
    447 IFF_LOOPBACK::     Link loopback network
    448 IFF_POINTOPOINT::  Point-to-point link
    449 IFF_NOARP::        ARP is not supported
    450 IFF_PROMISC::      Status of promiscious mode
    451 IFF_MASTER::       Master of a load balancer (bonding)
    452 IFF_SLAVE::        Slave to a master link
    453 IFF_PORTSEL::      Driver supports setting media type (only used by ARM ethernet)
    454 IFF_AUTOMEDIA::    Link selects port automatically (only used by ARM ethernet)
    455 IFF_ECHO::         Echo sent packets (testing feature, CAN only)
    456 IFF_DYNAMIC::      Unused (BSD compatibility)
    457 IFF_NOTRAILERS::   Unused (BSD compatibility)
    458 
    459 To translate a link flag to a link flag name or vice versa:
    460 
    461 [source,c]
    462 -----
    463 #include <netlink/route/link.h>
    464 
    465 char *rtnl_link_flags2str(int flags, char *buf, size_t size);
    466 int rtnl_link_str2flags(const char *flag_name);
    467 -----
    468 
    469 [[link_attr_txqlen]]
    470 ==== Transmission Queue Length
    471 
    472 The transmission queue holds packets before packets are delivered to
    473 the driver for transmission. It is usually specified in number of
    474 packets but the unit may be specific to the link type.
    475 
    476 [source,c]
    477 -----
    478 #include <netlink/route/link.h>
    479 
    480 void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen);
    481 unsigned int rtnl_link_get_txqlen(struct rtnl_link *link);
    482 -----
    483 
    484 [[link_attr_operstate]]
    485 ==== Operational Status
    486 The operational status has been introduced to provide extended information
    487 on the link status. Traditionally the link state has been described using
    488 the link flags +IFF_UP, IFF_RUNNING, IFF_LOWER_UP+, and +IFF_DORMANT+ which
    489 was no longer sufficient for some link types.
    490 
    491 [source,c]
    492 -----
    493 #include <netlink/route/link.h>
    494 
    495 void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t state);
    496 uint8_t rtnl_link_get_operstate(struct rtnl_link *link);
    497 -----
    498 
    499 [options="compact"]
    500 [horizontal]
    501 IF_OPER_UNKNOWN::          Unknown state
    502 IF_OPER_NOTPRESENT::       Link not present
    503 IF_OPER_DOWN::             Link down
    504 IF_OPER_LOWERLAYERDOWN::   L1 down
    505 IF_OPER_TESTING::          Testing
    506 IF_OPER_DORMANT::          Dormant
    507 IF_OPER_UP::               Link up
    508 
    509 Translation of operational status code to string and vice versa:
    510 
    511 [source,c]
    512 -----
    513 #include <netlink/route/link.h>
    514 
    515 char *rtnl_link_operstate2str(uint8_t state, char *buf, size_t size);
    516 int rtnl_link_str2operstate(const char *name);
    517 -----
    518 
    519 [[link_attr_mode]]
    520 ==== Mode
    521 Currently known link modes are:
    522 
    523 [options="compact"]
    524 [horizontal]
    525 IF_LINK_MODE_DEFAULT::   Default link mode
    526 IF_LINK_MODE_DORMANT::   Limit upward transition to dormant
    527 
    528 [source,c]
    529 -----
    530 #include <netlink/route/link.h>
    531 
    532 void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode);
    533 uint8_t rtnl_link_get_linkmode(struct rtnl_link *link);
    534 -----
    535 
    536 Translation of link mode to string and vice versa:
    537 
    538 [source,c]
    539 -----
    540 char *rtnl_link_mode2str(uint8_t mode, char *buf, size_t len);
    541 uint8_t rtnl_link_str2mode(const char *name);
    542 -----
    543 
    544 [[link_attr_alias]]
    545 ==== IfAlias
    546 Alternative name for the link, primarly used for SNMP IfAlias.
    547 
    548 [source,c]
    549 -----
    550 #include <netlink/route/link.h>
    551 
    552 const char *rtnl_link_get_ifalias(struct rtnl_link *link);
    553 void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias);
    554 -----
    555 
    556 *Length limit:* 256
    557 
    558 [[link_attr_arptype]]
    559 ==== Hardware Type
    560 
    561 [source,c]
    562 -----
    563 #include <netlink/route/link.h>
    564 #include <linux/if_arp.h>
    565 
    566 void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype);
    567 unsigned int rtnl_link_get_arptype(struct rtnl_link *link);
    568 ----
    569 
    570 Translation of hardware type to character string and vice versa:
    571 
    572 [source,c]
    573 -----
    574 #include <netlink/utils.h>
    575 
    576 char *nl_llproto2str(int arptype, char *buf, size_t len);
    577 int nl_str2llproto(const char *name);
    578 -----
    579 
    580 [[link_attr_qdisc]]
    581 ==== Qdisc
    582 The name of the queueing discipline used by the link is of informational
    583 nature only. It is a read-only attribute provided by the kernel and cannot
    584 be modified. The set function is provided solely for the purpose of creating
    585 link objects to be used for comparison.
    586 
    587 For more information on how to modify the qdisc of a link, see section
    588 <<route_tc>>.
    589 
    590 [source,c]
    591 -----
    592 #include <netlink/route/link.h>
    593 
    594 void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name);
    595 char *rtnl_link_get_qdisc(struct rtnl_link *link);
    596 -----
    597 
    598 [[link_attr_promiscuity]]
    599 ==== Promiscuity
    600 The number of subsystem currently depending on the link being promiscuous mode.
    601 A value of 0 indicates that the link is not in promiscuous mode. It is a
    602 read-only attribute provided by the kernel and cannot be modified. The set
    603 function is provided solely for the purpose of creating link objects to be
    604 used for comparison.
    605 
    606 [source,c]
    607 -----
    608 #include <netlink/route/link.h>
    609 
    610 void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count);
    611 uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link);
    612 -----
    613 
    614 [[link_num_rxtx_queues]]
    615 ==== RX/TX Queues
    616 The number of RX/TX queues the link provides. The attribute is writable but
    617 will only be considered when creating a new network device via netlink.
    618 
    619 [source,c]
    620 -----
    621 #include <netlink/route/link.h>
    622 
    623 void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues);
    624 uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link);
    625 
    626 void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues);
    627 uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link);
    628 -----
    629 
    630 [[link_attr_weight]]
    631 ==== Weight
    632 This attribute is unused and obsoleted in all recent kernels.
    633 
    634 
    635 [[link_modules]]
    636 === Modules
    637 
    638 [[link_bonding]]
    639 ==== Bonding
    640 
    641 .Example: Add bonding link
    642 [source,c]
    643 -----
    644 #include <netlink/route/link.h>
    645 
    646 struct rtnl_link *link;
    647 
    648 link = rtnl_link_bond_alloc();
    649 rtnl_link_set_name(link, "my_bond");
    650 
    651 /* requires admin privileges */
    652 if (rtnl_link_add(sk, link, NLM_F_CREATE) < 0)
    653 	/* error */
    654 
    655 rtnl_link_put(link);
    656 -----
    657 
    658 [[link_vlan]]
    659 ==== VLAN
    660 
    661 [source,c]
    662 -----
    663 extern char *		rtnl_link_vlan_flags2str(int, char *, size_t);
    664 extern int		rtnl_link_vlan_str2flags(const char *);
    665 
    666 extern int		rtnl_link_vlan_set_id(struct rtnl_link *, int);
    667 extern int		rtnl_link_vlan_get_id(struct rtnl_link *);
    668 
    669 extern int		rtnl_link_vlan_set_flags(struct rtnl_link *,
    670 						 unsigned int);
    671 extern int		rtnl_link_vlan_unset_flags(struct rtnl_link *,
    672 						   unsigned int);
    673 extern unsigned int	rtnl_link_vlan_get_flags(struct rtnl_link *);
    674 
    675 extern int		rtnl_link_vlan_set_ingress_map(struct rtnl_link *,
    676 						       int, uint32_t);
    677 extern uint32_t *	rtnl_link_vlan_get_ingress_map(struct rtnl_link *);
    678 
    679 extern int		rtnl_link_vlan_set_egress_map(struct rtnl_link *,
    680 						      uint32_t, int);
    681 extern struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *,
    682 						      int *);
    683 -----
    684 
    685 .Example: Add a VLAN device
    686 [source,c]
    687 -----
    688 struct rtnl_link *link;
    689 int master_index;
    690 
    691 /* lookup interface index of eth0 */
    692 if (!(master_index = rtnl_link_name2i(link_cache, "eth0")))
    693 	/* error */
    694 
    695 /* allocate new link object of type vlan */
    696 link = rtnl_link_vlan_alloc();
    697 
    698 /* set eth0 to be our master device */
    699 rtnl_link_set_link(link, master_index);
    700 
    701 rtnl_link_vlan_set_id(link, 10);
    702 
    703 if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
    704 	/* error */
    705 
    706 rtnl_link_put(link);
    707 -----
    708 
    709 [[link_macvlan]]
    710 ==== MACVLAN
    711 
    712 [source,c]
    713 -----
    714 extern struct rtnl_link *rtnl_link_macvlan_alloc(void);
    715 
    716 extern int		rtnl_link_is_macvlan(struct rtnl_link *);
    717 
    718 extern char *		rtnl_link_macvlan_mode2str(int, char *, size_t);
    719 extern int		rtnl_link_macvlan_str2mode(const char *);
    720 
    721 extern char *		rtnl_link_macvlan_flags2str(int, char *, size_t);
    722 extern int		rtnl_link_macvlan_str2flags(const char *);
    723 
    724 extern int		rtnl_link_macvlan_set_mode(struct rtnl_link *,
    725 			                           uint32_t);
    726 extern uint32_t		rtnl_link_macvlan_get_mode(struct rtnl_link *);
    727 
    728 extern int		rtnl_link_macvlan_set_flags(struct rtnl_link *,
    729 						 uint16_t);
    730 extern int		rtnl_link_macvlan_unset_flags(struct rtnl_link *,
    731 						   uint16_t);
    732 extern uint16_t		rtnl_link_macvlan_get_flags(struct rtnl_link *);
    733 -----
    734 
    735 .Example: Add a MACVLAN device
    736 [source,c]
    737 -----
    738 struct rtnl_link *link;
    739 int master_index;
    740 struct nl_addr* addr;
    741 
    742 /* lookup interface index of eth0 */
    743 if (!(master_index = rtnl_link_name2i(link_cache, "eth0")))
    744 	/* error */
    745 
    746 /* allocate new link object of type macvlan */
    747 link = rtnl_link_macvlan_alloc();
    748 
    749 /* set eth0 to be our master device */
    750 rtnl_link_set_link(link, master_index);
    751 
    752 /* set address of virtual interface */
    753 addr = nl_addr_build(AF_LLC, ether_aton("00:11:22:33:44:55"), ETH_ALEN);
    754 rtnl_link_set_addr(link, addr);
    755 nl_addr_put(addr);
    756 
    757 /* set mode of virtual interface */
    758 rtnl_link_macvlan_set_mode(link, rtnl_link_macvlan_str2mode("bridge"));
    759 
    760 if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
    761 	/* error */
    762 
    763 rtnl_link_put(link);
    764 -----
    765 
    766 [[link_vxlan]]
    767 ==== VXLAN
    768 
    769 [source,c]
    770 -----
    771 extern struct rtnl_link *rtnl_link_vxlan_alloc(void);
    772 
    773 extern int	rtnl_link_is_vxlan(struct rtnl_link *);
    774 
    775 extern int	rtnl_link_vxlan_set_id(struct rtnl_link *, uint32_t);
    776 extern int	rtnl_link_vxlan_get_id(struct rtnl_link *, uint32_t *);
    777 
    778 extern int	rtnl_link_vxlan_set_group(struct rtnl_link *, struct nl_addr *);
    779 extern int	rtnl_link_vxlan_get_group(struct rtnl_link *, struct nl_addr **);
    780 
    781 extern int	rtnl_link_vxlan_set_link(struct rtnl_link *, uint32_t);
    782 extern int	rtnl_link_vxlan_get_link(struct rtnl_link *, uint32_t *);
    783 
    784 extern int	rtnl_link_vxlan_set_local(struct rtnl_link *, struct nl_addr *);
    785 extern int	rtnl_link_vxlan_get_local(struct rtnl_link *, struct nl_addr **);
    786 
    787 extern int	rtnl_link_vxlan_set_ttl(struct rtnl_link *, uint8_t);
    788 extern int	rtnl_link_vxlan_get_ttl(struct rtnl_link *);
    789 
    790 extern int	rtnl_link_vxlan_set_tos(struct rtnl_link *, uint8_t);
    791 extern int	rtnl_link_vxlan_get_tos(struct rtnl_link *);
    792 
    793 extern int	rtnl_link_vxlan_set_learning(struct rtnl_link *, uint8_t);
    794 extern int	rtnl_link_vxlan_get_learning(struct rtnl_link *);
    795 extern int	rtnl_link_vxlan_enable_learning(struct rtnl_link *);
    796 extern int	rtnl_link_vxlan_disable_learning(struct rtnl_link *);
    797 
    798 extern int	rtnl_link_vxlan_set_ageing(struct rtnl_link *, uint32_t);
    799 extern int	rtnl_link_vxlan_get_ageing(struct rtnl_link *, uint32_t *);
    800 
    801 extern int	rtnl_link_vxlan_set_limit(struct rtnl_link *, uint32_t);
    802 extern int	rtnl_link_vxlan_get_limit(struct rtnl_link *, uint32_t *);
    803 
    804 extern int	rtnl_link_vxlan_set_port_range(struct rtnl_link *,
    805 					       struct ifla_vxlan_port_range *);
    806 extern int	rtnl_link_vxlan_get_port_range(struct rtnl_link *,
    807 					       struct ifla_vxlan_port_range *);
    808 
    809 extern int	rtnl_link_vxlan_set_proxy(struct rtnl_link *, uint8_t);
    810 extern int	rtnl_link_vxlan_get_proxy(struct rtnl_link *);
    811 extern int	rtnl_link_vxlan_enable_proxy(struct rtnl_link *);
    812 extern int	rtnl_link_vxlan_disable_proxy(struct rtnl_link *);
    813 
    814 extern int	rtnl_link_vxlan_set_rsc(struct rtnl_link *, uint8_t);
    815 extern int	rtnl_link_vxlan_get_rsc(struct rtnl_link *);
    816 extern int	rtnl_link_vxlan_enable_rsc(struct rtnl_link *);
    817 extern int	rtnl_link_vxlan_disable_rsc(struct rtnl_link *);
    818 
    819 extern int	rtnl_link_vxlan_set_l2miss(struct rtnl_link *, uint8_t);
    820 extern int	rtnl_link_vxlan_get_l2miss(struct rtnl_link *);
    821 extern int	rtnl_link_vxlan_enable_l2miss(struct rtnl_link *);
    822 extern int	rtnl_link_vxlan_disable_l2miss(struct rtnl_link *);
    823 
    824 extern int	rtnl_link_vxlan_set_l3miss(struct rtnl_link *, uint8_t);
    825 extern int	rtnl_link_vxlan_get_l3miss(struct rtnl_link *);
    826 extern int	rtnl_link_vxlan_enable_l3miss(struct rtnl_link *);
    827 extern int	rtnl_link_vxlan_disable_l3miss(struct rtnl_link *);
    828 -----
    829 
    830 .Example: Add a VXLAN device
    831 [source,c]
    832 -----
    833 struct rtnl_link *link;
    834 struct nl_addr* addr;
    835 
    836 /* allocate new link object of type vxlan */
    837 link = rtnl_link_vxlan_alloc();
    838 
    839 /* set interface name */
    840 rtnl_link_set_name(link, "vxlan128");
    841 
    842 /* set VXLAN network identifier */
    843 if ((err = rtnl_link_vxlan_set_id(link, 128)) < 0)
    844 	/* error */
    845 
    846 /* set multicast address to join */
    847 if ((err = nl_addr_parse("239.0.0.1", AF_INET, &addr)) < 0)
    848 	/* error */
    849 
    850 if ((err = rtnl_link_set_group(link, addr)) < 0)
    851 	/* error */
    852 
    853 nl_addr_put(addr);
    854 
    855 if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
    856 	/* error */
    857 
    858 rtnl_link_put(link);
    859 -----
    860 
    861 [[link_ipip]]
    862 ==== IPIP
    863 
    864 [source,c]
    865 -----
    866 extern struct rtnl_link *rtnl_link_ipip_alloc(void);
    867 extern int rtnl_link_ipip_add(struct nl_sock *sk, const char *name);
    868 
    869 extern int rtnl_link_ipip_set_link(struct rtnl_link *link,  uint32_t index);
    870 extern uint32_t rtnl_link_ipip_get_link(struct rtnl_link *link);
    871 
    872 extern int rtnl_link_ipip_set_local(struct rtnl_link *link, uint32_t addr);
    873 extern uint32_t rtnl_link_ipip_get_local(struct rtnl_link *link);
    874 
    875 extern int rtnl_link_ipip_set_remote(struct rtnl_link *link, uint32_t addr);
    876 extern uint32_t rtnl_link_ipip_get_remote(struct rtnl_link *link);
    877 
    878 extern int rtnl_link_ipip_set_ttl(struct rtnl_link *link, uint8_t ttl);
    879 extern uint8_t rtnl_link_ipip_get_ttl(struct rtnl_link *link);
    880 
    881 extern int rtnl_link_ipip_set_tos(struct rtnl_link *link, uint8_t tos);
    882 extern uint8_t rtnl_link_ipip_get_tos(struct rtnl_link *link);
    883 
    884 extern int rtnl_link_ipip_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
    885 extern uint8_t rtnl_link_ipip_get_pmtudisc(struct rtnl_link *link);
    886 
    887 -----
    888 
    889 .Example: Add a ipip tunnel device
    890 [source,c]
    891 -----
    892 struct rtnl_link *link
    893 struct in_addr addr
    894 
    895 /* allocate new link object of type vxlan */
    896 if(!(link = rtnl_link_ipip_alloc()))
    897         /* error */
    898 
    899 /* set ipip tunnel name */
    900 if ((err = rtnl_link_set_name(link, "ipip-tun")) < 0)
    901          /* error */
    902 
    903 /* set link index  */
    904 if ((err = rtnl_link_ipip_set_link(link, if_index)) < 0)
    905         /* error */
    906 
    907 /* set local address */
    908 inet_pton(AF_INET, "192.168.254.12", &addr.s_addr);
    909 if ((err = rtnl_link_ipip_set_local(link, addr.s_addr)) < 0)
    910         /* error */
    911 
    912 /* set remote address */
    913 inet_pton(AF_INET, "192.168.254.13", &addr.s_addr
    914 if ((err = rtnl_link_ipip_set_remote(link, addr.s_addr)) < 0)
    915         /* error */
    916 
    917 /* set tunnel ttl  */
    918 if ((err = rtnl_link_ipip_set_ttl(link, 64)) < 0)
    919         /* error */
    920 
    921 if((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
    922         /* error */
    923 
    924 rtnl_link_put(link);
    925 -----
    926 
    927 [[link_ipgre]]
    928 ==== IPGRE
    929 
    930 [source,c]
    931 -----
    932 extern struct rtnl_link *rtnl_link_ipgre_alloc(void);
    933 extern int rtnl_link_ipgre_add(struct nl_sock *sk, const char *name);
    934 
    935 extern int rtnl_link_ipgre_set_link(struct rtnl_link *link,  uint32_t index);
    936 extern uint32_t rtnl_link_ipgre_get_link(struct rtnl_link *link);
    937 
    938 extern int rtnl_link_ipgre_set_iflags(struct rtnl_link *link, uint16_t iflags);
    939 extern uint16_t rtnl_link_get_iflags(struct rtnl_link *link);
    940 
    941 extern int rtnl_link_ipgre_set_oflags(struct rtnl_link *link, uint16_t oflags);
    942 extern uint16_t rtnl_link_get_oflags(struct rtnl_link *link);
    943 
    944 extern int rtnl_link_ipgre_set_ikey(struct rtnl_link *link, uint32_t ikey);
    945 extern uint32_t rtnl_link_get_ikey(struct rtnl_link *link);
    946 
    947 extern int rtnl_link_ipgre_set_okey(struct rtnl_link *link, uint32_t okey);
    948 extern uint32_t rtnl_link_get_okey(struct rtnl_link *link)
    949 
    950 extern int rtnl_link_ipgre_set_local(struct rtnl_link *link, uint32_t addr);
    951 extern uint32_t rtnl_link_ipgre_get_local(struct rtnl_link *link);
    952 
    953 extern int rtnl_link_ipgre_set_remote(struct rtnl_link *link, uint32_t addr);
    954 extern uint32_t rtnl_link_ipgre_get_remote(struct rtnl_link *link);
    955 
    956 extern int rtnl_link_ipgre_set_ttl(struct rtnl_link *link, uint8_t ttl);
    957 extern uint8_t rtnl_link_ipgre_get_ttl(struct rtnl_link *link);
    958 
    959 extern int rtnl_link_ipgre_set_tos(struct rtnl_link *link, uint8_t tos);
    960 extern uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link);
    961 
    962 extern int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
    963 extern uint8_t rtnl_link_ipgre_get_pmtudisc(struct rtnl_link *link);
    964 
    965 -----
    966 
    967 .Example: Add a ipgre tunnel device
    968 [source,c]
    969 -----
    970 struct rtnl_link *link
    971 struct in_addr addr
    972 
    973 /* allocate new link object of type vxlan */
    974 if(!(link = rtnl_link_ipgre_alloc()))
    975 	/* error */
    976 
    977 /* set ipgre tunnel name */
    978 if ((err = rtnl_link_set_name(link, "ipgre-tun")) < 0)
    979 	/* error */
    980 
    981 /* set link index  */
    982 if ((err = rtnl_link_ipgre_set_link(link, if_index)) < 0)
    983 	/* error */
    984 
    985 /* set local address */
    986 inet_pton(AF_INET, "192.168.254.12", &addr.s_addr);
    987 if ((err = rtnl_link_ipgre_set_local(link, addr.s_addr)) < 0)
    988 	/* error */
    989 
    990 /* set remote address */
    991 inet_pton(AF_INET, "192.168.254.13", &addr.s_addr
    992 if ((err = rtnl_link_ipgre_set_remote(link, addr.s_addr)) < 0)
    993 	/* error */
    994 
    995 /* set tunnel ttl  */
    996 if ((err = rtnl_link_ipgre_set_ttl(link, 64)) < 0)
    997 	/* error */
    998 
    999 if((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
   1000 	/* error */
   1001 
   1002 rtnl_link_put(link);
   1003 -----
   1004 
   1005 [[link_sit]]
   1006 ==== SIT
   1007 
   1008 [source,c]
   1009 -----
   1010 extern struct rtnl_link *rtnl_link_sit_alloc(void);
   1011 extern int rtnl_link_sit_add(struct nl_sock *sk, const char *name);
   1012 
   1013 extern int rtnl_link_sit_set_link(struct rtnl_link *link,  uint32_t index);
   1014 extern uint32_t rtnl_link_sit_get_link(struct rtnl_link *link);
   1015 
   1016 extern int rtnl_link_sit_set_iflags(struct rtnl_link *link, uint16_t iflags);
   1017 extern uint16_t rtnl_link_get_iflags(struct rtnl_link *link);
   1018 
   1019 extern int rtnl_link_sit_set_oflags(struct rtnl_link *link, uint16_t oflags);
   1020 extern uint16_t rtnl_link_get_oflags(struct rtnl_link *link);
   1021 
   1022 extern int rtnl_link_sit_set_ikey(struct rtnl_link *link, uint32_t ikey);
   1023 extern uint32_t rtnl_link_get_ikey(struct rtnl_link *link);
   1024 
   1025 extern int rtnl_link_sit_set_okey(struct rtnl_link *link, uint32_t okey);
   1026 extern uint32_t rtnl_link_get_okey(struct rtnl_link *link)
   1027 
   1028 extern int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr);
   1029 extern uint32_t rtnl_link_sit_get_local(struct rtnl_link *link);
   1030 
   1031 extern int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr);
   1032 extern uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link);
   1033 
   1034 extern int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl);
   1035 extern uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link);
   1036 
   1037 extern int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos);
   1038 extern uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link);
   1039 
   1040 extern int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc);
   1041 extern uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link);
   1042 
   1043 -----
   1044 
   1045 .Example: Add a sit tunnel device
   1046 [source,c]
   1047 -----
   1048 struct rtnl_link *link
   1049 struct in_addr addr
   1050 
   1051 /* allocate new link object of type vxlan */
   1052 if(!(link = rtnl_link_sit_alloc()))
   1053 	/* error */
   1054 
   1055 /* set sit tunnel name */
   1056 if ((err = rtnl_link_set_name(link, "sit-tun")) < 0)
   1057 	/* error */
   1058 
   1059 /* set link index  */
   1060 if ((err = rtnl_link_sit_set_link(link, if_index)) < 0)
   1061 	/* error */
   1062 
   1063 /* set local address */
   1064 inet_pton(AF_INET, "192.168.254.12", &addr.s_addr);
   1065 if ((err = rtnl_link_sit_set_local(link, addr.s_addr)) < 0)
   1066 	/* error */
   1067 
   1068 /* set remote address */
   1069 inet_pton(AF_INET, "192.168.254.13", &addr.s_addr
   1070 if ((err = rtnl_link_sit_set_remote(link, addr.s_addr)) < 0)
   1071 	/* error */
   1072 
   1073 /* set tunnel ttl  */
   1074 if ((err = rtnl_link_sit_set_ttl(link, 64)) < 0)
   1075 	/* error */
   1076 
   1077 if((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
   1078         /* error */
   1079 
   1080 rtnl_link_put(link);
   1081 -----
   1082 
   1083 
   1084 [[link_ipvti]]
   1085 ==== IPVTI
   1086 
   1087 [source,c]
   1088 -----
   1089 extern struct rtnl_link *rtnl_link_ipvti_alloc(void);
   1090 extern int rtnl_link_ipvti_add(struct nl_sock *sk, const char *name);
   1091 
   1092 extern int rtnl_link_ipvti_set_link(struct rtnl_link *link,  uint32_t index);
   1093 extern uint32_t rtnl_link_ipvti_get_link(struct rtnl_link *link);
   1094 
   1095 extern int rtnl_link_ipvti_set_ikey(struct rtnl_link *link, uint32_t ikey);
   1096 extern uint32_t rtnl_link_get_ikey(struct rtnl_link *link);
   1097 
   1098 extern int rtnl_link_ipvti_set_okey(struct rtnl_link *link, uint32_t okey);
   1099 extern uint32_t rtnl_link_get_okey(struct rtnl_link *link)
   1100 
   1101 extern int rtnl_link_ipvti_set_local(struct rtnl_link *link, uint32_t addr);
   1102 extern uint32_t rtnl_link_ipvti_get_local(struct rtnl_link *link);
   1103 
   1104 extern int rtnl_link_ipvti_set_remote(struct rtnl_link *link, uint32_t addr);
   1105 extern uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link);
   1106 
   1107 -----
   1108 
   1109 .Example: Add a ipvti tunnel device
   1110 [source,c]
   1111 -----
   1112 struct rtnl_link *link
   1113 struct in_addr addr
   1114 
   1115 /* allocate new link object of type vxlan */
   1116 if(!(link = rtnl_link_ipvti_alloc()))
   1117 	/* error */
   1118 
   1119 /* set ipvti tunnel name */
   1120 if ((err = rtnl_link_set_name(link, "ipvti-tun")) < 0)
   1121 	/* error */
   1122 
   1123 /* set link index  */
   1124 if ((err = rtnl_link_ipvti_set_link(link, if_index)) < 0)
   1125 	/* error */
   1126 
   1127 /* set local address */
   1128 inet_pton(AF_INET, "192.168.254.12", &addr.s_addr);
   1129 if ((err = rtnl_link_ipvti_set_local(link, addr.s_addr)) < 0)
   1130 	/* error */
   1131 
   1132 /* set remote address */
   1133 inet_pton(AF_INET, "192.168.254.13", &addr.s_addr
   1134 if ((err = rtnl_link_ipvti_set_remote(link, addr.s_addr)) < 0)
   1135 	/* error */
   1136 
   1137 if((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
   1138 	/* error */
   1139 
   1140 rtnl_link_put(link);
   1141 -----
   1142 
   1143 [[link_ip6tnl]]
   1144 ==== IP6TNL
   1145 
   1146 [source,c]
   1147 -----
   1148 extern struct rtnl_link *rtnl_link_ip6_tnl_alloc(void);
   1149 extern int rtnl_link_ip6_tnl_add(struct nl_sock *sk, const char *name);
   1150 
   1151 extern int rtnl_link_ip6_tnl_set_link(struct rtnl_link *link,  uint32_t index);
   1152 extern uint32_t rtnl_link_ip6_tnl_get_link(struct rtnl_link *link);
   1153 
   1154 extern int rtnl_link_ip6_tnl_set_local(struct rtnl_link *link, struct in6_addr *);
   1155 extern int rtnl_link_ip6_tnl_get_local(struct rtnl_link *link, struct in6_addr *);
   1156 
   1157 extern int rtnl_link_ip6_tnl_set_remote(struct rtnl_link *link, struct in6_addr *);
   1158 extern int rtnl_link_ip6_tnl_get_remote(struct rtnl_link *link, struct in6_addr *);
   1159 
   1160 extern int rtnl_link_ip6_tnl_set_ttl(struct rtnl_link *link, uint8_t ttl);
   1161 extern uint8_t rtnl_link_ip6_tnl_get_ttl(struct rtnl_link *link);
   1162 
   1163 extern int rtnl_link_ip6_tnl_set_tos(struct rtnl_link *link, uint8_t tos);
   1164 extern uint8_t rtnl_link_ip6_tnl_get_tos(struct rtnl_link *link);
   1165 
   1166 extern int rtnl_link_ip6_tnl_set_encaplimit(struct rtnl_link *link, uint8_t encap_limit);
   1167 extern uint8_t rtnl_link_ip6_tnl_get_encaplimit(struct rtnl_link *link);
   1168 
   1169 extern int rtnl_link_ip6_tnl_set_flags(struct rtnl_link *link, uint32_t flags);
   1170 extern uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link);
   1171 
   1172 extern uint32_t rtnl_link_ip6_tnl_get_flowinfo(struct rtnl_link *link);
   1173 extern int rtnl_link_ip6_tnl_set_flowinfo(struct rtnl_link *link, uint32_t flowinfo);
   1174 
   1175 extern int rtnl_link_ip6_tnl_set_proto(struct rtnl_link *link, uint8_t proto);
   1176 extern uint8_t rtnl_link_ip6_tnl_get_proto(struct rtnl_link *link);
   1177 
   1178 -----
   1179 
   1180 .Example: Add a ip6tnl tunnel device
   1181 [source,c]
   1182 -----
   1183 struct rtnl_link *link
   1184 struct in6_addr addr
   1185 
   1186 link = rtnl_link_ip6_tnl_alloc();
   1187 
   1188 rtnl_link_set_name(link, "ip6tnl-tun");
   1189 rtnl_link_ip6_tnl_set_link(link, if_index);
   1190 
   1191 inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr);
   1192 rtnl_link_ip6_tnl_set_local(link, &addr);
   1193 
   1194 inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr);
   1195 rtnl_link_ip6_tnl_set_remote(link, &addr);
   1196 
   1197 rtnl_link_add(sk, link, NLM_F_CREATE);
   1198 rtnl_link_put(link);
   1199 
   1200 -----
   1201 
   1202 
   1203 == Neighbouring
   1204 
   1205 == Routing
   1206 
   1207 [[route_tc]]
   1208 == Traffic Control
   1209 
   1210 The traffic control architecture allows the queueing and
   1211 prioritization of packets before they are enqueued to the network
   1212 driver. To a limited degree it is also possible to take control of
   1213 network traffic as it enters the network stack.
   1214 
   1215 The architecture consists of three different types of modules:
   1216 
   1217 - *Queueing disciplines (qdisc)* provide a mechanism to enqueue packets
   1218   in different forms. They may be used to implement fair queueing,
   1219   prioritization of differentiated services, enforce bandwidth
   1220   limitations, or even to simulate network behaviour such as packet
   1221   loss and packet delay. Qdiscs can be classful in which case they
   1222   allow traffic classes described in the next paragraph to be attached
   1223   to them.
   1224 
   1225 - *Traffic classes (class)* are supported by several qdiscs to build
   1226   a tree structure for different types of traffic. Each class may be
   1227   assigned its own set of attributes such as bandwidth limits or
   1228   queueing priorities. Some qdiscs even allow borrowing of bandwidth
   1229   between classes.
   1230 
   1231 - *Classifiers (cls)* are used to decide which qdisc/class the packet
   1232   should be enqueued to. Different types of classifiers exists,
   1233   ranging from classification based on protocol header values to
   1234   classification based on packet priority or firewall marks.
   1235   Additionally most classifiers support *extended matches (ematch)*
   1236   which allow extending classifiers by a set of matcher modules, and
   1237   *actions* which allow classifiers to take actions such as mangling,
   1238   mirroring, or even rerouting of packets.
   1239 
   1240 .Default Qdisc
   1241 
   1242 The default qdisc used on all network devices is `pfifo_fast`.
   1243 Network devices which do not require a transmit queue such as the
   1244 loopback device do not have a default qdisc attached. The `pfifo_fast`
   1245 qdisc provides three bands to prioritize interactive traffic over bulk
   1246 traffic. Classification is based on the packet priority (diffserv).
   1247 
   1248 image:qdisc_default.png["Default Qdisc"]
   1249 
   1250 .Multiqueue Default Qdisc
   1251 
   1252 If the network device provides multiple transmit queues the `mq`
   1253 qdisc is used by default. It will automatically create a separate
   1254 class for each transmit queue available and will also replace
   1255 the single per device tx lock with a per queue lock.
   1256 
   1257 image:qdisc_mq.png["Multiqueue default Qdisc"]
   1258 
   1259 .Example of a customized classful qdisc setup
   1260 
   1261 The following figure illustrates a possible combination of different
   1262 queueing and classification modules to implement quality of service
   1263 needs.
   1264 
   1265 image:tc_overview.png["Classful Qdisc diagram"]
   1266 
   1267 === Traffic Control Object
   1268 
   1269 Each type traffic control module (qdisc, class, classifier) is
   1270 represented by its own structure. All of them are based on the traffic
   1271 control object represented by `struct rtnl_tc` which itself is based
   1272 on the generic object `struct nl_object` to make it cacheable. The
   1273 traffic control object contains all attributes, implementation details
   1274 and statistics that are shared by all of the traffic control object
   1275 types.
   1276 
   1277 image:tc_obj.png["struct rtnl_tc hierarchy"]
   1278 
   1279 It is not possible to allocate a `struct rtnl_tc` object, instead the
   1280 actual tc object types must be allocated directly using
   1281 `rtnl_qdisc_alloc()`, `rtnl_class_alloc()`, `rtnl_cls_alloc()` and
   1282 then casted to `struct rtnl_tc` using the `TC_CAST()` macro.
   1283 
   1284 .Usage Example: Allocation, Casting, Freeing
   1285 [source,c]
   1286 -----
   1287 #include <netlink/route/tc.h>
   1288 #include <netlink/route/qdisc.h>
   1289 
   1290 struct rtnl_qdisc *qdisc;
   1291 
   1292 /* Allocation of a qdisc object */
   1293 qdisc = rtnl_qdisc_alloc();
   1294 
   1295 /* Cast the qdisc to a tc object using TC_CAST() to use rtnl_tc_ functions. */
   1296 rtnl_tc_set_mpu(TC_CAST(qdisc), 64);
   1297 
   1298 /* Free the qdisc object */
   1299 rtnl_qdisc_put(qdisc);
   1300 -----
   1301 
   1302 [[tc_attr]]
   1303 ==== Attributes
   1304 
   1305 Handle::
   1306 The handle uniquely identifies a tc object and is used to refer
   1307 to other tc objects when constructing tc trees.
   1308 +
   1309 [source,c]
   1310 -----
   1311 void rtnl_tc_set_handle(struct rtnl_tc *tc, uint32_t handle);
   1312 uint32_t rtnl_tc_get_handle(struct rtnl_tc *tc);
   1313 -----
   1314 
   1315 Interface Index::
   1316 The interface index specifies the network device the traffic object
   1317 is attached to. The function `rtnl_tc_set_link()` should be preferred
   1318 when setting the interface index. It stores the reference to the link
   1319 object in the tc object and allows retrieving the `mtu` and `linktype`
   1320 automatically.
   1321 +
   1322 [source,c]
   1323 -----
   1324 void rtnl_tc_set_ifindex(struct rtnl_tc *tc, int ifindex);
   1325 void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link);
   1326 int rtnl_tc_get_ifindex(struct rtnl_tc *tc);
   1327 -----
   1328 
   1329 Link Type::
   1330 The link type specifies the kind of link that is used by the network
   1331 device (e.g. ethernet, ATM, ...). It is derived automatically when
   1332 the network device is specified with `rtnl_tc_set_link()`.
   1333 The default fallback is `ARPHRD_ETHER` (ethernet).
   1334 +
   1335 [source,c]
   1336 -----
   1337 void rtnl_tc_set_linktype(struct rtnl_tc *tc, uint32_t type);
   1338 uint32_t rtnl_tc_get_linktype(struct rtnl_tc *tc);
   1339 -----
   1340 
   1341 Kind::
   1342 The kind character string specifies the type of qdisc, class,
   1343 classifier. Setting the kind results in the module specific
   1344 structure being allocated. Therefore it is imperative to call 
   1345 `rtnl_tc_set_kind()` before using any type specific API functions
   1346 such as `rtnl_htb_set_rate()`.
   1347 +
   1348 [source,c]
   1349 -----
   1350 int rtnl_tc_set_kind(struct rtnl_tc *tc, const char *kind);
   1351 char *rtnl_tc_get_kind(struct rtnl_tc *tc);
   1352 -----
   1353 
   1354 MPU::
   1355 The Minimum Packet Unit specifies the minimum packet size which will
   1356 be transmitted
   1357 ever be seen by this traffic control object. This value is used for
   1358 rate calculations. Not all object implementations will make use of
   1359 this value. The default value is 0.
   1360 +
   1361 [source,c]
   1362 -----
   1363 void rtnl_tc_set_mpu(struct rtnl_tc *tc, uint32_t mpu);
   1364 uint32_t rtnl_tc_get_mpu(struct rtnl_tc *tc);
   1365 -----
   1366 
   1367 MTU::
   1368 The Maximum Transmission Unit specifies the maximum packet size which
   1369 will be transmitted. The value is derived from the link specified
   1370 with `rtnl_tc_set_link()` if not overwritten with `rtnl_tc_set_mtu()`.
   1371 If no link and MTU is specified, the value defaults to 1500
   1372 (ethernet).
   1373 +
   1374 [source,c]
   1375 -----
   1376 void rtnl_tc_set_mtu(struct rtnl_tc *tc, uint32_t mtu);
   1377 uint32_t rtnl_tc_get_mtu(struct rtnl_tc *tc);
   1378 -----
   1379 
   1380 Overhead::
   1381 The overhead specifies the additional overhead per packet caused by
   1382 the network layer. This value can be used to correct packet size
   1383 calculations if the packet size on the wire does not match the packet
   1384 size seen by the kernel. The default value is 0.
   1385 +
   1386 [source,c]
   1387 -----
   1388 void rtnl_tc_set_overhead(struct rtnl_tc *tc, uint32_t overhead);
   1389 uint32_t rtnl_tc_get_overhead(struct rtnl_tc *tc);
   1390 -----
   1391 
   1392 Parent::
   1393 Specifies the parent traffic control object. The parent is identifier
   1394 by its handle. Special values are:
   1395 - `TC_H_ROOT`: attach tc object directly to network device (root
   1396   qdisc, root classifier)
   1397 - `TC_H_INGRESS`: same as `TC_H_ROOT` but on the ingress side of the
   1398   network stack.
   1399 +
   1400 [source,c]
   1401 -----
   1402 void rtnl_tc_set_parent(struct rtnl_tc *tc, uint32_t parent);
   1403 uint32_t rtnl_tc_get_parent(struct rtnl_tc *tc);
   1404 -----
   1405 
   1406 Statistics::
   1407 Generic statistics, see <<tc_stats>> for additional information.
   1408 +
   1409 [source,c]
   1410 -----
   1411 uint64_t rtnl_tc_get_stat(struct rtnl_tc *tc, enum rtnl_tc_stat id);
   1412 -----
   1413 
   1414 [[tc_stats]]
   1415 ==== Accessing Statistics
   1416 
   1417 The traffic control object holds a set of generic statistics. Not all
   1418 traffic control modules will make use of all of these statistics. Some
   1419 modules may provide additional statistics via their own APIs.
   1420 
   1421 .Statistic identifiers `(enum rtnl_tc_stat)`
   1422 [cols="m,,", options="header", frame="topbot"]
   1423 |====================================================================
   1424 | ID                 | Type    | Description
   1425 | RTNL_TC_PACKETS    | Counter | Total # of packets transmitted
   1426 | RTNL_TC_BYTES      | Counter | Total # of bytes transmitted
   1427 | RTNL_TC_RATE_BPS   | Rate    | Current bytes/s rate
   1428 | RTNL_TC_RATE_PPS   | Rate    | Current packets/s rate
   1429 | RTNL_TC_QLEN       | Rate    | Current length of the queue
   1430 | RTNL_TC_BACKLOG    | Rate    | # of packets currently backloged
   1431 | RTNL_TC_DROPS      | Counter | # of packets dropped
   1432 | RTNL_TC_REQUEUES   | Counter | # of packets requeued
   1433 | RTNL_TC_OVERLIMITS | Counter | # of packets that exceeded the limit
   1434 |====================================================================
   1435 
   1436 NOTE: `RTNL_TC_RATE_BPS` and `RTNL_TC_RATE_PPS` only return meaningful
   1437       values if a rate estimator has been configured.
   1438 
   1439 .Usage Example: Retrieving tc statistics
   1440 [source,c]
   1441 -------
   1442 #include <netlink/route/tc.h>
   1443 
   1444 uint64_t drops, qlen;
   1445 
   1446 drops = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_DROPS);
   1447 qlen  = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_QLEN);
   1448 -------
   1449 
   1450 ==== Rate Table Calculations
   1451 
   1452 [[tc_qdisc]]
   1453 === Queueing Discipline (qdisc)
   1454 
   1455 .Classless Qdisc
   1456 
   1457 The queueing discipline (qdisc) is used to implement fair queueing,
   1458 priorization or rate control. It provides a _enqueue()_ and
   1459 _dequeue()_ operation. Whenever a network packet leaves the networking
   1460 stack over a network device, be it a physical or virtual device, it
   1461 will be enqueued to a qdisc unless the device is queueless. The
   1462 _enqueue()_ operation is followed by an immediate call to _dequeue()_
   1463 for the same qdisc to eventually retrieve a packet which can be
   1464 scheduled for transmission by the driver. Additionally, the networking
   1465 stack runs a watchdog which polls the qdisc regularly to dequeue and
   1466 send packets even if no new packets are being enqueued.
   1467 
   1468 This additional watchdog is required due to the fact that qdiscs may
   1469 hold on to packets and not return any packets upon _dequeue()_ in
   1470 order to enforce bandwidth restrictions.
   1471 
   1472 image:classless_qdisc_nbands.png[alt="Multiband Qdisc", float="right"]
   1473 
   1474 The figure illustrates a trivial example of a classless qdisc
   1475 consisting of three bands (queues). Use of multiple bands is a common
   1476 technique in qdiscs to implement fair queueing between flows or
   1477 prioritize differentiated services.
   1478 
   1479 Classless qdiscs can be regarded as a blackbox, their inner workings
   1480 can only be steered using the configuration parameters provided by the
   1481 qdisc. There is no way of taking influence on the structure of its
   1482 internal queues itself.
   1483 
   1484 .Classful Qdisc
   1485 
   1486 Classful qdiscs allow for the queueing structure and classification
   1487 process to be created by the user. 
   1488 
   1489 image:classful_qdisc.png["Classful Qdisc"]
   1490 
   1491 The figure above shows a classful qdisc with a classifier attached to
   1492 it which will make the decision whether to enqueue a packet to traffic
   1493 class +1:1+ or +1:2+. Unlike with classless qdiscs, classful qdiscs
   1494 allow the classification process and the structure of the queues to be
   1495 defined by the user. This allows for complex traffic class rules to
   1496 be applied.
   1497 
   1498 .List of Qdisc Implementations
   1499 [options="header", frame="topbot", cols="2,1^,8"]
   1500 |======================================================================
   1501 | Qdisc     | Classful | Description
   1502 | ATM       | Yes      | FIXME
   1503 | Blackhole | No       | This qdisc will drop all packets passed to it.
   1504 | CBQ       | Yes      |
   1505 The CBQ (Class Based Queueing) is a classful qdisc which allows
   1506 creating traffic classes and enforce bandwidth limitations for each
   1507 class.
   1508 | DRR       | Yes      |
   1509 The DRR (Deficit Round Robin) scheduler is a classful qdisc
   1510 impelemting fair queueing. Each class is assigned a quantum specyfing
   1511 the maximum number of bytes that can be served per round.  Unused
   1512 quantum at the end of the round is carried over to the next round.
   1513 | DSMARK   | Yes       | FIXME
   1514 | FIFO     | No        | FIXME
   1515 | GRED     | No        | FIXME
   1516 | HFSC     | Yes       | FIXME
   1517 | HTB      | Yes       | FIXME
   1518 | mq       | Yes       | FIXME
   1519 | multiq   | Yes       | FIXME
   1520 | netem    | No        | FIXME
   1521 | Prio     | Yes       | FIXME
   1522 | RED      | Yes       | FIXME
   1523 | SFQ      | Yes       | FIXME
   1524 | TBF      | Yes       | FIXME
   1525 | teql     | No        | FIXME
   1526 |======================================================================
   1527 
   1528 
   1529 .QDisc API Overview
   1530 [cols="a,a", options="header", frame="topbot"]
   1531 |====================================================================
   1532 | Attribute | C Interface
   1533 |
   1534 Allocation / Freeing::
   1535 |
   1536 [source,c]
   1537 -----
   1538 struct rtnl_qdisc *rtnl_qdisc_alloc(void);
   1539 void rtnl_qdisc_put(struct rtnl_qdisc *qdisc);
   1540 -----
   1541 |
   1542 Addition::
   1543 |
   1544 [source,c]
   1545 -----
   1546 int rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc, int flags,
   1547 				 struct nl_msg **result);
   1548 int rtnl_qdisc_add(struct nl_sock *sock, struct rtnl_qdisc *qdisc,
   1549                    int flags);
   1550 -----
   1551 |
   1552 Modification::
   1553 |
   1554 [source,c]
   1555 -----
   1556 int rtnl_qdisc_build_change_request(struct rtnl_qdisc *old,
   1557 				    struct rtnl_qdisc *new,
   1558 				    struct nl_msg **result);
   1559 int rtnl_qdisc_change(struct nl_sock *sock, struct rtnl_qdisc *old,
   1560 		      struct rtnl_qdisc *new);
   1561 -----
   1562 |
   1563 Deletion::
   1564 |
   1565 [source,c]
   1566 -----
   1567 int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc,
   1568 				    struct nl_msg **result);
   1569 int rtnl_qdisc_delete(struct nl_sock *sock, struct rtnl_qdisc *qdisc);
   1570 -----
   1571 |
   1572 Cache::
   1573 |
   1574 [source,c]
   1575 -----
   1576 int rtnl_qdisc_alloc_cache(struct nl_sock *sock,
   1577 			   struct nl_cache **cache);
   1578 struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int, uint32_t);
   1579 
   1580 struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *, int, uint32_t);
   1581 -----
   1582 |====================================================================
   1583 
   1584 [[qdisc_get]]
   1585 ==== Retrieving Qdisc Configuration
   1586 
   1587 The function rtnl_qdisc_alloc_cache() is used to retrieve the current
   1588 qdisc configuration in the kernel. It will construct a +RTM_GETQDISC+
   1589 netlink message, requesting the complete list of qdiscs configured in
   1590 the kernel.
   1591 
   1592 [source,c]
   1593 -------
   1594 #include <netlink/route/qdisc.h>
   1595 
   1596 struct nl_cache *all_qdiscs;
   1597 
   1598 if (rtnl_link_alloc_cache(sock, &all_qdiscs) < 0)
   1599 	/* error while retrieving qdisc cfg */
   1600 -------
   1601 
   1602 The cache can be accessed using the following functions:
   1603 
   1604 - Search qdisc with matching ifindex and handle:
   1605 +
   1606 [source,c]
   1607 --------
   1608 struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int ifindex, uint32_t handle);
   1609 --------
   1610 - Search qdisc with matching ifindex and parent:
   1611 +
   1612 [source,c]
   1613 --------
   1614 struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *cache, int ifindex , uint32_t parent);
   1615 --------
   1616 - Or any of the generic cache functions (e.g. nl_cache_search(), nl_cache_dump(), etc.)
   1617 
   1618 .Example: Search and print qdisc
   1619 [source,c]
   1620 -------
   1621 struct rtnl_qdisc *qdisc;
   1622 int ifindex;
   1623 
   1624 ifindex = rtnl_link_get_ifindex(eth0_obj);
   1625 
   1626 /* search for qdisc on eth0 with handle 1:0 */
   1627 if (!(qdisc = rtnl_qdisc_get(all_qdiscs, ifindex, TC_HANDLE(1, 0))))
   1628 	/* no such qdisc found */
   1629 
   1630 nl_object_dump(OBJ_CAST(qdisc), NULL);
   1631 
   1632 rtnl_qdisc_put(qdisc);
   1633 -------
   1634 
   1635 [[qdisc_add]]
   1636 ==== Adding a Qdisc
   1637 
   1638 In order to add a new qdisc to the kernel, a qdisc object needs to be
   1639 allocated. It will hold all attributes of the new qdisc.
   1640 
   1641 [source,c]
   1642 -----
   1643 #include <netlink/route/qdisc.h>
   1644 
   1645 struct rtnl_qdisc *qdisc;
   1646 
   1647 if (!(qdisc = rtnl_qdisc_alloc()))
   1648 	/* OOM error */
   1649 -----
   1650 
   1651 The next step is to specify all generic qdisc attributes using the tc
   1652 object interface described in the section <<tc_attr>>.
   1653 
   1654 The following attributes must be specified:
   1655 - IfIndex
   1656 - Parent
   1657 - Kind
   1658 
   1659 [source,c]
   1660 -----
   1661 /* Attach qdisc to device eth0 */
   1662 rtnl_tc_set_link(TC_CAST(qdisc), eth0_obj);
   1663 
   1664 /* Make this the root qdisc */
   1665 rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
   1666 
   1667 /* Set qdisc identifier to 1:0, if left unspecified, a handle will be generated by the kernel. */
   1668 rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(1, 0));
   1669 
   1670 /* Make this a HTB qdisc */
   1671 rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
   1672 -----
   1673 
   1674 After specyfing the qdisc kind (rtnl_tc_set_kind()) the qdisc type
   1675 specific interface can be used to set attributes which are specific
   1676 to the respective qdisc implementations:
   1677 
   1678 [source,c]
   1679 ------
   1680 /* HTB feature: Make unclassified packets go to traffic class 1:5 */
   1681 rtnl_htb_set_defcls(qdisc, TC_HANDLE(1, 5));
   1682 ------
   1683 
   1684 Finally, the qdisc is ready to be added and can be passed on to the
   1685 function rntl_qdisc_add() which takes care of constructing a netlink
   1686 message requesting the addition of the new qdisc, sends the message to
   1687 the kernel and waits for the response by the kernel. The function
   1688 returns 0 if the qdisc has been added or updated successfully or a
   1689 negative error code if an error occured.
   1690 
   1691 CAUTION: The kernel operation for updating and adding a qdisc is the
   1692          same. Therefore when calling rtnl_qdisc_add() any existing
   1693          qdisc with matching handle will be updated unless the flag
   1694          NLM_F_EXCL is specified.
   1695 
   1696 The following flags may be specified:
   1697 [horizontal]
   1698 NLM_F_CREATE::  Create qdisc if it does not exist, otherwise
   1699                 -NLE_OBJ_NOTFOUND is returned.
   1700 NLM_F_REPLACE:: If another qdisc is already attached to the same
   1701                 parent and their handles mismatch, replace the qdisc
   1702                 instead of returning -EEXIST.
   1703 NLM_F_EXCL::    Return -NLE_EXISTS if a qdisc with matching handles
   1704                 exists already.
   1705 
   1706 WARNING: The function rtnl_qdisc_add() requires administrator
   1707          privileges.
   1708 
   1709 [source,c]
   1710 ------
   1711 /* Submit request to kernel and wait for response */
   1712 err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE);
   1713 
   1714 /* Return the qdisc object to free memory resources */
   1715 rtnl_qdisc_put(qdisc);
   1716 
   1717 if (err < 0) {
   1718 	fprintf(stderr, "Unable to add qdisc: %s\n", nl_geterror(err));
   1719 	return err;
   1720 }
   1721 ------
   1722 
   1723 ==== Deleting a qdisc
   1724 
   1725 [source,c]
   1726 ------
   1727 #include <netlink/route/qdisc.h>
   1728 
   1729 struct rtnl_qdisc *qdisc;
   1730 
   1731 qdisc = rtnl_qdisc_alloc();
   1732 
   1733 rtnl_tc_set_link(TC_CAST(qdisc), eth0_obj);
   1734 rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
   1735 
   1736 rtnl_qdisc_delete(sock, qdisc)
   1737 
   1738 rtnl_qdisc_put(qdisc);
   1739 ------
   1740 
   1741 WARNING: The function rtnl_qdisc_delete() requires administrator
   1742          privileges.
   1743 
   1744 
   1745 [[qdisc_htb]]
   1746 ==== HTB - Hierarchical Token Bucket
   1747 
   1748 .HTB Qdisc Attributes
   1749 
   1750 Default Class::
   1751 The default class is the fallback class to which all traffic which
   1752 remained unclassified is directed to. If no default class or an
   1753 invalid default class is specified, packets are transmitted directly
   1754 to the next layer (direct transmissions).
   1755 +
   1756 [source,c]
   1757 -----
   1758 uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc);
   1759 int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls);
   1760 -----
   1761 
   1762 Rate to Quantum (r2q)::
   1763 TODO
   1764 +
   1765 [source,c]
   1766 -----
   1767 uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc);
   1768 int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *qdisc, uint32_t rate2quantum);
   1769 -----
   1770 
   1771 
   1772 .HTB Class Attributes
   1773 
   1774 Priority::
   1775 +
   1776 [source,c]
   1777 -----
   1778 uint32_t rtnl_htb_get_prio(struct rtnl_class *class);
   1779 int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio);
   1780 -----
   1781 
   1782 Rate::
   1783 The rate (bytes/s) specifies the maximum bandwidth an invidivual class
   1784 can use without borrowing. The rate of a class should always be greater
   1785 or erqual than the rate of its children.
   1786 +
   1787 [source,c]
   1788 -----
   1789 uint32_t rtnl_htb_get_rate(struct rtnl_class *class);
   1790 int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t ceil);
   1791 -----
   1792 
   1793 Ceil Rate::
   1794 The ceil rate specifies the maximum bandwidth an invidivual class
   1795 can use. This includes bandwidth that is being borrowed from other
   1796 classes. Ceil defaults to the class rate implying that by default
   1797 the class will not borrow. The ceil rate of a class should always
   1798 be greater or erqual than the ceil rate of its children.
   1799 +
   1800 [source,c]
   1801 -----
   1802 uint32_t rtnl_htb_get_ceil(struct rtnl_class *class);
   1803 int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil);
   1804 -----
   1805 
   1806 Burst::
   1807 TODO
   1808 +
   1809 [source,c]
   1810 -----
   1811 uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class);
   1812 int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t burst);
   1813 -----
   1814 
   1815 Ceil Burst::
   1816 TODO
   1817 +
   1818 [source,c]
   1819 -----
   1820 uint32_t rtnl_htb_get_bbuffer(struct rtnl_class *class);
   1821 int rtnl_htb_set_bbuffer(struct rtnl_class *class, uint32_t burst);
   1822 -----
   1823 
   1824 Quantum::
   1825 TODO
   1826 +
   1827 [source,c]
   1828 -----
   1829 int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum);
   1830 -----
   1831 
   1832 extern int	rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t);
   1833 
   1834 
   1835 
   1836 
   1837 [[tc_class]]
   1838 === Class
   1839 
   1840 [options="header", cols="s,a,a,a,a"]
   1841 |=======================================================================
   1842 |        | UNSPEC             | TC_H_ROOT          | 0:pY  | pX:pY
   1843 | UNSPEC 3+^|
   1844 [horizontal]
   1845 qdisc =:: root-qdisc
   1846 class =:: root-qdisc:0
   1847 |
   1848 [horizontal]
   1849 qdisc =:: pX:0
   1850 class =:: pX:0
   1851 | 0:hY 3+^|
   1852 [horizontal]
   1853 qdisc =:: root-qdisc
   1854 class =:: root-qdisc:hY
   1855 |
   1856 [horizontal]
   1857 qdisc =:: pX:0
   1858 class =:: pX:hY
   1859 | hX:hY 3+^|
   1860 [horizontal]
   1861 qdisc =:: hX:
   1862 class =:: hX:hY
   1863 |
   1864 if pX != hX
   1865     return -EINVAL
   1866 [horizontal]
   1867 qdisc =:: hX:
   1868 class =:: hX:hY
   1869 |=======================================================================
   1870 
   1871 [[tc_cls]]
   1872 === Classifier (cls)
   1873 
   1874 TODO
   1875 
   1876 [[tc_classid_mngt]]
   1877 === ClassID Management
   1878 
   1879 TODO
   1880 
   1881 [[tc_pktloc]]
   1882 === Packet Location Aliasing (pktloc)
   1883 
   1884 TODO
   1885 
   1886 [[tc_api]]
   1887 === Traffic Control Module API
   1888 
   1889 TODO
   1890