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