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. 811155370f520cb64657e25153255cf7dc1424317fThomas Graf * struct nl_cache *cache = rtnl_link_alloc_cache(sk); 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: 1151155370f520cb64657e25153255cf7dc1424317fThomas Graf * rtnl_link_change(sk, 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); 1201155370f520cb64657e25153255cf7dc1424317fThomas Graf * nl_send_auto_complete(sk, 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 Graferrout: 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4251155370f520cb64657e25153255cf7dc1424317fThomas Grafstatic int link_request_update(struct nl_cache *cache, struct nl_sock *sk) 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 4271155370f520cb64657e25153255cf7dc1424317fThomas Graf return nl_rtgen_request(sk, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf 430d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void link_dump_line(struct nl_object *obj, struct nl_dump_params *p) 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf 436d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "%s %s ", link->l_name, 437d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 4383ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 4393ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->l_addr && !nl_addr_iszero(link->l_addr)) 440d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf))); 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 44344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 444d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "master %s ", master ? master->l_name : "inv"); 44544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 451d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "<%s> ", buf); 452a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 453a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 454a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 455d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE"); 456a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (ll) 457a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf rtnl_link_put(ll); 458a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 459a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 460d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_LINE]) 461d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link->l_info_ops->io_dump[NL_DUMP_LINE](link, p); 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf 463d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "\n"); 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46544d362409d5469aed47d19e7908d19bd194493aThomas Graf 466d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void link_dump_details(struct nl_object *obj, struct nl_dump_params *p) 46744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf 471d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link_dump_line(obj, p); 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf 473d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " mtu %u ", link->l_mtu); 474d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "txqlen %u weight %u ", link->l_txqlen, link->l_weight); 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 477d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "qdisc %s ", link->l_qdisc); 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq) 480d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "irq %u ", link->l_map.lm_irq); 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFINDEX) 483d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "index %u ", link->l_index); 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4853ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 486d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "\n"); 487d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " "); 4883ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 490d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "brd %s ", nl_addr2str(link->l_bcast, buf, 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf sizeof(buf))); 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf 4933ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if ((link->ce_mask & LINK_ATTR_OPERSTATE) && 4943ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_operstate != IF_OPER_UNKNOWN) { 4953ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf rtnl_link_operstate2str(link->l_operstate, buf, sizeof(buf)); 496d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "state %s ", buf); 4973ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf } 4983ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 499d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "mode %s\n", 5003ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf rtnl_link_mode2str(link->l_linkmode, buf, sizeof(buf))); 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf 502d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS]) 503d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p); 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf 506d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf char *unit, fmt[64]; 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf float res; 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf 512d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link_dump_details(obj, p); 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf 514d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " Stats: bytes packets errors " 515d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf " dropped fifo-err compressed\n"); 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit); 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf 5197f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf strcpy(fmt, " RX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf 522d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, fmt, res, unit, 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_PACKETS], 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_ERRORS], 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_DROPPED], 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FIFO_ERR], 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_COMPRESSED]); 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit); 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf 5317f6b7a8eea0334b34d58dec72c66121a76f08958Thomas Graf strcpy(fmt, " TX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf 534d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, fmt, res, unit, 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_PACKETS], 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ERRORS], 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_DROPPED], 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_FIFO_ERR], 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COMPRESSED]); 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf 541d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " Errors: length over crc " 542d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf " frame missed multicast\n"); 54344d362409d5469aed47d19e7908d19bd194493aThomas Graf 544d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " RX %10" PRIu64 " %10" PRIu64 " %10" 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 "\n", 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_LEN_ERR], 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_OVER_ERR], 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_CRC_ERR], 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FRAME_ERR], 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_MISSED_ERR], 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_MULTICAST]); 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf 554d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " aborted carrier heartbeat " 555d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf " window collision\n"); 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf 557d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " TX %10" PRIu64 " %10" PRIu64 " %10" 558d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ABORT_ERR], 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_CARRIER_ERR], 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_HBEAT_ERR], 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_WIN_ERR], 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COLLISIONS]); 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf 565a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS]) 566d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link->l_info_ops->io_dump[NL_DUMP_STATS](link, p); 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf 569d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void link_dump_env(struct nl_object *obj, struct nl_dump_params *p) 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 574d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf int i; 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf 576d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_NAME=%s\n", link->l_name); 577d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_IFINDEX=%u\n", link->l_index); 578d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_FAMILY=%s\n", 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(link->l_family, buf, sizeof(buf))); 580d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_TYPE=%s\n", 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 583d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_ADDRESS=%s\n", 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_addr, buf, sizeof(buf))); 585d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_MTU=%u\n", link->l_mtu); 586d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_TXQUEUELEN=%u\n", link->l_txqlen); 587d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_WEIGHT=%u\n", link->l_weight); 58844d362409d5469aed47d19e7908d19bd194493aThomas Graf 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags & ~IFF_RUNNING, buf, sizeof(buf)); 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 591d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_FLAGS=%s\n", buf); 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 594d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_QDISC=%s\n", link->l_qdisc); 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf 599d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_LINK_IFINDEX=%d\n", link->l_link); 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) { 601d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_LINK_IFNAME=%s\n", ll->l_name); 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 608d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_MASTER=%s\n", 60944d362409d5469aed47d19e7908d19bd194493aThomas Graf master ? master->l_name : "none"); 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 615d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "LINK_BROADCAST=%s\n", 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_bcast, buf, sizeof(buf))); 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_STATS) { 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) { 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf char *c = buf; 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf sprintf(buf, "LINK_"); 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_stat2str(i, buf + 5, sizeof(buf) - 5); 62444d362409d5469aed47d19e7908d19bd194493aThomas Graf while (*c) { 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf *c = toupper(*c); 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf c++; 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 628d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "%s=%" PRIu64 "\n", buf, link->l_stats[i]); 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 63044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf 632a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_ENV]) 633d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf link->l_info_ops->io_dump[NL_DUMP_ENV](link, p); 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 63744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb) 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *l = (struct rtnl_link *) a; 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *c = dp_cache(a); 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf int nevents = 0; 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change == ~0U) { 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->ce_msgtype == RTM_NEWLINK) 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_register(l); 64644d362409d5469aed47d19e7908d19bd194493aThomas Graf else 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_unregister(l); 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf 64944d362409d5469aed47d19e7908d19bd194493aThomas Graf return 1; 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_SLAVE) { 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_flags & IFF_SLAVE) { 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *m = rtnl_link_get(c, l->l_master); 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_new_bonding(l, m); 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (m) 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(m); 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 65944d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_cancel_bonding(l); 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING) 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s changed state to %s.\n", 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_UP ? "up" : "down"); 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_PROMISC) { 66844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(p, line++); 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "link %s %s promiscuous mode.\n", 67044d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left"); 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf 67344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (line == 0) 67444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s sent unknown event.\n", 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name); 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 67744d362409d5469aed47d19e7908d19bd194493aThomas Graf 67844d362409d5469aed47d19e7908d19bd194493aThomas Graf return nevents; 67944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 68044d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 68144d362409d5469aed47d19e7908d19bd194493aThomas Graf 68244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_compare(struct nl_object *_a, struct nl_object *_b, 68344d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 68444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 68544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *a = (struct rtnl_link *) _a; 68644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *b = (struct rtnl_link *) _b; 68744d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 68844d362409d5469aed47d19e7908d19bd194493aThomas Graf 68944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, LINK_ATTR_##ATTR, a, b, EXPR) 69044d362409d5469aed47d19e7908d19bd194493aThomas Graf 69144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index); 69244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu); 69344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(LINK, a->l_link != b->l_link); 69444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen); 69544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight); 69644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MASTER, a->l_master != b->l_master); 69744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FAMILY, a->l_family != b->l_family); 6983ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf diff |= LINK_DIFF(OPERSTATE, a->l_operstate != b->l_operstate); 6993ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf diff |= LINK_DIFF(LINKMODE, a->l_linkmode != b->l_linkmode); 70044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(QDISC, strcmp(a->l_qdisc, b->l_qdisc)); 70144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFNAME, strcmp(a->l_name, b->l_name)); 70244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(ADDR, nl_addr_cmp(a->l_addr, b->l_addr)); 70344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(BRD, nl_addr_cmp(a->l_bcast, b->l_bcast)); 70444d362409d5469aed47d19e7908d19bd194493aThomas Graf 705535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf if (flags & LOOSE_COMPARISON) 70644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, 70744d362409d5469aed47d19e7908d19bd194493aThomas Graf (a->l_flags ^ b->l_flags) & b->l_flag_mask); 70844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 70944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags); 71044d362409d5469aed47d19e7908d19bd194493aThomas Graf 71144d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef LINK_DIFF 71244d362409d5469aed47d19e7908d19bd194493aThomas Graf 71344d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 71444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 71544d362409d5469aed47d19e7908d19bd194493aThomas Graf 71644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_attrs[] = { 71744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MTU, mtu) 71844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_LINK, link) 71944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_TXQLEN, txqlen) 72044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_WEIGHT, weight) 72144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MASTER, master) 72244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_QDISC, qdisc) 72344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MAP, map) 72444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ADDR, address) 72544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_BRD, broadcast) 72644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FLAGS, flags) 72744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFNAME, name) 72844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFINDEX, ifindex) 72944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FAMILY, family) 73044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ARPTYPE, arptype) 73144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_STATS, stats) 73244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_CHANGE, change) 7333ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(LINK_ATTR_OPERSTATE, operstate) 7343ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(LINK_ATTR_LINKMODE, linkmode) 73544d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 73644d362409d5469aed47d19e7908d19bd194493aThomas Graf 73744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *link_attrs2str(int attrs, char *buf, size_t len) 73844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 73944d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, link_attrs, 74044d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_attrs)); 74144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 74244d362409d5469aed47d19e7908d19bd194493aThomas Graf 74344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 74444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 74544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 74644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 74744d362409d5469aed47d19e7908d19bd194493aThomas Graf 74844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_alloc(void) 74944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 75044d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); 75144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 75244d362409d5469aed47d19e7908d19bd194493aThomas Graf 75344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_put(struct rtnl_link *link) 75444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 75544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) link); 75644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 75744d362409d5469aed47d19e7908d19bd194493aThomas Graf 75844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 75944d362409d5469aed47d19e7908d19bd194493aThomas Graf 76044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 76144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Cache Management 76244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 76344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 76444d362409d5469aed47d19e7908d19bd194493aThomas Graf 76544d362409d5469aed47d19e7908d19bd194493aThomas Graf 76644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 76744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocate link cache and fill in all configured links. 7681155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 7698a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * @arg result Pointer to store resulting cache. 77044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 77144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocates a new link cache, initializes it properly and updates it 77244d362409d5469aed47d19e7908d19bd194493aThomas Graf * to include all links currently configured in the kernel. 77344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 7748a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * @return 0 on success or a negative error code. 77544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 7761155370f520cb64657e25153255cf7dc1424317fThomas Grafint rtnl_link_alloc_cache(struct nl_sock *sk, struct nl_cache **result) 77744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7781155370f520cb64657e25153255cf7dc1424317fThomas Graf return nl_cache_alloc_and_fill(&rtnl_link_ops, sk, result); 77944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 78044d362409d5469aed47d19e7908d19bd194493aThomas Graf 78144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 78244d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by interface index in the provided cache 78344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 78444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 78544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 78644d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 78744d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 78844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 78944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 79044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 79144d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) 79244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 79344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 79444d362409d5469aed47d19e7908d19bd194493aThomas Graf 79544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 79644d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 79744d362409d5469aed47d19e7908d19bd194493aThomas Graf 79844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 79944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_index == ifindex) { 80044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 80144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 80244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 80344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 80444d362409d5469aed47d19e7908d19bd194493aThomas Graf 80544d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 80644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 80744d362409d5469aed47d19e7908d19bd194493aThomas Graf 80844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 80944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by link name in the provided cache 81044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 81144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 81244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 81344d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 81444d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 81544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 81644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 81744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 81844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, 81944d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *name) 82044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 82144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 82244d362409d5469aed47d19e7908d19bd194493aThomas Graf 82344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 82444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 82544d362409d5469aed47d19e7908d19bd194493aThomas Graf 82644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 82744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcmp(name, link->l_name)) { 82844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 82944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 83044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 83144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 83244d362409d5469aed47d19e7908d19bd194493aThomas Graf 83344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 83444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 83544d362409d5469aed47d19e7908d19bd194493aThomas Graf 83644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 83744d362409d5469aed47d19e7908d19bd194493aThomas Graf 83844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 83944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Modifications 84044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 84144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 84244d362409d5469aed47d19e7908d19bd194493aThomas Graf 84344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 84444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a netlink change request message to change link attributes 84544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 84644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 84744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 84844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 84944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message requesting a change of link attributes. 85044d362409d5469aed47d19e7908d19bd194493aThomas Graf * The netlink message header isn't fully equipped with all relevant 85144d362409d5469aed47d19e7908d19bd194493aThomas Graf * fields and must be sent out via nl_send_auto_complete() or 85244d362409d5469aed47d19e7908d19bd194493aThomas Graf * supplemented as needed. 85344d362409d5469aed47d19e7908d19bd194493aThomas Graf * \a old must point to a link currently configured in the kernel 85444d362409d5469aed47d19e7908d19bd194493aThomas Graf * and \a tmpl must contain the attributes to be changed set via 85544d362409d5469aed47d19e7908d19bd194493aThomas Graf * \c rtnl_link_set_* functions. 85644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 85744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return New netlink message 85844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 85944d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 86044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 8618a3efffa5b3fde252675239914118664d36a2c24Thomas Grafint rtnl_link_build_change_request(struct rtnl_link *old, 8628a3efffa5b3fde252675239914118664d36a2c24Thomas Graf struct rtnl_link *tmpl, int flags, 8638a3efffa5b3fde252675239914118664d36a2c24Thomas Graf struct nl_msg **result) 86444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 86544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 86644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct ifinfomsg ifi = { 86744d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_family = old->l_family, 86844d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_index = old->l_index, 86944d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 87044d362409d5469aed47d19e7908d19bd194493aThomas Graf 87144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_FLAGS) { 87244d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags = old->l_flags & ~tmpl->l_flag_mask; 87344d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags |= tmpl->l_flags; 87444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 87544d362409d5469aed47d19e7908d19bd194493aThomas Graf 87644d362409d5469aed47d19e7908d19bd194493aThomas Graf msg = nlmsg_alloc_simple(RTM_SETLINK, flags); 87744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!msg) 8788a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 87944d362409d5469aed47d19e7908d19bd194493aThomas Graf 88044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) 88144d362409d5469aed47d19e7908d19bd194493aThomas Graf goto nla_put_failure; 88244d362409d5469aed47d19e7908d19bd194493aThomas Graf 88344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_ADDR) 88444d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_ADDRESS, tmpl->l_addr); 88544d362409d5469aed47d19e7908d19bd194493aThomas Graf 88644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_BRD) 88744d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_BROADCAST, tmpl->l_bcast); 88844d362409d5469aed47d19e7908d19bd194493aThomas Graf 88944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_MTU) 89044d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_MTU, tmpl->l_mtu); 89144d362409d5469aed47d19e7908d19bd194493aThomas Graf 89244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_TXQLEN) 89344d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_TXQLEN, tmpl->l_txqlen); 89444d362409d5469aed47d19e7908d19bd194493aThomas Graf 89544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_WEIGHT) 89644d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_WEIGHT, tmpl->l_weight); 89744d362409d5469aed47d19e7908d19bd194493aThomas Graf 89844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_IFNAME) 89944d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_STRING(msg, IFLA_IFNAME, tmpl->l_name); 90044d362409d5469aed47d19e7908d19bd194493aThomas Graf 9013ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tmpl->ce_mask & LINK_ATTR_OPERSTATE) 9023ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf NLA_PUT_U8(msg, IFLA_OPERSTATE, tmpl->l_operstate); 9033ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 9043ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (tmpl->ce_mask & LINK_ATTR_LINKMODE) 9053ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf NLA_PUT_U8(msg, IFLA_LINKMODE, tmpl->l_linkmode); 9063ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 907a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((tmpl->ce_mask & LINK_ATTR_LINKINFO) && tmpl->l_info_ops && 908a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf tmpl->l_info_ops->io_put_attrs) { 909a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct nlattr *info; 910a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 911a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (!(info = nla_nest_start(msg, IFLA_LINKINFO))) 912a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto nla_put_failure; 913a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 914a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf NLA_PUT_STRING(msg, IFLA_INFO_KIND, tmpl->l_info_ops->io_name); 915a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 916a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (tmpl->l_info_ops->io_put_attrs(msg, tmpl) < 0) 917a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf goto nla_put_failure; 918a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 919a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf nla_nest_end(msg, info); 920a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf } 921a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 9228a3efffa5b3fde252675239914118664d36a2c24Thomas Graf *result = msg; 9238a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return 0; 92444d362409d5469aed47d19e7908d19bd194493aThomas Graf 92544d362409d5469aed47d19e7908d19bd194493aThomas Grafnla_put_failure: 92644d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 9278a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_MSGSIZE; 92844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 92944d362409d5469aed47d19e7908d19bd194493aThomas Graf 93044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 93144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Change link attributes 9321155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 93344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 93444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 93544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 93644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 93744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message by calling rtnl_link_build_change_request(), 93844d362409d5469aed47d19e7908d19bd194493aThomas Graf * sends the request to the kernel and waits for the next ACK to be 93944d362409d5469aed47d19e7908d19bd194493aThomas Graf * received, i.e. blocks until the request has been processed. 94044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 94144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code 94244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 94344d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 94444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 9451155370f520cb64657e25153255cf7dc1424317fThomas Grafint rtnl_link_change(struct nl_sock *sk, struct rtnl_link *old, 94644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *tmpl, int flags) 94744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 94844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 9498a3efffa5b3fde252675239914118664d36a2c24Thomas Graf int err; 95044d362409d5469aed47d19e7908d19bd194493aThomas Graf 9518a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if ((err = rtnl_link_build_change_request(old, tmpl, flags, &msg)) < 0) 9528a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return err; 95344d362409d5469aed47d19e7908d19bd194493aThomas Graf 954ef50a38fbd8682a5c9efd559e7db68664977f080Thomas Graf err = nl_send_auto_complete(sk, msg); 955ef50a38fbd8682a5c9efd559e7db68664977f080Thomas Graf nlmsg_free(msg); 956ef50a38fbd8682a5c9efd559e7db68664977f080Thomas Graf if (err < 0) 95744d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 95844d362409d5469aed47d19e7908d19bd194493aThomas Graf 959cfcfca070355b246028df60da79813f09ed65755Thomas Graf return wait_for_ack(sk); 96044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 96144d362409d5469aed47d19e7908d19bd194493aThomas Graf 96244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 96344d362409d5469aed47d19e7908d19bd194493aThomas Graf 96444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 96544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Name <-> Index Translations 96644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 96744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 96844d362409d5469aed47d19e7908d19bd194493aThomas Graf 96944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 97044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate an interface index to the corresponding link name 97144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 97244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 97344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg dst destination buffer 97444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg len length of destination buffer 97544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 97644d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translates the specified interface index to the corresponding 97744d362409d5469aed47d19e7908d19bd194493aThomas Graf * link name and stores the name in the destination buffer. 97844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 97944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return link name or NULL if no match was found. 98044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 98144d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, 98244d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t len) 98344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 98444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = rtnl_link_get(cache, ifindex); 98544d362409d5469aed47d19e7908d19bd194493aThomas Graf 98644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 98744d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(dst, link->l_name, len - 1); 98844d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 98944d362409d5469aed47d19e7908d19bd194493aThomas Graf return dst; 99044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 99144d362409d5469aed47d19e7908d19bd194493aThomas Graf 99244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 99344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 99444d362409d5469aed47d19e7908d19bd194493aThomas Graf 99544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 99644d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate a link name to the corresponding interface index 99744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 99844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 99944d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1000b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf * @return interface index or 0 if no match was found. 100144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 100244d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_name2i(struct nl_cache *cache, const char *name) 100344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1004b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf int ifindex = 0; 100544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 100644d362409d5469aed47d19e7908d19bd194493aThomas Graf 100744d362409d5469aed47d19e7908d19bd194493aThomas Graf link = rtnl_link_get_by_name(cache, name); 100844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 100944d362409d5469aed47d19e7908d19bd194493aThomas Graf ifindex = link->l_index; 101044d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 101144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 101244d362409d5469aed47d19e7908d19bd194493aThomas Graf 101344d362409d5469aed47d19e7908d19bd194493aThomas Graf return ifindex; 101444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 101544d362409d5469aed47d19e7908d19bd194493aThomas Graf 101644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 101744d362409d5469aed47d19e7908d19bd194493aThomas Graf 101844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 101944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Flags Translations 102044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 102144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 102244d362409d5469aed47d19e7908d19bd194493aThomas Graf 102344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_flags[] = { 102444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOOPBACK, loopback) 102544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_BROADCAST, broadcast) 102644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_POINTOPOINT, pointopoint) 102744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MULTICAST, multicast) 102844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOARP, noarp) 102944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_ALLMULTI, allmulti) 103044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PROMISC, promisc) 103144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MASTER, master) 103244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_SLAVE, slave) 103344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DEBUG, debug) 103444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DYNAMIC, dynamic) 103544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_AUTOMEDIA, automedia) 103644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PORTSEL, portsel) 103744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOTRAILERS, notrailers) 103844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_UP, up) 103944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_RUNNING, running) 104044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOWER_UP, lowerup) 104144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DORMANT, dormant) 1042195241473723527e2f30ac120087f106c607ce3eThomas Graf __ADD(IFF_ECHO, echo) 104344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 104444d362409d5469aed47d19e7908d19bd194493aThomas Graf 104544d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_flags2str(int flags, char *buf, size_t len) 104644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 104744d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(flags, buf, len, link_flags, 104844d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_flags)); 104944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 105044d362409d5469aed47d19e7908d19bd194493aThomas Graf 105144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2flags(const char *name) 105244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 105344d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); 105444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 105544d362409d5469aed47d19e7908d19bd194493aThomas Graf 105644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 105744d362409d5469aed47d19e7908d19bd194493aThomas Graf 105844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 105944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Statistics Translations 106044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 106144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 106244d362409d5469aed47d19e7908d19bd194493aThomas Graf 106344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_stats[] = { 106444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_PACKETS, rx_packets) 106544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_PACKETS, tx_packets) 106644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_BYTES, rx_bytes) 106744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_BYTES, tx_bytes) 106844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_ERRORS, rx_errors) 106944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ERRORS, tx_errors) 107044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_DROPPED, rx_dropped) 107144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_DROPPED, tx_dropped) 107244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed) 107344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed) 107444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err) 107544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err) 107644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err) 107744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err) 107844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err) 107944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err) 108044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err) 108144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err) 108244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err) 108344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err) 108444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err) 108544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COLLISIONS, tx_collision) 108644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_MULTICAST, multicast) 108744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 108844d362409d5469aed47d19e7908d19bd194493aThomas Graf 108944d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_stat2str(int st, char *buf, size_t len) 109044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 109144d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); 109244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 109344d362409d5469aed47d19e7908d19bd194493aThomas Graf 109444d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2stat(const char *name) 109544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 109644d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); 109744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 109844d362409d5469aed47d19e7908d19bd194493aThomas Graf 109944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 110044d362409d5469aed47d19e7908d19bd194493aThomas Graf 110144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 11023ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @name Link Operstate Translations 11033ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @{ 11043ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf */ 11053ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11063ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafstatic struct trans_tbl link_operstates[] = { 11073ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_UNKNOWN, unknown) 11083ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_NOTPRESENT, notpresent) 11093ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_DOWN, down) 11103ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown) 11113ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_TESTING, testing) 11123ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_DORMANT, dormant) 11133ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_OPER_UP, up) 11143ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf}; 11153ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11163ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafchar *rtnl_link_operstate2str(int st, char *buf, size_t len) 11173ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 11183ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __type2str(st, buf, len, link_operstates, 11193ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf ARRAY_SIZE(link_operstates)); 11203ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 11213ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11223ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafint rtnl_link_str2operstate(const char *name) 11233ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 11243ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __str2type(name, link_operstates, 11253ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf ARRAY_SIZE(link_operstates)); 11263ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 11273ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11283ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** @} */ 11293ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11303ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** 11313ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @name Link Mode Translations 11323ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf * @{ 11333ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf */ 11343ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11353ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafstatic struct trans_tbl link_modes[] = { 11363ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_LINK_MODE_DEFAULT, default) 11373ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf __ADD(IF_LINK_MODE_DORMANT, dormant) 11383ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf}; 11393ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11403ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafchar *rtnl_link_mode2str(int st, char *buf, size_t len) 11413ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 11423ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes)); 11433ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 11443ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11453ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafint rtnl_link_str2mode(const char *name) 11463ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 11473ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return __str2type(name, link_modes, ARRAY_SIZE(link_modes)); 11483ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 11493ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11503ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** @} */ 11513ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 11523ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf/** 115344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 115444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 115544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 115644d362409d5469aed47d19e7908d19bd194493aThomas Graf 115744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_qdisc(struct rtnl_link *link, const char *qdisc) 115844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 115944d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_qdisc, qdisc, sizeof(link->l_qdisc) - 1); 116044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_QDISC; 116144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 116244d362409d5469aed47d19e7908d19bd194493aThomas Graf 116344d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_qdisc(struct rtnl_link *link) 116444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 116544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 116644d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_qdisc; 116744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 116844d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 116944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 117044d362409d5469aed47d19e7908d19bd194493aThomas Graf 117144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_name(struct rtnl_link *link, const char *name) 117244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 117344d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_name, name, sizeof(link->l_name) - 1); 117444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFNAME; 117544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 117644d362409d5469aed47d19e7908d19bd194493aThomas Graf 117744d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_name(struct rtnl_link *link) 117844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 117944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFNAME) 118044d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_name; 118144d362409d5469aed47d19e7908d19bd194493aThomas Graf else 118244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 118344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 118444d362409d5469aed47d19e7908d19bd194493aThomas Graf 118544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, 118644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *new, int flag) 118744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 118844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*pos) 118944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(*pos); 119044d362409d5469aed47d19e7908d19bd194493aThomas Graf 119144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(new); 119244d362409d5469aed47d19e7908d19bd194493aThomas Graf *pos = new; 119344d362409d5469aed47d19e7908d19bd194493aThomas Graf 119444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= flag; 119544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 119644d362409d5469aed47d19e7908d19bd194493aThomas Graf 119744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr) 119844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 119944d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR); 120044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 120144d362409d5469aed47d19e7908d19bd194493aThomas Graf 120244d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_addr(struct rtnl_link *link) 120344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 120444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 120544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_addr; 120644d362409d5469aed47d19e7908d19bd194493aThomas Graf else 120744d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 120844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 120944d362409d5469aed47d19e7908d19bd194493aThomas Graf 121044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *brd) 121144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 121244d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_bcast, brd, LINK_ATTR_BRD); 121344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 121444d362409d5469aed47d19e7908d19bd194493aThomas Graf 121544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link) 121644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 121744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 121844d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_bcast; 121944d362409d5469aed47d19e7908d19bd194493aThomas Graf else 122044d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 122144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 122244d362409d5469aed47d19e7908d19bd194493aThomas Graf 122344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) 122444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 122544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 122644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags |= flags; 122744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 122844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 122944d362409d5469aed47d19e7908d19bd194493aThomas Graf 123044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) 123144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 123244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 123344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags &= ~flags; 123444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 123544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 123644d362409d5469aed47d19e7908d19bd194493aThomas Graf 123744d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_flags(struct rtnl_link *link) 123844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 123944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_flags; 124044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 124144d362409d5469aed47d19e7908d19bd194493aThomas Graf 124244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_family(struct rtnl_link *link, int family) 124344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 124444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_family = family; 124544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FAMILY; 124644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 124744d362409d5469aed47d19e7908d19bd194493aThomas Graf 124844d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_family(struct rtnl_link *link) 124944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 125044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_family & LINK_ATTR_FAMILY) 125144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_family; 125244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 125344d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 125444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 125544d362409d5469aed47d19e7908d19bd194493aThomas Graf 125644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype) 125744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 125844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_arptype = arptype; 125944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 126044d362409d5469aed47d19e7908d19bd194493aThomas Graf 126144d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_arptype(struct rtnl_link *link) 126244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 126344d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_arptype; 126444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 126544d362409d5469aed47d19e7908d19bd194493aThomas Graf 126644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex) 126744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 126844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_index = ifindex; 126944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFINDEX; 127044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 127144d362409d5469aed47d19e7908d19bd194493aThomas Graf 127244d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_ifindex(struct rtnl_link *link) 127344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1274b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_index; 127544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 127644d362409d5469aed47d19e7908d19bd194493aThomas Graf 127744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu) 127844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 127944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_mtu = mtu; 128044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MTU; 128144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 128244d362409d5469aed47d19e7908d19bd194493aThomas Graf 128344d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_mtu(struct rtnl_link *link) 128444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 128544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MTU) 128644d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_mtu; 128744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 128844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 128944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 129044d362409d5469aed47d19e7908d19bd194493aThomas Graf 129144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen) 129244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 129344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_txqlen = txqlen; 129444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_TXQLEN; 129544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 129644d362409d5469aed47d19e7908d19bd194493aThomas Graf 129744d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_txqlen(struct rtnl_link *link) 129844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 129944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_TXQLEN) 130044d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_txqlen; 130144d362409d5469aed47d19e7908d19bd194493aThomas Graf else 130244d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 130344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 130444d362409d5469aed47d19e7908d19bd194493aThomas Graf 130544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) 130644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 130744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_weight = weight; 130844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_WEIGHT; 130944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 131044d362409d5469aed47d19e7908d19bd194493aThomas Graf 131144d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_weight(struct rtnl_link *link) 131244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 131344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_WEIGHT) 131444d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_weight; 131544d362409d5469aed47d19e7908d19bd194493aThomas Graf else 131644d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 131744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 131844d362409d5469aed47d19e7908d19bd194493aThomas Graf 131944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_link(struct rtnl_link *link, int ifindex) 132044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 132144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_link = ifindex; 132244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_LINK; 132344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 132444d362409d5469aed47d19e7908d19bd194493aThomas Graf 132544d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_link(struct rtnl_link *link) 132644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1327b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_link; 132844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 132944d362409d5469aed47d19e7908d19bd194493aThomas Graf 133044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_master(struct rtnl_link *link, int ifindex) 133144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 133244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_master = ifindex; 133344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MASTER; 133444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 133544d362409d5469aed47d19e7908d19bd194493aThomas Graf 133644d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_master(struct rtnl_link *link) 133744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1338b4fbe1d34d6f54045b5c6236d86aacd4340ec83dThomas Graf return link->l_master; 133944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 134044d362409d5469aed47d19e7908d19bd194493aThomas Graf 13413ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafvoid rtnl_link_set_operstate(struct rtnl_link *link, uint8_t operstate) 13423ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 13433ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_operstate = operstate; 13443ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_OPERSTATE; 13453ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 13463ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 13473ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafuint8_t rtnl_link_get_operstate(struct rtnl_link *link) 13483ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 13493ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->ce_mask & LINK_ATTR_OPERSTATE) 13503ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return link->l_operstate; 13513ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf else 13523ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return IF_OPER_UNKNOWN; 13533ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 13543ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 13553ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafvoid rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t linkmode) 13563ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 13573ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->l_linkmode = linkmode; 13583ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf link->ce_mask |= LINK_ATTR_LINKMODE; 13593ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 13603ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 13613ad4665be2f192291238cbe78118a57ec42436c6Thomas Grafuint8_t rtnl_link_get_linkmode(struct rtnl_link *link) 13623ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf{ 13633ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf if (link->ce_mask & LINK_ATTR_LINKMODE) 13643ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return link->l_linkmode; 13653ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf else 13663ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf return IF_LINK_MODE_DEFAULT; 13673ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf} 13683ad4665be2f192291238cbe78118a57ec42436c6Thomas Graf 136944d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t rtnl_link_get_stat(struct rtnl_link *link, int id) 137044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 137144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (id < 0 || id > RTNL_LINK_STATS_MAX) 137244d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 137344d362409d5469aed47d19e7908d19bd194493aThomas Graf 137444d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_stats[id]; 137544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 137644d362409d5469aed47d19e7908d19bd194493aThomas Graf 1377a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf/** 1378a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Specify the info type of a link 1379a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg link link object 1380a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg type info type 1381a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1382a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Looks up the info type and prepares the link to store info type 1383a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * specific attributes. If an info type has been assigned already 1384a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * it will be released with all changes lost. 1385a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1386a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @return 0 on success or a negative errror code. 1387a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf */ 1388a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafint rtnl_link_set_info_type(struct rtnl_link *link, const char *type) 1389a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf{ 1390a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf struct rtnl_link_info_ops *io; 1391a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf int err; 1392a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1393a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((io = rtnl_link_info_ops_lookup(type)) == NULL) 13948a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_OPNOTSUPP; 1395a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1396a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops) 1397a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf release_link_info(link); 1398a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1399a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if ((err = io->io_alloc(link)) < 0) 1400a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return err; 1401a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1402a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf link->l_info_ops = io; 1403a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1404a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return 0; 1405a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf} 1406a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 1407a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf/** 1408a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * Return info type of a link 1409a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @arg link link object 1410a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * 1411a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @note The returned pointer is only valid as long as the link exists 1412a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf * @return Info type name or NULL if unknown. 1413a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf */ 1414a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Grafchar *rtnl_link_get_info_type(struct rtnl_link *link) 1415a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf{ 1416a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf if (link->l_info_ops) 1417a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return link->l_info_ops->io_name; 1418a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf else 1419a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf return NULL; 1420a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf} 1421a7469ce758fac3631df6ce72eb3f89150070e7f8Thomas Graf 142244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 142344d362409d5469aed47d19e7908d19bd194493aThomas Graf 142444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops link_obj_ops = { 142544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "route/link", 142644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct rtnl_link), 142744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = link_free_data, 142844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = link_clone, 1429d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf .oo_dump = { 1430d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_LINE] = link_dump_line, 1431d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_DETAILS] = link_dump_details, 1432d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_STATS] = link_dump_stats, 1433d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_ENV] = link_dump_env, 1434d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf }, 143544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = link_compare, 143644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = link_attrs2str, 143744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_id_attrs = LINK_ATTR_IFINDEX, 143844d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 143944d362409d5469aed47d19e7908d19bd194493aThomas Graf 144044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_af_group link_groups[] = { 144144d362409d5469aed47d19e7908d19bd194493aThomas Graf { AF_UNSPEC, RTNLGRP_LINK }, 144244d362409d5469aed47d19e7908d19bd194493aThomas Graf { END_OF_GROUP_LIST }, 144344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 144444d362409d5469aed47d19e7908d19bd194493aThomas Graf 144544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops rtnl_link_ops = { 144644d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_name = "route/link", 144744d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_hdrsize = sizeof(struct ifinfomsg), 144844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msgtypes = { 144944d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_NEWLINK, NL_ACT_NEW, "new" }, 145044d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_DELLINK, NL_ACT_DEL, "del" }, 145144d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_GETLINK, NL_ACT_GET, "get" }, 145244d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, 145344d362409d5469aed47d19e7908d19bd194493aThomas Graf }, 145444d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_protocol = NETLINK_ROUTE, 145544d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_groups = link_groups, 145644d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_request_update = link_request_update, 145744d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msg_parser = link_msg_parser, 145844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_obj_ops = &link_obj_ops, 145944d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 146044d362409d5469aed47d19e7908d19bd194493aThomas Graf 146144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __init link_init(void) 146244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 146344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_register(&rtnl_link_ops); 146444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 146544d362409d5469aed47d19e7908d19bd194493aThomas Graf 146644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __exit link_exit(void) 146744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 146844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_unregister(&rtnl_link_ops); 146944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 147044d362409d5469aed47d19e7908d19bd194493aThomas Graf 147144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 1472