link.c revision b4fbe1d34d6f54045b5c6236d86aacd4340ec83d
144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/route/link.c Links (Interfaces) 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 98a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @ingroup rtnl 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup link Links (Interfaces) 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @brief 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Link Identification 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf * A link can be identified by either its interface index or by its 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf * name. The kernel favours the interface index but falls back to the 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf * interface name if the interface index is lesser-than 0 for kernels 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf * >= 2.6.11. Therefore you can request changes without mapping a 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf * interface name to the corresponding index first. 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Changeable Attributes 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @anchor link_changeable 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link layer address 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link layer broadcast address 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf * - device mapping (ifmap) (>= 2.6.9) 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf * - MTU (>= 2.6.9) 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Transmission queue length (>= 2.6.9) 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Weight (>= 2.6.9) 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link name (only via access through interface index) (>= 2.6.9) 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Flags (>= 2.6.9) 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_DEBUG 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_NOTRAILERS 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_NOARP 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_DYNAMIC 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_MULTICAST 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_PORTSEL 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_AUTOMEDIA 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_UP 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_PROMISC 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_ALLMULTI 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Link Flags (linux/if.h) 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @anchor link_flags 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_UP Status of link (up|down) 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_BROADCAST Indicates this link allows broadcasting 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_MULTICAST Indicates this link allows multicasting 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_ALLMULTI Indicates this link is doing multicast routing 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_DEBUG Tell the driver to do debugging (currently unused) 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_LOOPBACK This is the loopback link 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_POINTOPOINT Point-to-point link 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_NOARP Link is unable to perform ARP 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_PROMISC Status of promiscious mode flag 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_MASTER Used by teql 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_SLAVE Used by teql 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_PORTSEL Indicates this link allows port selection 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_AUTOMEDIA Indicates this link selects port automatically 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_DYNAMIC Indicates the address of this link is dynamic 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_RUNNING Link is running and carrier is ok. 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_NOTRAILERS Unused, BSD compat. 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Notes on IFF_PROMISC and IFF_ALLMULTI flags 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Although you can query the status of IFF_PROMISC and IFF_ALLMULTI 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf * they do not represent the actual state in the kernel but rather 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf * whether the flag has been enabled/disabled by userspace. The link 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf * may be in promiscious mode even if IFF_PROMISC is not set in a link 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf * dump request response because promiscity might be needed by the driver 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf * for a period of time. 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note The unit of the transmission queue length depends on the 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf * link type, a common unit is \a packets. 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par 1) Retrieving information about available links 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // The first step is to retrieve a list of all available interfaces within 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf * // the kernel and put them into a cache. 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct nl_cache *cache = rtnl_link_alloc_cache(nl_handle); 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // In a second step, a specific link may be looked up by either interface 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf * // index or interface name. 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *link = rtnl_link_get_by_name(cache, "lo"); 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf * // rtnl_link_get_by_name() is the short version for translating the 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // interface name to an interface index first like this: 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf * int ifindex = rtnl_link_name2i(cache, "lo"); 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *link = rtnl_link_get(cache, ifindex); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // After successful usage, the object must be given back to the cache 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_put(link); 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par 2) Changing link attributes 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // In order to change any attributes of an existing link, we must allocate 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // a new link to hold the change requests: 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *request = rtnl_link_alloc(); 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Now we can go on and specify the attributes we want to change: 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_set_weight(request, 300); 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_set_mtu(request, 1360); 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf * // We can also shut an interface down administratively 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_unset_flags(request, rtnl_link_str2flags("up")); 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Actually, we should know which link to change, so let's look it up 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *old = rtnl_link_get(cache, "eth0"); 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Two ways exist to commit this change request, the first one is to 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // build the required netlink message and send it out in one single 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf * // step: 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_change(nl_handle, old, request); 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf * // An alternative way is to build the netlink message and send it 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // out yourself using nl_send_auto_complete() 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct nl_msg *msg = rtnl_link_build_change_request(old, request); 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf * nl_send_auto_complete(nl_handle, nlmsg_hdr(msg)); 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf * nlmsg_free(msg); 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Don't forget to give back the link object ;-> 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_put(old); 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 126a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 127a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @par 3) Link Type Specific Attributes 128a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @code 129a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // Some link types offer additional parameters and statistics specific 130a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // to their type. F.e. a VLAN link can be configured like this: 131a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // 132a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // Allocate a new link and set the info type to "vlan". This is required 133a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // to prepare the link to hold vlan specific attributes. 134a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * struct rtnl_link *request = rtnl_link_alloc(); 135a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * rtnl_link_set_info_type(request, "vlan"); 136a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 137a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // Now vlan specific attributes can be set: 138a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * rtnl_link_vlan_set_id(request, 10); 139a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * rtnl_link_vlan_set_ingress_map(request, 2, 8); 140a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 141a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // Of course the attributes can also be read, check the info type 142a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * // to make sure you are using the right access functions: 143a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * char *type = rtnl_link_get_info_type(link); 144a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * if (!strcmp(type, "vlan")) 145a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * int id = rtnl_link_vlan_get_id(link); 146a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @endcode 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/attr.h> 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/object.h> 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/rtnl.h> 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/link.h> 157a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf#include <netlink/route/link/info-api.h> 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */ 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MTU 0x0001 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_LINK 0x0002 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_TXQLEN 0x0004 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_WEIGHT 0x0008 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MASTER 0x0010 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_QDISC 0x0020 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MAP 0x0040 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_ADDR 0x0080 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_BRD 0x0100 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_FLAGS 0x0200 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_IFNAME 0x0400 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_IFINDEX 0x0800 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_FAMILY 0x1000 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_ARPTYPE 0x2000 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_STATS 0x4000 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_CHANGE 0x8000 1763ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf#define LINK_ATTR_OPERSTATE 0x10000 1773ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf#define LINK_ATTR_LINKMODE 0x20000 178a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf#define LINK_ATTR_LINKINFO 0x40000 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf 18044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops rtnl_link_ops; 18144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops link_obj_ops; 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */ 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf 184a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafstatic void release_link_info(struct rtnl_link *link) 185a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf{ 186a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link_info_ops *io = link->l_info_ops; 187a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 188a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (io != NULL) { 189a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf io->io_refcnt--; 190a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf io->io_free(link); 191a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf link->l_info_ops = NULL; 192a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 193a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf} 194a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 19544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void link_free_data(struct nl_object *c) 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = nl_object_priv(c); 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 200a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link_info_ops *io; 201a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 202a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((io = link->l_info_ops) != NULL) 203a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf release_link_info(link); 204a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(link->l_addr); 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(link->l_bcast); 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf 21044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_clone(struct nl_object *_dst, struct nl_object *_src) 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *dst = nl_object_priv(_dst); 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *src = nl_object_priv(_src); 214a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf int err; 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->l_addr) 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->l_addr = nl_addr_clone(src->l_addr))) 2188a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->l_bcast) 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->l_bcast = nl_addr_clone(src->l_bcast))) 2228a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf 224a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (src->l_info_ops && src->l_info_ops->io_clone) { 225a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf err = src->l_info_ops->io_clone(dst, src); 226a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (err < 0) 2278a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return err; 228a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 229a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf 23344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nla_policy link_policy[IFLA_MAX+1] = { 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_IFNAME] = { .type = NLA_STRING, 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf .maxlen = IFNAMSIZ }, 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MTU] = { .type = NLA_U32 }, 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_TXQLEN] = { .type = NLA_U32 }, 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_LINK] = { .type = NLA_U32 }, 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_WEIGHT] = { .type = NLA_U32 }, 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MASTER] = { .type = NLA_U32 }, 2413ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf [IFLA_OPERSTATE]= { .type = NLA_U8 }, 2423ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf [IFLA_LINKMODE] = { .type = NLA_U8 }, 243a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf [IFLA_LINKINFO] = { .type = NLA_NESTED }, 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_QDISC] = { .type = NLA_STRING, 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf .maxlen = IFQDISCSIZ }, 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_STATS] = { .minlen = sizeof(struct rtnl_link_stats) }, 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) }, 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf 250a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafstatic struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = { 251a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf [IFLA_INFO_KIND] = { .type = NLA_STRING }, 252a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 253a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf [IFLA_INFO_XSTATS] = { .type = NLA_NESTED }, 254a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf}; 255a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 25644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 2573040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf struct nlmsghdr *n, struct nl_parser_param *pp) 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct ifinfomsg *ifi; 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nlattr *tb[IFLA_MAX+1]; 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf link = rtnl_link_alloc(); 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link == NULL) { 2668a3efffa5b3fde252675239914118664d36a2c24Thomas Graf err = -NLE_NOMEM; 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_msgtype = n->nlmsg_type; 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy); 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_IFNAME] == NULL) { 2778a3efffa5b3fde252675239914118664d36a2c24Thomas Graf err = -NLE_MISSING_ATTR; 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ); 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi = nlmsg_data(n); 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_family = ifi->ifi_family; 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_arptype = ifi->ifi_type; 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_index = ifi->ifi_index; 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags = ifi->ifi_flags; 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_change = ifi->ifi_change; 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY | 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX | 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf LINK_ATTR_FLAGS | LINK_ATTR_CHANGE); 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_STATS]) { 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]); 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_PACKETS] = st->rx_packets; 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_BYTES] = st->rx_bytes; 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_ERRORS] = st->rx_errors; 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_DROPPED] = st->rx_dropped; 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_COMPRESSED] = st->rx_compressed; 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st->rx_fifo_errors; 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_PACKETS] = st->tx_packets; 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_BYTES] = st->tx_bytes; 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ERRORS] = st->tx_errors; 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_DROPPED] = st->tx_dropped; 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COMPRESSED] = st->tx_compressed; 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st->tx_fifo_errors; 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_LEN_ERR] = st->rx_length_errors; 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_OVER_ERR] = st->rx_over_errors; 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_CRC_ERR] = st->rx_crc_errors; 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st->rx_frame_errors; 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st->rx_missed_errors; 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st->tx_aborted_errors; 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st->tx_carrier_errors; 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st->tx_heartbeat_errors; 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_WIN_ERR] = st->tx_window_errors; 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_MULTICAST] = st->multicast; 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_STATS; 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_TXQLEN]) { 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_txqlen = nla_get_u32(tb[IFLA_TXQLEN]); 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_TXQLEN; 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MTU]) { 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_mtu = nla_get_u32(tb[IFLA_MTU]); 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MTU; 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_ADDRESS]) { 333eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf link->l_addr = nl_addr_alloc_attr(tb[IFLA_ADDRESS], AF_UNSPEC); 334eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf if (link->l_addr == NULL) { 335eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf err = -NLE_NOMEM; 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 337eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf } 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_set_family(link->l_addr, 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_guess_family(link->l_addr)); 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_ADDR; 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_BROADCAST]) { 344eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf link->l_bcast = nl_addr_alloc_attr(tb[IFLA_BROADCAST], 345eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf AF_UNSPEC); 346eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf if (link->l_bcast == NULL) { 347eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf err = -NLE_NOMEM; 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 349eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf } 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_set_family(link->l_bcast, 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_guess_family(link->l_bcast)); 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_BRD; 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_LINK]) { 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_link = nla_get_u32(tb[IFLA_LINK]); 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_LINK; 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_WEIGHT]) { 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]); 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_WEIGHT; 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_QDISC]) { 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ); 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_QDISC; 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MAP]) { 3710ca291d9e4ca1a9fd75982e7edb43325b40f5f10Thomas Graf nla_memcpy(&link->l_map, tb[IFLA_MAP], 3720ca291d9e4ca1a9fd75982e7edb43325b40f5f10Thomas Graf sizeof(struct rtnl_link_ifmap)); 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MAP; 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MASTER]) { 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_master = nla_get_u32(tb[IFLA_MASTER]); 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MASTER; 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf 3813ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tb[IFLA_OPERSTATE]) { 3823ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_operstate = nla_get_u8(tb[IFLA_OPERSTATE]); 3833ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_OPERSTATE; 3843ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf } 3853ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 3863ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tb[IFLA_LINKMODE]) { 3873ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_linkmode = nla_get_u8(tb[IFLA_LINKMODE]); 3883ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_LINKMODE; 3893ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf } 3903ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 391a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (tb[IFLA_LINKINFO]) { 392a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct nlattr *li[IFLA_INFO_MAX+1]; 393a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 394a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], 395a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf link_info_policy); 396a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (err < 0) 397a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto errout; 398a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 399a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (li[IFLA_INFO_KIND] && 400a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf (li[IFLA_INFO_DATA] || li[IFLA_INFO_XSTATS])) { 401a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link_info_ops *ops; 402a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf char *kind; 403a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 404a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf kind = nla_get_string(li[IFLA_INFO_KIND]); 405a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf ops = rtnl_link_info_ops_lookup(kind); 406a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (ops != NULL) { 407a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf ops->io_refcnt++; 408a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf link->l_info_ops = ops; 409a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf err = ops->io_parse(link, li[IFLA_INFO_DATA], 410a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf li[IFLA_INFO_XSTATS]); 411a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (err < 0) 412a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto errout; 413a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } else { 414a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf /* XXX: Warn about unparsed info? */ 415a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 416a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 417a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 418a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf err = pp->pp_cb((struct nl_object *) link, pp); 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf 423155ad439a49df034ec58ee4218834bc5b0120515Thomas Graf err = P_ACCEPT; 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf 42544d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf 43044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_request_update(struct nl_cache *c, struct nl_handle *h) 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_rtgen_request(h, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf 43544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_brief(struct nl_object *obj, struct nl_dump_params *p) 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf int line = 1; 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf 442a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf dp_dump(p, "%s %s ", link->l_name, 443a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 4443ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 4453ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->l_addr && !nl_addr_iszero(link->l_addr)) 4463ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf))); 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "master %s ", master ? master->l_name : "inv"); 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 457a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf dp_dump(p, "<%s> ", buf); 458a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 459a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 460a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 461a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf dp_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); 462a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (ll) 463a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf rtnl_link_put(ll); 464a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 465a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 466a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_BRIEF]) 467a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf line = link->l_info_ops->io_dump[NL_DUMP_BRIEF](link, p, line); 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf 47444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_full(struct nl_object *obj, struct nl_dump_params *p) 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf int line; 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf 48044d362409d5469aed47d19e7908d19bd194493aThomas Graf line = link_dump_brief(obj, p); 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(p, line++); 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf 4833ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, " mtu %u ", link->l_mtu); 4843ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "txqlen %u weight %u ", link->l_txqlen, link->l_weight); 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "qdisc %s ", link->l_qdisc); 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq) 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "irq %u ", link->l_map.lm_irq); 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFINDEX) 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "index %u ", link->l_index); 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4953ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 4963ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "\n"); 4973ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_new_line(p, line++); 4983ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 4993ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, " "); 5003ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 5023ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "brd %s ", nl_addr2str(link->l_bcast, buf, 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf sizeof(buf))); 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf 5053ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if ((link->ce_mask & LINK_ATTR_OPERSTATE) && 5063ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_operstate != IF_OPER_UNKNOWN) { 5073ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf rtnl_link_operstate2str(link->l_operstate, buf, sizeof(buf)); 5083ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "state %s ", buf); 5093ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf } 5103ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 5113ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf dp_dump(p, "mode %s\n", 5123ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf rtnl_link_mode2str(link->l_linkmode, buf, sizeof(buf))); 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf 514a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_FULL]) 515a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf line = link->l_info_ops->io_dump[NL_DUMP_FULL](link, p, line); 516a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf 52044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf char *unit, fmt[64]; 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf float res; 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf int line; 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf line = link_dump_full(obj, p); 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " Stats: bytes packets errors " 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf " dropped fifo-err compressed\n"); 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit); 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf 5347f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf strcpy(fmt, " RX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, fmt, 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf res, unit, 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_PACKETS], 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_ERRORS], 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_DROPPED], 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FIFO_ERR], 54344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_COMPRESSED]); 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit); 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf 5477f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf strcpy(fmt, " TX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, fmt, 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf res, unit, 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_PACKETS], 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ERRORS], 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_DROPPED], 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_FIFO_ERR], 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COMPRESSED]); 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " Errors: length over crc " 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf " frame missed multicast\n"); 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf 5617f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf dp_dump_line(p, line++, " RX %10" PRIu64 " %10" PRIu64 " %10" 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 "\n", 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_LEN_ERR], 56544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_OVER_ERR], 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_CRC_ERR], 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FRAME_ERR], 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_MISSED_ERR], 56944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_MULTICAST]); 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf 5717f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf dp_dump_line(p, line++, " aborted carrier heartbeat " 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf " window collision\n"); 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf 5747f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf dp_dump_line(p, line++, " TX %10" PRIu64 " %10" PRIu64 " %10" 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ABORT_ERR], 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_CARRIER_ERR], 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_HBEAT_ERR], 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_WIN_ERR], 58044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COLLISIONS]); 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf 582a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS]) 583a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf line = link->l_info_ops->io_dump[NL_DUMP_STATS](link, p, line); 584a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 58744d362409d5469aed47d19e7908d19bd194493aThomas Graf 58844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_xml(struct nl_object *obj, struct nl_dump_params *p) 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, line = 0; 59444d362409d5469aed47d19e7908d19bd194493aThomas Graf 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "<link name=\"%s\" index=\"%u\">\n", 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_name, link->l_index); 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <family>%s</family>\n", 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(link->l_family, buf, sizeof(buf))); 59944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <arptype>%s</arptype>\n", 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <address>%s</address>\n", 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_addr, buf, sizeof(buf))); 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <mtu>%u</mtu>\n", link->l_mtu); 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <txqlen>%u</txqlen>\n", link->l_txqlen); 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <weight>%u</weight>\n", link->l_weight); 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 60944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <flags>%s</flags>\n", buf); 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <qdisc>%s</qdisc>\n", link->l_qdisc); 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 61544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <link>%s</link>\n", 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf ll ? ll->l_name : "none"); 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 62444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <master>%s</master>\n", 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf master ? master->l_name : "none"); 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 62844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf 63044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <broadcast>%s</broadcast>\n", 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_bcast, buf, sizeof(buf))); 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_STATS) { 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <stats>\n"); 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) { 63744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_stat2str(i, buf, sizeof(buf)); 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf " <%s>%" PRIu64 "</%s>\n", 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, link->l_stats[i], buf); 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " </stats>\n"); 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf 645a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_XML]) { 646a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf dp_dump_line(p, line++, " <info>\n"); 647a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf line = link->l_info_ops->io_dump[NL_DUMP_XML](link, p, line); 648a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf dp_dump_line(p, line++, " </info>\n"); 649a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 650a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "</link>\n"); 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t l_change; /**< Change mask */ 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_lifmap l_map; /**< Interface device mapping */ 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 65944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf 66144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_env(struct nl_object *obj, struct nl_dump_params *p) 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, line = 0; 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf 66844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_NAME=%s\n", link->l_name); 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_IFINDEX=%u\n", link->l_index); 67044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_FAMILY=%s\n", 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(link->l_family, buf, sizeof(buf))); 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_TYPE=%s\n", 67344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 67444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_ADDRESS=%s\n", 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_addr, buf, sizeof(buf))); 67744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_MTU=%u\n", link->l_mtu); 67844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_TXQUEUELEN=%u\n", link->l_txqlen); 67944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_WEIGHT=%u\n", link->l_weight); 68044d362409d5469aed47d19e7908d19bd194493aThomas Graf 68144d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags & ~IFF_RUNNING, buf, sizeof(buf)); 68244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 68344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_FLAGS=%s\n", buf); 68444d362409d5469aed47d19e7908d19bd194493aThomas Graf 68544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 68644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_QDISC=%s\n", link->l_qdisc); 68744d362409d5469aed47d19e7908d19bd194493aThomas Graf 68844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 68944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 69044d362409d5469aed47d19e7908d19bd194493aThomas Graf 69144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_LINK_IFINDEX=%d\n", link->l_link); 69244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) { 69344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_LINK_IFNAME=%s\n", 69444d362409d5469aed47d19e7908d19bd194493aThomas Graf ll->l_name); 69544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 69644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 69744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 69844d362409d5469aed47d19e7908d19bd194493aThomas Graf 69944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 70044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 70144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_MASTER=%s\n", 70244d362409d5469aed47d19e7908d19bd194493aThomas Graf master ? master->l_name : "none"); 70344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 70444d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 70544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 70644d362409d5469aed47d19e7908d19bd194493aThomas Graf 70744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 70844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_BROADCAST=%s\n", 70944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_bcast, buf, sizeof(buf))); 71044d362409d5469aed47d19e7908d19bd194493aThomas Graf 71144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_STATS) { 71244d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) { 71344d362409d5469aed47d19e7908d19bd194493aThomas Graf char *c = buf; 71444d362409d5469aed47d19e7908d19bd194493aThomas Graf 71544d362409d5469aed47d19e7908d19bd194493aThomas Graf sprintf(buf, "LINK_"); 71644d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_stat2str(i, buf + 5, sizeof(buf) - 5); 71744d362409d5469aed47d19e7908d19bd194493aThomas Graf while (*c) { 71844d362409d5469aed47d19e7908d19bd194493aThomas Graf *c = toupper(*c); 71944d362409d5469aed47d19e7908d19bd194493aThomas Graf c++; 72044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 72144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, 72244d362409d5469aed47d19e7908d19bd194493aThomas Graf "%s=%" PRIu64 "\n", buf, link->l_stats[i]); 72344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 72444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 72544d362409d5469aed47d19e7908d19bd194493aThomas Graf 726a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_ENV]) 727a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf line = link->l_info_ops->io_dump[NL_DUMP_ENV](link, p, line); 728a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 72944d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 73044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 73144d362409d5469aed47d19e7908d19bd194493aThomas Graf 73244d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 73344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb) 73444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 73544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *l = (struct rtnl_link *) a; 73644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *c = dp_cache(a); 73744d362409d5469aed47d19e7908d19bd194493aThomas Graf int nevents = 0; 73844d362409d5469aed47d19e7908d19bd194493aThomas Graf 73944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change == ~0U) { 74044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->ce_msgtype == RTM_NEWLINK) 74144d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_register(l); 74244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 74344d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_unregister(l); 74444d362409d5469aed47d19e7908d19bd194493aThomas Graf 74544d362409d5469aed47d19e7908d19bd194493aThomas Graf return 1; 74644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 74744d362409d5469aed47d19e7908d19bd194493aThomas Graf 74844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_SLAVE) { 74944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_flags & IFF_SLAVE) { 75044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *m = rtnl_link_get(c, l->l_master); 75144d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_new_bonding(l, m); 75244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (m) 75344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(m); 75444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 75544d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_cancel_bonding(l); 75644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 75744d362409d5469aed47d19e7908d19bd194493aThomas Graf 75844d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 75944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING) 76044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s changed state to %s.\n", 76144d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_UP ? "up" : "down"); 76244d362409d5469aed47d19e7908d19bd194493aThomas Graf 76344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_PROMISC) { 76444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(p, line++); 76544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "link %s %s promiscuous mode.\n", 76644d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left"); 76744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 76844d362409d5469aed47d19e7908d19bd194493aThomas Graf 76944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (line == 0) 77044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s sent unknown event.\n", 77144d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name); 77244d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 77344d362409d5469aed47d19e7908d19bd194493aThomas Graf 77444d362409d5469aed47d19e7908d19bd194493aThomas Graf return nevents; 77544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 77644d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 77744d362409d5469aed47d19e7908d19bd194493aThomas Graf 77844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_compare(struct nl_object *_a, struct nl_object *_b, 77944d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 78044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 78144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *a = (struct rtnl_link *) _a; 78244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *b = (struct rtnl_link *) _b; 78344d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 78444d362409d5469aed47d19e7908d19bd194493aThomas Graf 78544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, LINK_ATTR_##ATTR, a, b, EXPR) 78644d362409d5469aed47d19e7908d19bd194493aThomas Graf 78744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index); 78844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu); 78944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(LINK, a->l_link != b->l_link); 79044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen); 79144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight); 79244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MASTER, a->l_master != b->l_master); 79344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FAMILY, a->l_family != b->l_family); 7943ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf diff |= LINK_DIFF(OPERSTATE, a->l_operstate != b->l_operstate); 7953ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf diff |= LINK_DIFF(LINKMODE, a->l_linkmode != b->l_linkmode); 79644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(QDISC, strcmp(a->l_qdisc, b->l_qdisc)); 79744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFNAME, strcmp(a->l_name, b->l_name)); 79844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(ADDR, nl_addr_cmp(a->l_addr, b->l_addr)); 79944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(BRD, nl_addr_cmp(a->l_bcast, b->l_bcast)); 80044d362409d5469aed47d19e7908d19bd194493aThomas Graf 801535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf if (flags & LOOSE_COMPARISON) 80244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, 80344d362409d5469aed47d19e7908d19bd194493aThomas Graf (a->l_flags ^ b->l_flags) & b->l_flag_mask); 80444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 80544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags); 80644d362409d5469aed47d19e7908d19bd194493aThomas Graf 80744d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef LINK_DIFF 80844d362409d5469aed47d19e7908d19bd194493aThomas Graf 80944d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 81044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 81144d362409d5469aed47d19e7908d19bd194493aThomas Graf 81244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_attrs[] = { 81344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MTU, mtu) 81444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_LINK, link) 81544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_TXQLEN, txqlen) 81644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_WEIGHT, weight) 81744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MASTER, master) 81844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_QDISC, qdisc) 81944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MAP, map) 82044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ADDR, address) 82144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_BRD, broadcast) 82244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FLAGS, flags) 82344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFNAME, name) 82444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFINDEX, ifindex) 82544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FAMILY, family) 82644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ARPTYPE, arptype) 82744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_STATS, stats) 82844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_CHANGE, change) 8293ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(LINK_ATTR_OPERSTATE, operstate) 8303ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(LINK_ATTR_LINKMODE, linkmode) 83144d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 83244d362409d5469aed47d19e7908d19bd194493aThomas Graf 83344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *link_attrs2str(int attrs, char *buf, size_t len) 83444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 83544d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, link_attrs, 83644d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_attrs)); 83744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 83844d362409d5469aed47d19e7908d19bd194493aThomas Graf 83944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 84044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 84144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 84244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 84344d362409d5469aed47d19e7908d19bd194493aThomas Graf 84444d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_alloc(void) 84544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 84644d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); 84744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 84844d362409d5469aed47d19e7908d19bd194493aThomas Graf 84944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_put(struct rtnl_link *link) 85044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 85144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) link); 85244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 85344d362409d5469aed47d19e7908d19bd194493aThomas Graf 85444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 85544d362409d5469aed47d19e7908d19bd194493aThomas Graf 85644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 85744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Cache Management 85844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 85944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 86044d362409d5469aed47d19e7908d19bd194493aThomas Graf 86144d362409d5469aed47d19e7908d19bd194493aThomas Graf 86244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 86344d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocate link cache and fill in all configured links. 86444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg handle Netlink handle. 8658a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * @arg result Pointer to store resulting cache. 86644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 86744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocates a new link cache, initializes it properly and updates it 86844d362409d5469aed47d19e7908d19bd194493aThomas Graf * to include all links currently configured in the kernel. 86944d362409d5469aed47d19e7908d19bd194493aThomas Graf * 8708a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * @return 0 on success or a negative error code. 87144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 8728a3efffa5b3fde252675239914118664d36a2c24Thomas Grafint rtnl_link_alloc_cache(struct nl_handle *sock, struct nl_cache **result) 87344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 8748a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return nl_cache_alloc_and_fill(&rtnl_link_ops, sock, result); 87544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 87644d362409d5469aed47d19e7908d19bd194493aThomas Graf 87744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 87844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by interface index in the provided cache 87944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 88044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 88144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 88244d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 88344d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 88444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 88544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 88644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 88744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) 88844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 88944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 89044d362409d5469aed47d19e7908d19bd194493aThomas Graf 89144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 89244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 89344d362409d5469aed47d19e7908d19bd194493aThomas Graf 89444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 89544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_index == ifindex) { 89644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 89744d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 89844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 89944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 90044d362409d5469aed47d19e7908d19bd194493aThomas Graf 90144d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 90244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 90344d362409d5469aed47d19e7908d19bd194493aThomas Graf 90444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 90544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by link name in the provided cache 90644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 90744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 90844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 90944d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 91044d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 91144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 91244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 91344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 91444d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, 91544d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *name) 91644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 91744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 91844d362409d5469aed47d19e7908d19bd194493aThomas Graf 91944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 92044d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 92144d362409d5469aed47d19e7908d19bd194493aThomas Graf 92244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 92344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcmp(name, link->l_name)) { 92444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 92544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 92644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 92744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 92844d362409d5469aed47d19e7908d19bd194493aThomas Graf 92944d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 93044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 93144d362409d5469aed47d19e7908d19bd194493aThomas Graf 93244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 93344d362409d5469aed47d19e7908d19bd194493aThomas Graf 93444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 93544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Modifications 93644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 93744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 93844d362409d5469aed47d19e7908d19bd194493aThomas Graf 93944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 94044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a netlink change request message to change link attributes 94144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 94244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 94344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 94444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 94544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message requesting a change of link attributes. 94644d362409d5469aed47d19e7908d19bd194493aThomas Graf * The netlink message header isn't fully equipped with all relevant 94744d362409d5469aed47d19e7908d19bd194493aThomas Graf * fields and must be sent out via nl_send_auto_complete() or 94844d362409d5469aed47d19e7908d19bd194493aThomas Graf * supplemented as needed. 94944d362409d5469aed47d19e7908d19bd194493aThomas Graf * \a old must point to a link currently configured in the kernel 95044d362409d5469aed47d19e7908d19bd194493aThomas Graf * and \a tmpl must contain the attributes to be changed set via 95144d362409d5469aed47d19e7908d19bd194493aThomas Graf * \c rtnl_link_set_* functions. 95244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 95344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return New netlink message 95444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 95544d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 95644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 9578a3efffa5b3fde252675239914118664d36a2c24Thomas Grafint rtnl_link_build_change_request(struct rtnl_link *old, 9588a3efffa5b3fde252675239914118664d36a2c24Thomas Graf struct rtnl_link *tmpl, int flags, 9598a3efffa5b3fde252675239914118664d36a2c24Thomas Graf struct nl_msg **result) 96044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 96144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 96244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct ifinfomsg ifi = { 96344d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_family = old->l_family, 96444d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_index = old->l_index, 96544d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 96644d362409d5469aed47d19e7908d19bd194493aThomas Graf 96744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_FLAGS) { 96844d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags = old->l_flags & ~tmpl->l_flag_mask; 96944d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags |= tmpl->l_flags; 97044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 97144d362409d5469aed47d19e7908d19bd194493aThomas Graf 97244d362409d5469aed47d19e7908d19bd194493aThomas Graf msg = nlmsg_alloc_simple(RTM_SETLINK, flags); 97344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!msg) 9748a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 97544d362409d5469aed47d19e7908d19bd194493aThomas Graf 97644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) 97744d362409d5469aed47d19e7908d19bd194493aThomas Graf goto nla_put_failure; 97844d362409d5469aed47d19e7908d19bd194493aThomas Graf 97944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_ADDR) 98044d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_ADDRESS, tmpl->l_addr); 98144d362409d5469aed47d19e7908d19bd194493aThomas Graf 98244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_BRD) 98344d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_BROADCAST, tmpl->l_bcast); 98444d362409d5469aed47d19e7908d19bd194493aThomas Graf 98544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_MTU) 98644d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_MTU, tmpl->l_mtu); 98744d362409d5469aed47d19e7908d19bd194493aThomas Graf 98844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_TXQLEN) 98944d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_TXQLEN, tmpl->l_txqlen); 99044d362409d5469aed47d19e7908d19bd194493aThomas Graf 99144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_WEIGHT) 99244d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_WEIGHT, tmpl->l_weight); 99344d362409d5469aed47d19e7908d19bd194493aThomas Graf 99444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_IFNAME) 99544d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_STRING(msg, IFLA_IFNAME, tmpl->l_name); 99644d362409d5469aed47d19e7908d19bd194493aThomas Graf 9973ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tmpl->ce_mask & LINK_ATTR_OPERSTATE) 9983ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf NLA_PUT_U8(msg, IFLA_OPERSTATE, tmpl->l_operstate); 9993ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 10003ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tmpl->ce_mask & LINK_ATTR_LINKMODE) 10013ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf NLA_PUT_U8(msg, IFLA_LINKMODE, tmpl->l_linkmode); 10023ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 1003a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((tmpl->ce_mask & LINK_ATTR_LINKINFO) && tmpl->l_info_ops && 1004a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf tmpl->l_info_ops->io_put_attrs) { 1005a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct nlattr *info; 1006a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1007a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (!(info = nla_nest_start(msg, IFLA_LINKINFO))) 1008a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto nla_put_failure; 1009a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1010a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf NLA_PUT_STRING(msg, IFLA_INFO_KIND, tmpl->l_info_ops->io_name); 1011a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1012a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (tmpl->l_info_ops->io_put_attrs(msg, tmpl) < 0) 1013a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto nla_put_failure; 1014a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1015a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf nla_nest_end(msg, info); 1016a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 1017a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 10188a3efffa5b3fde252675239914118664d36a2c24Thomas Graf *result = msg; 10198a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return 0; 102044d362409d5469aed47d19e7908d19bd194493aThomas Graf 102144d362409d5469aed47d19e7908d19bd194493aThomas Grafnla_put_failure: 102244d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 10238a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_MSGSIZE; 102444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 102544d362409d5469aed47d19e7908d19bd194493aThomas Graf 102644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 102744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Change link attributes 102844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg handle netlink handle 102944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 103044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 103144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 103244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 103344d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message by calling rtnl_link_build_change_request(), 103444d362409d5469aed47d19e7908d19bd194493aThomas Graf * sends the request to the kernel and waits for the next ACK to be 103544d362409d5469aed47d19e7908d19bd194493aThomas Graf * received, i.e. blocks until the request has been processed. 103644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 103744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code 103844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 103944d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 104044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 104144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_change(struct nl_handle *handle, struct rtnl_link *old, 104244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *tmpl, int flags) 104344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 104444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 10458a3efffa5b3fde252675239914118664d36a2c24Thomas Graf int err; 104644d362409d5469aed47d19e7908d19bd194493aThomas Graf 10478a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if ((err = rtnl_link_build_change_request(old, tmpl, flags, &msg)) < 0) 10488a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return err; 104944d362409d5469aed47d19e7908d19bd194493aThomas Graf 10508a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if ((err = nl_send_auto_complete(handle, msg)) < 0) 105144d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 105244d362409d5469aed47d19e7908d19bd194493aThomas Graf 105344d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 105444d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_wait_for_ack(handle); 105544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 105644d362409d5469aed47d19e7908d19bd194493aThomas Graf 105744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 105844d362409d5469aed47d19e7908d19bd194493aThomas Graf 105944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 106044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Name <-> Index Translations 106144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 106244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 106344d362409d5469aed47d19e7908d19bd194493aThomas Graf 106444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 106544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate an interface index to the corresponding link name 106644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 106744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 106844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg dst destination buffer 106944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg len length of destination buffer 107044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 107144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translates the specified interface index to the corresponding 107244d362409d5469aed47d19e7908d19bd194493aThomas Graf * link name and stores the name in the destination buffer. 107344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 107444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return link name or NULL if no match was found. 107544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 107644d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, 107744d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t len) 107844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 107944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = rtnl_link_get(cache, ifindex); 108044d362409d5469aed47d19e7908d19bd194493aThomas Graf 108144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 108244d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(dst, link->l_name, len - 1); 108344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 108444d362409d5469aed47d19e7908d19bd194493aThomas Graf return dst; 108544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 108644d362409d5469aed47d19e7908d19bd194493aThomas Graf 108744d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 108844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 108944d362409d5469aed47d19e7908d19bd194493aThomas Graf 109044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 109144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate a link name to the corresponding interface index 109244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 109344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 109444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1095b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf * @return interface index or 0 if no match was found. 109644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 109744d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_name2i(struct nl_cache *cache, const char *name) 109844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1099b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf int ifindex = 0; 110044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 110144d362409d5469aed47d19e7908d19bd194493aThomas Graf 110244d362409d5469aed47d19e7908d19bd194493aThomas Graf link = rtnl_link_get_by_name(cache, name); 110344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 110444d362409d5469aed47d19e7908d19bd194493aThomas Graf ifindex = link->l_index; 110544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 110644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 110744d362409d5469aed47d19e7908d19bd194493aThomas Graf 110844d362409d5469aed47d19e7908d19bd194493aThomas Graf return ifindex; 110944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 111044d362409d5469aed47d19e7908d19bd194493aThomas Graf 111144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 111244d362409d5469aed47d19e7908d19bd194493aThomas Graf 111344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 111444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Flags Translations 111544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 111644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 111744d362409d5469aed47d19e7908d19bd194493aThomas Graf 111844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_flags[] = { 111944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOOPBACK, loopback) 112044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_BROADCAST, broadcast) 112144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_POINTOPOINT, pointopoint) 112244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MULTICAST, multicast) 112344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOARP, noarp) 112444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_ALLMULTI, allmulti) 112544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PROMISC, promisc) 112644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MASTER, master) 112744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_SLAVE, slave) 112844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DEBUG, debug) 112944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DYNAMIC, dynamic) 113044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_AUTOMEDIA, automedia) 113144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PORTSEL, portsel) 113244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOTRAILERS, notrailers) 113344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_UP, up) 113444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_RUNNING, running) 113544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOWER_UP, lowerup) 113644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DORMANT, dormant) 1137195241473723527e2f30ac120087f106c607ce3eThomas Graf __ADD(IFF_ECHO, echo) 113844d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 113944d362409d5469aed47d19e7908d19bd194493aThomas Graf 114044d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_flags2str(int flags, char *buf, size_t len) 114144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 114244d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(flags, buf, len, link_flags, 114344d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_flags)); 114444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 114544d362409d5469aed47d19e7908d19bd194493aThomas Graf 114644d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2flags(const char *name) 114744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 114844d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); 114944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 115044d362409d5469aed47d19e7908d19bd194493aThomas Graf 115144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 115244d362409d5469aed47d19e7908d19bd194493aThomas Graf 115344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 115444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Statistics Translations 115544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 115644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 115744d362409d5469aed47d19e7908d19bd194493aThomas Graf 115844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_stats[] = { 115944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_PACKETS, rx_packets) 116044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_PACKETS, tx_packets) 116144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_BYTES, rx_bytes) 116244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_BYTES, tx_bytes) 116344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_ERRORS, rx_errors) 116444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ERRORS, tx_errors) 116544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_DROPPED, rx_dropped) 116644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_DROPPED, tx_dropped) 116744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed) 116844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed) 116944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err) 117044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err) 117144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err) 117244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err) 117344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err) 117444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err) 117544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err) 117644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err) 117744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err) 117844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err) 117944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err) 118044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COLLISIONS, tx_collision) 118144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_MULTICAST, multicast) 118244d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 118344d362409d5469aed47d19e7908d19bd194493aThomas Graf 118444d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_stat2str(int st, char *buf, size_t len) 118544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 118644d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); 118744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 118844d362409d5469aed47d19e7908d19bd194493aThomas Graf 118944d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2stat(const char *name) 119044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 119144d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); 119244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 119344d362409d5469aed47d19e7908d19bd194493aThomas Graf 119444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 119544d362409d5469aed47d19e7908d19bd194493aThomas Graf 119644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 11973ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @name Link Operstate Translations 11983ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @{ 11993ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf */ 12003ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12013ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafstatic struct trans_tbl link_operstates[] = { 12023ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_UNKNOWN, unknown) 12033ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_NOTPRESENT, notpresent) 12043ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_DOWN, down) 12053ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown) 12063ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_TESTING, testing) 12073ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_DORMANT, dormant) 12083ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_UP, up) 12093ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf}; 12103ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12113ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafchar *rtnl_link_operstate2str(int st, char *buf, size_t len) 12123ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 12133ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __type2str(st, buf, len, link_operstates, 12143ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf ARRAY_SIZE(link_operstates)); 12153ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 12163ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12173ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafint rtnl_link_str2operstate(const char *name) 12183ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 12193ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __str2type(name, link_operstates, 12203ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf ARRAY_SIZE(link_operstates)); 12213ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 12223ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12233ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** @} */ 12243ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12253ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** 12263ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @name Link Mode Translations 12273ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @{ 12283ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf */ 12293ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12303ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafstatic struct trans_tbl link_modes[] = { 12313ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_LINK_MODE_DEFAULT, default) 12323ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_LINK_MODE_DORMANT, dormant) 12333ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf}; 12343ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12353ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafchar *rtnl_link_mode2str(int st, char *buf, size_t len) 12363ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 12373ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes)); 12383ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 12393ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12403ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafint rtnl_link_str2mode(const char *name) 12413ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 12423ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __str2type(name, link_modes, ARRAY_SIZE(link_modes)); 12433ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 12443ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12453ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** @} */ 12463ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 12473ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** 124844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 124944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 125044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 125144d362409d5469aed47d19e7908d19bd194493aThomas Graf 125244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_qdisc(struct rtnl_link *link, const char *qdisc) 125344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 125444d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_qdisc, qdisc, sizeof(link->l_qdisc) - 1); 125544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_QDISC; 125644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 125744d362409d5469aed47d19e7908d19bd194493aThomas Graf 125844d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_qdisc(struct rtnl_link *link) 125944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 126044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 126144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_qdisc; 126244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 126344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 126444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 126544d362409d5469aed47d19e7908d19bd194493aThomas Graf 126644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_name(struct rtnl_link *link, const char *name) 126744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 126844d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_name, name, sizeof(link->l_name) - 1); 126944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFNAME; 127044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 127144d362409d5469aed47d19e7908d19bd194493aThomas Graf 127244d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_name(struct rtnl_link *link) 127344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 127444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFNAME) 127544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_name; 127644d362409d5469aed47d19e7908d19bd194493aThomas Graf else 127744d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 127844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 127944d362409d5469aed47d19e7908d19bd194493aThomas Graf 128044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, 128144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *new, int flag) 128244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 128344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*pos) 128444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(*pos); 128544d362409d5469aed47d19e7908d19bd194493aThomas Graf 128644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(new); 128744d362409d5469aed47d19e7908d19bd194493aThomas Graf *pos = new; 128844d362409d5469aed47d19e7908d19bd194493aThomas Graf 128944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= flag; 129044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 129144d362409d5469aed47d19e7908d19bd194493aThomas Graf 129244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr) 129344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 129444d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR); 129544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 129644d362409d5469aed47d19e7908d19bd194493aThomas Graf 129744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_addr(struct rtnl_link *link) 129844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 129944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 130044d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_addr; 130144d362409d5469aed47d19e7908d19bd194493aThomas Graf else 130244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 130344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 130444d362409d5469aed47d19e7908d19bd194493aThomas Graf 130544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *brd) 130644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 130744d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_bcast, brd, LINK_ATTR_BRD); 130844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 130944d362409d5469aed47d19e7908d19bd194493aThomas Graf 131044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link) 131144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 131244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 131344d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_bcast; 131444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 131544d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 131644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 131744d362409d5469aed47d19e7908d19bd194493aThomas Graf 131844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) 131944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 132044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 132144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags |= flags; 132244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 132344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 132444d362409d5469aed47d19e7908d19bd194493aThomas Graf 132544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) 132644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 132744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 132844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags &= ~flags; 132944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 133044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 133144d362409d5469aed47d19e7908d19bd194493aThomas Graf 133244d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_flags(struct rtnl_link *link) 133344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 133444d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_flags; 133544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 133644d362409d5469aed47d19e7908d19bd194493aThomas Graf 133744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_family(struct rtnl_link *link, int family) 133844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 133944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_family = family; 134044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FAMILY; 134144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 134244d362409d5469aed47d19e7908d19bd194493aThomas Graf 134344d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_family(struct rtnl_link *link) 134444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 134544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_family & LINK_ATTR_FAMILY) 134644d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_family; 134744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 134844d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 134944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 135044d362409d5469aed47d19e7908d19bd194493aThomas Graf 135144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype) 135244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 135344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_arptype = arptype; 135444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 135544d362409d5469aed47d19e7908d19bd194493aThomas Graf 135644d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_arptype(struct rtnl_link *link) 135744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 135844d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_arptype; 135944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 136044d362409d5469aed47d19e7908d19bd194493aThomas Graf 136144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex) 136244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 136344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_index = ifindex; 136444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFINDEX; 136544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 136644d362409d5469aed47d19e7908d19bd194493aThomas Graf 136744d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_ifindex(struct rtnl_link *link) 136844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1369b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_index; 137044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 137144d362409d5469aed47d19e7908d19bd194493aThomas Graf 137244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu) 137344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 137444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_mtu = mtu; 137544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MTU; 137644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 137744d362409d5469aed47d19e7908d19bd194493aThomas Graf 137844d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_mtu(struct rtnl_link *link) 137944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 138044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MTU) 138144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_mtu; 138244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 138344d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 138444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 138544d362409d5469aed47d19e7908d19bd194493aThomas Graf 138644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen) 138744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 138844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_txqlen = txqlen; 138944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_TXQLEN; 139044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 139144d362409d5469aed47d19e7908d19bd194493aThomas Graf 139244d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_txqlen(struct rtnl_link *link) 139344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 139444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_TXQLEN) 139544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_txqlen; 139644d362409d5469aed47d19e7908d19bd194493aThomas Graf else 139744d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 139844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 139944d362409d5469aed47d19e7908d19bd194493aThomas Graf 140044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) 140144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 140244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_weight = weight; 140344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_WEIGHT; 140444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 140544d362409d5469aed47d19e7908d19bd194493aThomas Graf 140644d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_weight(struct rtnl_link *link) 140744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 140844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_WEIGHT) 140944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_weight; 141044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 141144d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 141244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 141344d362409d5469aed47d19e7908d19bd194493aThomas Graf 141444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_link(struct rtnl_link *link, int ifindex) 141544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 141644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_link = ifindex; 141744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_LINK; 141844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 141944d362409d5469aed47d19e7908d19bd194493aThomas Graf 142044d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_link(struct rtnl_link *link) 142144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1422b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_link; 142344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 142444d362409d5469aed47d19e7908d19bd194493aThomas Graf 142544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_master(struct rtnl_link *link, int ifindex) 142644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 142744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_master = ifindex; 142844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MASTER; 142944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 143044d362409d5469aed47d19e7908d19bd194493aThomas Graf 143144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_master(struct rtnl_link *link) 143244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1433b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_master; 143444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 143544d362409d5469aed47d19e7908d19bd194493aThomas Graf 14363ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafvoid rtnl_link_set_operstate(struct rtnl_link *link, uint8_t operstate) 14373ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 14383ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_operstate = operstate; 14393ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_OPERSTATE; 14403ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 14413ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 14423ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafuint8_t rtnl_link_get_operstate(struct rtnl_link *link) 14433ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 14443ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->ce_mask & LINK_ATTR_OPERSTATE) 14453ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return link->l_operstate; 14463ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf else 14473ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return IF_OPER_UNKNOWN; 14483ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 14493ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 14503ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafvoid rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t linkmode) 14513ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 14523ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_linkmode = linkmode; 14533ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_LINKMODE; 14543ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 14553ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 14563ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafuint8_t rtnl_link_get_linkmode(struct rtnl_link *link) 14573ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 14583ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->ce_mask & LINK_ATTR_LINKMODE) 14593ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return link->l_linkmode; 14603ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf else 14613ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return IF_LINK_MODE_DEFAULT; 14623ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 14633ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 146444d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t rtnl_link_get_stat(struct rtnl_link *link, int id) 146544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 146644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (id < 0 || id > RTNL_LINK_STATS_MAX) 146744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 146844d362409d5469aed47d19e7908d19bd194493aThomas Graf 146944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_stats[id]; 147044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 147144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1472a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf/** 1473a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Specify the info type of a link 1474a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg link link object 1475a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg type info type 1476a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1477a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Looks up the info type and prepares the link to store info type 1478a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * specific attributes. If an info type has been assigned already 1479a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * it will be released with all changes lost. 1480a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1481a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @return 0 on success or a negative errror code. 1482a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf */ 1483a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafint rtnl_link_set_info_type(struct rtnl_link *link, const char *type) 1484a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf{ 1485a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link_info_ops *io; 1486a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf int err; 1487a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1488a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((io = rtnl_link_info_ops_lookup(type)) == NULL) 14898a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_OPNOTSUPP; 1490a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1491a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops) 1492a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf release_link_info(link); 1493a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1494a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((err = io->io_alloc(link)) < 0) 1495a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return err; 1496a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1497a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf link->l_info_ops = io; 1498a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1499a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return 0; 1500a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf} 1501a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1502a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf/** 1503a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Return info type of a link 1504a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg link link object 1505a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1506a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @note The returned pointer is only valid as long as the link exists 1507a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @return Info type name or NULL if unknown. 1508a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf */ 1509a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafchar *rtnl_link_get_info_type(struct rtnl_link *link) 1510a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf{ 1511a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops) 1512a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return link->l_info_ops->io_name; 1513a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf else 1514a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return NULL; 1515a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf} 1516a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 151744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 151844d362409d5469aed47d19e7908d19bd194493aThomas Graf 151944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops link_obj_ops = { 152044d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "route/link", 152144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct rtnl_link), 152244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = link_free_data, 152344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = link_clone, 152444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_BRIEF] = link_dump_brief, 152544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_FULL] = link_dump_full, 152644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_STATS] = link_dump_stats, 152744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_XML] = link_dump_xml, 152844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_ENV] = link_dump_env, 152944d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = link_compare, 153044d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = link_attrs2str, 153144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_id_attrs = LINK_ATTR_IFINDEX, 153244d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 153344d362409d5469aed47d19e7908d19bd194493aThomas Graf 153444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_af_group link_groups[] = { 153544d362409d5469aed47d19e7908d19bd194493aThomas Graf { AF_UNSPEC, RTNLGRP_LINK }, 153644d362409d5469aed47d19e7908d19bd194493aThomas Graf { END_OF_GROUP_LIST }, 153744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 153844d362409d5469aed47d19e7908d19bd194493aThomas Graf 153944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops rtnl_link_ops = { 154044d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_name = "route/link", 154144d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_hdrsize = sizeof(struct ifinfomsg), 154244d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msgtypes = { 154344d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_NEWLINK, NL_ACT_NEW, "new" }, 154444d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_DELLINK, NL_ACT_DEL, "del" }, 154544d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_GETLINK, NL_ACT_GET, "get" }, 154644d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, 154744d362409d5469aed47d19e7908d19bd194493aThomas Graf }, 154844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_protocol = NETLINK_ROUTE, 154944d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_groups = link_groups, 155044d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_request_update = link_request_update, 155144d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msg_parser = link_msg_parser, 155244d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_obj_ops = &link_obj_ops, 155344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 155444d362409d5469aed47d19e7908d19bd194493aThomas Graf 155544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __init link_init(void) 155644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 155744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_register(&rtnl_link_ops); 155844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 155944d362409d5469aed47d19e7908d19bd194493aThomas Graf 156044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __exit link_exit(void) 156144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 156244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_unregister(&rtnl_link_ops); 156344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 156444d362409d5469aed47d19e7908d19bd194493aThomas Graf 156544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 1566