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