summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2011-07-28 16:23:57 +0200
committerThomas Graf <tgraf@suug.ch>2011-07-28 16:23:57 +0200
commit70c93717607a15d37b60d7caefb58e78d28c5e59 (patch)
tree52b991c5cb5fab3f4190015f0a3fd8d8cdf68653
parent915a23fd16315eed2b13dda38c96ca824935e844 (diff)
downloadlibnl-70c93717607a15d37b60d7caefb58e78d28c5e59.tar.gz
Updated link documentation
- API documentation - developer guide - enabled doxygen navbar - fixed css
-rw-r--r--doc/Doxyfile.in16
-rw-r--r--doc/DoxygenLayout.xml10
-rw-r--r--doc/libnl.css41
-rw-r--r--doc/route.txt287
-rw-r--r--doc/src/hidden.c35
-rw-r--r--doc/stylesheets/asciidoc.css3
-rw-r--r--include/netlink/route/link.h142
-rw-r--r--lib/fib_lookup/lookup.c2
-rw-r--r--lib/route/link.c1259
-rw-r--r--lib/route/link/bonding.c4
-rw-r--r--lib/route/link/dummy.c4
-rw-r--r--lib/route/link/vlan.c5
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}
*
* @{
*/