diff options
author | Thomas Graf <tgraf@suug.ch> | 2011-07-28 14:23:57 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2011-07-28 14:23:57 (GMT) |
commit | 70c93717607a15d37b60d7caefb58e78d28c5e59 (patch) | |
tree | 52b991c5cb5fab3f4190015f0a3fd8d8cdf68653 | |
parent | 915a23fd16315eed2b13dda38c96ca824935e844 (diff) | |
download | libnl-70c93717607a15d37b60d7caefb58e78d28c5e59.zip libnl-70c93717607a15d37b60d7caefb58e78d28c5e59.tar.gz libnl-70c93717607a15d37b60d7caefb58e78d28c5e59.tar.bz2 |
Updated link documentation
- API documentation
- developer guide
- enabled doxygen navbar
- fixed css
-rw-r--r-- | doc/Doxyfile.in | 16 | ||||
-rw-r--r-- | doc/DoxygenLayout.xml | 10 | ||||
-rw-r--r-- | doc/libnl.css | 41 | ||||
-rw-r--r-- | doc/route.txt | 287 | ||||
-rw-r--r-- | doc/src/hidden.c | 35 | ||||
-rw-r--r-- | doc/stylesheets/asciidoc.css | 3 | ||||
-rw-r--r-- | include/netlink/route/link.h | 142 | ||||
-rw-r--r-- | lib/fib_lookup/lookup.c | 2 | ||||
-rw-r--r-- | lib/route/link.c | 1259 | ||||
-rw-r--r-- | lib/route/link/bonding.c | 4 | ||||
-rw-r--r-- | lib/route/link/dummy.c | 4 | ||||
-rw-r--r-- | lib/route/link/vlan.c | 5 |
12 files changed, 1075 insertions, 733 deletions
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 5deba44..33d5a8c 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -181,6 +181,12 @@ TAB_SIZE = 8 ALIASES = arg=\param +ALIASES += ref_asciidoc{3}="<a href=\"../\1.html#\2\">\3</a>" +ALIASES += ref_core{2}="\ref_asciidoc{core,\1,\2 (Netlink Library)}" +ALIASES += ref_route{2}="\ref_asciidoc{route,\1,\2 (Routing Family Library)}" +ALIASES += core_doc{2}="\par Related Documentation:\n\ref_core{\1,\2}" +ALIASES += route_doc{2}="\par Related Documentation:\n\ref_route{\1,\2}" + # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -487,13 +493,13 @@ SHOW_USED_FILES = NO # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. -SHOW_DIRECTORIES = YES +SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. -SHOW_FILES = YES +SHOW_FILES = NO # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. @@ -1012,7 +1018,7 @@ GENERATE_ECLIPSEHELP = NO # the directory name containing the HTML and XML files should also have # this name. -ECLIPSE_DOC_ID = org.doxygen.Project +ECLIPSE_DOC_ID = org.infradead.libnl # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and @@ -1033,7 +1039,7 @@ ENUM_VALUES_PER_LINE = 1 # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. @@ -1044,7 +1050,7 @@ USE_INLINE_TREES = YES # used to set the initial width (in pixels) of the frame in which the tree # is shown. -TREEVIEW_WIDTH = 250 +TREEVIEW_WIDTH = 205 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. diff --git a/doc/DoxygenLayout.xml b/doc/DoxygenLayout.xml index 29049d1..8d3e3ff 100644 --- a/doc/DoxygenLayout.xml +++ b/doc/DoxygenLayout.xml @@ -14,11 +14,11 @@ <tab type="hierarchy" visible="yes" title="" intro=""/> <tab type="classmembers" visible="yes" title="" intro=""/> </tab> - <tab type="files" visible="yes" title=""> + <tab type="files" visible="no" title=""> <tab type="files" visible="yes" title="" intro=""/> <tab type="globals" visible="yes" title="" intro=""/> </tab> - <tab type="dirs" visible="yes" title="" intro=""/> + <tab type="dirs" visible="no" title="" intro=""/> <tab type="examples" visible="yes" title="" intro=""/> </navindex> @@ -64,13 +64,13 @@ <detaileddescription title=""/> <memberdef> <typedefs title=""/> - <enums title=""/> <constructors title=""/> <functions title=""/> <related title=""/> <variables title=""/> <properties title=""/> <events title=""/> + <enums title=""/> </memberdef> <usedfiles visible="$SHOW_USED_FILES"/> <authorsection visible="yes"/> @@ -132,14 +132,13 @@ <groupgraph visible="$GROUP_GRAPHS"/> <detaileddescription title=""/> <memberdecl> - <classes visible="yes" title=""/> <namespaces visible="yes" title=""/> <dirs visible="yes" title=""/> <nestedgroups visible="yes" title=""/> + <classes visible="yes" title=""/> <files visible="yes" title=""/> <defines title=""/> <typedefs title=""/> - <enums title=""/> <enumvalues title=""/> <functions title=""/> <variables title=""/> @@ -151,6 +150,7 @@ <properties title=""/> <friends title=""/> <membergroups visible="yes"/> + <enums title=""/> </memberdecl> <memberdef> <pagedocs/> diff --git a/doc/libnl.css b/doc/libnl.css index 65fabaa..6b04f0d 100644 --- a/doc/libnl.css +++ b/doc/libnl.css @@ -376,7 +376,7 @@ table.memberdecls { } .memItemLeft, .memItemRight, .memTemplParams { - border-top: 1px solid #C4CFE5; + border-top: 1px solid #a7a7a7; } .memItemLeft, .memTemplItemLeft { @@ -428,18 +428,17 @@ table.memberdecls { .memname { white-space: nowrap; - font-weight: bold; + font-family: monospace, fixed; + font-weight: bold; + font-size: 110%; margin-left: 6px; } .memproto { - border-top: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - border-bottom: 1px solid #A8B8D9; + border: 1px solid #990000; padding: 6px 0px 6px 0px; - color: #253555; - font-weight: bold; + /* color: #253555; */ + color: #990000; /* text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); */ /* opera specific markup */ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); @@ -453,17 +452,16 @@ table.memberdecls { -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -webkit-border-top-right-radius: 8px; -webkit-border-top-left-radius: 8px; - background-image:url('nav_f.png'); - background-repeat:repeat-x; - background-color: #E2E8F2; - + /* background-image:url('nav_f.png'); + background-repeat:repeat-x; */ + background-color: #f1f1f1; } .memdoc { - border-bottom: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; - padding: 2px 5px; + border-bottom: 1px solid #990000; + border-left: 1px solid #990000; + border-right: 1px solid #990000; + padding: 10px 15px; background-color: #FBFCFD; border-top-width: 0; /* opera specific markup */ @@ -487,13 +485,15 @@ table.memberdecls { } .paramtype { + color: #c87424; white-space: nowrap; + font-family: monospace, fixed; } .paramname { - /* color: #602020; */ - color: black; + color: #990000; white-space: nowrap; + font-family: monospace, fixed; } .paramname em { font-style: normal; @@ -751,6 +751,11 @@ dl padding: 0 0 0 10px; } +.memdoc > dl +{ + padding: 0px; +} + dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug { border-left:4px solid; diff --git a/doc/route.txt b/doc/route.txt index d48c26e..757b4bd 100644 --- a/doc/route.txt +++ b/doc/route.txt @@ -15,6 +15,7 @@ This library provides APIs to the kernel interfaces of the routing family. == Addresses +[[route_link]] == Links (Network Devices) The link configuration interface is part of the +NETLINK_ROUTE+ protocol @@ -171,34 +172,6 @@ Notification sent by the kernel to the multicast group +RTNLGRP_LINK+ when a. a network device was unregistered (change == ~0) b. a bridging device was deleted (address family will be +PF_BRIDGE+) -[source,c] ------ -#define IFF_UP 0x1 /* interface is up */ -#define IFF_BROADCAST 0x2 /* broadcast address valid */ -#define IFF_DEBUG 0x4 /* turn on debugging */ -#define IFF_LOOPBACK 0x8 /* is a loopback net */ -#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */ -#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */ -#define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */ -#define IFF_NOARP 0x80 /* no ARP protocol */ -#define IFF_PROMISC 0x100 /* receive all packets */ -#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/ - -#define IFF_MASTER 0x400 /* master of a load balancer */ -#define IFF_SLAVE 0x800 /* slave of a load balancer */ - -#define IFF_MULTICAST 0x1000 /* Supports multicast */ - -#define IFF_PORTSEL 0x2000 /* can set media type */ -#define IFF_AUTOMEDIA 0x4000 /* auto media select active */ -#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ - -#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ -#define IFF_DORMANT 0x20000 /* driver signals dormant */ - -#define IFF_ECHO 0x40000 /* echo sent packets */ ------ - === Get / List [[link_list]] @@ -252,6 +225,7 @@ rtnl_link_put(link); nl_cache_put(cache); ----- +[[link_direct_lookup]] ==== Lookup Single Link (Direct Lookup) If only a single link is of interest, the link can be looked up directly @@ -287,6 +261,7 @@ NOTE: While using this function can save a substantial amount of bandwidth to rtnl_link_get_kernel() will always trigger sending a +RTM_GETLINK+ request. +[[link_translate_ifindex]] ==== Translating interface index to link name Applications which require to translate interface index to a link name or @@ -347,68 +322,267 @@ rtnl_link_put(link); [[link_object]] === Link Object -Name:: -The name of a network device is the human readable representation of a -network device and secondary identification parameter besides the interface -index. -+ +A link is represented by the structure +struct rtnl_link+. Instances may be +created with the function +rtnl_link_alloc()+ or via a link cache (see +<<link_list>>) and are freed again using the function +rtnl_link_put()+. + +[source,c] +----- +#include <netlink/route/link.h> + +struct rtnl_link *rtnl_link_alloc(void); +void rtnl_link_put(struct rtnl_link *link); +----- + +[[link_attr_name]] +==== Name +The name serves as unique, human readable description of the link. By +default, links are named based on their type and then enumerated, e.g. +eth0, eth1, ethn but they may be renamed at any time. + Kernels >= 2.6.11 support identification by link name. -+ + [source,c] ----- -void rtnl_link_set_name(struct rtnl_link *link, const char *name); +#include <netlink/route/link.h> + +void rtnl_link_set_name(struct rtnl_link *link, const char *name); char *rtnl_link_get_name(struct rtnl_link *link); ----- -Interface Index:: -The interface index is an integer uniquely identifying a network device. -If present, it will be used to identify an existing network device. -+ +*Accepted link name format:* +[^ /]*+ (maximum length: 15 characters) + +[[link_attr_ifindex]] +==== Interface Index (Identifier) +The interface index is an integer uniquely identifying a link. If present +in any link message, it will be used to identify an existing link. + [source,c] ----- +#include <netlink/route/link.h> + void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex); -int rtnl_link_get_ifindex(struct rtnl_link *link); +int rtnl_link_get_ifindex(struct rtnl_link *link); ----- +[[link_attr_address]] +==== Link Layer Address +The link layer address (e.g. MAC address). -Address:: -The link layer address (MAC address). -+ [source,c] ----- -void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr); +#include <netlink/route/link.h> + +void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr); struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link); ----- -Broadcast Address:: -Foo -+ +[[link_attr_broadcast]] +==== Broadcast Address +The link layer broadcast address + [source,c] ----- -void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr); +#include <netlink/route/link.h> + +void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr); struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link); ----- -MTU:: +[[link_attr_mtu]] +==== MTU (Maximum Transmission Unit) The maximum transmission unit specifies the maximum packet size a network device can transmit or receive. This value may be lower than the capability of the physical network device. -+ + [source,c] ----- -void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu); +#include <netlink/route/link.h> + +void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu); unsigned int rtnl_link_get_mtu(struct rtnl_link *link); ----- -Weight:: -Foo -+ +[[link_attr_flags]] +==== Flags +The flags of a link enable or disable various link features or inform about +the state of the link. + +[source,c] +----- +#include <netlink/route/link.h> + +void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags); +void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags); +unsigned int rtnl_link_get_flags(struct rtnl_link *link); +----- + +[options="compact"] +[horizontal] +IFF_UP:: Link is up (administratively) +IFF_RUNNING:: Link is up and carrier is OK (RFC2863 OPER_UP) +IFF_LOWER_UP:: Link layer is operational +IFF_DORMANT:: Driver signals dormant +IFF_BROADCAST:: Link supports broadcasting +IFF_MULTICAST:: Link supports multicasting +IFF_ALLMULTI:: Link supports multicast routing +IFF_DEBUG:: Tell driver to do debugging (currently unused) +IFF_LOOPBACK:: Link loopback network +IFF_POINTOPOINT:: Point-to-point link +IFF_NOARP:: ARP is not supported +IFF_PROMISC:: Status of promiscious mode +IFF_MASTER:: Master of a load balancer (bonding) +IFF_SLAVE:: Slave to a master link +IFF_PORTSEL:: Driver supports setting media type (only used by ARM ethernet) +IFF_AUTOMEDIA:: Link selects port automatically (only used by ARM ethernet) +IFF_ECHO:: Echo sent packets (testing feature, CAN only) +IFF_DYNAMIC:: Unused (BSD compatibility) +IFF_NOTRAILERS:: Unused (BSD compatibility) + +To translate a link flag to a link flag name or vice versa: + [source,c] ----- -void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight); -unsigned int rtnl_link_get_weight(struct rtnl_link *link); +#include <netlink/route/link.h> + +char *rtnl_link_flags2str(int flags, char *buf, size_t size); +int rtnl_link_str2flags(const char *flag_name); +----- + +[[link_attr_txqlen]] +==== Transmission Queue Length + +The transmission queue holds packets before packets are delivered to +the driver for transmission. It is usually specified in number of +packets but the unit may be specific to the link type. + +[source,c] +----- +#include <netlink/route/link.h> + +void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen); +unsigned int rtnl_link_get_txqlen(struct rtnl_link *link); +----- + +[[link_attr_operstate]] +==== Operational Status +The operational status has been introduced to provide extended information +on the link status. Traditionally the link state has been described using +the link flags +IFF_UP, IFF_RUNNING, IFF_LOWER_UP+, and +IFF_DORMANT+ which +was no longer sufficient for some link types. + +[source,c] +----- +#include <netlink/route/link.h> + +void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t state); +uint8_t rtnl_link_get_operstate(struct rtnl_link *link); +----- + +[options="compact"] +[horizontal] +IF_OPER_UNKNOWN:: Unknown state +IF_OPER_NOTPRESENT:: Link not present +IF_OPER_DOWN:: Link down +IF_OPER_LOWERLAYERDOWN:: L1 down +IF_OPER_TESTING:: Testing +IF_OPER_DORMANT:: Dormant +IF_OPER_UP:: Link up + +Translation of operational status code to string and vice versa: + +[source,c] +----- +#include <netlink/route/link.h> + +char *rtnl_link_operstate2str(uint8_t state, char *buf, size_t size); +int rtnl_link_str2operstate(const char *name); +----- + +[[link_attr_mode]] +==== Mode +Currently known link modes are: + +[options="compact"] +[horizontal] +IF_LINK_MODE_DEFAULT:: Default link mode +IF_LINK_MODE_DORMANT:: Limit upward transition to dormant + +[source,c] +----- +#include <netlink/route/link.h> + +void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode); +uint8_t rtnl_link_get_linkmode(struct rtnl_link *link); +----- + +Translation of link mode to string and vice versa: + +[source,c] +----- +char *rtnl_link_mode2str(uint8_t mode, char *buf, size_t len); +uint8_t rtnl_link_str2mode(const char *name); +----- + +[[link_attr_alias]] +==== IfAlias +Alternative name for the link, primarly used for SNMP IfAlias. + +[source,c] +----- +#include <netlink/route/link.h> + +const char *rtnl_link_get_ifalias(struct rtnl_link *link); +void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias); +----- + +*Length limit:* 256 + +[[link_attr_arptype]] +==== Hardware Type + +[source,c] +----- +#include <netlink/route/link.h> +#include <linux/if_arp.h> + +void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype); +unsigned int rtnl_link_get_arptype(struct rtnl_link *link); +---- + +Translation of hardware type to character string and vice versa: + +[source,c] +----- +#include <netlink/utils.h> + +char *nl_llproto2str(int arptype, char *buf, size_t len); +int nl_str2llproto(const char *name); +----- + +[[link_attr_qdisc]] +==== Qdisc +The name of the queueing discipline used by the link is of informational +nature only. It is a read-only attribute provided by the kernel and cannot +be modified. The set function is provided solely for the purpose of creating +link objects to be used for comparison. + +For more information on how to modify the qdisc of a link, see section +<<route_tc>>. + +[[link_attr_weight]] +==== Weight +This attribute is unused and obsoleted in all recent kernels. + +[source,c] +----- +#include <netlink/route/link.h> + +extern void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name); +extern char *rtnl_link_get_qdisc(struct rtnl_link *link); ----- +[[link_modules]] === Modules [[link_bonding]] @@ -490,6 +664,7 @@ rtnl_link_put(link); == Routing +[[route_tc]] == Traffic Control The traffic control architecture allows the queueing and diff --git a/doc/src/hidden.c b/doc/src/hidden.c new file mode 100644 index 0000000..be4a042 --- /dev/null +++ b/doc/src/hidden.c @@ -0,0 +1,35 @@ +/** + * \cond skip + * vim:syntax=doxygen + * \endcond + +\page auto_ack_warning Disabling Auto-ACK + +\attention Disabling Auto-ACK (nl_socket_disable_auto_ack()) will cause this + function to return immediately after sending the netlink message. + The function will not wait for an eventual error message. It is + the responsibility of the caller to handle any error messages or + ACKs returned. + +\page pointer_lifetime_warning Pointer Lifetime + +\attention The reference counter of the returned object is not incremented. + Therefore, the returned pointer is only valid during the lifetime + of the parent object. Increment the reference counter if the object + is supposed to stay around after the parent object was freed. + +\page private_struct Private Structure + +\note The definition of this structure is private to allow modification + without breaking API. Use the designated accessor functions to + access individual object attributes. + +\page read_only_attribute Read-Only Attribute + +\note The attribute this accessor is modifying is a read-only attribute + which can not be modified in the kernel. Any changes to the + attribute only have an effect on the local copy of the object. The + accessor function is provided solely for the purpose of creating + objects for comparison and filtering. + +*/ diff --git a/doc/stylesheets/asciidoc.css b/doc/stylesheets/asciidoc.css index 8ded7c9..2852168 100644 --- a/doc/stylesheets/asciidoc.css +++ b/doc/stylesheets/asciidoc.css @@ -285,7 +285,8 @@ td.hdlist1 { vertical-align: top; font-style: normal; padding-right: 0.8em; - color: navy; + /* color: navy; */ + color: #990000; } td.hdlist2 { vertical-align: top; diff --git a/include/netlink/route/link.h b/include/netlink/route/link.h index 2e5274a..79c2d56 100644 --- a/include/netlink/route/link.h +++ b/include/netlink/route/link.h @@ -21,77 +21,86 @@ extern "C" { #endif +/** + * @struct rtnl_link link.h "netlink/route/link.h" + * @brief Link object + * @implements nl_object + * @ingroup link + * + * @copydoc private_struct + */ struct rtnl_link; -enum rtnl_link_st { - RTNL_LINK_RX_PACKETS, - RTNL_LINK_TX_PACKETS, - RTNL_LINK_RX_BYTES, - RTNL_LINK_TX_BYTES, - RTNL_LINK_RX_ERRORS, - RTNL_LINK_TX_ERRORS, - RTNL_LINK_RX_DROPPED, - RTNL_LINK_TX_DROPPED, - RTNL_LINK_RX_COMPRESSED, - RTNL_LINK_TX_COMPRESSED, - RTNL_LINK_RX_FIFO_ERR, - RTNL_LINK_TX_FIFO_ERR, - RTNL_LINK_RX_LEN_ERR, - RTNL_LINK_RX_OVER_ERR, - RTNL_LINK_RX_CRC_ERR, - RTNL_LINK_RX_FRAME_ERR, - RTNL_LINK_RX_MISSED_ERR, - RTNL_LINK_TX_ABORT_ERR, - RTNL_LINK_TX_CARRIER_ERR, - RTNL_LINK_TX_HBEAT_ERR, - RTNL_LINK_TX_WIN_ERR, - RTNL_LINK_COLLISIONS, - RTNL_LINK_MULTICAST, - RTNL_LINK_IP6_INPKTS, /* InReceives */ - RTNL_LINK_IP6_INHDRERRORS, /* InHdrErrors */ - RTNL_LINK_IP6_INTOOBIGERRORS, /* InTooBigErrors */ - RTNL_LINK_IP6_INNOROUTES, /* InNoRoutes */ - RTNL_LINK_IP6_INADDRERRORS, /* InAddrErrors */ - RTNL_LINK_IP6_INUNKNOWNPROTOS, /* InUnknownProtos */ - RTNL_LINK_IP6_INTRUNCATEDPKTS, /* InTruncatedPkts */ - RTNL_LINK_IP6_INDISCARDS, /* InDiscards */ - RTNL_LINK_IP6_INDELIVERS, /* InDelivers */ - RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* OutForwDatagrams */ - RTNL_LINK_IP6_OUTPKTS, /* OutRequests */ - RTNL_LINK_IP6_OUTDISCARDS, /* OutDiscards */ - RTNL_LINK_IP6_OUTNOROUTES, /* OutNoRoutes */ - RTNL_LINK_IP6_REASMTIMEOUT, /* ReasmTimeout */ - RTNL_LINK_IP6_REASMREQDS, /* ReasmReqds */ - RTNL_LINK_IP6_REASMOKS, /* ReasmOKs */ - RTNL_LINK_IP6_REASMFAILS, /* ReasmFails */ - RTNL_LINK_IP6_FRAGOKS, /* FragOKs */ - RTNL_LINK_IP6_FRAGFAILS, /* FragFails */ - RTNL_LINK_IP6_FRAGCREATES, /* FragCreates */ - RTNL_LINK_IP6_INMCASTPKTS, /* InMcastPkts */ - RTNL_LINK_IP6_OUTMCASTPKTS, /* OutMcastPkts */ - RTNL_LINK_IP6_INBCASTPKTS, /* InBcastPkts */ - RTNL_LINK_IP6_OUTBCASTPKTS, /* OutBcastPkts */ - RTNL_LINK_IP6_INOCTETS, /* InOctets */ - RTNL_LINK_IP6_OUTOCTETS, /* OutOctets */ - RTNL_LINK_IP6_INMCASTOCTETS, /* InMcastOctets */ - RTNL_LINK_IP6_OUTMCASTOCTETS, /* OutMcastOctets */ - RTNL_LINK_IP6_INBCASTOCTETS, /* InBcastOctets */ - RTNL_LINK_IP6_OUTBCASTOCTETS, /* OutBcastOctets */ - RTNL_LINK_ICMP6_INMSGS, /* InMsgs */ - RTNL_LINK_ICMP6_INERRORS, /* InErrors */ - RTNL_LINK_ICMP6_OUTMSGS, /* OutMsgs */ - RTNL_LINK_ICMP6_OUTERRORS, /* OutErrors */ +/** + * @ingroup link + */ +typedef enum { + RTNL_LINK_RX_PACKETS, /*!< Packets received */ + RTNL_LINK_TX_PACKETS, /*!< Packets sent */ + RTNL_LINK_RX_BYTES, /*!< Bytes received */ + RTNL_LINK_TX_BYTES, /*!< Bytes sent */ + RTNL_LINK_RX_ERRORS, /*!< Receive errors */ + RTNL_LINK_TX_ERRORS, /*!< Send errors */ + RTNL_LINK_RX_DROPPED, /*!< Received packets dropped */ + RTNL_LINK_TX_DROPPED, /*!< Packets dropped during transmit */ + RTNL_LINK_RX_COMPRESSED, /*!< Compressed packets received */ + RTNL_LINK_TX_COMPRESSED, /*!< Compressed packets sent */ + RTNL_LINK_RX_FIFO_ERR, /*!< Receive FIFO errors */ + RTNL_LINK_TX_FIFO_ERR, /*!< Send FIFO errors */ + RTNL_LINK_RX_LEN_ERR, /*!< Length errors */ + RTNL_LINK_RX_OVER_ERR, /*!< Over errors */ + RTNL_LINK_RX_CRC_ERR, /*!< CRC errors */ + RTNL_LINK_RX_FRAME_ERR, /*!< Frame errors */ + RTNL_LINK_RX_MISSED_ERR, /*!< Missed errors */ + RTNL_LINK_TX_ABORT_ERR, /*!< Aborted errors */ + RTNL_LINK_TX_CARRIER_ERR, /*!< Carrier errors */ + RTNL_LINK_TX_HBEAT_ERR, /*!< Heartbeat errors */ + RTNL_LINK_TX_WIN_ERR, /*!< Window errors */ + RTNL_LINK_COLLISIONS, /*!< Send collisions */ + RTNL_LINK_MULTICAST, /*!< Multicast */ + RTNL_LINK_IP6_INPKTS, /*!< IPv6 SNMP InReceives */ + RTNL_LINK_IP6_INHDRERRORS, /*!< IPv6 SNMP InHdrErrors */ + RTNL_LINK_IP6_INTOOBIGERRORS, /*!< IPv6 SNMP InTooBigErrors */ + RTNL_LINK_IP6_INNOROUTES, /*!< IPv6 SNMP InNoRoutes */ + RTNL_LINK_IP6_INADDRERRORS, /*!< IPv6 SNMP InAddrErrors */ + RTNL_LINK_IP6_INUNKNOWNPROTOS, /*!< IPv6 SNMP InUnknownProtos */ + RTNL_LINK_IP6_INTRUNCATEDPKTS, /*!< IPv6 SNMP InTruncatedPkts */ + RTNL_LINK_IP6_INDISCARDS, /*!< IPv6 SNMP InDiscards */ + RTNL_LINK_IP6_INDELIVERS, /*!< IPv6 SNMP InDelivers */ + RTNL_LINK_IP6_OUTFORWDATAGRAMS, /*!< IPv6 SNMP OutForwDatagrams */ + RTNL_LINK_IP6_OUTPKTS, /*!< IPv6 SNMP OutRequests */ + RTNL_LINK_IP6_OUTDISCARDS, /*!< IPv6 SNMP OutDiscards */ + RTNL_LINK_IP6_OUTNOROUTES, /*!< IPv6 SNMP OutNoRoutes */ + RTNL_LINK_IP6_REASMTIMEOUT, /*!< IPv6 SNMP ReasmTimeout */ + RTNL_LINK_IP6_REASMREQDS, /*!< IPv6 SNMP ReasmReqds */ + RTNL_LINK_IP6_REASMOKS, /*!< IPv6 SNMP ReasmOKs */ + RTNL_LINK_IP6_REASMFAILS, /*!< IPv6 SNMP ReasmFails */ + RTNL_LINK_IP6_FRAGOKS, /*!< IPv6 SNMP FragOKs */ + RTNL_LINK_IP6_FRAGFAILS, /*!< IPv6 SNMP FragFails */ + RTNL_LINK_IP6_FRAGCREATES, /*!< IPv6 SNMP FragCreates */ + RTNL_LINK_IP6_INMCASTPKTS, /*!< IPv6 SNMP InMcastPkts */ + RTNL_LINK_IP6_OUTMCASTPKTS, /*!< IPv6 SNMP OutMcastPkts */ + RTNL_LINK_IP6_INBCASTPKTS, /*!< IPv6 SNMP InBcastPkts */ + RTNL_LINK_IP6_OUTBCASTPKTS, /*!< IPv6 SNMP OutBcastPkts */ + RTNL_LINK_IP6_INOCTETS, /*!< IPv6 SNMP InOctets */ + RTNL_LINK_IP6_OUTOCTETS, /*!< IPv6 SNMP OutOctets */ + RTNL_LINK_IP6_INMCASTOCTETS, /*!< IPv6 SNMP InMcastOctets */ + RTNL_LINK_IP6_OUTMCASTOCTETS, /*!< IPv6 SNMP OutMcastOctets */ + RTNL_LINK_IP6_INBCASTOCTETS, /*!< IPv6 SNMP InBcastOctets */ + RTNL_LINK_IP6_OUTBCASTOCTETS, /*!< IPv6 SNMP OutBcastOctets */ + RTNL_LINK_ICMP6_INMSGS, /*!< ICMPv6 SNMP InMsgs */ + RTNL_LINK_ICMP6_INERRORS, /*!< ICMPv6 SNMP InErrors */ + RTNL_LINK_ICMP6_OUTMSGS, /*!< ICMPv6 SNMP OutMsgs */ + RTNL_LINK_ICMP6_OUTERRORS, /*!< ICMPv6 SNMP OutErrors */ __RTNL_LINK_STATS_MAX, -}; +} rtnl_link_stat_id_t; #define RTNL_LINK_STATS_MAX (__RTNL_LINK_STATS_MAX - 1) -/* link object allocation/freeage */ extern struct rtnl_link *rtnl_link_alloc(void); extern void rtnl_link_put(struct rtnl_link *); extern void rtnl_link_free(struct rtnl_link *); -/* link cache management */ extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **); extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int); extern struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *, const char *); @@ -149,9 +158,6 @@ extern unsigned int rtnl_link_get_mtu(struct rtnl_link *); extern void rtnl_link_set_txqlen(struct rtnl_link *, unsigned int); extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *); -extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int); -extern unsigned int rtnl_link_get_weight(struct rtnl_link *); - extern void rtnl_link_set_ifindex(struct rtnl_link *, int); extern int rtnl_link_get_ifindex(struct rtnl_link *); @@ -184,15 +190,19 @@ extern void rtnl_link_set_ifalias(struct rtnl_link *, const char *); extern int rtnl_link_get_num_vf(struct rtnl_link *, uint32_t *); -extern uint64_t rtnl_link_get_stat(struct rtnl_link *, int); -extern int rtnl_link_set_stat(struct rtnl_link *, const unsigned int, +extern uint64_t rtnl_link_get_stat(struct rtnl_link *, rtnl_link_stat_id_t); +extern int rtnl_link_set_stat(struct rtnl_link *, rtnl_link_stat_id_t, const uint64_t); extern int rtnl_link_set_type(struct rtnl_link *, const char *); extern char * rtnl_link_get_type(struct rtnl_link *); +/* deprecated */ extern int rtnl_link_set_info_type(struct rtnl_link *, const char *) __attribute__((deprecated)); extern char * rtnl_link_get_info_type(struct rtnl_link *) __attribute__((deprecated)); +extern void rtnl_link_set_weight(struct rtnl_link *, unsigned int) __attribute__((deprecated)); +extern unsigned int rtnl_link_get_weight(struct rtnl_link *) __attribute__((deprecated)); + #ifdef __cplusplus } diff --git a/lib/fib_lookup/lookup.c b/lib/fib_lookup/lookup.c index 61984c7..6018251 100644 --- a/lib/fib_lookup/lookup.c +++ b/lib/fib_lookup/lookup.c @@ -203,8 +203,6 @@ struct nl_cache *flnl_result_alloc_cache(void) * \c rtnl_link_set_* functions. * * @return 0 on success or a negative error code. - * @note Not all attributes can be changed, see - * \ref link_changeable "Changeable Attributes" for more details. */ int flnl_lookup_build_request(struct flnl_request *req, int flags, struct nl_msg **result) diff --git a/lib/route/link.c b/lib/route/link.c index 6268886..4932722 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -6,144 +6,15 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch> + * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch> */ /** * @ingroup rtnl * @defgroup link Links (Interfaces) - * @brief - * - * @par Link Identification - * A link can be identified by either its interface index or by its - * name. The kernel favours the interface index but falls back to the - * interface name if the interface index is lesser-than 0 for kernels - * >= 2.6.11. Therefore you can request changes without mapping a - * interface name to the corresponding index first. - * - * @par Changeable Attributes - * @anchor link_changeable - * - Link layer address - * - Link layer broadcast address - * - device mapping (ifmap) (>= 2.6.9) - * - MTU (>= 2.6.9) - * - Transmission queue length (>= 2.6.9) - * - Weight (>= 2.6.9) - * - Link name (only via access through interface index) (>= 2.6.9) - * - Flags (>= 2.6.9) - * - IFF_DEBUG - * - IFF_NOTRAILERS - * - IFF_NOARP - * - IFF_DYNAMIC - * - IFF_MULTICAST - * - IFF_PORTSEL - * - IFF_AUTOMEDIA - * - IFF_UP - * - IFF_PROMISC - * - IFF_ALLMULTI - * - * @par Link Flags (linux/if.h) - * @anchor link_flags - * @code - * IFF_UP Status of link (up|down) - * IFF_BROADCAST Indicates this link allows broadcasting - * IFF_MULTICAST Indicates this link allows multicasting - * IFF_ALLMULTI Indicates this link is doing multicast routing - * IFF_DEBUG Tell the driver to do debugging (currently unused) - * IFF_LOOPBACK This is the loopback link - * IFF_POINTOPOINT Point-to-point link - * IFF_NOARP Link is unable to perform ARP - * IFF_PROMISC Status of promiscious mode flag - * IFF_MASTER Used by teql - * IFF_SLAVE Used by teql - * IFF_PORTSEL Indicates this link allows port selection - * IFF_AUTOMEDIA Indicates this link selects port automatically - * IFF_DYNAMIC Indicates the address of this link is dynamic - * IFF_RUNNING Link is running and carrier is ok. - * IFF_NOTRAILERS Unused, BSD compat. - * @endcode - * - * @par Notes on IFF_PROMISC and IFF_ALLMULTI flags - * Although you can query the status of IFF_PROMISC and IFF_ALLMULTI - * they do not represent the actual state in the kernel but rather - * whether the flag has been enabled/disabled by userspace. The link - * may be in promiscious mode even if IFF_PROMISC is not set in a link - * dump request response because promiscity might be needed by the driver - * for a period of time. - * - * @note The unit of the transmission queue length depends on the - * link type, a common unit is \a packets. - * - * @par 1) Retrieving information about available links - * @code - * // The first step is to retrieve a list of all available interfaces within - * // the kernel and put them into a cache. - * struct nl_cache *cache = rtnl_link_alloc_cache(sk); - * - * // In a second step, a specific link may be looked up by either interface - * // index or interface name. - * struct rtnl_link *link = rtnl_link_get_by_name(cache, "lo"); - * - * // rtnl_link_get_by_name() is the short version for translating the - * // interface name to an interface index first like this: - * int ifindex = rtnl_link_name2i(cache, "lo"); - * struct rtnl_link *link = rtnl_link_get(cache, ifindex); - * - * // After successful usage, the object must be given back to the cache - * rtnl_link_put(link); - * @endcode - * - * @par 2) Changing link attributes - * @code - * // In order to change any attributes of an existing link, we must allocate - * // a new link to hold the change requests: - * struct rtnl_link *request = rtnl_link_alloc(); - * - * // Now we can go on and specify the attributes we want to change: - * rtnl_link_set_weight(request, 300); - * rtnl_link_set_mtu(request, 1360); - * - * // We can also shut an interface down administratively - * rtnl_link_unset_flags(request, rtnl_link_str2flags("up")); - * - * // Actually, we should know which link to change, so let's look it up - * struct rtnl_link *old = rtnl_link_get(cache, "eth0"); - * - * // Two ways exist to commit this change request, the first one is to - * // build the required netlink message and send it out in one single - * // step: - * rtnl_link_change(sk, old, request, 0); - * - * // An alternative way is to build the netlink message and send it - * // out yourself using nl_send_auto_complete() - * struct nl_msg *msg = rtnl_link_build_change_request(old, request); - * nl_send_auto_complete(sk, nlmsg_hdr(msg)); - * nlmsg_free(msg); - * - * // Don't forget to give back the link object ;-> - * rtnl_link_put(old); - * @endcode - * - * @par 3) Link Type Specific Attributes - * @code - * // Some link types offer additional parameters and statistics specific - * // to their type. F.e. a VLAN link can be configured like this: - * // - * // Allocate a new link and set the info type to "vlan". This is required - * // to prepare the link to hold vlan specific attributes. - * struct rtnl_link *request = rtnl_link_alloc(); - * rtnl_link_set_info_type(request, "vlan"); - * - * // Now vlan specific attributes can be set: - * rtnl_link_vlan_set_id(request, 10); - * rtnl_link_vlan_set_ingress_map(request, 2, 8); - * - * // Of course the attributes can also be read, check the info type - * // to make sure you are using the right access functions: - * char *type = rtnl_link_get_info_type(link); - * if (!strcmp(type, "vlan")) - * int id = rtnl_link_vlan_get_id(link); - * @endcode + * + * @details + * @route_doc{route_link, Link Documentation} * @{ */ @@ -918,24 +789,7 @@ static char *link_attrs2str(int attrs, char *buf, size_t len) } /** - * @name Allocation/Freeing - * @{ - */ - -struct rtnl_link *rtnl_link_alloc(void) -{ - return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); -} - -void rtnl_link_put(struct rtnl_link *link) -{ - nl_object_put((struct nl_object *) link); -} - -/** @} */ - -/** - * @name Cache Management + * @name Get / List * @{ */ @@ -946,9 +800,21 @@ void rtnl_link_put(struct rtnl_link *link) * @arg family Link address family or AF_UNSPEC * @arg result Pointer to store resulting cache. * - * Allocates a new link cache, initializes it properly and updates it - * to include all links currently configured in the kernel. - * + * Allocates and initializes a new link cache. A netlink message is sent to + * the kernel requesting a full dump of all configured links. The returned + * messages are parsed and filled into the cache. If the operation succeeds + * the resulting cache will a link object for each link configured in the + * kernel. + * + * If \c family is set to an address family other than \c AF_UNSPEC the + * contents of the cache can be limited to a specific address family. + * Currently the following address families are supported: + * - AF_BRIDGE + * - AF_INET6 + * + * @route_doc{link_list, Get List of Links} + * @see rtnl_link_get() + * @see rtnl_link_get_by_name() * @return 0 on success or a negative error code. */ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result) @@ -972,14 +838,19 @@ int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **resu } /** - * Look up link by interface index in the provided cache - * @arg cache link cache - * @arg ifindex link interface index + * Lookup link in cache by interface index + * @arg cache Link cache + * @arg ifindex Interface index * - * The caller owns a reference on the returned object and - * must give the object back via rtnl_link_put(). + * Searches through the provided cache looking for a link with matching + * interface index. * - * @return pointer to link inside the cache or NULL if no match was found. + * @attention The reference counter of the returned link object will be + * incremented. Use rtnl_link_put() to release the reference. + * + * @route_doc{link_list, Get List of Links} + * @see rtnl_link_get_by_name() + * @return Link object or NULL if no match was found. */ struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) { @@ -999,14 +870,19 @@ struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) } /** - * Look up link by link name in the provided cache - * @arg cache link cache - * @arg name link name + * Lookup link in cache by link name + * @arg cache Link cache + * @arg name Name of link + * + * Searches through the provided cache looking for a link with matching + * link name * - * The caller owns a reference on the returned object and - * must give the object back via rtnl_link_put(). + * @attention The reference counter of the returned link object will be + * incremented. Use rtnl_link_put() to release the reference. * - * @return pointer to link inside the cache or NULL if no match was found. + * @route_doc{link_list, Get List of Links} + * @see rtnl_link_get() + * @return Link object or NULL if no match was found. */ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, const char *name) @@ -1026,12 +902,145 @@ struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, return NULL; } -/** @} */ +/** + * Construct RTM_GETLINK netlink message + * @arg ifindex Interface index + * @arg name Name of link + * @arg result Pointer to store resulting netlink message + * + * The behaviour of this function is identical to rtnl_link_get_kernel() + * with the exception that it will not send the message but return it in + * the provided return pointer instead. + * + * @see rtnl_link_get_kernel() + * + * @return 0 on success or a negative error code. + */ +int rtnl_link_build_get_request(int ifindex, const char *name, + struct nl_msg **result) +{ + struct ifinfomsg ifi; + struct nl_msg *msg; + + if (ifindex <= 0 && !name) { + APPBUG("ifindex or name must be specified"); + return -NLE_MISSING_ATTR; + } + + memset(&ifi, 0, sizeof(ifi)); + + if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, 0))) + return -NLE_NOMEM; + + if (ifindex > 0) + ifi.ifi_index = ifindex; + + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) + goto nla_put_failure; + + if (name) + NLA_PUT_STRING(msg, IFLA_IFNAME, name); + + *result = msg; + return 0; + +nla_put_failure: + nlmsg_free(msg); + return -NLE_MSGSIZE; +} /** - * @name Link Modifications - * @{ + * Get a link object directly from kernel + * @arg sk Netlink socket + * @arg ifindex Interface index + * @arg name Name of link + * @arg result Pointer to store resulting link object + * + * This function builds a \c RTM_GETLINK netlink message to request + * a specific link directly from the kernel. The returned answer is + * parsed into a struct rtnl_link object and returned via the result + * pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was + * found. + * + * @route_doc{link_direct_lookup, Lookup Single Link (Direct Lookup)} + * @return 0 on success or a negative error code. + */ +int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, + struct rtnl_link **result) +{ + struct nl_msg *msg = NULL; + struct nl_object *obj; + int err; + + if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0) + return err; + + err = nl_send_auto(sk, msg); + nlmsg_free(msg); + if (err < 0) + return err; + + if ((err = nl_pickup(sk, link_msg_parser, &obj)) < 0) + return err; + + /* We have used link_msg_parser(), object is definitely a link */ + *result = (struct rtnl_link *) obj; + + return 0; +} + +/** + * Translate interface index to corresponding link name + * @arg cache Link cache + * @arg ifindex Interface index + * @arg dst String to store name + * @arg len Length of destination string + * + * Translates the specified interface index to the corresponding + * link name and stores the name in the destination string. + * + * @route_doc{link_translate_ifindex, Translating interface index to link name} + * @see rtnl_link_name2i() + * @return Name of link or NULL if no match was found. */ +char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, + size_t len) +{ + struct rtnl_link *link = rtnl_link_get(cache, ifindex); + + if (link) { + strncpy(dst, link->l_name, len - 1); + rtnl_link_put(link); + return dst; + } + + return NULL; +} + +/** + * Translate link name to corresponding interface index + * @arg cache Link cache + * @arg name Name of link + * + * @route_doc{link_translate_ifindex, Translating interface index to link name} + * @see rtnl_link_i2name() + * @return Interface index or 0 if no match was found. + */ +int rtnl_link_name2i(struct nl_cache *cache, const char *name) +{ + int ifindex = 0; + struct rtnl_link *link; + + link = rtnl_link_get_by_name(cache, name); + if (link) { + ifindex = link->l_index; + rtnl_link_put(link); + } + + return ifindex; +} + +/** @} */ static int build_link_msg(int cmd, struct ifinfomsg *hdr, struct rtnl_link *link, int flags, struct nl_msg **result) @@ -1108,7 +1117,12 @@ nla_put_failure: } /** - * Build a netlink message requesting the addition of a new virtual link + * @name Add / Modify + * @{ + */ + +/** + * Build a netlink message requesting the addition of new virtual link * @arg link new link to add * @arg flags additional netlink message flags * @arg result pointer to store resulting netlink message @@ -1148,10 +1162,7 @@ int rtnl_link_build_add_request(struct rtnl_link *link, int flags, * error message to be received and will therefore block until the * operation has been completed. * - * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause - * this function to return immediately after sending. In this case, - * it is the responsibility of the caller to handle any error - * messages returned. + * @copydoc auto_ack_warning * * @return 0 on success or a negative error code. */ @@ -1164,16 +1175,11 @@ int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags) if (err < 0) return err; - err = nl_send_auto_complete(sk, msg); - nlmsg_free(msg); - if (err < 0) - return err; - - return wait_for_ack(sk); + return nl_send_sync(sk, msg); } /** - * Build a netlink message requesting the modification of a link + * Build a netlink message requesting the modification of link * @arg orig original link to change * @arg changes link containing the changes to be made * @arg flags additional netlink message flags @@ -1252,10 +1258,7 @@ errout: * error message to be received and will therefore block until the * operation has been completed. * - * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause - * this function to return immediately after sending. In this case, - * it is the responsibility of the caller to handle any error - * messages returned. + * @copydoc auto_ack_warning * * @note The link name can only be changed if the link has been put * in opertional down state. (~IF_UP) @@ -1288,6 +1291,13 @@ errout: return err; } +/** @} */ + +/** + * @name Delete + * @{ + */ + /** * Build a netlink message requesting the deletion of a link * @arg link Link to delete @@ -1347,10 +1357,7 @@ nla_put_failure: * error message to be received and will therefore block until the * operation has been completed. * - * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause - * this function to return immediately after sending. In this case, - * it is the responsibility of the caller to handle any error - * messages returned. + * @copydoc auto_ack_warning * * @note Only virtual links such as dummy interface or vlan interfaces * can be deleted. It is not possible to delete physical interfaces @@ -1369,353 +1376,65 @@ int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link) return nl_send_sync(sk, msg); } - -/** - * Build a netlink message requesting a link - * @arg ifindex Interface index - * @arg name Name of link - * @arg result Pointer to store resulting netlink message - * - * The behaviour of this function is identical to rtnl_link_get_kernel() - * with the exception that it will not send the message but return it in - * the provided return pointer instead. - * - * @see rtnl_link_get_kernel() - * - * @return 0 on success or a negative error code. - */ -int rtnl_link_build_get_request(int ifindex, const char *name, - struct nl_msg **result) -{ - struct ifinfomsg ifi; - struct nl_msg *msg; - - if (ifindex <= 0 && !name) { - APPBUG("ifindex or name must be specified"); - return -NLE_MISSING_ATTR; - } - - memset(&ifi, 0, sizeof(ifi)); - - if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, 0))) - return -NLE_NOMEM; - - if (ifindex > 0) - ifi.ifi_index = ifindex; - - if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) - goto nla_put_failure; - - if (name) - NLA_PUT_STRING(msg, IFLA_IFNAME, name); - - *result = msg; - return 0; - -nla_put_failure: - nlmsg_free(msg); - return -NLE_MSGSIZE; -} - -/** - * Get a link object directly from the kernel - * @arg sk Netlink socket - * @arg ifindex Interface index - * @arg name name of link - * @arg result result pointer to return link object - * - * This function builds a \c RTM_GETLINK netlink message to request - * a specific link directly from the kernel. The returned answer is - * parsed into a struct rtnl_link object and returned via the result - * pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was - * found. - * - * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause - * this function to return immediately after sending. In this case, - * it is the responsibility of the caller to handle any error - * messages returned. - * - * @return 0 on success or a negative error code. - */ -int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, - struct rtnl_link **result) -{ - struct nl_msg *msg = NULL; - struct nl_object *obj; - int err; - - if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0) - return err; - - err = nl_send_auto(sk, msg); - nlmsg_free(msg); - if (err < 0) - return err; - - if ((err = nl_pickup(sk, link_msg_parser, &obj)) < 0) - return err; - - /* We have used link_msg_parser(), object is definitely a link */ - *result = (struct rtnl_link *) obj; - - return 0; -} - /** @} */ /** - * @name Name <-> Index Translations + * @name Link Object * @{ */ /** - * Translate an interface index to the corresponding link name - * @arg cache link cache - * @arg ifindex link interface index - * @arg dst destination buffer - * @arg len length of destination buffer - * - * Translates the specified interface index to the corresponding - * link name and stores the name in the destination buffer. + * Allocate link object * - * @return link name or NULL if no match was found. + * @see rtnl_link_put() + * @return New link object or NULL if allocation failed */ -char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, - size_t len) +struct rtnl_link *rtnl_link_alloc(void) { - struct rtnl_link *link = rtnl_link_get(cache, ifindex); - - if (link) { - strncpy(dst, link->l_name, len - 1); - rtnl_link_put(link); - return dst; - } - - return NULL; + return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); } /** - * Translate a link name to the corresponding interface index - * @arg cache link cache - * @arg name link name + * Return a link object reference * - * @return interface index or 0 if no match was found. - */ -int rtnl_link_name2i(struct nl_cache *cache, const char *name) -{ - int ifindex = 0; - struct rtnl_link *link; - - link = rtnl_link_get_by_name(cache, name); - if (link) { - ifindex = link->l_index; - rtnl_link_put(link); - } - - return ifindex; -} - -/** @} */ - -/** - * @name Link Flags Translations - * @{ - */ - -static const struct trans_tbl link_flags[] = { - __ADD(IFF_LOOPBACK, loopback) - __ADD(IFF_BROADCAST, broadcast) - __ADD(IFF_POINTOPOINT, pointopoint) - __ADD(IFF_MULTICAST, multicast) - __ADD(IFF_NOARP, noarp) - __ADD(IFF_ALLMULTI, allmulti) - __ADD(IFF_PROMISC, promisc) - __ADD(IFF_MASTER, master) - __ADD(IFF_SLAVE, slave) - __ADD(IFF_DEBUG, debug) - __ADD(IFF_DYNAMIC, dynamic) - __ADD(IFF_AUTOMEDIA, automedia) - __ADD(IFF_PORTSEL, portsel) - __ADD(IFF_NOTRAILERS, notrailers) - __ADD(IFF_UP, up) - __ADD(IFF_RUNNING, running) - __ADD(IFF_LOWER_UP, lowerup) - __ADD(IFF_DORMANT, dormant) - __ADD(IFF_ECHO, echo) -}; - -char * rtnl_link_flags2str(int flags, char *buf, size_t len) -{ - return __flags2str(flags, buf, len, link_flags, - ARRAY_SIZE(link_flags)); -} - -int rtnl_link_str2flags(const char *name) -{ - return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); -} - -/** @} */ - -/** - * @name Link Statistics Translations - * @{ - */ - -static const struct trans_tbl link_stats[] = { - __ADD(RTNL_LINK_RX_PACKETS, rx_packets) - __ADD(RTNL_LINK_TX_PACKETS, tx_packets) - __ADD(RTNL_LINK_RX_BYTES, rx_bytes) - __ADD(RTNL_LINK_TX_BYTES, tx_bytes) - __ADD(RTNL_LINK_RX_ERRORS, rx_errors) - __ADD(RTNL_LINK_TX_ERRORS, tx_errors) - __ADD(RTNL_LINK_RX_DROPPED, rx_dropped) - __ADD(RTNL_LINK_TX_DROPPED, tx_dropped) - __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed) - __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed) - __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err) - __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err) - __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err) - __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err) - __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err) - __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err) - __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err) - __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err) - __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err) - __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err) - __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err) - __ADD(RTNL_LINK_COLLISIONS, collisions) - __ADD(RTNL_LINK_MULTICAST, multicast) - __ADD(RTNL_LINK_IP6_INPKTS, Ip6InReceives) - __ADD(RTNL_LINK_IP6_INHDRERRORS, Ip6InHdrErrors) - __ADD(RTNL_LINK_IP6_INTOOBIGERRORS, Ip6InTooBigErrors) - __ADD(RTNL_LINK_IP6_INNOROUTES, Ip6InNoRoutes) - __ADD(RTNL_LINK_IP6_INADDRERRORS, Ip6InAddrErrors) - __ADD(RTNL_LINK_IP6_INUNKNOWNPROTOS, Ip6InUnknownProtos) - __ADD(RTNL_LINK_IP6_INTRUNCATEDPKTS, Ip6InTruncatedPkts) - __ADD(RTNL_LINK_IP6_INDISCARDS, Ip6InDiscards) - __ADD(RTNL_LINK_IP6_INDELIVERS, Ip6InDelivers) - __ADD(RTNL_LINK_IP6_OUTFORWDATAGRAMS, Ip6OutForwDatagrams) - __ADD(RTNL_LINK_IP6_OUTPKTS, Ip6OutRequests) - __ADD(RTNL_LINK_IP6_OUTDISCARDS, Ip6OutDiscards) - __ADD(RTNL_LINK_IP6_OUTNOROUTES, Ip6OutNoRoutes) - __ADD(RTNL_LINK_IP6_REASMTIMEOUT, Ip6ReasmTimeout) - __ADD(RTNL_LINK_IP6_REASMREQDS, Ip6ReasmReqds) - __ADD(RTNL_LINK_IP6_REASMOKS, Ip6ReasmOKs) - __ADD(RTNL_LINK_IP6_REASMFAILS, Ip6ReasmFails) - __ADD(RTNL_LINK_IP6_FRAGOKS, Ip6FragOKs) - __ADD(RTNL_LINK_IP6_FRAGFAILS, Ip6FragFails) - __ADD(RTNL_LINK_IP6_FRAGCREATES, Ip6FragCreates) - __ADD(RTNL_LINK_IP6_INMCASTPKTS, Ip6InMcastPkts) - __ADD(RTNL_LINK_IP6_OUTMCASTPKTS, Ip6OutMcastPkts) - __ADD(RTNL_LINK_IP6_INBCASTPKTS, Ip6InBcastPkts) - __ADD(RTNL_LINK_IP6_OUTBCASTPKTS, Ip6OutBcastPkts) - __ADD(RTNL_LINK_IP6_INOCTETS, Ip6InOctets) - __ADD(RTNL_LINK_IP6_OUTOCTETS, Ip6OutOctets) - __ADD(RTNL_LINK_IP6_INMCASTOCTETS, Ip6InMcastOctets) - __ADD(RTNL_LINK_IP6_OUTMCASTOCTETS, Ip6OutMcastOctets) - __ADD(RTNL_LINK_IP6_INBCASTOCTETS, Ip6InBcastOctets) - __ADD(RTNL_LINK_IP6_OUTBCASTOCTETS, Ip6OutBcastOctets) - __ADD(RTNL_LINK_ICMP6_INMSGS, ICMP6_InMsgs) - __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors) - __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs) - __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors) -}; - -char *rtnl_link_stat2str(int st, char *buf, size_t len) -{ - return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); -} - -int rtnl_link_str2stat(const char *name) -{ - return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); -} - -/** @} */ - -/** - * @name Link Operstate Translations - * @{ - */ - -static const struct trans_tbl link_operstates[] = { - __ADD(IF_OPER_UNKNOWN, unknown) - __ADD(IF_OPER_NOTPRESENT, notpresent) - __ADD(IF_OPER_DOWN, down) - __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown) - __ADD(IF_OPER_TESTING, testing) - __ADD(IF_OPER_DORMANT, dormant) - __ADD(IF_OPER_UP, up) -}; - -char *rtnl_link_operstate2str(uint8_t st, char *buf, size_t len) -{ - return __type2str(st, buf, len, link_operstates, - ARRAY_SIZE(link_operstates)); -} - -int rtnl_link_str2operstate(const char *name) -{ - return __str2type(name, link_operstates, - ARRAY_SIZE(link_operstates)); -} - -/** @} */ - -/** - * @name Link Mode Translations - * @{ + * @copydetails nl_object_put() */ - -static const struct trans_tbl link_modes[] = { - __ADD(IF_LINK_MODE_DEFAULT, default) - __ADD(IF_LINK_MODE_DORMANT, dormant) -}; - -char *rtnl_link_mode2str(uint8_t st, char *buf, size_t len) -{ - return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes)); -} - -int rtnl_link_str2mode(const char *name) +void rtnl_link_put(struct rtnl_link *link) { - return __str2type(name, link_modes, ARRAY_SIZE(link_modes)); + nl_object_put((struct nl_object *) link); } -/** @} */ - /** - * @name Attributes - * @{ + * Set name of link object + * @arg link Link object + * @arg name New name + * + * @note To change the name of a link in the kernel, set the interface + * index to the link you wish to change, modify the link name using + * this function and pass the link object to rtnl_link_change() or + * rtnl_link_add(). + * + * @route_doc{link_attr_name, Link Name} + * @see rtnl_link_get_name() + * @see rtnl_link_set_ifindex() */ - -void rtnl_link_set_qdisc(struct rtnl_link *link, const char *qdisc) -{ - strncpy(link->l_qdisc, qdisc, sizeof(link->l_qdisc) - 1); - link->ce_mask |= LINK_ATTR_QDISC; -} - -char *rtnl_link_get_qdisc(struct rtnl_link *link) -{ - if (link->ce_mask & LINK_ATTR_QDISC) - return link->l_qdisc; - else - return NULL; -} - void rtnl_link_set_name(struct rtnl_link *link, const char *name) { strncpy(link->l_name, name, sizeof(link->l_name) - 1); link->ce_mask |= LINK_ATTR_IFNAME; } +/** + * Return name of link object + * @arg link Link object + * + * @route_doc{link_attr_name, Link Name} + * @see rtnl_link_set_name() + * @return Link name or NULL if name is not specified + */ char *rtnl_link_get_name(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_IFNAME) - return link->l_name; - else - return NULL; + return link->ce_mask & LINK_ATTR_IFNAME ? link->l_name : NULL; } static inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, @@ -1730,32 +1449,75 @@ static inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, link->ce_mask |= flag; } +/** + * Set link layer address of link object + * @arg link Link object + * @arg addr New link layer address + * + * The function increments the reference counter of the address object + * and overwrites any existing link layer address previously assigned. + * + * @route_doc{link_attr_address, Link layer address} + * @see rtnl_link_get_addr() + */ void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr) { __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR); } +/** + * Return link layer address of link object + * @arg link Link object + * + * @copydoc pointer_lifetime_warning + * @route_doc{link_attr_address, Link Layer Address} + * @see rtnl_link_set_addr() + * @return Link layer address or NULL if not set. + */ struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_ADDR) - return link->l_addr; - else - return NULL; + return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL; } -void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *brd) +/** + * Set link layer broadcast address of link object + * @arg link Link object + * @arg addr New broadcast address + * + * The function increments the reference counter of the address object + * and overwrites any existing link layer broadcast address previously + * assigned. + * + * @route_doc{link_attr_broadcast, Link Layer Broadcast Address} + * @see rtnl_link_get_broadcast() + */ +void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr) { - __assign_addr(link, &link->l_bcast, brd, LINK_ATTR_BRD); + __assign_addr(link, &link->l_bcast, addr, LINK_ATTR_BRD); } +/** + * Return link layer broadcast address of link object + * @arg link Link object + * + * @copydoc pointer_lifetime_warning + * @route_doc{link_attr_address, Link Layer Address} + * @see rtnl_link_set_broadcast() + * @return Link layer address or NULL if not set. + */ struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_BRD) - return link->l_bcast; - else - return NULL; + return link->ce_mask & LINK_ATTR_BRD ? link->l_bcast : NULL; } +/** + * Set flags of link object + * @arg link Link object + * @arg flags Flags + * + * @see rtnl_link_get_flags() + * @see rtnl_link_unset_flags() + */ void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) { link->l_flag_mask |= flags; @@ -1763,6 +1525,14 @@ void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) link->ce_mask |= LINK_ATTR_FLAGS; } +/** + * Unset flags of link object + * @arg link Link object + * @arg flags Flags + * + * @see rtnl_link_set_flags() + * @see rtnl_link_get_flags() + */ void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) { link->l_flag_mask |= flags; @@ -1770,86 +1540,158 @@ void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) link->ce_mask |= LINK_ATTR_FLAGS; } +/** + * Return flags of link object + * @arg link Link object + * + * @route_doc{link_attr_flags, Link Flags} + * @see rtnl_link_set_flags() + * @see rtnl_link_unset_flags() + * @return Link flags or 0 if none have been set. + */ unsigned int rtnl_link_get_flags(struct rtnl_link *link) { return link->l_flags; } +/** + * Set address family of link object + * + * @see rtnl_link_get_family() + */ void rtnl_link_set_family(struct rtnl_link *link, int family) { link->l_family = family; link->ce_mask |= LINK_ATTR_FAMILY; } +/** + * Return address family of link object + * @arg link Link object + * + * @see rtnl_link_set_family() + * @return Address family or \c AF_UNSPEC if not specified. + */ int rtnl_link_get_family(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_FAMILY) - return link->l_family; - else - return AF_UNSPEC; + return link->ce_mask & LINK_ATTR_FAMILY ? link->l_family : AF_UNSPEC; } +/** + * Set hardware type of link object + * @arg link Link object + * @arg arptype New hardware type \c (ARPHRD_*) + * + * @route_doc{link_attr_arptype, Hardware Type} + * @copydoc read_only_attribute + * @see rtnl_link_get_arptype() + */ void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype) { link->l_arptype = arptype; + link->ce_mask |= LINK_ATTR_ARPTYPE; } +/** + * Get hardware type of link object + * @arg link Link object + * + * @route_doc{link_attr_arptype, Hardware Type} + * @see rtnl_link_set_arptype() + * @return Hardware type \c (ARPHRD_ETHER *) or \c ARPHRD_VOID + */ unsigned int rtnl_link_get_arptype(struct rtnl_link *link) { - return link->l_arptype; + if (link->ce_mask & LINK_ATTR_ARPTYPE) + return link->l_arptype; + else + return ARPHRD_VOID; } +/** + * Set interface index of link object + * @arg link Link object + * @arg ifindex Interface index + * + * @route_doc{link_attr_ifindex, Interface Index} + * @see rtnl_link_get_ifindex() + */ void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex) { link->l_index = ifindex; link->ce_mask |= LINK_ATTR_IFINDEX; } + +/** + * Return interface index of link object + * @arg link Link object + * + * @route_doc{link_attr_ifindex, Interface Index} + * @see rtnl_link_set_ifindex() + * @return Interface index or 0 if not set. + */ int rtnl_link_get_ifindex(struct rtnl_link *link) { return link->l_index; } +/** + * Set Maximum Transmission Unit of link object + * @arg link Link object + * @arg mtu New MTU value in number of bytes + * + * @route_doc{link_attr_mtu, Maximum Transmission Unit} + * @see rtnl_link_get_mtu() + */ void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu) { link->l_mtu = mtu; link->ce_mask |= LINK_ATTR_MTU; } +/** + * Return maximum transmission unit of link object + * @arg link Link object + * + * @route_doc{link_attr_mtu, Maximum Transmission Unit} + * @see rtnl_link_set_mtu() + * @return MTU in bytes or 0 if not set + */ unsigned int rtnl_link_get_mtu(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_MTU) - return link->l_mtu; - else - return 0; + return link->l_mtu; } +/** + * Set transmission queue length + * @arg link Link object + * @arg txqlen New queue length + * + * The unit is dependant on the link type. The most common units is number + * of packets. + * + * @route_doc{link_attr_txqlen, Transmission Queue Length} + */ void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen) { link->l_txqlen = txqlen; link->ce_mask |= LINK_ATTR_TXQLEN; } +/** + * Return transmission queue length + * @arg link Link object + * + * The unit is dependant on the link type. The most common units is number + * of packets. + * + * @route_doc{link_attr_txqlen, Transmission Queue Length} + * @return queue length or 0 if not specified. + */ unsigned int rtnl_link_get_txqlen(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_TXQLEN) - return link->l_txqlen; - else - return UINT_MAX; -} - -void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) -{ - link->l_weight = weight; - link->ce_mask |= LINK_ATTR_WEIGHT; -} - -unsigned int rtnl_link_get_weight(struct rtnl_link *link) -{ - if (link->ce_mask & LINK_ATTR_WEIGHT) - return link->l_weight; - else - return UINT_MAX; + return link->ce_mask & LINK_ATTR_TXQLEN ? link->l_txqlen : 0; } void rtnl_link_set_link(struct rtnl_link *link, int ifindex) @@ -1863,49 +1705,91 @@ int rtnl_link_get_link(struct rtnl_link *link) return link->l_link; } +/** + * Set master link of link object + * @arg link Link object + * @arg ifindex Interface index of master link + * + * @see rtnl_link_get_master() + */ void rtnl_link_set_master(struct rtnl_link *link, int ifindex) { link->l_master = ifindex; link->ce_mask |= LINK_ATTR_MASTER; } +/** + * Return master link of link object + * @arg link Link object + * + * @see rtnl_link_set_master() + * @return Interface index of master link or 0 if not specified + */ int rtnl_link_get_master(struct rtnl_link *link) { return link->l_master; } -void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t operstate) +/** + * Set operational status of link object + * @arg link Link object + * @arg status New opertional status + * + * @route_doc{link_attr_operstate, Operational Status}} + * @see rtnl_link_get_operstate() + */ +void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status) { - link->l_operstate = operstate; + link->l_operstate = status; link->ce_mask |= LINK_ATTR_OPERSTATE; } +/** + * Return operational status of link object + * @arg link Link object + * + * @route_doc{link_attr_operstate, Operational Status} + * @see rtnl_link_set_operstate() + * @return Opertional state or \c IF_OPER_UNKNOWN + */ uint8_t rtnl_link_get_operstate(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_OPERSTATE) - return link->l_operstate; - else - return IF_OPER_UNKNOWN; + return link->l_operstate; } -void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t linkmode) +/** + * Set link mode of link object + * @arg link Link object + * @arg mode New link mode + * + * @route_doc{link_attr_mode, Mode} + * @see rtnl_link_get_linkmode() + */ +void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode) { - link->l_linkmode = linkmode; + link->l_linkmode = mode; link->ce_mask |= LINK_ATTR_LINKMODE; } +/** + * Return link mode of link object + * @arg link Link object + * + * @route_doc{link_attr_mode, Mode} + * @see rtnl_link_get_linkmode() + * @return Link mode or \c IF_LINK_MODE_DEFAULT + */ uint8_t rtnl_link_get_linkmode(struct rtnl_link *link) { - if (link->ce_mask & LINK_ATTR_LINKMODE) - return link->l_linkmode; - else - return IF_LINK_MODE_DEFAULT; + return link->l_linkmode; } /** - * Return alias name of link (SNMP IfAlias) + * Return alias name of link object (SNMP IfAlias) * @arg link Link object * + * @route_doc{link_attr_alias, Alias} + * @see rtnl_link_set_ifalias() * @return Alias name or NULL if not set. */ const char *rtnl_link_get_ifalias(struct rtnl_link *link) @@ -1914,13 +1798,16 @@ const char *rtnl_link_get_ifalias(struct rtnl_link *link) } /** - * Set alias name of link (SNMP IfAlias) + * Set alias name of link object (SNMP IfAlias) * @arg link Link object * @arg alias Alias name or NULL to unset * * Sets the alias name of the link to the specified name. The alias * name can be unset by specyfing NULL as the alias. The name will * be strdup()ed, so no need to provide a persistent character string. + * + * @route_doc{link_attr_alias, Alias} + * @see rtnl_link_get_ifalias() */ void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias) { @@ -1934,11 +1821,44 @@ void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias) } /** - * Retrieve number of PCI VFs of link + * Set queueing discipline name of link object + * @arg link Link object + * @arg name Name of queueing discipline + * + * @copydoc read_only_attribute + * + * For more information on how to modify the qdisc of a link, see section + * @ref_route{route_tc, Traffic Control}. + * + * @route_doc{link_attr_qdisc, Queueing Discipline Name} + * @see rtnl_link_get_qdisc() + */ +void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name) +{ + strncpy(link->l_qdisc, name, sizeof(link->l_qdisc) - 1); + link->ce_mask |= LINK_ATTR_QDISC; +} + +/** + * Return name of queueing discipline of link object + * @arg link Link object + * + * @route_doc{link_attr_qdisc, Queueing Discipline Name} + * @see rtnl_link_set_qdisc() + * @return Name of qdisc or NULL if not specified. + */ +char *rtnl_link_get_qdisc(struct rtnl_link *link) +{ + return link->ce_mask & LINK_ATTR_QDISC ? link->l_qdisc : NULL; +} + + +/** + * Return number of PCI virtual functions of link object * @arg link Link object * @arg num_vf Pointer to store number of VFs * - * @return 0 if value is available or -NLE_OPNOTSUPP if not. + * @return 0 on success or -NLE_OPNOTSUPP if not available */ int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf) { @@ -1949,23 +1869,33 @@ int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf) return -NLE_OPNOTSUPP; } -uint64_t rtnl_link_get_stat(struct rtnl_link *link, int id) +/** + * Return value of link statistics counter + * @arg link Link object + * @arg id Identifier of statistical counter + * + * @return Value of counter or 0 if not specified. + */ +uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id) { - if (id < 0 || id > RTNL_LINK_STATS_MAX) + if (id > RTNL_LINK_STATS_MAX) return 0; return link->l_stats[id]; } /** - * Set value of a link statistics counter + * Set value of link statistics counter * @arg link Link object - * @arg id Counter ID + * @arg id Identifier of statistical counter * @arg value New value * + * \note Changing the value of a statistical counter will not change the + * value in the kernel. + * * @return 0 on success or a negative error code */ -int rtnl_link_set_stat(struct rtnl_link *link, const unsigned int id, +int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id, const uint64_t value) { if (id > RTNL_LINK_STATS_MAX) @@ -1977,14 +1907,15 @@ int rtnl_link_set_stat(struct rtnl_link *link, const unsigned int id, } /** - * Set link type - * @arg link Link object - * @arg type Type of link + * Set type of link object + * @arg link Link object + * @arg type Name of link type * - * Looks up the link type modules and prepares the link to store type + * Looks up the link type module and prepares the link to store type * specific attributes. If a type has been assigned already it will * be released with all link type specific attributes lost. * + * @route_doc{link_modules, Link Modules} * @return 0 on success or a negative errror code. */ int rtnl_link_set_type(struct rtnl_link *link, const char *type) @@ -2008,29 +1939,203 @@ int rtnl_link_set_type(struct rtnl_link *link, const char *type) } /** - * Get type of link - * @arg link Link object + * Return type of link + * @arg link Link object * - * @return Name of link type or NULL if unknown. + * @route_doc{link_modules, Link Modules} + * @return Name of link type or NULL if not specified. */ char *rtnl_link_get_type(struct rtnl_link *link) { - if (link->l_info_ops) - return link->l_info_ops->io_name; - else - return NULL; + return link->l_info_ops ? link->l_info_ops->io_name : NULL; +} + +/** @} */ + +/** + * @name Utilities + * @{ + */ + +static const struct trans_tbl link_flags[] = { + __ADD(IFF_LOOPBACK, loopback) + __ADD(IFF_BROADCAST, broadcast) + __ADD(IFF_POINTOPOINT, pointopoint) + __ADD(IFF_MULTICAST, multicast) + __ADD(IFF_NOARP, noarp) + __ADD(IFF_ALLMULTI, allmulti) + __ADD(IFF_PROMISC, promisc) + __ADD(IFF_MASTER, master) + __ADD(IFF_SLAVE, slave) + __ADD(IFF_DEBUG, debug) + __ADD(IFF_DYNAMIC, dynamic) + __ADD(IFF_AUTOMEDIA, automedia) + __ADD(IFF_PORTSEL, portsel) + __ADD(IFF_NOTRAILERS, notrailers) + __ADD(IFF_UP, up) + __ADD(IFF_RUNNING, running) + __ADD(IFF_LOWER_UP, lowerup) + __ADD(IFF_DORMANT, dormant) + __ADD(IFF_ECHO, echo) +}; + +char *rtnl_link_flags2str(int flags, char *buf, size_t len) +{ + return __flags2str(flags, buf, len, link_flags, + ARRAY_SIZE(link_flags)); +} + +int rtnl_link_str2flags(const char *name) +{ + return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); +} + +static const struct trans_tbl link_stats[] = { + __ADD(RTNL_LINK_RX_PACKETS, rx_packets) + __ADD(RTNL_LINK_TX_PACKETS, tx_packets) + __ADD(RTNL_LINK_RX_BYTES, rx_bytes) + __ADD(RTNL_LINK_TX_BYTES, tx_bytes) + __ADD(RTNL_LINK_RX_ERRORS, rx_errors) + __ADD(RTNL_LINK_TX_ERRORS, tx_errors) + __ADD(RTNL_LINK_RX_DROPPED, rx_dropped) + __ADD(RTNL_LINK_TX_DROPPED, tx_dropped) + __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed) + __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed) + __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err) + __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err) + __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err) + __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err) + __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err) + __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err) + __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err) + __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err) + __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err) + __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err) + __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err) + __ADD(RTNL_LINK_COLLISIONS, collisions) + __ADD(RTNL_LINK_MULTICAST, multicast) + __ADD(RTNL_LINK_IP6_INPKTS, Ip6InReceives) + __ADD(RTNL_LINK_IP6_INHDRERRORS, Ip6InHdrErrors) + __ADD(RTNL_LINK_IP6_INTOOBIGERRORS, Ip6InTooBigErrors) + __ADD(RTNL_LINK_IP6_INNOROUTES, Ip6InNoRoutes) + __ADD(RTNL_LINK_IP6_INADDRERRORS, Ip6InAddrErrors) + __ADD(RTNL_LINK_IP6_INUNKNOWNPROTOS, Ip6InUnknownProtos) + __ADD(RTNL_LINK_IP6_INTRUNCATEDPKTS, Ip6InTruncatedPkts) + __ADD(RTNL_LINK_IP6_INDISCARDS, Ip6InDiscards) + __ADD(RTNL_LINK_IP6_INDELIVERS, Ip6InDelivers) + __ADD(RTNL_LINK_IP6_OUTFORWDATAGRAMS, Ip6OutForwDatagrams) + __ADD(RTNL_LINK_IP6_OUTPKTS, Ip6OutRequests) + __ADD(RTNL_LINK_IP6_OUTDISCARDS, Ip6OutDiscards) + __ADD(RTNL_LINK_IP6_OUTNOROUTES, Ip6OutNoRoutes) + __ADD(RTNL_LINK_IP6_REASMTIMEOUT, Ip6ReasmTimeout) + __ADD(RTNL_LINK_IP6_REASMREQDS, Ip6ReasmReqds) + __ADD(RTNL_LINK_IP6_REASMOKS, Ip6ReasmOKs) + __ADD(RTNL_LINK_IP6_REASMFAILS, Ip6ReasmFails) + __ADD(RTNL_LINK_IP6_FRAGOKS, Ip6FragOKs) + __ADD(RTNL_LINK_IP6_FRAGFAILS, Ip6FragFails) + __ADD(RTNL_LINK_IP6_FRAGCREATES, Ip6FragCreates) + __ADD(RTNL_LINK_IP6_INMCASTPKTS, Ip6InMcastPkts) + __ADD(RTNL_LINK_IP6_OUTMCASTPKTS, Ip6OutMcastPkts) + __ADD(RTNL_LINK_IP6_INBCASTPKTS, Ip6InBcastPkts) + __ADD(RTNL_LINK_IP6_OUTBCASTPKTS, Ip6OutBcastPkts) + __ADD(RTNL_LINK_IP6_INOCTETS, Ip6InOctets) + __ADD(RTNL_LINK_IP6_OUTOCTETS, Ip6OutOctets) + __ADD(RTNL_LINK_IP6_INMCASTOCTETS, Ip6InMcastOctets) + __ADD(RTNL_LINK_IP6_OUTMCASTOCTETS, Ip6OutMcastOctets) + __ADD(RTNL_LINK_IP6_INBCASTOCTETS, Ip6InBcastOctets) + __ADD(RTNL_LINK_IP6_OUTBCASTOCTETS, Ip6OutBcastOctets) + __ADD(RTNL_LINK_ICMP6_INMSGS, ICMP6_InMsgs) + __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors) + __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs) + __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors) +}; + +char *rtnl_link_stat2str(int st, char *buf, size_t len) +{ + return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); +} + +int rtnl_link_str2stat(const char *name) +{ + return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); +} + +static const struct trans_tbl link_operstates[] = { + __ADD(IF_OPER_UNKNOWN, unknown) + __ADD(IF_OPER_NOTPRESENT, notpresent) + __ADD(IF_OPER_DOWN, down) + __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown) + __ADD(IF_OPER_TESTING, testing) + __ADD(IF_OPER_DORMANT, dormant) + __ADD(IF_OPER_UP, up) +}; + +char *rtnl_link_operstate2str(uint8_t st, char *buf, size_t len) +{ + return __type2str(st, buf, len, link_operstates, + ARRAY_SIZE(link_operstates)); } +int rtnl_link_str2operstate(const char *name) +{ + return __str2type(name, link_operstates, + ARRAY_SIZE(link_operstates)); +} + +static const struct trans_tbl link_modes[] = { + __ADD(IF_LINK_MODE_DEFAULT, default) + __ADD(IF_LINK_MODE_DORMANT, dormant) +}; + +char *rtnl_link_mode2str(uint8_t st, char *buf, size_t len) +{ + return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes)); +} + +int rtnl_link_str2mode(const char *name) +{ + return __str2type(name, link_modes, ARRAY_SIZE(link_modes)); +} + +/** @} */ + +/** + * @name Deprecated Functions + */ + +/** + * @deprecated Use of this function is deprecated, use rtnl_link_set_type() + */ int rtnl_link_set_info_type(struct rtnl_link *link, const char *type) { return rtnl_link_set_type(link, type); } +/** + * @deprecated Use of this function is deprecated, use rtnl_link_get_type() + */ char *rtnl_link_get_info_type(struct rtnl_link *link) { return rtnl_link_get_type(link); } +/** + * @deprecated The weight attribute is unused and obsoleted in all recent kernels + */ +void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) +{ + link->l_weight = weight; + link->ce_mask |= LINK_ATTR_WEIGHT; +} + +/** + * @deprecated The weight attribute is unused and obsoleted in all recent kernels + */ +unsigned int rtnl_link_get_weight(struct rtnl_link *link) +{ + return link->l_weight; +} + /** @} */ static struct nl_object_ops link_obj_ops = { diff --git a/lib/route/link/bonding.c b/lib/route/link/bonding.c index c53bf52..176be27 100644 --- a/lib/route/link/bonding.c +++ b/lib/route/link/bonding.c @@ -13,8 +13,10 @@ * @ingroup link * @defgroup bonding Bonding * - * <a href="../route.html#_links_network_devices">Link Documentation</a> + * @details + * \b Link Type Name: "bond" * + * @route_doc{link_bonding, Bonding Documentation} * @{ */ diff --git a/lib/route/link/dummy.c b/lib/route/link/dummy.c index b837f48..c7dabc1 100644 --- a/lib/route/link/dummy.c +++ b/lib/route/link/dummy.c @@ -12,7 +12,9 @@ /** * @ingroup link * @defgroup dummy Dummy - * @brief + * + * @details + * \b Link Type Name: "dummy" * * @{ */ diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c index cd831ce..a30ff77 100644 --- a/lib/route/link/vlan.c +++ b/lib/route/link/vlan.c @@ -14,7 +14,10 @@ * @defgroup vlan VLAN * Virtual LAN link module * - * See <a href="../route.html#link_vlan">VLAN API documentation</a> for more information + * @details + * \b Link Type Name: "vlan" + * + * @route_doc{link_vlan, VLAN Documentation} * * @{ */ |