link.c revision 155ad439a49df034ec58ee4218834bc5b0120515
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 * 944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @ingroup rtnl 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup link Links (Interfaces) 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @brief 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Link Identification 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf * A link can be identified by either its interface index or by its 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf * name. The kernel favours the interface index but falls back to the 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf * interface name if the interface index is lesser-than 0 for kernels 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf * >= 2.6.11. Therefore you can request changes without mapping a 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf * interface name to the corresponding index first. 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Changeable Attributes 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @anchor link_changeable 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link layer address 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link layer broadcast address 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf * - device mapping (ifmap) (>= 2.6.9) 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf * - MTU (>= 2.6.9) 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Transmission queue length (>= 2.6.9) 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Weight (>= 2.6.9) 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Link name (only via access through interface index) (>= 2.6.9) 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf * - Flags (>= 2.6.9) 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_DEBUG 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_NOTRAILERS 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_NOARP 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_DYNAMIC 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_MULTICAST 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_PORTSEL 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_AUTOMEDIA 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_UP 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_PROMISC 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf * - IFF_ALLMULTI 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Link Flags (linux/if.h) 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @anchor link_flags 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_UP Status of link (up|down) 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_BROADCAST Indicates this link allows broadcasting 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_MULTICAST Indicates this link allows multicasting 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_ALLMULTI Indicates this link is doing multicast routing 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_DEBUG Tell the driver to do debugging (currently unused) 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_LOOPBACK This is the loopback link 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_POINTOPOINT Point-to-point link 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_NOARP Link is unable to perform ARP 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_PROMISC Status of promiscious mode flag 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_MASTER Used by teql 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_SLAVE Used by teql 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_PORTSEL Indicates this link allows port selection 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_AUTOMEDIA Indicates this link selects port automatically 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_DYNAMIC Indicates the address of this link is dynamic 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_RUNNING Link is running and carrier is ok. 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf * IFF_NOTRAILERS Unused, BSD compat. 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par Notes on IFF_PROMISC and IFF_ALLMULTI flags 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf * Although you can query the status of IFF_PROMISC and IFF_ALLMULTI 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf * they do not represent the actual state in the kernel but rather 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf * whether the flag has been enabled/disabled by userspace. The link 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf * may be in promiscious mode even if IFF_PROMISC is not set in a link 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf * dump request response because promiscity might be needed by the driver 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf * for a period of time. 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note The unit of the transmission queue length depends on the 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf * link type, a common unit is \a packets. 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par 1) Retrieving information about available links 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // The first step is to retrieve a list of all available interfaces within 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf * // the kernel and put them into a cache. 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct nl_cache *cache = rtnl_link_alloc_cache(nl_handle); 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // In a second step, a specific link may be looked up by either interface 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf * // index or interface name. 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *link = rtnl_link_get_by_name(cache, "lo"); 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf * // rtnl_link_get_by_name() is the short version for translating the 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // interface name to an interface index first like this: 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf * int ifindex = rtnl_link_name2i(cache, "lo"); 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *link = rtnl_link_get(cache, ifindex); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // After successful usage, the object must be given back to the cache 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_put(link); 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @par 2) Changing link attributes 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @code 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // In order to change any attributes of an existing link, we must allocate 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // a new link to hold the change requests: 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *request = rtnl_link_alloc(); 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Now we can go on and specify the attributes we want to change: 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_set_weight(request, 300); 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_set_mtu(request, 1360); 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf * // We can also shut an interface down administratively 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_unset_flags(request, rtnl_link_str2flags("up")); 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Actually, we should know which link to change, so let's look it up 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct rtnl_link *old = rtnl_link_get(cache, "eth0"); 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Two ways exist to commit this change request, the first one is to 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // build the required netlink message and send it out in one single 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf * // step: 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_change(nl_handle, old, request); 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf * // An alternative way is to build the netlink message and send it 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf * // out yourself using nl_send_auto_complete() 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf * struct nl_msg *msg = rtnl_link_build_change_request(old, request); 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf * nl_send_auto_complete(nl_handle, nlmsg_hdr(msg)); 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf * nlmsg_free(msg); 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf * 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf * // Don't forget to give back the link object ;-> 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf * rtnl_link_put(old); 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @endcode 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/attr.h> 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/object.h> 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/rtnl.h> 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/link.h> 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */ 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MTU 0x0001 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_LINK 0x0002 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_TXQLEN 0x0004 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_WEIGHT 0x0008 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MASTER 0x0010 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_QDISC 0x0020 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_MAP 0x0040 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_ADDR 0x0080 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_BRD 0x0100 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_FLAGS 0x0200 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_IFNAME 0x0400 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_IFINDEX 0x0800 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_FAMILY 0x1000 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_ARPTYPE 0x2000 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_STATS 0x4000 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_ATTR_CHANGE 0x8000 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf 15544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops rtnl_link_ops; 15644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops link_obj_ops; 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */ 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf 15944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void link_free_data(struct nl_object *c) 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = nl_object_priv(c); 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(link->l_addr); 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(link->l_bcast); 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf 16944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_clone(struct nl_object *_dst, struct nl_object *_src) 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *dst = nl_object_priv(_dst); 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *src = nl_object_priv(_src); 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->l_addr) 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->l_addr = nl_addr_clone(src->l_addr))) 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->l_bcast) 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->l_bcast = nl_addr_clone(src->l_bcast))) 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 18344d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_get_errno(); 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf 18744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nla_policy link_policy[IFLA_MAX+1] = { 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_IFNAME] = { .type = NLA_STRING, 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf .maxlen = IFNAMSIZ }, 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MTU] = { .type = NLA_U32 }, 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_TXQLEN] = { .type = NLA_U32 }, 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_LINK] = { .type = NLA_U32 }, 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_WEIGHT] = { .type = NLA_U32 }, 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MASTER] = { .type = NLA_U32 }, 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_QDISC] = { .type = NLA_STRING, 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf .maxlen = IFQDISCSIZ }, 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_STATS] = { .minlen = sizeof(struct rtnl_link_stats) }, 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf [IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) }, 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf 20144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 2023040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf struct nlmsghdr *n, struct nl_parser_param *pp) 20344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct ifinfomsg *ifi; 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nlattr *tb[IFLA_MAX+1]; 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf link = rtnl_link_alloc(); 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link == NULL) { 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf err = nl_errno(ENOMEM); 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_msgtype = n->nlmsg_type; 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy); 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_IFNAME] == NULL) { 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf err = nl_error(EINVAL, "Missing link name TLV"); 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ); 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi = nlmsg_data(n); 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_family = ifi->ifi_family; 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_arptype = ifi->ifi_type; 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_index = ifi->ifi_index; 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags = ifi->ifi_flags; 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_change = ifi->ifi_change; 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask = (LINK_ATTR_IFNAME | LINK_ATTR_FAMILY | 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX | 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf LINK_ATTR_FLAGS | LINK_ATTR_CHANGE); 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_STATS]) { 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]); 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_PACKETS] = st->rx_packets; 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_BYTES] = st->rx_bytes; 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_ERRORS] = st->rx_errors; 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_DROPPED] = st->rx_dropped; 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_COMPRESSED] = st->rx_compressed; 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st->rx_fifo_errors; 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_PACKETS] = st->tx_packets; 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_BYTES] = st->tx_bytes; 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ERRORS] = st->tx_errors; 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_DROPPED] = st->tx_dropped; 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COMPRESSED] = st->tx_compressed; 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st->tx_fifo_errors; 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_LEN_ERR] = st->rx_length_errors; 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_OVER_ERR] = st->rx_over_errors; 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_CRC_ERR] = st->rx_crc_errors; 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st->rx_frame_errors; 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st->rx_missed_errors; 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st->tx_aborted_errors; 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st->tx_carrier_errors; 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st->tx_heartbeat_errors; 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_WIN_ERR] = st->tx_window_errors; 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_MULTICAST] = st->multicast; 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_STATS; 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_TXQLEN]) { 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_txqlen = nla_get_u32(tb[IFLA_TXQLEN]); 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_TXQLEN; 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MTU]) { 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_mtu = nla_get_u32(tb[IFLA_MTU]); 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MTU; 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_ADDRESS]) { 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_addr = nla_get_addr(tb[IFLA_ADDRESS], AF_UNSPEC); 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_addr == NULL) 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_set_family(link->l_addr, 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_guess_family(link->l_addr)); 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_ADDR; 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_BROADCAST]) { 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_bcast = nla_get_addr(tb[IFLA_BROADCAST], AF_UNSPEC); 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_bcast == NULL) 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_set_family(link->l_bcast, 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_guess_family(link->l_bcast)); 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_BRD; 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_LINK]) { 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_link = nla_get_u32(tb[IFLA_LINK]); 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_LINK; 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_WEIGHT]) { 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]); 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_WEIGHT; 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_QDISC]) { 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ); 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_QDISC; 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MAP]) { 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link_ifmap *map = nla_data(tb[IFLA_MAP]); 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_mem_start = map->mem_start; 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_mem_end = map->mem_end; 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_base_addr = map->base_addr; 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_irq = map->irq; 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_dma = map->dma; 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_map.lm_port = map->port; 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MAP; 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tb[IFLA_MASTER]) { 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_master = nla_get_u32(tb[IFLA_MASTER]); 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MASTER; 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf err = pp->pp_cb((struct nl_object *) link, pp); 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf 330155ad439a49df034ec58ee4218834bc5b0120515Thomas Graf err = P_ACCEPT; 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf 33244d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf 33744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_request_update(struct nl_cache *c, struct nl_handle *h) 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_rtgen_request(h, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf 34244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_brief(struct nl_object *obj, struct nl_dump_params *p) 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf int line = 1; 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s ", link->l_name); 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "@%s", ll ? ll->l_name : "NONE"); 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s ", nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s ", link->l_addr ? nl_addr2str(link->l_addr, buf, 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf sizeof(buf)) : "none"); 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "mtu %u ", link->l_mtu); 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "master %s ", master ? master->l_name : "inv"); 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "<%s>", buf); 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf 37944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_full(struct nl_object *obj, struct nl_dump_params *p) 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf int line; 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf line = link_dump_brief(obj, p); 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(p, line++); 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, " txqlen %u weight %u ", link->l_txqlen, link->l_weight); 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "qdisc %s ", link->l_qdisc); 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq) 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "irq %u ", link->l_map.lm_irq); 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFINDEX) 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "index %u ", link->l_index); 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "brd %s", nl_addr2str(link->l_bcast, buf, 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf sizeof(buf))); 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf 40844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf char *unit, fmt[64]; 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf float res; 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf int line; 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf line = link_dump_full(obj, p); 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " Stats: bytes packets errors " 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf " dropped fifo-err compressed\n"); 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit); 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf strcpy(fmt, " RX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, fmt, 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf res, unit, 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_PACKETS], 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_ERRORS], 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_DROPPED], 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FIFO_ERR], 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_COMPRESSED]); 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit); 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf strcpy(fmt, " TX %X.2f %s %10llu %10llu %10llu %10llu %10llu\n"); 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf fmt[9] = *unit == 'B' ? '9' : '7'; 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, fmt, 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf res, unit, 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_PACKETS], 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ERRORS], 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_DROPPED], 44344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_FIFO_ERR], 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COMPRESSED]); 44544d362409d5469aed47d19e7908d19bd194493aThomas Graf 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " Errors: length over crc " 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf " frame missed multicast\n"); 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " RX %10" PRIu64 " %10" PRIu64 " %10" 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 "\n", 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_LEN_ERR], 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_OVER_ERR], 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_CRC_ERR], 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_FRAME_ERR], 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_RX_MISSED_ERR], 45744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_MULTICAST]); 45844d362409d5469aed47d19e7908d19bd194493aThomas Graf 45944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " Errors: aborted carrier heartbeat " 46044d362409d5469aed47d19e7908d19bd194493aThomas Graf " window collision\n"); 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " TX %10" PRIu64 " %10" PRIu64 " %10" 46344d362409d5469aed47d19e7908d19bd194493aThomas Graf PRIu64 " %10" PRIu64 " %10" PRIu64 "\n", 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_ABORT_ERR], 46544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_CARRIER_ERR], 46644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_HBEAT_ERR], 46744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_WIN_ERR], 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_stats[RTNL_LINK_TX_COLLISIONS]); 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf 47344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_xml(struct nl_object *obj, struct nl_dump_params *p) 47444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, line = 0; 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf 48044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "<link name=\"%s\" index=\"%u\">\n", 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_name, link->l_index); 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <family>%s</family>\n", 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(link->l_family, buf, sizeof(buf))); 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <arptype>%s</arptype>\n", 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <address>%s</address>\n", 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_addr, buf, sizeof(buf))); 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <mtu>%u</mtu>\n", link->l_mtu); 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <txqlen>%u</txqlen>\n", link->l_txqlen); 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <weight>%u</weight>\n", link->l_weight); 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags, buf, sizeof(buf)); 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <flags>%s</flags>\n", buf); 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf 49644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <qdisc>%s</qdisc>\n", link->l_qdisc); 49844d362409d5469aed47d19e7908d19bd194493aThomas Graf 49944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <link>%s</link>\n", 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf ll ? ll->l_name : "none"); 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <master>%s</master>\n", 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf master ? master->l_name : "none"); 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 51444d362409d5469aed47d19e7908d19bd194493aThomas Graf 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <broadcast>%s</broadcast>\n", 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_bcast, buf, sizeof(buf))); 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_STATS) { 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " <stats>\n"); 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) { 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_stat2str(i, buf, sizeof(buf)); 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf " <%s>%" PRIu64 "</%s>\n", 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, link->l_stats[i], buf); 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, " </stats>\n"); 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "</link>\n"); 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t l_change; /**< Change mask */ 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_lifmap l_map; /**< Interface device mapping */ 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf 54044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_dump_env(struct nl_object *obj, struct nl_dump_params *p) 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = (struct rtnl_link *) obj; 54344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache = dp_cache(obj); 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[128]; 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, line = 0; 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_NAME=%s\n", link->l_name); 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_IFINDEX=%u\n", link->l_index); 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_FAMILY=%s\n", 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_af2str(link->l_family, buf, sizeof(buf))); 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_TYPE=%s\n", 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_llproto2str(link->l_arptype, buf, sizeof(buf))); 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_ADDRESS=%s\n", 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_addr, buf, sizeof(buf))); 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_MTU=%u\n", link->l_mtu); 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_TXQUEUELEN=%u\n", link->l_txqlen); 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_WEIGHT=%u\n", link->l_weight); 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_flags2str(link->l_flags & ~IFF_RUNNING, buf, sizeof(buf)); 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (buf[0]) 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_FLAGS=%s\n", buf); 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 56544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_QDISC=%s\n", link->l_qdisc); 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) { 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *ll = rtnl_link_get(cache, link->l_link); 56944d362409d5469aed47d19e7908d19bd194493aThomas Graf 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_LINK_IFINDEX=%d\n", link->l_link); 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ll) { 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_LINK_IFNAME=%s\n", 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf ll->l_name); 57444d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(ll); 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) { 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *master = rtnl_link_get(cache, link->l_master); 58044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_MASTER=%s\n", 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf master ? master->l_name : "none"); 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (master) 58344d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(master); 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 58744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "LINK_BROADCAST=%s\n", 58844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(link->l_bcast, buf, sizeof(buf))); 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_STATS) { 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; i <= RTNL_LINK_STATS_MAX; i++) { 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf char *c = buf; 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf 59444d362409d5469aed47d19e7908d19bd194493aThomas Graf sprintf(buf, "LINK_"); 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_stat2str(i, buf + 5, sizeof(buf) - 5); 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf while (*c) { 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf *c = toupper(*c); 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf c++; 59944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf "%s=%" PRIu64 "\n", buf, link->l_stats[i]); 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf return line; 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 60944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb) 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *l = (struct rtnl_link *) a; 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *c = dp_cache(a); 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf int nevents = 0; 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf 61544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change == ~0U) { 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->ce_msgtype == RTM_NEWLINK) 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_register(l); 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_unregister(l); 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf return 1; 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf 62444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_SLAVE) { 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_flags & IFF_SLAVE) { 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *m = rtnl_link_get(c, l->l_master); 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_new_bonding(l, m); 62844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (m) 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(m); 63044d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf cb->le_cancel_bonding(l); 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf#if 0 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING) 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s changed state to %s.\n", 63744d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_UP ? "up" : "down"); 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (l->l_change & IFF_PROMISC) { 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_new_line(p, line++); 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "link %s %s promiscuous mode.\n", 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left"); 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (line == 0) 64644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump_line(p, line++, "link %s sent unknown event.\n", 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf l->l_name); 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 64944d362409d5469aed47d19e7908d19bd194493aThomas Graf 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf return nevents; 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf#endif 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf 65444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int link_compare(struct nl_object *_a, struct nl_object *_b, 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *a = (struct rtnl_link *) _a; 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *b = (struct rtnl_link *) _b; 65944d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define LINK_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, LINK_ATTR_##ATTR, a, b, EXPR) 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFINDEX, a->l_index != b->l_index); 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MTU, a->l_mtu != b->l_mtu); 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(LINK, a->l_link != b->l_link); 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(TXQLEN, a->l_txqlen != b->l_txqlen); 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(WEIGHT, a->l_weight != b->l_weight); 66844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(MASTER, a->l_master != b->l_master); 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FAMILY, a->l_family != b->l_family); 67044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(QDISC, strcmp(a->l_qdisc, b->l_qdisc)); 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(IFNAME, strcmp(a->l_name, b->l_name)); 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(ADDR, nl_addr_cmp(a->l_addr, b->l_addr)); 67344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(BRD, nl_addr_cmp(a->l_bcast, b->l_bcast)); 67444d362409d5469aed47d19e7908d19bd194493aThomas Graf 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (flags & LOOSE_FLAG_COMPARISON) 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, 67744d362409d5469aed47d19e7908d19bd194493aThomas Graf (a->l_flags ^ b->l_flags) & b->l_flag_mask); 67844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 67944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags); 68044d362409d5469aed47d19e7908d19bd194493aThomas Graf 68144d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef LINK_DIFF 68244d362409d5469aed47d19e7908d19bd194493aThomas Graf 68344d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 68444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 68544d362409d5469aed47d19e7908d19bd194493aThomas Graf 68644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_attrs[] = { 68744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MTU, mtu) 68844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_LINK, link) 68944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_TXQLEN, txqlen) 69044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_WEIGHT, weight) 69144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MASTER, master) 69244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_QDISC, qdisc) 69344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_MAP, map) 69444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ADDR, address) 69544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_BRD, broadcast) 69644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FLAGS, flags) 69744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFNAME, name) 69844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_IFINDEX, ifindex) 69944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_FAMILY, family) 70044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_ARPTYPE, arptype) 70144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_STATS, stats) 70244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(LINK_ATTR_CHANGE, change) 70344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 70444d362409d5469aed47d19e7908d19bd194493aThomas Graf 70544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *link_attrs2str(int attrs, char *buf, size_t len) 70644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 70744d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, link_attrs, 70844d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_attrs)); 70944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 71044d362409d5469aed47d19e7908d19bd194493aThomas Graf 71144d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 71244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 71344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 71444d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 71544d362409d5469aed47d19e7908d19bd194493aThomas Graf 71644d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_alloc(void) 71744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 71844d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct rtnl_link *) nl_object_alloc(&link_obj_ops); 71944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 72044d362409d5469aed47d19e7908d19bd194493aThomas Graf 72144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_put(struct rtnl_link *link) 72244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 72344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) link); 72444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 72544d362409d5469aed47d19e7908d19bd194493aThomas Graf 72644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 72744d362409d5469aed47d19e7908d19bd194493aThomas Graf 72844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 72944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Cache Management 73044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 73144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 73244d362409d5469aed47d19e7908d19bd194493aThomas Graf 73344d362409d5469aed47d19e7908d19bd194493aThomas Graf 73444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 73544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocate link cache and fill in all configured links. 73644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg handle Netlink handle. 73744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 73844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocates a new link cache, initializes it properly and updates it 73944d362409d5469aed47d19e7908d19bd194493aThomas Graf * to include all links currently configured in the kernel. 74044d362409d5469aed47d19e7908d19bd194493aThomas Graf * 74144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Free the memory after usage. 74244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return Newly allocated cache or NULL if an error occured. 74344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 74444d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_cache *rtnl_link_alloc_cache(struct nl_handle *handle) 74544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 74644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache * cache; 74744d362409d5469aed47d19e7908d19bd194493aThomas Graf 74844d362409d5469aed47d19e7908d19bd194493aThomas Graf cache = nl_cache_alloc(&rtnl_link_ops); 74944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache == NULL) 75044d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 75144d362409d5469aed47d19e7908d19bd194493aThomas Graf 75244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (handle && nl_cache_refill(handle, cache) < 0) { 75344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_free(cache); 75444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 75544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 75644d362409d5469aed47d19e7908d19bd194493aThomas Graf 75744d362409d5469aed47d19e7908d19bd194493aThomas Graf return cache; 75844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 75944d362409d5469aed47d19e7908d19bd194493aThomas Graf 76044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 76144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by interface index in the provided cache 76244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 76344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 76444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 76544d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 76644d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 76744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 76844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 76944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 77044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex) 77144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 77244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 77344d362409d5469aed47d19e7908d19bd194493aThomas Graf 77444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 77544d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 77644d362409d5469aed47d19e7908d19bd194493aThomas Graf 77744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 77844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_index == ifindex) { 77944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 78044d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 78144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 78244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 78344d362409d5469aed47d19e7908d19bd194493aThomas Graf 78444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 78544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 78644d362409d5469aed47d19e7908d19bd194493aThomas Graf 78744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 78844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Look up link by link name in the provided cache 78944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 79044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 79144d362409d5469aed47d19e7908d19bd194493aThomas Graf * 79244d362409d5469aed47d19e7908d19bd194493aThomas Graf * The caller owns a reference on the returned object and 79344d362409d5469aed47d19e7908d19bd194493aThomas Graf * must give the object back via rtnl_link_put(). 79444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 79544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return pointer to link inside the cache or NULL if no match was found. 79644d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 79744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, 79844d362409d5469aed47d19e7908d19bd194493aThomas Graf const char *name) 79944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 80044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 80144d362409d5469aed47d19e7908d19bd194493aThomas Graf 80244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (cache->c_ops != &rtnl_link_ops) 80344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 80444d362409d5469aed47d19e7908d19bd194493aThomas Graf 80544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_list_for_each_entry(link, &cache->c_items, ce_list) { 80644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcmp(name, link->l_name)) { 80744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) link); 80844d362409d5469aed47d19e7908d19bd194493aThomas Graf return link; 80944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 81044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 81144d362409d5469aed47d19e7908d19bd194493aThomas Graf 81244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 81344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 81444d362409d5469aed47d19e7908d19bd194493aThomas Graf 81544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 81644d362409d5469aed47d19e7908d19bd194493aThomas Graf 81744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 81844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Modifications 81944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 82044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 82144d362409d5469aed47d19e7908d19bd194493aThomas Graf 82244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 82344d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a netlink change request message to change link attributes 82444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 82544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 82644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 82744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 82844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message requesting a change of link attributes. 82944d362409d5469aed47d19e7908d19bd194493aThomas Graf * The netlink message header isn't fully equipped with all relevant 83044d362409d5469aed47d19e7908d19bd194493aThomas Graf * fields and must be sent out via nl_send_auto_complete() or 83144d362409d5469aed47d19e7908d19bd194493aThomas Graf * supplemented as needed. 83244d362409d5469aed47d19e7908d19bd194493aThomas Graf * \a old must point to a link currently configured in the kernel 83344d362409d5469aed47d19e7908d19bd194493aThomas Graf * and \a tmpl must contain the attributes to be changed set via 83444d362409d5469aed47d19e7908d19bd194493aThomas Graf * \c rtnl_link_set_* functions. 83544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 83644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return New netlink message 83744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 83844d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 83944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 84044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_msg * rtnl_link_build_change_request(struct rtnl_link *old, 84144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *tmpl, 84244d362409d5469aed47d19e7908d19bd194493aThomas Graf int flags) 84344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 84444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 84544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct ifinfomsg ifi = { 84644d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_family = old->l_family, 84744d362409d5469aed47d19e7908d19bd194493aThomas Graf .ifi_index = old->l_index, 84844d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 84944d362409d5469aed47d19e7908d19bd194493aThomas Graf 85044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_FLAGS) { 85144d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags = old->l_flags & ~tmpl->l_flag_mask; 85244d362409d5469aed47d19e7908d19bd194493aThomas Graf ifi.ifi_flags |= tmpl->l_flags; 85344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 85444d362409d5469aed47d19e7908d19bd194493aThomas Graf 85544d362409d5469aed47d19e7908d19bd194493aThomas Graf msg = nlmsg_alloc_simple(RTM_SETLINK, flags); 85644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!msg) 85744d362409d5469aed47d19e7908d19bd194493aThomas Graf goto nla_put_failure; 85844d362409d5469aed47d19e7908d19bd194493aThomas Graf 85944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0) 86044d362409d5469aed47d19e7908d19bd194493aThomas Graf goto nla_put_failure; 86144d362409d5469aed47d19e7908d19bd194493aThomas Graf 86244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_ADDR) 86344d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_ADDRESS, tmpl->l_addr); 86444d362409d5469aed47d19e7908d19bd194493aThomas Graf 86544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_BRD) 86644d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_ADDR(msg, IFLA_BROADCAST, tmpl->l_bcast); 86744d362409d5469aed47d19e7908d19bd194493aThomas Graf 86844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_MTU) 86944d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_MTU, tmpl->l_mtu); 87044d362409d5469aed47d19e7908d19bd194493aThomas Graf 87144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_TXQLEN) 87244d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_TXQLEN, tmpl->l_txqlen); 87344d362409d5469aed47d19e7908d19bd194493aThomas Graf 87444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_WEIGHT) 87544d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_U32(msg, IFLA_WEIGHT, tmpl->l_weight); 87644d362409d5469aed47d19e7908d19bd194493aThomas Graf 87744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (tmpl->ce_mask & LINK_ATTR_IFNAME) 87844d362409d5469aed47d19e7908d19bd194493aThomas Graf NLA_PUT_STRING(msg, IFLA_IFNAME, tmpl->l_name); 87944d362409d5469aed47d19e7908d19bd194493aThomas Graf 88044d362409d5469aed47d19e7908d19bd194493aThomas Graf return msg; 88144d362409d5469aed47d19e7908d19bd194493aThomas Graf 88244d362409d5469aed47d19e7908d19bd194493aThomas Grafnla_put_failure: 88344d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 88444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 88544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 88644d362409d5469aed47d19e7908d19bd194493aThomas Graf 88744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 88844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Change link attributes 88944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg handle netlink handle 89044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg old link to be changed 89144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg tmpl template with requested changes 89244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 89344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 89444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message by calling rtnl_link_build_change_request(), 89544d362409d5469aed47d19e7908d19bd194493aThomas Graf * sends the request to the kernel and waits for the next ACK to be 89644d362409d5469aed47d19e7908d19bd194493aThomas Graf * received, i.e. blocks until the request has been processed. 89744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 89844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code 89944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Not all attributes can be changed, see 90044d362409d5469aed47d19e7908d19bd194493aThomas Graf * \ref link_changeable "Changeable Attributes" for more details. 90144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 90244d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_change(struct nl_handle *handle, struct rtnl_link *old, 90344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *tmpl, int flags) 90444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 90544d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 90644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 90744d362409d5469aed47d19e7908d19bd194493aThomas Graf 90844d362409d5469aed47d19e7908d19bd194493aThomas Graf msg = rtnl_link_build_change_request(old, tmpl, flags); 90944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!msg) 91044d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_errno(ENOMEM); 91144d362409d5469aed47d19e7908d19bd194493aThomas Graf 91244d362409d5469aed47d19e7908d19bd194493aThomas Graf err = nl_send_auto_complete(handle, msg); 91344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 91444d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 91544d362409d5469aed47d19e7908d19bd194493aThomas Graf 91644d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 91744d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_wait_for_ack(handle); 91844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 91944d362409d5469aed47d19e7908d19bd194493aThomas Graf 92044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 92144d362409d5469aed47d19e7908d19bd194493aThomas Graf 92244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 92344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Name <-> Index Translations 92444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 92544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 92644d362409d5469aed47d19e7908d19bd194493aThomas Graf 92744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 92844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate an interface index to the corresponding link name 92944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 93044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg ifindex link interface index 93144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg dst destination buffer 93244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg len length of destination buffer 93344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 93444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translates the specified interface index to the corresponding 93544d362409d5469aed47d19e7908d19bd194493aThomas Graf * link name and stores the name in the destination buffer. 93644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 93744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return link name or NULL if no match was found. 93844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 93944d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, 94044d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t len) 94144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 94244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link = rtnl_link_get(cache, ifindex); 94344d362409d5469aed47d19e7908d19bd194493aThomas Graf 94444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 94544d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(dst, link->l_name, len - 1); 94644d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 94744d362409d5469aed47d19e7908d19bd194493aThomas Graf return dst; 94844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 94944d362409d5469aed47d19e7908d19bd194493aThomas Graf 95044d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 95144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 95244d362409d5469aed47d19e7908d19bd194493aThomas Graf 95344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 95444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Translate a link name to the corresponding interface index 95544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache link cache 95644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg name link name 95744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 95844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return interface index or RTNL_LINK_NOT_FOUND if no match was found. 95944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 96044d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_name2i(struct nl_cache *cache, const char *name) 96144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 96244d362409d5469aed47d19e7908d19bd194493aThomas Graf int ifindex = RTNL_LINK_NOT_FOUND; 96344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct rtnl_link *link; 96444d362409d5469aed47d19e7908d19bd194493aThomas Graf 96544d362409d5469aed47d19e7908d19bd194493aThomas Graf link = rtnl_link_get_by_name(cache, name); 96644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link) { 96744d362409d5469aed47d19e7908d19bd194493aThomas Graf ifindex = link->l_index; 96844d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_link_put(link); 96944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 97044d362409d5469aed47d19e7908d19bd194493aThomas Graf 97144d362409d5469aed47d19e7908d19bd194493aThomas Graf return ifindex; 97244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 97344d362409d5469aed47d19e7908d19bd194493aThomas Graf 97444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 97544d362409d5469aed47d19e7908d19bd194493aThomas Graf 97644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 97744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Flags Translations 97844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 97944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 98044d362409d5469aed47d19e7908d19bd194493aThomas Graf 98144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_flags[] = { 98244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOOPBACK, loopback) 98344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_BROADCAST, broadcast) 98444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_POINTOPOINT, pointopoint) 98544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MULTICAST, multicast) 98644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOARP, noarp) 98744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_ALLMULTI, allmulti) 98844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PROMISC, promisc) 98944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_MASTER, master) 99044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_SLAVE, slave) 99144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DEBUG, debug) 99244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DYNAMIC, dynamic) 99344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_AUTOMEDIA, automedia) 99444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_PORTSEL, portsel) 99544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_NOTRAILERS, notrailers) 99644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_UP, up) 99744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_RUNNING, running) 99844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_LOWER_UP, lowerup) 99944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(IFF_DORMANT, dormant) 100044d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 100144d362409d5469aed47d19e7908d19bd194493aThomas Graf 100244d362409d5469aed47d19e7908d19bd194493aThomas Grafchar * rtnl_link_flags2str(int flags, char *buf, size_t len) 100344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 100444d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(flags, buf, len, link_flags, 100544d362409d5469aed47d19e7908d19bd194493aThomas Graf ARRAY_SIZE(link_flags)); 100644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 100744d362409d5469aed47d19e7908d19bd194493aThomas Graf 100844d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2flags(const char *name) 100944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 101044d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2flags(name, link_flags, ARRAY_SIZE(link_flags)); 101144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 101244d362409d5469aed47d19e7908d19bd194493aThomas Graf 101344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 101444d362409d5469aed47d19e7908d19bd194493aThomas Graf 101544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 101644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Link Statistics Translations 101744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 101844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 101944d362409d5469aed47d19e7908d19bd194493aThomas Graf 102044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl link_stats[] = { 102144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_PACKETS, rx_packets) 102244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_PACKETS, tx_packets) 102344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_BYTES, rx_bytes) 102444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_BYTES, tx_bytes) 102544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_ERRORS, rx_errors) 102644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ERRORS, tx_errors) 102744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_DROPPED, rx_dropped) 102844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_DROPPED, tx_dropped) 102944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed) 103044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed) 103144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err) 103244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err) 103344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err) 103444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err) 103544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err) 103644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err) 103744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err) 103844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err) 103944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err) 104044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err) 104144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err) 104244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_TX_COLLISIONS, tx_collision) 104344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(RTNL_LINK_MULTICAST, multicast) 104444d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 104544d362409d5469aed47d19e7908d19bd194493aThomas Graf 104644d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_stat2str(int st, char *buf, size_t len) 104744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 104844d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats)); 104944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 105044d362409d5469aed47d19e7908d19bd194493aThomas Graf 105144d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_str2stat(const char *name) 105244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 105344d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, link_stats, ARRAY_SIZE(link_stats)); 105444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 105544d362409d5469aed47d19e7908d19bd194493aThomas Graf 105644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 105744d362409d5469aed47d19e7908d19bd194493aThomas Graf 105844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 105944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 106044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 106144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 106244d362409d5469aed47d19e7908d19bd194493aThomas Graf 106344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_qdisc(struct rtnl_link *link, const char *qdisc) 106444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 106544d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_qdisc, qdisc, sizeof(link->l_qdisc) - 1); 106644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_QDISC; 106744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 106844d362409d5469aed47d19e7908d19bd194493aThomas Graf 106944d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_qdisc(struct rtnl_link *link) 107044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 107144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_QDISC) 107244d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_qdisc; 107344d362409d5469aed47d19e7908d19bd194493aThomas Graf else 107444d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 107544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 107644d362409d5469aed47d19e7908d19bd194493aThomas Graf 107744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_name(struct rtnl_link *link, const char *name) 107844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 107944d362409d5469aed47d19e7908d19bd194493aThomas Graf strncpy(link->l_name, name, sizeof(link->l_name) - 1); 108044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFNAME; 108144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 108244d362409d5469aed47d19e7908d19bd194493aThomas Graf 108344d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *rtnl_link_get_name(struct rtnl_link *link) 108444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 108544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFNAME) 108644d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_name; 108744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 108844d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 108944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 109044d362409d5469aed47d19e7908d19bd194493aThomas Graf 109144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos, 109244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *new, int flag) 109344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 109444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*pos) 109544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(*pos); 109644d362409d5469aed47d19e7908d19bd194493aThomas Graf 109744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(new); 109844d362409d5469aed47d19e7908d19bd194493aThomas Graf *pos = new; 109944d362409d5469aed47d19e7908d19bd194493aThomas Graf 110044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= flag; 110144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 110244d362409d5469aed47d19e7908d19bd194493aThomas Graf 110344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr) 110444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 110544d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR); 110644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 110744d362409d5469aed47d19e7908d19bd194493aThomas Graf 110844d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_addr(struct rtnl_link *link) 110944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 111044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_ADDR) 111144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_addr; 111244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 111344d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 111444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 111544d362409d5469aed47d19e7908d19bd194493aThomas Graf 111644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *brd) 111744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 111844d362409d5469aed47d19e7908d19bd194493aThomas Graf __assign_addr(link, &link->l_bcast, brd, LINK_ATTR_BRD); 111944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 112044d362409d5469aed47d19e7908d19bd194493aThomas Graf 112144d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link) 112244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 112344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_BRD) 112444d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_bcast; 112544d362409d5469aed47d19e7908d19bd194493aThomas Graf else 112644d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 112744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 112844d362409d5469aed47d19e7908d19bd194493aThomas Graf 112944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags) 113044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 113144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 113244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags |= flags; 113344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 113444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 113544d362409d5469aed47d19e7908d19bd194493aThomas Graf 113644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags) 113744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 113844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flag_mask |= flags; 113944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_flags &= ~flags; 114044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FLAGS; 114144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 114244d362409d5469aed47d19e7908d19bd194493aThomas Graf 114344d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_flags(struct rtnl_link *link) 114444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 114544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_flags; 114644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 114744d362409d5469aed47d19e7908d19bd194493aThomas Graf 114844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_family(struct rtnl_link *link, int family) 114944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 115044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_family = family; 115144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_FAMILY; 115244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 115344d362409d5469aed47d19e7908d19bd194493aThomas Graf 115444d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_family(struct rtnl_link *link) 115544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 115644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->l_family & LINK_ATTR_FAMILY) 115744d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_family; 115844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 115944d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 116044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 116144d362409d5469aed47d19e7908d19bd194493aThomas Graf 116244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype) 116344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 116444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_arptype = arptype; 116544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 116644d362409d5469aed47d19e7908d19bd194493aThomas Graf 116744d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_arptype(struct rtnl_link *link) 116844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 116944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_arptype; 117044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 117144d362409d5469aed47d19e7908d19bd194493aThomas Graf 117244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex) 117344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 117444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_index = ifindex; 117544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_IFINDEX; 117644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 117744d362409d5469aed47d19e7908d19bd194493aThomas Graf 117844d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_ifindex(struct rtnl_link *link) 117944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 118044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_IFINDEX) 118144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_index; 118244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 118344d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTNL_LINK_NOT_FOUND; 118444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 118544d362409d5469aed47d19e7908d19bd194493aThomas Graf 118644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu) 118744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 118844d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_mtu = mtu; 118944d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MTU; 119044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 119144d362409d5469aed47d19e7908d19bd194493aThomas Graf 119244d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_mtu(struct rtnl_link *link) 119344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 119444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MTU) 119544d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_mtu; 119644d362409d5469aed47d19e7908d19bd194493aThomas Graf else 119744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 119844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 119944d362409d5469aed47d19e7908d19bd194493aThomas Graf 120044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen) 120144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 120244d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_txqlen = txqlen; 120344d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_TXQLEN; 120444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 120544d362409d5469aed47d19e7908d19bd194493aThomas Graf 120644d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_txqlen(struct rtnl_link *link) 120744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 120844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_TXQLEN) 120944d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_txqlen; 121044d362409d5469aed47d19e7908d19bd194493aThomas Graf else 121144d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 121244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 121344d362409d5469aed47d19e7908d19bd194493aThomas Graf 121444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight) 121544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 121644d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_weight = weight; 121744d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_WEIGHT; 121844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 121944d362409d5469aed47d19e7908d19bd194493aThomas Graf 122044d362409d5469aed47d19e7908d19bd194493aThomas Grafunsigned int rtnl_link_get_weight(struct rtnl_link *link) 122144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 122244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_WEIGHT) 122344d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_weight; 122444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 122544d362409d5469aed47d19e7908d19bd194493aThomas Graf return UINT_MAX; 122644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 122744d362409d5469aed47d19e7908d19bd194493aThomas Graf 122844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_link(struct rtnl_link *link, int ifindex) 122944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 123044d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_link = ifindex; 123144d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_LINK; 123244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 123344d362409d5469aed47d19e7908d19bd194493aThomas Graf 123444d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_link(struct rtnl_link *link) 123544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 123644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_LINK) 123744d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_link; 123844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 123944d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTNL_LINK_NOT_FOUND; 124044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 124144d362409d5469aed47d19e7908d19bd194493aThomas Graf 124244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid rtnl_link_set_master(struct rtnl_link *link, int ifindex) 124344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 124444d362409d5469aed47d19e7908d19bd194493aThomas Graf link->l_master = ifindex; 124544d362409d5469aed47d19e7908d19bd194493aThomas Graf link->ce_mask |= LINK_ATTR_MASTER; 124644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 124744d362409d5469aed47d19e7908d19bd194493aThomas Graf 124844d362409d5469aed47d19e7908d19bd194493aThomas Grafint rtnl_link_get_master(struct rtnl_link *link) 124944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 125044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (link->ce_mask & LINK_ATTR_MASTER) 125144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_master; 125244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 125344d362409d5469aed47d19e7908d19bd194493aThomas Graf return RTNL_LINK_NOT_FOUND; 125444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 125544d362409d5469aed47d19e7908d19bd194493aThomas Graf 125644d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t rtnl_link_get_stat(struct rtnl_link *link, int id) 125744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 125844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (id < 0 || id > RTNL_LINK_STATS_MAX) 125944d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 126044d362409d5469aed47d19e7908d19bd194493aThomas Graf 126144d362409d5469aed47d19e7908d19bd194493aThomas Graf return link->l_stats[id]; 126244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 126344d362409d5469aed47d19e7908d19bd194493aThomas Graf 126444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 126544d362409d5469aed47d19e7908d19bd194493aThomas Graf 126644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops link_obj_ops = { 126744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "route/link", 126844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct rtnl_link), 126944d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = link_free_data, 127044d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = link_clone, 127144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_BRIEF] = link_dump_brief, 127244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_FULL] = link_dump_full, 127344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_STATS] = link_dump_stats, 127444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_XML] = link_dump_xml, 127544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_ENV] = link_dump_env, 127644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = link_compare, 127744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = link_attrs2str, 127844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_id_attrs = LINK_ATTR_IFINDEX, 127944d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 128044d362409d5469aed47d19e7908d19bd194493aThomas Graf 128144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_af_group link_groups[] = { 128244d362409d5469aed47d19e7908d19bd194493aThomas Graf { AF_UNSPEC, RTNLGRP_LINK }, 128344d362409d5469aed47d19e7908d19bd194493aThomas Graf { END_OF_GROUP_LIST }, 128444d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 128544d362409d5469aed47d19e7908d19bd194493aThomas Graf 128644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops rtnl_link_ops = { 128744d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_name = "route/link", 128844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_hdrsize = sizeof(struct ifinfomsg), 128944d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msgtypes = { 129044d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_NEWLINK, NL_ACT_NEW, "new" }, 129144d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_DELLINK, NL_ACT_DEL, "del" }, 129244d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTM_GETLINK, NL_ACT_GET, "get" }, 129344d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, 129444d362409d5469aed47d19e7908d19bd194493aThomas Graf }, 129544d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_protocol = NETLINK_ROUTE, 129644d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_groups = link_groups, 129744d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_request_update = link_request_update, 129844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msg_parser = link_msg_parser, 129944d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_obj_ops = &link_obj_ops, 130044d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 130144d362409d5469aed47d19e7908d19bd194493aThomas Graf 130244d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __init link_init(void) 130344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 130444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_register(&rtnl_link_ops); 130544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 130644d362409d5469aed47d19e7908d19bd194493aThomas Graf 130744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __exit link_exit(void) 130844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 130944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_unregister(&rtnl_link_ops); 131044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 131144d362409d5469aed47d19e7908d19bd194493aThomas Graf 131244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 1313