1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2003-2012 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup rtnl
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup link Links (Interfaces)
9*4dc78e53SAndroid Build Coastguard Worker *
10*4dc78e53SAndroid Build Coastguard Worker * @details
11*4dc78e53SAndroid Build Coastguard Worker * @route_doc{route_link, Link Documentation}
12*4dc78e53SAndroid Build Coastguard Worker * @{
13*4dc78e53SAndroid Build Coastguard Worker */
14*4dc78e53SAndroid Build Coastguard Worker
15*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include <linux/if_arp.h>
18*4dc78e53SAndroid Build Coastguard Worker
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
20*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
21*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
22*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
23*4dc78e53SAndroid Build Coastguard Worker #include <netlink/hashtable.h>
24*4dc78e53SAndroid Build Coastguard Worker #include <netlink/data.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/rtnl.h>
26*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/link.h>
27*4dc78e53SAndroid Build Coastguard Worker
28*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-route/nl-route.h"
29*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
30*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/cache-api.h"
31*4dc78e53SAndroid Build Coastguard Worker #include "nl-route.h"
32*4dc78e53SAndroid Build Coastguard Worker #include "link-sriov.h"
33*4dc78e53SAndroid Build Coastguard Worker #include "link/link-api.h"
34*4dc78e53SAndroid Build Coastguard Worker
35*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
36*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_MTU (1 << 0)
37*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_LINK (1 << 1)
38*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_TXQLEN (1 << 2)
39*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_WEIGHT (1 << 3)
40*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_MASTER (1 << 4)
41*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_QDISC (1 << 5)
42*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_MAP (1 << 6)
43*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_ADDR (1 << 7)
44*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_BRD (1 << 8)
45*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_FLAGS (1 << 9)
46*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_IFNAME (1 << 10)
47*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_IFINDEX (1 << 11)
48*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_FAMILY (1 << 12)
49*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_ARPTYPE (1 << 13)
50*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_STATS (1 << 14)
51*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_CHANGE (1 << 15)
52*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_OPERSTATE (1 << 16)
53*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_LINKMODE (1 << 17)
54*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_LINKINFO (1 << 18)
55*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_IFALIAS (1 << 19)
56*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_NUM_VF (1 << 20)
57*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_PROMISCUITY (1 << 21)
58*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_NUM_TX_QUEUES (1 << 22)
59*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_NUM_RX_QUEUES (1 << 23)
60*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_GROUP (1 << 24)
61*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_CARRIER (1 << 25)
62*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_PROTINFO (1 << 26)
63*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_AF_SPEC (1 << 27)
64*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_PHYS_PORT_ID (1 << 28)
65*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_NS_FD (1 << 29)
66*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_NS_PID (1 << 30)
67*4dc78e53SAndroid Build Coastguard Worker /* 31 used by 32-bit api */
68*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_LINK_NETNSID ((uint64_t) 1 << 32)
69*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_VF_LIST ((uint64_t) 1 << 33)
70*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_CARRIER_CHANGES ((uint64_t) 1 << 34)
71*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_PHYS_PORT_NAME ((uint64_t) 1 << 35)
72*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_PHYS_SWITCH_ID ((uint64_t) 1 << 36)
73*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_GSO_MAX_SEGS ((uint64_t) 1 << 37)
74*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_GSO_MAX_SIZE ((uint64_t) 1 << 38)
75*4dc78e53SAndroid Build Coastguard Worker #define LINK_ATTR_LINKINFO_SLAVE_KIND ((uint64_t) 1 << 39)
76*4dc78e53SAndroid Build Coastguard Worker
77*4dc78e53SAndroid Build Coastguard Worker static struct nl_cache_ops rtnl_link_ops;
78*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops link_obj_ops;
79*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
80*4dc78e53SAndroid Build Coastguard Worker
link_lookup(struct nl_cache * cache,int ifindex)81*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex)
82*4dc78e53SAndroid Build Coastguard Worker {
83*4dc78e53SAndroid Build Coastguard Worker if (!cache) {
84*4dc78e53SAndroid Build Coastguard Worker cache = __nl_cache_mngt_require("route/link");
85*4dc78e53SAndroid Build Coastguard Worker if (!cache)
86*4dc78e53SAndroid Build Coastguard Worker return NULL;
87*4dc78e53SAndroid Build Coastguard Worker }
88*4dc78e53SAndroid Build Coastguard Worker
89*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_get(cache, ifindex);
90*4dc78e53SAndroid Build Coastguard Worker }
91*4dc78e53SAndroid Build Coastguard Worker
af_lookup_and_alloc(struct rtnl_link * link,int family)92*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link,
93*4dc78e53SAndroid Build Coastguard Worker int family)
94*4dc78e53SAndroid Build Coastguard Worker {
95*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_af_ops *af_ops;
96*4dc78e53SAndroid Build Coastguard Worker
97*4dc78e53SAndroid Build Coastguard Worker af_ops = rtnl_link_af_ops_lookup(family);
98*4dc78e53SAndroid Build Coastguard Worker if (!af_ops)
99*4dc78e53SAndroid Build Coastguard Worker return NULL;
100*4dc78e53SAndroid Build Coastguard Worker
101*4dc78e53SAndroid Build Coastguard Worker if (!rtnl_link_af_alloc(link, af_ops)) {
102*4dc78e53SAndroid Build Coastguard Worker rtnl_link_af_ops_put(af_ops);
103*4dc78e53SAndroid Build Coastguard Worker return NULL;
104*4dc78e53SAndroid Build Coastguard Worker }
105*4dc78e53SAndroid Build Coastguard Worker
106*4dc78e53SAndroid Build Coastguard Worker return af_ops;
107*4dc78e53SAndroid Build Coastguard Worker }
108*4dc78e53SAndroid Build Coastguard Worker
af_free(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)109*4dc78e53SAndroid Build Coastguard Worker static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
110*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
111*4dc78e53SAndroid Build Coastguard Worker {
112*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_free)
113*4dc78e53SAndroid Build Coastguard Worker ops->ao_free(link, data);
114*4dc78e53SAndroid Build Coastguard Worker
115*4dc78e53SAndroid Build Coastguard Worker rtnl_link_af_ops_put(ops);
116*4dc78e53SAndroid Build Coastguard Worker
117*4dc78e53SAndroid Build Coastguard Worker return 0;
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker
af_request_type(int af_type,struct rtnl_link * changes)120*4dc78e53SAndroid Build Coastguard Worker static int af_request_type(int af_type, struct rtnl_link *changes)
121*4dc78e53SAndroid Build Coastguard Worker {
122*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_af_ops *ops;
123*4dc78e53SAndroid Build Coastguard Worker
124*4dc78e53SAndroid Build Coastguard Worker ops = rtnl_link_af_ops_lookup(af_type);
125*4dc78e53SAndroid Build Coastguard Worker if (ops && ops->ao_override_rtm && ops->ao_override_rtm(changes))
126*4dc78e53SAndroid Build Coastguard Worker return RTM_SETLINK;
127*4dc78e53SAndroid Build Coastguard Worker
128*4dc78e53SAndroid Build Coastguard Worker return RTM_NEWLINK;
129*4dc78e53SAndroid Build Coastguard Worker }
130*4dc78e53SAndroid Build Coastguard Worker
af_clone(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)131*4dc78e53SAndroid Build Coastguard Worker static int af_clone(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
132*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
133*4dc78e53SAndroid Build Coastguard Worker {
134*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *dst = arg;
135*4dc78e53SAndroid Build Coastguard Worker
136*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_clone &&
137*4dc78e53SAndroid Build Coastguard Worker !(dst->l_af_data[ops->ao_family] = ops->ao_clone(dst, data)))
138*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
139*4dc78e53SAndroid Build Coastguard Worker
140*4dc78e53SAndroid Build Coastguard Worker return 0;
141*4dc78e53SAndroid Build Coastguard Worker }
142*4dc78e53SAndroid Build Coastguard Worker
af_fill(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)143*4dc78e53SAndroid Build Coastguard Worker static int af_fill(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
144*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
145*4dc78e53SAndroid Build Coastguard Worker {
146*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg = arg;
147*4dc78e53SAndroid Build Coastguard Worker struct nlattr *af_attr = NULL;
148*4dc78e53SAndroid Build Coastguard Worker int err;
149*4dc78e53SAndroid Build Coastguard Worker
150*4dc78e53SAndroid Build Coastguard Worker if (!ops->ao_fill_af)
151*4dc78e53SAndroid Build Coastguard Worker return 0;
152*4dc78e53SAndroid Build Coastguard Worker
153*4dc78e53SAndroid Build Coastguard Worker if (!ops->ao_fill_af_no_nest)
154*4dc78e53SAndroid Build Coastguard Worker if (!(af_attr = nla_nest_start(msg, ops->ao_family)))
155*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
156*4dc78e53SAndroid Build Coastguard Worker
157*4dc78e53SAndroid Build Coastguard Worker if ((err = ops->ao_fill_af(link, arg, data)) < 0)
158*4dc78e53SAndroid Build Coastguard Worker return err;
159*4dc78e53SAndroid Build Coastguard Worker
160*4dc78e53SAndroid Build Coastguard Worker if (!ops->ao_fill_af_no_nest)
161*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, af_attr);
162*4dc78e53SAndroid Build Coastguard Worker
163*4dc78e53SAndroid Build Coastguard Worker return 0;
164*4dc78e53SAndroid Build Coastguard Worker }
165*4dc78e53SAndroid Build Coastguard Worker
af_fill_pi(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)166*4dc78e53SAndroid Build Coastguard Worker static int af_fill_pi(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
167*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
168*4dc78e53SAndroid Build Coastguard Worker {
169*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg = arg;
170*4dc78e53SAndroid Build Coastguard Worker struct nlattr *pi_attr;
171*4dc78e53SAndroid Build Coastguard Worker int err, pi_type = IFLA_PROTINFO;
172*4dc78e53SAndroid Build Coastguard Worker
173*4dc78e53SAndroid Build Coastguard Worker if (!ops->ao_fill_pi)
174*4dc78e53SAndroid Build Coastguard Worker return 0;
175*4dc78e53SAndroid Build Coastguard Worker
176*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_fill_pi_flags > 0)
177*4dc78e53SAndroid Build Coastguard Worker pi_type |= ops->ao_fill_pi_flags;
178*4dc78e53SAndroid Build Coastguard Worker
179*4dc78e53SAndroid Build Coastguard Worker if (!(pi_attr = nla_nest_start(msg, pi_type)))
180*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
181*4dc78e53SAndroid Build Coastguard Worker
182*4dc78e53SAndroid Build Coastguard Worker if ((err = ops->ao_fill_pi(link, arg, data)) < 0)
183*4dc78e53SAndroid Build Coastguard Worker return err;
184*4dc78e53SAndroid Build Coastguard Worker
185*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, pi_attr);
186*4dc78e53SAndroid Build Coastguard Worker
187*4dc78e53SAndroid Build Coastguard Worker return 0;
188*4dc78e53SAndroid Build Coastguard Worker }
189*4dc78e53SAndroid Build Coastguard Worker
af_dump_line(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)190*4dc78e53SAndroid Build Coastguard Worker static int af_dump_line(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
191*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
192*4dc78e53SAndroid Build Coastguard Worker {
193*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p = arg;
194*4dc78e53SAndroid Build Coastguard Worker
195*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_dump[NL_DUMP_LINE])
196*4dc78e53SAndroid Build Coastguard Worker ops->ao_dump[NL_DUMP_LINE](link, p, data);
197*4dc78e53SAndroid Build Coastguard Worker
198*4dc78e53SAndroid Build Coastguard Worker return 0;
199*4dc78e53SAndroid Build Coastguard Worker }
200*4dc78e53SAndroid Build Coastguard Worker
af_dump_details(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)201*4dc78e53SAndroid Build Coastguard Worker static int af_dump_details(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
202*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
203*4dc78e53SAndroid Build Coastguard Worker {
204*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p = arg;
205*4dc78e53SAndroid Build Coastguard Worker
206*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_dump[NL_DUMP_DETAILS])
207*4dc78e53SAndroid Build Coastguard Worker ops->ao_dump[NL_DUMP_DETAILS](link, p, data);
208*4dc78e53SAndroid Build Coastguard Worker
209*4dc78e53SAndroid Build Coastguard Worker return 0;
210*4dc78e53SAndroid Build Coastguard Worker }
211*4dc78e53SAndroid Build Coastguard Worker
af_dump_stats(struct rtnl_link * link,struct rtnl_link_af_ops * ops,void * data,void * arg)212*4dc78e53SAndroid Build Coastguard Worker static int af_dump_stats(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
213*4dc78e53SAndroid Build Coastguard Worker void *data, void *arg)
214*4dc78e53SAndroid Build Coastguard Worker {
215*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params *p = arg;
216*4dc78e53SAndroid Build Coastguard Worker
217*4dc78e53SAndroid Build Coastguard Worker if (ops->ao_dump[NL_DUMP_STATS])
218*4dc78e53SAndroid Build Coastguard Worker ops->ao_dump[NL_DUMP_STATS](link, p, data);
219*4dc78e53SAndroid Build Coastguard Worker
220*4dc78e53SAndroid Build Coastguard Worker return 0;
221*4dc78e53SAndroid Build Coastguard Worker }
222*4dc78e53SAndroid Build Coastguard Worker
do_foreach_af(struct rtnl_link * link,int (* cb)(struct rtnl_link *,struct rtnl_link_af_ops *,void *,void *),void * arg)223*4dc78e53SAndroid Build Coastguard Worker static int do_foreach_af(struct rtnl_link *link,
224*4dc78e53SAndroid Build Coastguard Worker int (*cb)(struct rtnl_link *,
225*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_af_ops *, void *, void *),
226*4dc78e53SAndroid Build Coastguard Worker void *arg)
227*4dc78e53SAndroid Build Coastguard Worker {
228*4dc78e53SAndroid Build Coastguard Worker int i, err;
229*4dc78e53SAndroid Build Coastguard Worker
230*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < AF_MAX; i++) {
231*4dc78e53SAndroid Build Coastguard Worker if (link->l_af_data[i]) {
232*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *ops = NULL;
233*4dc78e53SAndroid Build Coastguard Worker
234*4dc78e53SAndroid Build Coastguard Worker if (!(ops = rtnl_link_af_ops_lookup(i)))
235*4dc78e53SAndroid Build Coastguard Worker BUG();
236*4dc78e53SAndroid Build Coastguard Worker
237*4dc78e53SAndroid Build Coastguard Worker err = cb(link, ops, link->l_af_data[i], arg);
238*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
239*4dc78e53SAndroid Build Coastguard Worker return err;
240*4dc78e53SAndroid Build Coastguard Worker }
241*4dc78e53SAndroid Build Coastguard Worker }
242*4dc78e53SAndroid Build Coastguard Worker
243*4dc78e53SAndroid Build Coastguard Worker return 0;
244*4dc78e53SAndroid Build Coastguard Worker }
245*4dc78e53SAndroid Build Coastguard Worker
release_link_info(struct rtnl_link * link)246*4dc78e53SAndroid Build Coastguard Worker static void release_link_info(struct rtnl_link *link)
247*4dc78e53SAndroid Build Coastguard Worker {
248*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_info_ops *io = link->l_info_ops;
249*4dc78e53SAndroid Build Coastguard Worker
250*4dc78e53SAndroid Build Coastguard Worker if (io != NULL) {
251*4dc78e53SAndroid Build Coastguard Worker if (io->io_free)
252*4dc78e53SAndroid Build Coastguard Worker io->io_free(link);
253*4dc78e53SAndroid Build Coastguard Worker else {
254*4dc78e53SAndroid Build Coastguard Worker /* Catch missing io_free() implementations */
255*4dc78e53SAndroid Build Coastguard Worker BUG_ON(link->l_info);
256*4dc78e53SAndroid Build Coastguard Worker }
257*4dc78e53SAndroid Build Coastguard Worker rtnl_link_info_ops_put(io);
258*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops = NULL;
259*4dc78e53SAndroid Build Coastguard Worker }
260*4dc78e53SAndroid Build Coastguard Worker }
261*4dc78e53SAndroid Build Coastguard Worker
link_free_data(struct nl_object * c)262*4dc78e53SAndroid Build Coastguard Worker static void link_free_data(struct nl_object *c)
263*4dc78e53SAndroid Build Coastguard Worker {
264*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link = nl_object_priv(c);
265*4dc78e53SAndroid Build Coastguard Worker
266*4dc78e53SAndroid Build Coastguard Worker if (link) {
267*4dc78e53SAndroid Build Coastguard Worker release_link_info(link);
268*4dc78e53SAndroid Build Coastguard Worker
269*4dc78e53SAndroid Build Coastguard Worker /* proto info af reference */
270*4dc78e53SAndroid Build Coastguard Worker rtnl_link_af_ops_put(link->l_af_ops);
271*4dc78e53SAndroid Build Coastguard Worker
272*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(link->l_addr);
273*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(link->l_bcast);
274*4dc78e53SAndroid Build Coastguard Worker
275*4dc78e53SAndroid Build Coastguard Worker free(link->l_ifalias);
276*4dc78e53SAndroid Build Coastguard Worker free(link->l_info_kind);
277*4dc78e53SAndroid Build Coastguard Worker free(link->l_info_slave_kind);
278*4dc78e53SAndroid Build Coastguard Worker
279*4dc78e53SAndroid Build Coastguard Worker do_foreach_af(link, af_free, NULL);
280*4dc78e53SAndroid Build Coastguard Worker
281*4dc78e53SAndroid Build Coastguard Worker nl_data_free(link->l_phys_port_id);
282*4dc78e53SAndroid Build Coastguard Worker nl_data_free(link->l_phys_switch_id);
283*4dc78e53SAndroid Build Coastguard Worker
284*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_VF_LIST)
285*4dc78e53SAndroid Build Coastguard Worker rtnl_link_sriov_free_data(link);
286*4dc78e53SAndroid Build Coastguard Worker }
287*4dc78e53SAndroid Build Coastguard Worker }
288*4dc78e53SAndroid Build Coastguard Worker
link_clone(struct nl_object * _dst,struct nl_object * _src)289*4dc78e53SAndroid Build Coastguard Worker static int link_clone(struct nl_object *_dst, struct nl_object *_src)
290*4dc78e53SAndroid Build Coastguard Worker {
291*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *dst = nl_object_priv(_dst);
292*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *src = nl_object_priv(_src);
293*4dc78e53SAndroid Build Coastguard Worker int err;
294*4dc78e53SAndroid Build Coastguard Worker
295*4dc78e53SAndroid Build Coastguard Worker dst->l_addr = NULL;
296*4dc78e53SAndroid Build Coastguard Worker dst->l_bcast = NULL;
297*4dc78e53SAndroid Build Coastguard Worker dst->l_info_kind = NULL;
298*4dc78e53SAndroid Build Coastguard Worker dst->l_info_slave_kind = NULL;
299*4dc78e53SAndroid Build Coastguard Worker dst->l_info_ops = NULL;
300*4dc78e53SAndroid Build Coastguard Worker memset(dst->l_af_data, 0, sizeof (dst->l_af_data));
301*4dc78e53SAndroid Build Coastguard Worker dst->l_info = NULL;
302*4dc78e53SAndroid Build Coastguard Worker dst->l_ifalias = NULL;
303*4dc78e53SAndroid Build Coastguard Worker dst->l_af_ops = NULL;
304*4dc78e53SAndroid Build Coastguard Worker dst->l_phys_port_id = NULL;
305*4dc78e53SAndroid Build Coastguard Worker dst->l_phys_switch_id = NULL;
306*4dc78e53SAndroid Build Coastguard Worker dst->l_vf_list = NULL;
307*4dc78e53SAndroid Build Coastguard Worker
308*4dc78e53SAndroid Build Coastguard Worker if (src->l_addr)
309*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_addr = nl_addr_clone(src->l_addr)))
310*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
311*4dc78e53SAndroid Build Coastguard Worker
312*4dc78e53SAndroid Build Coastguard Worker if (src->l_bcast)
313*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_bcast = nl_addr_clone(src->l_bcast)))
314*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
315*4dc78e53SAndroid Build Coastguard Worker
316*4dc78e53SAndroid Build Coastguard Worker if (src->l_ifalias)
317*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_ifalias = strdup(src->l_ifalias)))
318*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
319*4dc78e53SAndroid Build Coastguard Worker
320*4dc78e53SAndroid Build Coastguard Worker if (src->l_info_kind)
321*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_info_kind = strdup(src->l_info_kind)))
322*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
323*4dc78e53SAndroid Build Coastguard Worker
324*4dc78e53SAndroid Build Coastguard Worker if (src->l_info_slave_kind)
325*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_info_slave_kind = strdup(src->l_info_slave_kind)))
326*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
327*4dc78e53SAndroid Build Coastguard Worker
328*4dc78e53SAndroid Build Coastguard Worker if (src->l_info_ops) {
329*4dc78e53SAndroid Build Coastguard Worker
330*4dc78e53SAndroid Build Coastguard Worker rtnl_link_info_ops_get(src->l_info_ops);
331*4dc78e53SAndroid Build Coastguard Worker dst->l_info_ops = src->l_info_ops;
332*4dc78e53SAndroid Build Coastguard Worker
333*4dc78e53SAndroid Build Coastguard Worker if (src->l_info_ops->io_clone) {
334*4dc78e53SAndroid Build Coastguard Worker err = src->l_info_ops->io_clone(dst, src);
335*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
336*4dc78e53SAndroid Build Coastguard Worker return err;
337*4dc78e53SAndroid Build Coastguard Worker }
338*4dc78e53SAndroid Build Coastguard Worker }
339*4dc78e53SAndroid Build Coastguard Worker
340*4dc78e53SAndroid Build Coastguard Worker if ((err = do_foreach_af(src, af_clone, dst)) < 0)
341*4dc78e53SAndroid Build Coastguard Worker return err;
342*4dc78e53SAndroid Build Coastguard Worker
343*4dc78e53SAndroid Build Coastguard Worker if (src->l_af_ops)
344*4dc78e53SAndroid Build Coastguard Worker dst->l_af_ops = af_lookup_and_alloc(dst, src->l_af_ops->ao_family);
345*4dc78e53SAndroid Build Coastguard Worker
346*4dc78e53SAndroid Build Coastguard Worker if (src->l_phys_port_id)
347*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_phys_port_id = nl_data_clone(src->l_phys_port_id)))
348*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
349*4dc78e53SAndroid Build Coastguard Worker
350*4dc78e53SAndroid Build Coastguard Worker if (src->l_phys_switch_id)
351*4dc78e53SAndroid Build Coastguard Worker if (!(dst->l_phys_switch_id = nl_data_clone(src->l_phys_switch_id)))
352*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
353*4dc78e53SAndroid Build Coastguard Worker
354*4dc78e53SAndroid Build Coastguard Worker if (src->ce_mask & LINK_ATTR_VF_LIST)
355*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_sriov_clone(dst, src)) < 0)
356*4dc78e53SAndroid Build Coastguard Worker return err;
357*4dc78e53SAndroid Build Coastguard Worker
358*4dc78e53SAndroid Build Coastguard Worker return 0;
359*4dc78e53SAndroid Build Coastguard Worker }
360*4dc78e53SAndroid Build Coastguard Worker
361*4dc78e53SAndroid Build Coastguard Worker struct nla_policy rtln_link_policy[IFLA_MAX+1] = {
362*4dc78e53SAndroid Build Coastguard Worker [IFLA_IFNAME] = { .type = NLA_STRING,
363*4dc78e53SAndroid Build Coastguard Worker .maxlen = IFNAMSIZ },
364*4dc78e53SAndroid Build Coastguard Worker [IFLA_MTU] = { .type = NLA_U32 },
365*4dc78e53SAndroid Build Coastguard Worker [IFLA_TXQLEN] = { .type = NLA_U32 },
366*4dc78e53SAndroid Build Coastguard Worker [IFLA_LINK] = { .type = NLA_U32 },
367*4dc78e53SAndroid Build Coastguard Worker [IFLA_WEIGHT] = { .type = NLA_U32 },
368*4dc78e53SAndroid Build Coastguard Worker [IFLA_MASTER] = { .type = NLA_U32 },
369*4dc78e53SAndroid Build Coastguard Worker [IFLA_OPERSTATE] = { .type = NLA_U8 },
370*4dc78e53SAndroid Build Coastguard Worker [IFLA_LINKMODE] = { .type = NLA_U8 },
371*4dc78e53SAndroid Build Coastguard Worker [IFLA_LINKINFO] = { .type = NLA_NESTED },
372*4dc78e53SAndroid Build Coastguard Worker [IFLA_QDISC] = { .type = NLA_STRING,
373*4dc78e53SAndroid Build Coastguard Worker .maxlen = IFQDISCSIZ },
374*4dc78e53SAndroid Build Coastguard Worker [IFLA_STATS] = { .minlen = _nl_offsetofend (struct rtnl_link_stats, tx_compressed) },
375*4dc78e53SAndroid Build Coastguard Worker [IFLA_STATS64] = { .minlen = _nl_offsetofend (struct rtnl_link_stats64, tx_compressed) },
376*4dc78e53SAndroid Build Coastguard Worker [IFLA_MAP] = { .minlen = sizeof(struct rtnl_link_ifmap) },
377*4dc78e53SAndroid Build Coastguard Worker [IFLA_IFALIAS] = { .type = NLA_STRING, .maxlen = IFALIASZ },
378*4dc78e53SAndroid Build Coastguard Worker [IFLA_NUM_VF] = { .type = NLA_U32 },
379*4dc78e53SAndroid Build Coastguard Worker [IFLA_VFINFO_LIST] = { .type = NLA_NESTED },
380*4dc78e53SAndroid Build Coastguard Worker [IFLA_AF_SPEC] = { .type = NLA_NESTED },
381*4dc78e53SAndroid Build Coastguard Worker [IFLA_PROMISCUITY] = { .type = NLA_U32 },
382*4dc78e53SAndroid Build Coastguard Worker [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
383*4dc78e53SAndroid Build Coastguard Worker [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
384*4dc78e53SAndroid Build Coastguard Worker [IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 },
385*4dc78e53SAndroid Build Coastguard Worker [IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 },
386*4dc78e53SAndroid Build Coastguard Worker [IFLA_GROUP] = { .type = NLA_U32 },
387*4dc78e53SAndroid Build Coastguard Worker [IFLA_CARRIER] = { .type = NLA_U8 },
388*4dc78e53SAndroid Build Coastguard Worker [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 },
389*4dc78e53SAndroid Build Coastguard Worker [IFLA_PHYS_PORT_ID] = { .type = NLA_UNSPEC },
390*4dc78e53SAndroid Build Coastguard Worker [IFLA_PHYS_PORT_NAME] = { .type = NLA_STRING, .maxlen = IFNAMSIZ },
391*4dc78e53SAndroid Build Coastguard Worker [IFLA_PHYS_SWITCH_ID] = { .type = NLA_UNSPEC },
392*4dc78e53SAndroid Build Coastguard Worker [IFLA_NET_NS_PID] = { .type = NLA_U32 },
393*4dc78e53SAndroid Build Coastguard Worker [IFLA_NET_NS_FD] = { .type = NLA_U32 },
394*4dc78e53SAndroid Build Coastguard Worker };
395*4dc78e53SAndroid Build Coastguard Worker
396*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy link_info_policy[IFLA_INFO_MAX+1] = {
397*4dc78e53SAndroid Build Coastguard Worker [IFLA_INFO_KIND] = { .type = NLA_STRING },
398*4dc78e53SAndroid Build Coastguard Worker [IFLA_INFO_DATA] = { .type = NLA_NESTED },
399*4dc78e53SAndroid Build Coastguard Worker [IFLA_INFO_XSTATS] = { .type = NLA_NESTED },
400*4dc78e53SAndroid Build Coastguard Worker };
401*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_info_parse(struct rtnl_link * link,struct nlattr ** tb)402*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_info_parse(struct rtnl_link *link, struct nlattr **tb)
403*4dc78e53SAndroid Build Coastguard Worker {
404*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_IFNAME] == NULL)
405*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
406*4dc78e53SAndroid Build Coastguard Worker
407*4dc78e53SAndroid Build Coastguard Worker nla_strlcpy(link->l_name, tb[IFLA_IFNAME], IFNAMSIZ);
408*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_IFNAME;
409*4dc78e53SAndroid Build Coastguard Worker
410*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_STATS]) {
411*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_stats *st = nla_data(tb[IFLA_STATS]);
412*4dc78e53SAndroid Build Coastguard Worker
413*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_PACKETS] = st->rx_packets;
414*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_PACKETS] = st->tx_packets;
415*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_BYTES] = st->rx_bytes;
416*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_BYTES] = st->tx_bytes;
417*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_ERRORS] = st->rx_errors;
418*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ERRORS] = st->tx_errors;
419*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_DROPPED] = st->rx_dropped;
420*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_DROPPED] = st->tx_dropped;
421*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_MULTICAST] = st->multicast;
422*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_COLLISIONS] = st->collisions;
423*4dc78e53SAndroid Build Coastguard Worker
424*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_LEN_ERR] = st->rx_length_errors;
425*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_OVER_ERR] = st->rx_over_errors;
426*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_CRC_ERR] = st->rx_crc_errors;
427*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st->rx_frame_errors;
428*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st->rx_fifo_errors;
429*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st->rx_missed_errors;
430*4dc78e53SAndroid Build Coastguard Worker
431*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st->tx_aborted_errors;
432*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st->tx_carrier_errors;
433*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st->tx_fifo_errors;
434*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st->tx_heartbeat_errors;
435*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_WIN_ERR] = st->tx_window_errors;
436*4dc78e53SAndroid Build Coastguard Worker
437*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_COMPRESSED] = st->rx_compressed;
438*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_COMPRESSED] = st->tx_compressed;
439*4dc78e53SAndroid Build Coastguard Worker
440*4dc78e53SAndroid Build Coastguard Worker /* beware: @st might not be the full struct, only fields up to
441*4dc78e53SAndroid Build Coastguard Worker * tx_compressed are present. See _nl_offsetofend() above. */
442*4dc78e53SAndroid Build Coastguard Worker
443*4dc78e53SAndroid Build Coastguard Worker if (_nla_len(tb[IFLA_STATS]) >= _nl_offsetofend (struct rtnl_link_stats, rx_nohandler))
444*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_NOHANDLER] = st->rx_nohandler;
445*4dc78e53SAndroid Build Coastguard Worker else
446*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_NOHANDLER] = 0;
447*4dc78e53SAndroid Build Coastguard Worker
448*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_STATS;
449*4dc78e53SAndroid Build Coastguard Worker }
450*4dc78e53SAndroid Build Coastguard Worker
451*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_STATS64]) {
452*4dc78e53SAndroid Build Coastguard Worker /*
453*4dc78e53SAndroid Build Coastguard Worker * This structure contains 64bit parameters, and per the
454*4dc78e53SAndroid Build Coastguard Worker * documentation in lib/attr.c, must not be accessed
455*4dc78e53SAndroid Build Coastguard Worker * directly (because of alignment to 4 instead of 8).
456*4dc78e53SAndroid Build Coastguard Worker * Therefore, copy the data to the stack and access it from
457*4dc78e53SAndroid Build Coastguard Worker * there, where it will be aligned to 8.
458*4dc78e53SAndroid Build Coastguard Worker */
459*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_stats64 st = { 0 };
460*4dc78e53SAndroid Build Coastguard Worker
461*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(&st, tb[IFLA_STATS64], sizeof (st));
462*4dc78e53SAndroid Build Coastguard Worker
463*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_PACKETS] = st.rx_packets;
464*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_PACKETS] = st.tx_packets;
465*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_BYTES] = st.rx_bytes;
466*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_BYTES] = st.tx_bytes;
467*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_ERRORS] = st.rx_errors;
468*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ERRORS] = st.tx_errors;
469*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_DROPPED] = st.rx_dropped;
470*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_DROPPED] = st.tx_dropped;
471*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_MULTICAST] = st.multicast;
472*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_COLLISIONS] = st.collisions;
473*4dc78e53SAndroid Build Coastguard Worker
474*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_LEN_ERR] = st.rx_length_errors;
475*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_OVER_ERR] = st.rx_over_errors;
476*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_CRC_ERR] = st.rx_crc_errors;
477*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FRAME_ERR] = st.rx_frame_errors;
478*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FIFO_ERR] = st.rx_fifo_errors;
479*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_MISSED_ERR] = st.rx_missed_errors;
480*4dc78e53SAndroid Build Coastguard Worker
481*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ABORT_ERR] = st.tx_aborted_errors;
482*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_CARRIER_ERR] = st.tx_carrier_errors;
483*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_FIFO_ERR] = st.tx_fifo_errors;
484*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_HBEAT_ERR] = st.tx_heartbeat_errors;
485*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_WIN_ERR] = st.tx_window_errors;
486*4dc78e53SAndroid Build Coastguard Worker
487*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_COMPRESSED] = st.rx_compressed;
488*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_COMPRESSED] = st.tx_compressed;
489*4dc78e53SAndroid Build Coastguard Worker
490*4dc78e53SAndroid Build Coastguard Worker /* beware: @st might not be the full struct, only fields up to
491*4dc78e53SAndroid Build Coastguard Worker * tx_compressed are present. See _nl_offsetofend() above. */
492*4dc78e53SAndroid Build Coastguard Worker
493*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_NOHANDLER] = st.rx_nohandler;
494*4dc78e53SAndroid Build Coastguard Worker
495*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_STATS;
496*4dc78e53SAndroid Build Coastguard Worker }
497*4dc78e53SAndroid Build Coastguard Worker
498*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_TXQLEN]) {
499*4dc78e53SAndroid Build Coastguard Worker link->l_txqlen = nla_get_u32(tb[IFLA_TXQLEN]);
500*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_TXQLEN;
501*4dc78e53SAndroid Build Coastguard Worker }
502*4dc78e53SAndroid Build Coastguard Worker
503*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_MTU]) {
504*4dc78e53SAndroid Build Coastguard Worker link->l_mtu = nla_get_u32(tb[IFLA_MTU]);
505*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_MTU;
506*4dc78e53SAndroid Build Coastguard Worker }
507*4dc78e53SAndroid Build Coastguard Worker
508*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_ADDRESS]) {
509*4dc78e53SAndroid Build Coastguard Worker link->l_addr = nl_addr_alloc_attr(tb[IFLA_ADDRESS], AF_UNSPEC);
510*4dc78e53SAndroid Build Coastguard Worker if (link->l_addr == NULL)
511*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
512*4dc78e53SAndroid Build Coastguard Worker nl_addr_set_family(link->l_addr,
513*4dc78e53SAndroid Build Coastguard Worker nl_addr_guess_family(link->l_addr));
514*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_ADDR;
515*4dc78e53SAndroid Build Coastguard Worker }
516*4dc78e53SAndroid Build Coastguard Worker
517*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_BROADCAST]) {
518*4dc78e53SAndroid Build Coastguard Worker link->l_bcast = nl_addr_alloc_attr(tb[IFLA_BROADCAST],
519*4dc78e53SAndroid Build Coastguard Worker AF_UNSPEC);
520*4dc78e53SAndroid Build Coastguard Worker if (link->l_bcast == NULL)
521*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
522*4dc78e53SAndroid Build Coastguard Worker nl_addr_set_family(link->l_bcast,
523*4dc78e53SAndroid Build Coastguard Worker nl_addr_guess_family(link->l_bcast));
524*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_BRD;
525*4dc78e53SAndroid Build Coastguard Worker }
526*4dc78e53SAndroid Build Coastguard Worker
527*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_LINK]) {
528*4dc78e53SAndroid Build Coastguard Worker link->l_link = nla_get_u32(tb[IFLA_LINK]);
529*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINK;
530*4dc78e53SAndroid Build Coastguard Worker }
531*4dc78e53SAndroid Build Coastguard Worker
532*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_LINK_NETNSID]) {
533*4dc78e53SAndroid Build Coastguard Worker link->l_link_netnsid = nla_get_s32(tb[IFLA_LINK_NETNSID]);
534*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINK_NETNSID;
535*4dc78e53SAndroid Build Coastguard Worker }
536*4dc78e53SAndroid Build Coastguard Worker
537*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_WEIGHT]) {
538*4dc78e53SAndroid Build Coastguard Worker link->l_weight = nla_get_u32(tb[IFLA_WEIGHT]);
539*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_WEIGHT;
540*4dc78e53SAndroid Build Coastguard Worker }
541*4dc78e53SAndroid Build Coastguard Worker
542*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_QDISC]) {
543*4dc78e53SAndroid Build Coastguard Worker nla_strlcpy(link->l_qdisc, tb[IFLA_QDISC], IFQDISCSIZ);
544*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_QDISC;
545*4dc78e53SAndroid Build Coastguard Worker }
546*4dc78e53SAndroid Build Coastguard Worker
547*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_MAP]) {
548*4dc78e53SAndroid Build Coastguard Worker nla_memcpy(&link->l_map, tb[IFLA_MAP],
549*4dc78e53SAndroid Build Coastguard Worker sizeof(struct rtnl_link_ifmap));
550*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_MAP;
551*4dc78e53SAndroid Build Coastguard Worker }
552*4dc78e53SAndroid Build Coastguard Worker
553*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_MASTER]) {
554*4dc78e53SAndroid Build Coastguard Worker link->l_master = nla_get_u32(tb[IFLA_MASTER]);
555*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_MASTER;
556*4dc78e53SAndroid Build Coastguard Worker }
557*4dc78e53SAndroid Build Coastguard Worker
558*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_CARRIER]) {
559*4dc78e53SAndroid Build Coastguard Worker link->l_carrier = nla_get_u8(tb[IFLA_CARRIER]);
560*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_CARRIER;
561*4dc78e53SAndroid Build Coastguard Worker }
562*4dc78e53SAndroid Build Coastguard Worker
563*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_CARRIER_CHANGES]) {
564*4dc78e53SAndroid Build Coastguard Worker link->l_carrier_changes = nla_get_u32(tb[IFLA_CARRIER_CHANGES]);
565*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_CARRIER_CHANGES;
566*4dc78e53SAndroid Build Coastguard Worker }
567*4dc78e53SAndroid Build Coastguard Worker
568*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_OPERSTATE]) {
569*4dc78e53SAndroid Build Coastguard Worker link->l_operstate = nla_get_u8(tb[IFLA_OPERSTATE]);
570*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_OPERSTATE;
571*4dc78e53SAndroid Build Coastguard Worker }
572*4dc78e53SAndroid Build Coastguard Worker
573*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_LINKMODE]) {
574*4dc78e53SAndroid Build Coastguard Worker link->l_linkmode = nla_get_u8(tb[IFLA_LINKMODE]);
575*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKMODE;
576*4dc78e53SAndroid Build Coastguard Worker }
577*4dc78e53SAndroid Build Coastguard Worker
578*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_IFALIAS]) {
579*4dc78e53SAndroid Build Coastguard Worker link->l_ifalias = nla_strdup(tb[IFLA_IFALIAS]);
580*4dc78e53SAndroid Build Coastguard Worker if (link->l_ifalias == NULL)
581*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
582*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_IFALIAS;
583*4dc78e53SAndroid Build Coastguard Worker }
584*4dc78e53SAndroid Build Coastguard Worker
585*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_NET_NS_FD]) {
586*4dc78e53SAndroid Build Coastguard Worker link->l_ns_fd = nla_get_u32(tb[IFLA_NET_NS_FD]);
587*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NS_FD;
588*4dc78e53SAndroid Build Coastguard Worker }
589*4dc78e53SAndroid Build Coastguard Worker
590*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_NET_NS_PID]) {
591*4dc78e53SAndroid Build Coastguard Worker link->l_ns_pid = nla_get_u32(tb[IFLA_NET_NS_PID]);
592*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NS_PID;
593*4dc78e53SAndroid Build Coastguard Worker }
594*4dc78e53SAndroid Build Coastguard Worker
595*4dc78e53SAndroid Build Coastguard Worker return 0;
596*4dc78e53SAndroid Build Coastguard Worker }
597*4dc78e53SAndroid Build Coastguard Worker
link_msg_parser(struct nl_cache_ops * ops,struct sockaddr_nl * who,struct nlmsghdr * n,struct nl_parser_param * pp)598*4dc78e53SAndroid Build Coastguard Worker static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
599*4dc78e53SAndroid Build Coastguard Worker struct nlmsghdr *n, struct nl_parser_param *pp)
600*4dc78e53SAndroid Build Coastguard Worker {
601*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *link = NULL;
602*4dc78e53SAndroid Build Coastguard Worker struct nla_policy real_link_policy[ARRAY_SIZE(rtln_link_policy)];
603*4dc78e53SAndroid Build Coastguard Worker struct nla_policy *link_policy = rtln_link_policy;
604*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_af_ops *af_ops_family;
605*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg *ifi;
606*4dc78e53SAndroid Build Coastguard Worker struct nlattr *tb[IFLA_MAX+1];
607*4dc78e53SAndroid Build Coastguard Worker int err, family;
608*4dc78e53SAndroid Build Coastguard Worker
609*4dc78e53SAndroid Build Coastguard Worker link = rtnl_link_alloc();
610*4dc78e53SAndroid Build Coastguard Worker if (link == NULL)
611*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
612*4dc78e53SAndroid Build Coastguard Worker
613*4dc78e53SAndroid Build Coastguard Worker link->ce_msgtype = n->nlmsg_type;
614*4dc78e53SAndroid Build Coastguard Worker
615*4dc78e53SAndroid Build Coastguard Worker if (!nlmsg_valid_hdr(n, sizeof(*ifi)))
616*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSG_TOOSHORT;
617*4dc78e53SAndroid Build Coastguard Worker
618*4dc78e53SAndroid Build Coastguard Worker ifi = nlmsg_data(n);
619*4dc78e53SAndroid Build Coastguard Worker link->l_family = family = ifi->ifi_family;
620*4dc78e53SAndroid Build Coastguard Worker link->l_arptype = ifi->ifi_type;
621*4dc78e53SAndroid Build Coastguard Worker link->l_index = ifi->ifi_index;
622*4dc78e53SAndroid Build Coastguard Worker link->l_flags = ifi->ifi_flags;
623*4dc78e53SAndroid Build Coastguard Worker link->l_change = ifi->ifi_change;
624*4dc78e53SAndroid Build Coastguard Worker link->ce_mask = (LINK_ATTR_FAMILY |
625*4dc78e53SAndroid Build Coastguard Worker LINK_ATTR_ARPTYPE| LINK_ATTR_IFINDEX |
626*4dc78e53SAndroid Build Coastguard Worker LINK_ATTR_FLAGS | LINK_ATTR_CHANGE);
627*4dc78e53SAndroid Build Coastguard Worker
628*4dc78e53SAndroid Build Coastguard Worker if ((link->l_af_ops = af_lookup_and_alloc(link, family))) {
629*4dc78e53SAndroid Build Coastguard Worker if (link->l_af_ops->ao_protinfo_policy) {
630*4dc78e53SAndroid Build Coastguard Worker _NL_STATIC_ASSERT (sizeof(rtln_link_policy) == sizeof(real_link_policy));
631*4dc78e53SAndroid Build Coastguard Worker memcpy(&real_link_policy, rtln_link_policy, sizeof(rtln_link_policy));
632*4dc78e53SAndroid Build Coastguard Worker memcpy(&real_link_policy[IFLA_PROTINFO],
633*4dc78e53SAndroid Build Coastguard Worker link->l_af_ops->ao_protinfo_policy,
634*4dc78e53SAndroid Build Coastguard Worker sizeof(struct nla_policy));
635*4dc78e53SAndroid Build Coastguard Worker link_policy = real_link_policy;
636*4dc78e53SAndroid Build Coastguard Worker }
637*4dc78e53SAndroid Build Coastguard Worker }
638*4dc78e53SAndroid Build Coastguard Worker
639*4dc78e53SAndroid Build Coastguard Worker af_ops_family = link->l_af_ops;
640*4dc78e53SAndroid Build Coastguard Worker
641*4dc78e53SAndroid Build Coastguard Worker err = nlmsg_parse(n, sizeof(*ifi), tb, IFLA_MAX, link_policy);
642*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
643*4dc78e53SAndroid Build Coastguard Worker return err;
644*4dc78e53SAndroid Build Coastguard Worker
645*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_info_parse(link, tb);
646*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
647*4dc78e53SAndroid Build Coastguard Worker return err;
648*4dc78e53SAndroid Build Coastguard Worker
649*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_NUM_VF]) {
650*4dc78e53SAndroid Build Coastguard Worker link->l_num_vf = nla_get_u32(tb[IFLA_NUM_VF]);
651*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NUM_VF;
652*4dc78e53SAndroid Build Coastguard Worker if (link->l_num_vf && tb[IFLA_VFINFO_LIST]) {
653*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_sriov_parse_vflist(link, tb)) < 0)
654*4dc78e53SAndroid Build Coastguard Worker return err;
655*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_VF_LIST;
656*4dc78e53SAndroid Build Coastguard Worker }
657*4dc78e53SAndroid Build Coastguard Worker }
658*4dc78e53SAndroid Build Coastguard Worker
659*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_LINKINFO]) {
660*4dc78e53SAndroid Build Coastguard Worker struct nlattr *li[IFLA_INFO_MAX+1];
661*4dc78e53SAndroid Build Coastguard Worker
662*4dc78e53SAndroid Build Coastguard Worker err = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO],
663*4dc78e53SAndroid Build Coastguard Worker link_info_policy);
664*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
665*4dc78e53SAndroid Build Coastguard Worker return err;
666*4dc78e53SAndroid Build Coastguard Worker
667*4dc78e53SAndroid Build Coastguard Worker if (li[IFLA_INFO_KIND]) {
668*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_info_ops *ops;
669*4dc78e53SAndroid Build Coastguard Worker const char *kind = nla_get_string(li[IFLA_INFO_KIND]);
670*4dc78e53SAndroid Build Coastguard Worker int af;
671*4dc78e53SAndroid Build Coastguard Worker
672*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_set_type(link, kind);
673*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
674*4dc78e53SAndroid Build Coastguard Worker return err;
675*4dc78e53SAndroid Build Coastguard Worker
676*4dc78e53SAndroid Build Coastguard Worker if ( (af = nl_str2af(kind)) >= 0
677*4dc78e53SAndroid Build Coastguard Worker && !link->l_af_ops
678*4dc78e53SAndroid Build Coastguard Worker && (link->l_af_ops = af_lookup_and_alloc(link, af))) {
679*4dc78e53SAndroid Build Coastguard Worker link->l_family = af;
680*4dc78e53SAndroid Build Coastguard Worker if (link->l_af_ops->ao_protinfo_policy)
681*4dc78e53SAndroid Build Coastguard Worker tb[IFLA_PROTINFO] = (struct nlattr *)link->l_af_ops->ao_protinfo_policy;
682*4dc78e53SAndroid Build Coastguard Worker }
683*4dc78e53SAndroid Build Coastguard Worker
684*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops)
685*4dc78e53SAndroid Build Coastguard Worker release_link_info(link);
686*4dc78e53SAndroid Build Coastguard Worker
687*4dc78e53SAndroid Build Coastguard Worker ops = rtnl_link_info_ops_lookup(kind);
688*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops = ops;
689*4dc78e53SAndroid Build Coastguard Worker
690*4dc78e53SAndroid Build Coastguard Worker if (ops) {
691*4dc78e53SAndroid Build Coastguard Worker if (ops->io_parse &&
692*4dc78e53SAndroid Build Coastguard Worker (li[IFLA_INFO_DATA] || li[IFLA_INFO_XSTATS])) {
693*4dc78e53SAndroid Build Coastguard Worker err = ops->io_parse(link, li[IFLA_INFO_DATA],
694*4dc78e53SAndroid Build Coastguard Worker li[IFLA_INFO_XSTATS]);
695*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
696*4dc78e53SAndroid Build Coastguard Worker return err;
697*4dc78e53SAndroid Build Coastguard Worker } else {
698*4dc78e53SAndroid Build Coastguard Worker /* XXX: Warn about unparsed info? */
699*4dc78e53SAndroid Build Coastguard Worker }
700*4dc78e53SAndroid Build Coastguard Worker }
701*4dc78e53SAndroid Build Coastguard Worker
702*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKINFO;
703*4dc78e53SAndroid Build Coastguard Worker }
704*4dc78e53SAndroid Build Coastguard Worker
705*4dc78e53SAndroid Build Coastguard Worker if (li[IFLA_INFO_SLAVE_KIND]) {
706*4dc78e53SAndroid Build Coastguard Worker const char *kind = nla_get_string(li[IFLA_INFO_SLAVE_KIND]);
707*4dc78e53SAndroid Build Coastguard Worker
708*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_set_slave_type(link, kind);
709*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
710*4dc78e53SAndroid Build Coastguard Worker return err;
711*4dc78e53SAndroid Build Coastguard Worker
712*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
713*4dc78e53SAndroid Build Coastguard Worker }
714*4dc78e53SAndroid Build Coastguard Worker }
715*4dc78e53SAndroid Build Coastguard Worker
716*4dc78e53SAndroid Build Coastguard Worker if ( tb[IFLA_PROTINFO]
717*4dc78e53SAndroid Build Coastguard Worker && link->l_af_ops
718*4dc78e53SAndroid Build Coastguard Worker && link->l_af_ops->ao_parse_protinfo) {
719*4dc78e53SAndroid Build Coastguard Worker err = link->l_af_ops->ao_parse_protinfo(link, tb[IFLA_PROTINFO],
720*4dc78e53SAndroid Build Coastguard Worker link->l_af_data[link->l_family]);
721*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
722*4dc78e53SAndroid Build Coastguard Worker return err;
723*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PROTINFO;
724*4dc78e53SAndroid Build Coastguard Worker }
725*4dc78e53SAndroid Build Coastguard Worker
726*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_AF_SPEC]) {
727*4dc78e53SAndroid Build Coastguard Worker /* parsing of IFLA_AF_SPEC is dependent on the family used
728*4dc78e53SAndroid Build Coastguard Worker * in the request message.
729*4dc78e53SAndroid Build Coastguard Worker */
730*4dc78e53SAndroid Build Coastguard Worker if ( af_ops_family
731*4dc78e53SAndroid Build Coastguard Worker && af_ops_family->ao_parse_af_full) {
732*4dc78e53SAndroid Build Coastguard Worker err = af_ops_family->ao_parse_af_full(link,
733*4dc78e53SAndroid Build Coastguard Worker tb[IFLA_AF_SPEC],
734*4dc78e53SAndroid Build Coastguard Worker link->l_af_data[af_ops_family->ao_family]);
735*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
736*4dc78e53SAndroid Build Coastguard Worker return err;
737*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_AF_SPEC;
738*4dc78e53SAndroid Build Coastguard Worker } else if (family == AF_UNSPEC) {
739*4dc78e53SAndroid Build Coastguard Worker struct nlattr *af_attr;
740*4dc78e53SAndroid Build Coastguard Worker int remaining;
741*4dc78e53SAndroid Build Coastguard Worker
742*4dc78e53SAndroid Build Coastguard Worker nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC], remaining) {
743*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link_af_ops struct rtnl_link_af_ops *af_ops = NULL;
744*4dc78e53SAndroid Build Coastguard Worker
745*4dc78e53SAndroid Build Coastguard Worker af_ops = af_lookup_and_alloc(link, nla_type(af_attr));
746*4dc78e53SAndroid Build Coastguard Worker if (af_ops && af_ops->ao_parse_af) {
747*4dc78e53SAndroid Build Coastguard Worker char *af_data = link->l_af_data[nla_type(af_attr)];
748*4dc78e53SAndroid Build Coastguard Worker
749*4dc78e53SAndroid Build Coastguard Worker err = af_ops->ao_parse_af(link, af_attr, af_data);
750*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
751*4dc78e53SAndroid Build Coastguard Worker return err;
752*4dc78e53SAndroid Build Coastguard Worker }
753*4dc78e53SAndroid Build Coastguard Worker }
754*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_AF_SPEC;
755*4dc78e53SAndroid Build Coastguard Worker } else {
756*4dc78e53SAndroid Build Coastguard Worker NL_DBG(3, "IFLA_AF_SPEC parsing not implemented for family %d\n",
757*4dc78e53SAndroid Build Coastguard Worker family);
758*4dc78e53SAndroid Build Coastguard Worker }
759*4dc78e53SAndroid Build Coastguard Worker }
760*4dc78e53SAndroid Build Coastguard Worker
761*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_PROMISCUITY]) {
762*4dc78e53SAndroid Build Coastguard Worker link->l_promiscuity = nla_get_u32(tb[IFLA_PROMISCUITY]);
763*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PROMISCUITY;
764*4dc78e53SAndroid Build Coastguard Worker }
765*4dc78e53SAndroid Build Coastguard Worker
766*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_NUM_TX_QUEUES]) {
767*4dc78e53SAndroid Build Coastguard Worker link->l_num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
768*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
769*4dc78e53SAndroid Build Coastguard Worker }
770*4dc78e53SAndroid Build Coastguard Worker
771*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_NUM_RX_QUEUES]) {
772*4dc78e53SAndroid Build Coastguard Worker link->l_num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]);
773*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
774*4dc78e53SAndroid Build Coastguard Worker }
775*4dc78e53SAndroid Build Coastguard Worker
776*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_GSO_MAX_SEGS]) {
777*4dc78e53SAndroid Build Coastguard Worker link->l_gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
778*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_GSO_MAX_SEGS;
779*4dc78e53SAndroid Build Coastguard Worker }
780*4dc78e53SAndroid Build Coastguard Worker
781*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_GSO_MAX_SIZE]) {
782*4dc78e53SAndroid Build Coastguard Worker link->l_gso_max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]);
783*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_GSO_MAX_SIZE;
784*4dc78e53SAndroid Build Coastguard Worker }
785*4dc78e53SAndroid Build Coastguard Worker
786*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_GROUP]) {
787*4dc78e53SAndroid Build Coastguard Worker link->l_group = nla_get_u32(tb[IFLA_GROUP]);
788*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_GROUP;
789*4dc78e53SAndroid Build Coastguard Worker }
790*4dc78e53SAndroid Build Coastguard Worker
791*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_PHYS_PORT_ID]) {
792*4dc78e53SAndroid Build Coastguard Worker link->l_phys_port_id = nl_data_alloc_attr(tb[IFLA_PHYS_PORT_ID]);
793*4dc78e53SAndroid Build Coastguard Worker if (link->l_phys_port_id == NULL)
794*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
795*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PHYS_PORT_ID;
796*4dc78e53SAndroid Build Coastguard Worker }
797*4dc78e53SAndroid Build Coastguard Worker
798*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_PHYS_PORT_NAME]) {
799*4dc78e53SAndroid Build Coastguard Worker nla_strlcpy(link->l_phys_port_name, tb[IFLA_PHYS_PORT_NAME], IFNAMSIZ);
800*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PHYS_PORT_NAME;
801*4dc78e53SAndroid Build Coastguard Worker }
802*4dc78e53SAndroid Build Coastguard Worker
803*4dc78e53SAndroid Build Coastguard Worker if (tb[IFLA_PHYS_SWITCH_ID]) {
804*4dc78e53SAndroid Build Coastguard Worker link->l_phys_switch_id = nl_data_alloc_attr(tb[IFLA_PHYS_SWITCH_ID]);
805*4dc78e53SAndroid Build Coastguard Worker if (link->l_phys_switch_id == NULL)
806*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
807*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PHYS_SWITCH_ID;
808*4dc78e53SAndroid Build Coastguard Worker }
809*4dc78e53SAndroid Build Coastguard Worker
810*4dc78e53SAndroid Build Coastguard Worker return pp->pp_cb((struct nl_object *) link, pp);
811*4dc78e53SAndroid Build Coastguard Worker }
812*4dc78e53SAndroid Build Coastguard Worker
link_request_update(struct nl_cache * cache,struct nl_sock * sk)813*4dc78e53SAndroid Build Coastguard Worker static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
814*4dc78e53SAndroid Build Coastguard Worker {
815*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
816*4dc78e53SAndroid Build Coastguard Worker int family = cache->c_iarg1;
817*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg hdr = { .ifi_family = family };
818*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_af_ops *ops;
819*4dc78e53SAndroid Build Coastguard Worker int err;
820*4dc78e53SAndroid Build Coastguard Worker __u32 ext_filter_mask = RTEXT_FILTER_VF;
821*4dc78e53SAndroid Build Coastguard Worker
822*4dc78e53SAndroid Build Coastguard Worker msg = nlmsg_alloc_simple(RTM_GETLINK, NLM_F_DUMP);
823*4dc78e53SAndroid Build Coastguard Worker if (!msg)
824*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
825*4dc78e53SAndroid Build Coastguard Worker
826*4dc78e53SAndroid Build Coastguard Worker if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
827*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
828*4dc78e53SAndroid Build Coastguard Worker
829*4dc78e53SAndroid Build Coastguard Worker ops = rtnl_link_af_ops_lookup(family);
830*4dc78e53SAndroid Build Coastguard Worker if (ops && ops->ao_get_af) {
831*4dc78e53SAndroid Build Coastguard Worker err = ops->ao_get_af(msg, &ext_filter_mask);
832*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
833*4dc78e53SAndroid Build Coastguard Worker return err;
834*4dc78e53SAndroid Build Coastguard Worker }
835*4dc78e53SAndroid Build Coastguard Worker
836*4dc78e53SAndroid Build Coastguard Worker if (ext_filter_mask) {
837*4dc78e53SAndroid Build Coastguard Worker err = nla_put(msg, IFLA_EXT_MASK, sizeof(ext_filter_mask), &ext_filter_mask);
838*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
839*4dc78e53SAndroid Build Coastguard Worker return err;
840*4dc78e53SAndroid Build Coastguard Worker }
841*4dc78e53SAndroid Build Coastguard Worker
842*4dc78e53SAndroid Build Coastguard Worker err = nl_send_auto(sk, msg);
843*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
844*4dc78e53SAndroid Build Coastguard Worker return 0;
845*4dc78e53SAndroid Build Coastguard Worker
846*4dc78e53SAndroid Build Coastguard Worker return 0;
847*4dc78e53SAndroid Build Coastguard Worker }
848*4dc78e53SAndroid Build Coastguard Worker
link_dump_line(struct nl_object * obj,struct nl_dump_params * p)849*4dc78e53SAndroid Build Coastguard Worker static void link_dump_line(struct nl_object *obj, struct nl_dump_params *p)
850*4dc78e53SAndroid Build Coastguard Worker {
851*4dc78e53SAndroid Build Coastguard Worker char buf[128];
852*4dc78e53SAndroid Build Coastguard Worker struct nl_cache *cache = obj->ce_cache;
853*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link = (struct rtnl_link *) obj;
854*4dc78e53SAndroid Build Coastguard Worker int fetched_cache = 0;
855*4dc78e53SAndroid Build Coastguard Worker
856*4dc78e53SAndroid Build Coastguard Worker if (!cache) {
857*4dc78e53SAndroid Build Coastguard Worker cache = nl_cache_mngt_require_safe("route/link");
858*4dc78e53SAndroid Build Coastguard Worker fetched_cache = 1;
859*4dc78e53SAndroid Build Coastguard Worker }
860*4dc78e53SAndroid Build Coastguard Worker
861*4dc78e53SAndroid Build Coastguard Worker if (link->l_family != AF_UNSPEC)
862*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, "%s ", nl_af2str(link->l_family, buf, sizeof(buf)));
863*4dc78e53SAndroid Build Coastguard Worker
864*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, "%s %s ", link->l_name,
865*4dc78e53SAndroid Build Coastguard Worker nl_llproto2str(link->l_arptype, buf, sizeof(buf)));
866*4dc78e53SAndroid Build Coastguard Worker
867*4dc78e53SAndroid Build Coastguard Worker if (link->l_addr && !nl_addr_iszero(link->l_addr))
868*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "%s ", nl_addr2str(link->l_addr, buf, sizeof(buf)));
869*4dc78e53SAndroid Build Coastguard Worker
870*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_MASTER) {
871*4dc78e53SAndroid Build Coastguard Worker if (cache) {
872*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *master = rtnl_link_get(cache, link->l_master);
873*4dc78e53SAndroid Build Coastguard Worker
874*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "master %s ", master ? master->l_name : "inv");
875*4dc78e53SAndroid Build Coastguard Worker } else
876*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "master %d ", link->l_master);
877*4dc78e53SAndroid Build Coastguard Worker }
878*4dc78e53SAndroid Build Coastguard Worker
879*4dc78e53SAndroid Build Coastguard Worker rtnl_link_flags2str(link->l_flags, buf, sizeof(buf));
880*4dc78e53SAndroid Build Coastguard Worker if (buf[0])
881*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "<%s> ", buf);
882*4dc78e53SAndroid Build Coastguard Worker
883*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINK) {
884*4dc78e53SAndroid Build Coastguard Worker if ( cache
885*4dc78e53SAndroid Build Coastguard Worker && !(link->ce_mask & LINK_ATTR_LINK_NETNSID)) {
886*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *ll = rtnl_link_get(cache, link->l_link);
887*4dc78e53SAndroid Build Coastguard Worker
888*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "slave-of %s ", ll ? ll->l_name : "NONE");
889*4dc78e53SAndroid Build Coastguard Worker } else
890*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "slave-of %d ", link->l_link);
891*4dc78e53SAndroid Build Coastguard Worker }
892*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
893*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "link-netnsid %d ", link->l_link_netnsid);
894*4dc78e53SAndroid Build Coastguard Worker
895*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_GROUP)
896*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "group %u ", link->l_group);
897*4dc78e53SAndroid Build Coastguard Worker
898*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_LINE])
899*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops->io_dump[NL_DUMP_LINE](link, p);
900*4dc78e53SAndroid Build Coastguard Worker
901*4dc78e53SAndroid Build Coastguard Worker do_foreach_af(link, af_dump_line, p);
902*4dc78e53SAndroid Build Coastguard Worker
903*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
904*4dc78e53SAndroid Build Coastguard Worker
905*4dc78e53SAndroid Build Coastguard Worker if (fetched_cache)
906*4dc78e53SAndroid Build Coastguard Worker nl_cache_put(cache);
907*4dc78e53SAndroid Build Coastguard Worker }
908*4dc78e53SAndroid Build Coastguard Worker
link_dump_details(struct nl_object * obj,struct nl_dump_params * p)909*4dc78e53SAndroid Build Coastguard Worker static void link_dump_details(struct nl_object *obj, struct nl_dump_params *p)
910*4dc78e53SAndroid Build Coastguard Worker {
911*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link = (struct rtnl_link *) obj;
912*4dc78e53SAndroid Build Coastguard Worker char buf[64];
913*4dc78e53SAndroid Build Coastguard Worker
914*4dc78e53SAndroid Build Coastguard Worker link_dump_line(obj, p);
915*4dc78e53SAndroid Build Coastguard Worker
916*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " mtu %u ", link->l_mtu);
917*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "txqlen %u weight %u ", link->l_txqlen, link->l_weight);
918*4dc78e53SAndroid Build Coastguard Worker
919*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_QDISC)
920*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "qdisc %s ", link->l_qdisc);
921*4dc78e53SAndroid Build Coastguard Worker
922*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_MAP && link->l_map.lm_irq)
923*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "irq %u ", link->l_map.lm_irq);
924*4dc78e53SAndroid Build Coastguard Worker
925*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_IFINDEX)
926*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "index %u ", link->l_index);
927*4dc78e53SAndroid Build Coastguard Worker
928*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_PROMISCUITY && link->l_promiscuity > 0)
929*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "promisc-mode (%u users) ", link->l_promiscuity);
930*4dc78e53SAndroid Build Coastguard Worker
931*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
932*4dc78e53SAndroid Build Coastguard Worker
933*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_IFALIAS)
934*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " alias %s\n", link->l_ifalias);
935*4dc78e53SAndroid Build Coastguard Worker
936*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " ");
937*4dc78e53SAndroid Build Coastguard Worker
938*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
939*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "txq %u ", link->l_num_tx_queues);
940*4dc78e53SAndroid Build Coastguard Worker
941*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
942*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "rxq %u ", link->l_num_rx_queues);
943*4dc78e53SAndroid Build Coastguard Worker
944*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_BRD)
945*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "brd %s ", nl_addr2str(link->l_bcast, buf,
946*4dc78e53SAndroid Build Coastguard Worker sizeof(buf)));
947*4dc78e53SAndroid Build Coastguard Worker
948*4dc78e53SAndroid Build Coastguard Worker if ((link->ce_mask & LINK_ATTR_OPERSTATE) &&
949*4dc78e53SAndroid Build Coastguard Worker link->l_operstate != IF_OPER_UNKNOWN) {
950*4dc78e53SAndroid Build Coastguard Worker rtnl_link_operstate2str(link->l_operstate, buf, sizeof(buf));
951*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "state %s ", buf);
952*4dc78e53SAndroid Build Coastguard Worker }
953*4dc78e53SAndroid Build Coastguard Worker
954*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_VF)
955*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "num-vf %u ", link->l_num_vf);
956*4dc78e53SAndroid Build Coastguard Worker
957*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "mode %s ",
958*4dc78e53SAndroid Build Coastguard Worker rtnl_link_mode2str(link->l_linkmode, buf, sizeof(buf)));
959*4dc78e53SAndroid Build Coastguard Worker
960*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "carrier %s",
961*4dc78e53SAndroid Build Coastguard Worker rtnl_link_carrier2str(link->l_carrier, buf, sizeof(buf)));
962*4dc78e53SAndroid Build Coastguard Worker
963*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_CARRIER_CHANGES)
964*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " carrier-changes %u", link->l_carrier_changes);
965*4dc78e53SAndroid Build Coastguard Worker
966*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "\n");
967*4dc78e53SAndroid Build Coastguard Worker
968*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_DETAILS])
969*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops->io_dump[NL_DUMP_DETAILS](link, p);
970*4dc78e53SAndroid Build Coastguard Worker
971*4dc78e53SAndroid Build Coastguard Worker do_foreach_af(link, af_dump_details, p);
972*4dc78e53SAndroid Build Coastguard Worker
973*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_VF_LIST)
974*4dc78e53SAndroid Build Coastguard Worker rtnl_link_sriov_dump_details(link, p);
975*4dc78e53SAndroid Build Coastguard Worker }
976*4dc78e53SAndroid Build Coastguard Worker
link_dump_stats(struct nl_object * obj,struct nl_dump_params * p)977*4dc78e53SAndroid Build Coastguard Worker static void link_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
978*4dc78e53SAndroid Build Coastguard Worker {
979*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link = (struct rtnl_link *) obj;
980*4dc78e53SAndroid Build Coastguard Worker char *unit, fmt[64];
981*4dc78e53SAndroid Build Coastguard Worker float res;
982*4dc78e53SAndroid Build Coastguard Worker
983*4dc78e53SAndroid Build Coastguard Worker link_dump_details(obj, p);
984*4dc78e53SAndroid Build Coastguard Worker
985*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " Stats: bytes packets errors "
986*4dc78e53SAndroid Build Coastguard Worker " dropped fifo-err compressed\n");
987*4dc78e53SAndroid Build Coastguard Worker
988*4dc78e53SAndroid Build Coastguard Worker res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_RX_BYTES], &unit);
989*4dc78e53SAndroid Build Coastguard Worker
990*4dc78e53SAndroid Build Coastguard Worker strcpy(fmt, " RX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n");
991*4dc78e53SAndroid Build Coastguard Worker fmt[9] = *unit == 'B' ? '9' : '7';
992*4dc78e53SAndroid Build Coastguard Worker
993*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, fmt, res, unit,
994*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_PACKETS],
995*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_ERRORS],
996*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_DROPPED],
997*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FIFO_ERR],
998*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_COMPRESSED]);
999*4dc78e53SAndroid Build Coastguard Worker
1000*4dc78e53SAndroid Build Coastguard Worker res = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_TX_BYTES], &unit);
1001*4dc78e53SAndroid Build Coastguard Worker
1002*4dc78e53SAndroid Build Coastguard Worker strcpy(fmt, " TX %X.2f %s %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 "\n");
1003*4dc78e53SAndroid Build Coastguard Worker fmt[9] = *unit == 'B' ? '9' : '7';
1004*4dc78e53SAndroid Build Coastguard Worker
1005*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, fmt, res, unit,
1006*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_PACKETS],
1007*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ERRORS],
1008*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_DROPPED],
1009*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_FIFO_ERR],
1010*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_COMPRESSED]);
1011*4dc78e53SAndroid Build Coastguard Worker
1012*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " Errors: length over crc "
1013*4dc78e53SAndroid Build Coastguard Worker " frame missed multicast\n");
1014*4dc78e53SAndroid Build Coastguard Worker
1015*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " RX %10" PRIu64 " %10" PRIu64 " %10"
1016*4dc78e53SAndroid Build Coastguard Worker PRIu64 " %10" PRIu64 " %10" PRIu64 " %10"
1017*4dc78e53SAndroid Build Coastguard Worker PRIu64 "\n",
1018*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_LEN_ERR],
1019*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_OVER_ERR],
1020*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_CRC_ERR],
1021*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_FRAME_ERR],
1022*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_RX_MISSED_ERR],
1023*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_MULTICAST]);
1024*4dc78e53SAndroid Build Coastguard Worker
1025*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " aborted carrier heartbeat "
1026*4dc78e53SAndroid Build Coastguard Worker " window collision\n");
1027*4dc78e53SAndroid Build Coastguard Worker
1028*4dc78e53SAndroid Build Coastguard Worker nl_dump_line(p, " TX %10" PRIu64 " %10" PRIu64 " %10"
1029*4dc78e53SAndroid Build Coastguard Worker PRIu64 " %10" PRIu64 " %10" PRIu64 "\n",
1030*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_ABORT_ERR],
1031*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_CARRIER_ERR],
1032*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_HBEAT_ERR],
1033*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_TX_WIN_ERR],
1034*4dc78e53SAndroid Build Coastguard Worker link->l_stats[RTNL_LINK_COLLISIONS]);
1035*4dc78e53SAndroid Build Coastguard Worker
1036*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops && link->l_info_ops->io_dump[NL_DUMP_STATS])
1037*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops->io_dump[NL_DUMP_STATS](link, p);
1038*4dc78e53SAndroid Build Coastguard Worker
1039*4dc78e53SAndroid Build Coastguard Worker do_foreach_af(link, af_dump_stats, p);
1040*4dc78e53SAndroid Build Coastguard Worker
1041*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_VF_LIST)
1042*4dc78e53SAndroid Build Coastguard Worker rtnl_link_sriov_dump_stats(link, p);
1043*4dc78e53SAndroid Build Coastguard Worker }
1044*4dc78e53SAndroid Build Coastguard Worker
1045*4dc78e53SAndroid Build Coastguard Worker #if 0
1046*4dc78e53SAndroid Build Coastguard Worker static int link_handle_event(struct nl_object *a, struct rtnl_link_event_cb *cb)
1047*4dc78e53SAndroid Build Coastguard Worker {
1048*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *l = (struct rtnl_link *) a;
1049*4dc78e53SAndroid Build Coastguard Worker struct nl_cache *c = dp_cache(a);
1050*4dc78e53SAndroid Build Coastguard Worker int nevents = 0;
1051*4dc78e53SAndroid Build Coastguard Worker
1052*4dc78e53SAndroid Build Coastguard Worker if (l->l_change == ~0U) {
1053*4dc78e53SAndroid Build Coastguard Worker if (l->ce_msgtype == RTM_NEWLINK)
1054*4dc78e53SAndroid Build Coastguard Worker cb->le_register(l);
1055*4dc78e53SAndroid Build Coastguard Worker else
1056*4dc78e53SAndroid Build Coastguard Worker cb->le_unregister(l);
1057*4dc78e53SAndroid Build Coastguard Worker
1058*4dc78e53SAndroid Build Coastguard Worker return 1;
1059*4dc78e53SAndroid Build Coastguard Worker }
1060*4dc78e53SAndroid Build Coastguard Worker
1061*4dc78e53SAndroid Build Coastguard Worker if (l->l_change & IFF_SLAVE) {
1062*4dc78e53SAndroid Build Coastguard Worker if (l->l_flags & IFF_SLAVE) {
1063*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *m = rtnl_link_get(c, l->l_master);
1064*4dc78e53SAndroid Build Coastguard Worker cb->le_new_bonding(l, m);
1065*4dc78e53SAndroid Build Coastguard Worker if (m)
1066*4dc78e53SAndroid Build Coastguard Worker rtnl_link_put(m);
1067*4dc78e53SAndroid Build Coastguard Worker } else
1068*4dc78e53SAndroid Build Coastguard Worker cb->le_cancel_bonding(l);
1069*4dc78e53SAndroid Build Coastguard Worker }
1070*4dc78e53SAndroid Build Coastguard Worker
1071*4dc78e53SAndroid Build Coastguard Worker #if 0
1072*4dc78e53SAndroid Build Coastguard Worker if (l->l_change & IFF_UP && l->l_change & IFF_RUNNING)
1073*4dc78e53SAndroid Build Coastguard Worker dp_dump_line(p, line++, "link %s changed state to %s.\n",
1074*4dc78e53SAndroid Build Coastguard Worker l->l_name, l->l_flags & IFF_UP ? "up" : "down");
1075*4dc78e53SAndroid Build Coastguard Worker
1076*4dc78e53SAndroid Build Coastguard Worker if (l->l_change & IFF_PROMISC) {
1077*4dc78e53SAndroid Build Coastguard Worker dp_new_line(p, line++);
1078*4dc78e53SAndroid Build Coastguard Worker dp_dump(p, "link %s %s promiscuous mode.\n",
1079*4dc78e53SAndroid Build Coastguard Worker l->l_name, l->l_flags & IFF_PROMISC ? "entered" : "left");
1080*4dc78e53SAndroid Build Coastguard Worker }
1081*4dc78e53SAndroid Build Coastguard Worker
1082*4dc78e53SAndroid Build Coastguard Worker if (line == 0)
1083*4dc78e53SAndroid Build Coastguard Worker dp_dump_line(p, line++, "link %s sent unknown event.\n",
1084*4dc78e53SAndroid Build Coastguard Worker l->l_name);
1085*4dc78e53SAndroid Build Coastguard Worker #endif
1086*4dc78e53SAndroid Build Coastguard Worker
1087*4dc78e53SAndroid Build Coastguard Worker return nevents;
1088*4dc78e53SAndroid Build Coastguard Worker }
1089*4dc78e53SAndroid Build Coastguard Worker #endif
1090*4dc78e53SAndroid Build Coastguard Worker
1091*4dc78e53SAndroid Build Coastguard Worker
link_keygen(struct nl_object * obj,uint32_t * hashkey,uint32_t table_sz)1092*4dc78e53SAndroid Build Coastguard Worker static void link_keygen(struct nl_object *obj, uint32_t *hashkey,
1093*4dc78e53SAndroid Build Coastguard Worker uint32_t table_sz)
1094*4dc78e53SAndroid Build Coastguard Worker {
1095*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link = (struct rtnl_link *) obj;
1096*4dc78e53SAndroid Build Coastguard Worker unsigned int lkey_sz;
1097*4dc78e53SAndroid Build Coastguard Worker struct link_hash_key {
1098*4dc78e53SAndroid Build Coastguard Worker uint32_t l_index;
1099*4dc78e53SAndroid Build Coastguard Worker uint32_t l_family;
1100*4dc78e53SAndroid Build Coastguard Worker } _nl_packed lkey;
1101*4dc78e53SAndroid Build Coastguard Worker
1102*4dc78e53SAndroid Build Coastguard Worker lkey_sz = sizeof(lkey);
1103*4dc78e53SAndroid Build Coastguard Worker lkey.l_index = link->l_index;
1104*4dc78e53SAndroid Build Coastguard Worker lkey.l_family = link->l_family;
1105*4dc78e53SAndroid Build Coastguard Worker
1106*4dc78e53SAndroid Build Coastguard Worker *hashkey = nl_hash(&lkey, lkey_sz, 0) % table_sz;
1107*4dc78e53SAndroid Build Coastguard Worker
1108*4dc78e53SAndroid Build Coastguard Worker NL_DBG(5, "link %p key (dev %d fam %d) keysz %d, hash 0x%x\n",
1109*4dc78e53SAndroid Build Coastguard Worker link, lkey.l_index, lkey.l_family, lkey_sz, *hashkey);
1110*4dc78e53SAndroid Build Coastguard Worker
1111*4dc78e53SAndroid Build Coastguard Worker return;
1112*4dc78e53SAndroid Build Coastguard Worker }
1113*4dc78e53SAndroid Build Coastguard Worker
link_compare(struct nl_object * _a,struct nl_object * _b,uint64_t attrs,int flags)1114*4dc78e53SAndroid Build Coastguard Worker static uint64_t link_compare(struct nl_object *_a, struct nl_object *_b,
1115*4dc78e53SAndroid Build Coastguard Worker uint64_t attrs, int flags)
1116*4dc78e53SAndroid Build Coastguard Worker {
1117*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *a = (struct rtnl_link *) _a;
1118*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *b = (struct rtnl_link *) _b;
1119*4dc78e53SAndroid Build Coastguard Worker uint64_t diff = 0;
1120*4dc78e53SAndroid Build Coastguard Worker
1121*4dc78e53SAndroid Build Coastguard Worker #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
1122*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_IFINDEX, a->l_index != b->l_index);
1123*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_MTU, a->l_mtu != b->l_mtu);
1124*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_LINK, a->l_link != b->l_link);
1125*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_LINK_NETNSID,
1126*4dc78e53SAndroid Build Coastguard Worker a->l_link_netnsid != b->l_link_netnsid);
1127*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_TXQLEN, a->l_txqlen != b->l_txqlen);
1128*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_WEIGHT, a->l_weight != b->l_weight);
1129*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_MASTER, a->l_master != b->l_master);
1130*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_FAMILY, a->l_family != b->l_family);
1131*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_OPERSTATE, a->l_operstate != b->l_operstate);
1132*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_LINKMODE, a->l_linkmode != b->l_linkmode);
1133*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_QDISC, strcmp(a->l_qdisc, b->l_qdisc));
1134*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_IFNAME, strcmp(a->l_name, b->l_name));
1135*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_ADDR, nl_addr_cmp(a->l_addr, b->l_addr));
1136*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_BRD, nl_addr_cmp(a->l_bcast, b->l_bcast));
1137*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_IFALIAS, strcmp(a->l_ifalias, b->l_ifalias));
1138*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_NUM_VF, a->l_num_vf != b->l_num_vf);
1139*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_PROMISCUITY,
1140*4dc78e53SAndroid Build Coastguard Worker a->l_promiscuity != b->l_promiscuity);
1141*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_NUM_TX_QUEUES,
1142*4dc78e53SAndroid Build Coastguard Worker a->l_num_tx_queues != b->l_num_tx_queues);
1143*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_NUM_RX_QUEUES,
1144*4dc78e53SAndroid Build Coastguard Worker a->l_num_rx_queues != b->l_num_rx_queues);
1145*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_GROUP, a->l_group != b->l_group);
1146*4dc78e53SAndroid Build Coastguard Worker
1147*4dc78e53SAndroid Build Coastguard Worker if (flags & LOOSE_COMPARISON)
1148*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_FLAGS,
1149*4dc78e53SAndroid Build Coastguard Worker (a->l_flags ^ b->l_flags) & b->l_flag_mask);
1150*4dc78e53SAndroid Build Coastguard Worker else
1151*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_FLAGS, a->l_flags != b->l_flags);
1152*4dc78e53SAndroid Build Coastguard Worker
1153*4dc78e53SAndroid Build Coastguard Worker /*
1154*4dc78e53SAndroid Build Coastguard Worker * Compare LINK_ATTR_PROTINFO af_data
1155*4dc78e53SAndroid Build Coastguard Worker */
1156*4dc78e53SAndroid Build Coastguard Worker if (a->l_family == b->l_family) {
1157*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_af_data_compare(a, b, a->l_family) != 0)
1158*4dc78e53SAndroid Build Coastguard Worker goto protinfo_mismatch;
1159*4dc78e53SAndroid Build Coastguard Worker }
1160*4dc78e53SAndroid Build Coastguard Worker
1161*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_LINKINFO, rtnl_link_info_data_compare(a, b, flags) != 0);
1162*4dc78e53SAndroid Build Coastguard Worker out:
1163*4dc78e53SAndroid Build Coastguard Worker return diff;
1164*4dc78e53SAndroid Build Coastguard Worker
1165*4dc78e53SAndroid Build Coastguard Worker protinfo_mismatch:
1166*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(LINK_ATTR_PROTINFO, 1);
1167*4dc78e53SAndroid Build Coastguard Worker goto out;
1168*4dc78e53SAndroid Build Coastguard Worker
1169*4dc78e53SAndroid Build Coastguard Worker #undef _DIFF
1170*4dc78e53SAndroid Build Coastguard Worker }
1171*4dc78e53SAndroid Build Coastguard Worker
1172*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl link_attrs[] = {
1173*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_MTU, mtu),
1174*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_LINK, link),
1175*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_TXQLEN, txqlen),
1176*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_WEIGHT, weight),
1177*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_MASTER, master),
1178*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_QDISC, qdisc),
1179*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_MAP, map),
1180*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_ADDR, address),
1181*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_BRD, broadcast),
1182*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_FLAGS, flags),
1183*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_IFNAME, name),
1184*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_IFINDEX, ifindex),
1185*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_FAMILY, family),
1186*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_ARPTYPE, arptype),
1187*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_STATS, stats),
1188*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_CHANGE, change),
1189*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_OPERSTATE, operstate),
1190*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_LINKMODE, linkmode),
1191*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_IFALIAS, ifalias),
1192*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_NUM_VF, num_vf),
1193*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_PROMISCUITY, promiscuity),
1194*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_NUM_TX_QUEUES, num_tx_queues),
1195*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_NUM_RX_QUEUES, num_rx_queues),
1196*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_GSO_MAX_SEGS, gso_max_segs),
1197*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_GSO_MAX_SIZE, gso_max_size),
1198*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_GROUP, group),
1199*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_CARRIER, carrier),
1200*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_CARRIER_CHANGES, carrier_changes),
1201*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_PHYS_PORT_ID, phys_port_id),
1202*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_PHYS_PORT_NAME, phys_port_name),
1203*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_PHYS_SWITCH_ID, phys_switch_id),
1204*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_NS_FD, ns_fd),
1205*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_NS_PID, ns_pid),
1206*4dc78e53SAndroid Build Coastguard Worker __ADD(LINK_ATTR_LINK_NETNSID, link_netnsid),
1207*4dc78e53SAndroid Build Coastguard Worker };
1208*4dc78e53SAndroid Build Coastguard Worker
link_attrs2str(int attrs,char * buf,size_t len)1209*4dc78e53SAndroid Build Coastguard Worker static char *link_attrs2str(int attrs, char *buf, size_t len)
1210*4dc78e53SAndroid Build Coastguard Worker {
1211*4dc78e53SAndroid Build Coastguard Worker return __flags2str(attrs, buf, len, link_attrs,
1212*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(link_attrs));
1213*4dc78e53SAndroid Build Coastguard Worker }
1214*4dc78e53SAndroid Build Coastguard Worker
1215*4dc78e53SAndroid Build Coastguard Worker /**
1216*4dc78e53SAndroid Build Coastguard Worker * @name Get / List
1217*4dc78e53SAndroid Build Coastguard Worker * @{
1218*4dc78e53SAndroid Build Coastguard Worker */
1219*4dc78e53SAndroid Build Coastguard Worker
1220*4dc78e53SAndroid Build Coastguard Worker
1221*4dc78e53SAndroid Build Coastguard Worker /**
1222*4dc78e53SAndroid Build Coastguard Worker * Allocate link cache and fill in all configured links.
1223*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket.
1224*4dc78e53SAndroid Build Coastguard Worker * @arg family Link address family or AF_UNSPEC
1225*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting cache.
1226*4dc78e53SAndroid Build Coastguard Worker * @arg flags Flags to set in link cache before filling
1227*4dc78e53SAndroid Build Coastguard Worker *
1228*4dc78e53SAndroid Build Coastguard Worker * Allocates and initializes a new link cache. If \c sk is valid, a netlink
1229*4dc78e53SAndroid Build Coastguard Worker * message is sent to the kernel requesting a full dump of all configured
1230*4dc78e53SAndroid Build Coastguard Worker * links. The returned messages are parsed and filled into the cache. If
1231*4dc78e53SAndroid Build Coastguard Worker * the operation succeeds, the resulting cache will contain a link object for
1232*4dc78e53SAndroid Build Coastguard Worker * each link configured in the kernel. If \c sk is NULL, returns 0 but the
1233*4dc78e53SAndroid Build Coastguard Worker * cache is still empty.
1234*4dc78e53SAndroid Build Coastguard Worker *
1235*4dc78e53SAndroid Build Coastguard Worker * If \c family is set to an address family other than \c AF_UNSPEC the
1236*4dc78e53SAndroid Build Coastguard Worker * contents of the cache can be limited to a specific address family.
1237*4dc78e53SAndroid Build Coastguard Worker * Currently the following address families are supported:
1238*4dc78e53SAndroid Build Coastguard Worker * - AF_BRIDGE
1239*4dc78e53SAndroid Build Coastguard Worker * - AF_INET6
1240*4dc78e53SAndroid Build Coastguard Worker *
1241*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_list, Get List of Links}
1242*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get()
1243*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_by_name()
1244*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1245*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_alloc_cache_flags(struct nl_sock * sk,int family,struct nl_cache ** result,unsigned int flags)1246*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_alloc_cache_flags(struct nl_sock *sk, int family,
1247*4dc78e53SAndroid Build Coastguard Worker struct nl_cache **result, unsigned int flags)
1248*4dc78e53SAndroid Build Coastguard Worker {
1249*4dc78e53SAndroid Build Coastguard Worker struct nl_cache * cache;
1250*4dc78e53SAndroid Build Coastguard Worker int err;
1251*4dc78e53SAndroid Build Coastguard Worker
1252*4dc78e53SAndroid Build Coastguard Worker cache = nl_cache_alloc(&rtnl_link_ops);
1253*4dc78e53SAndroid Build Coastguard Worker if (!cache)
1254*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1255*4dc78e53SAndroid Build Coastguard Worker
1256*4dc78e53SAndroid Build Coastguard Worker cache->c_iarg1 = family;
1257*4dc78e53SAndroid Build Coastguard Worker
1258*4dc78e53SAndroid Build Coastguard Worker if (flags)
1259*4dc78e53SAndroid Build Coastguard Worker nl_cache_set_flags(cache, flags);
1260*4dc78e53SAndroid Build Coastguard Worker
1261*4dc78e53SAndroid Build Coastguard Worker if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
1262*4dc78e53SAndroid Build Coastguard Worker nl_cache_free(cache);
1263*4dc78e53SAndroid Build Coastguard Worker return err;
1264*4dc78e53SAndroid Build Coastguard Worker }
1265*4dc78e53SAndroid Build Coastguard Worker
1266*4dc78e53SAndroid Build Coastguard Worker *result = cache;
1267*4dc78e53SAndroid Build Coastguard Worker return 0;
1268*4dc78e53SAndroid Build Coastguard Worker }
1269*4dc78e53SAndroid Build Coastguard Worker
1270*4dc78e53SAndroid Build Coastguard Worker /**
1271*4dc78e53SAndroid Build Coastguard Worker * Allocate link cache and fill in all configured links.
1272*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket.
1273*4dc78e53SAndroid Build Coastguard Worker * @arg family Link address family or AF_UNSPEC
1274*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting cache.
1275*4dc78e53SAndroid Build Coastguard Worker *
1276*4dc78e53SAndroid Build Coastguard Worker * Allocates and initializes a new link cache. If \c sk is valid, a netlink
1277*4dc78e53SAndroid Build Coastguard Worker * message is sent to the kernel requesting a full dump of all configured
1278*4dc78e53SAndroid Build Coastguard Worker * links. The returned messages are parsed and filled into the cache. If
1279*4dc78e53SAndroid Build Coastguard Worker * the operation succeeds, the resulting cache will contain a link object for
1280*4dc78e53SAndroid Build Coastguard Worker * each link configured in the kernel. If \c sk is NULL, returns 0 but the
1281*4dc78e53SAndroid Build Coastguard Worker * cache is still empty.
1282*4dc78e53SAndroid Build Coastguard Worker *
1283*4dc78e53SAndroid Build Coastguard Worker * If \c family is set to an address family other than \c AF_UNSPEC the
1284*4dc78e53SAndroid Build Coastguard Worker * contents of the cache can be limited to a specific address family.
1285*4dc78e53SAndroid Build Coastguard Worker * Currently the following address families are supported:
1286*4dc78e53SAndroid Build Coastguard Worker * - AF_BRIDGE
1287*4dc78e53SAndroid Build Coastguard Worker * - AF_INET6
1288*4dc78e53SAndroid Build Coastguard Worker *
1289*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_list, Get List of Links}
1290*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get()
1291*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_by_name()
1292*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1293*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_alloc_cache(struct nl_sock * sk,int family,struct nl_cache ** result)1294*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
1295*4dc78e53SAndroid Build Coastguard Worker {
1296*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_alloc_cache_flags(sk, family, result, 0);
1297*4dc78e53SAndroid Build Coastguard Worker }
1298*4dc78e53SAndroid Build Coastguard Worker
1299*4dc78e53SAndroid Build Coastguard Worker
1300*4dc78e53SAndroid Build Coastguard Worker /**
1301*4dc78e53SAndroid Build Coastguard Worker * Lookup link in cache by interface index
1302*4dc78e53SAndroid Build Coastguard Worker * @arg cache Link cache
1303*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
1304*4dc78e53SAndroid Build Coastguard Worker *
1305*4dc78e53SAndroid Build Coastguard Worker * Searches through the provided cache looking for a link with matching
1306*4dc78e53SAndroid Build Coastguard Worker * interface index.
1307*4dc78e53SAndroid Build Coastguard Worker *
1308*4dc78e53SAndroid Build Coastguard Worker * @attention The reference counter of the returned link object will be
1309*4dc78e53SAndroid Build Coastguard Worker * incremented. Use rtnl_link_put() to release the reference.
1310*4dc78e53SAndroid Build Coastguard Worker *
1311*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_list, Get List of Links}
1312*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_by_name()
1313*4dc78e53SAndroid Build Coastguard Worker * @return Link object or NULL if no match was found.
1314*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get(struct nl_cache * cache,int ifindex)1315*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex)
1316*4dc78e53SAndroid Build Coastguard Worker {
1317*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link;
1318*4dc78e53SAndroid Build Coastguard Worker
1319*4dc78e53SAndroid Build Coastguard Worker if (cache->c_ops != &rtnl_link_ops)
1320*4dc78e53SAndroid Build Coastguard Worker return NULL;
1321*4dc78e53SAndroid Build Coastguard Worker
1322*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1323*4dc78e53SAndroid Build Coastguard Worker if (link->l_index == ((unsigned)ifindex)) {
1324*4dc78e53SAndroid Build Coastguard Worker nl_object_get((struct nl_object *) link);
1325*4dc78e53SAndroid Build Coastguard Worker return link;
1326*4dc78e53SAndroid Build Coastguard Worker }
1327*4dc78e53SAndroid Build Coastguard Worker }
1328*4dc78e53SAndroid Build Coastguard Worker
1329*4dc78e53SAndroid Build Coastguard Worker return NULL;
1330*4dc78e53SAndroid Build Coastguard Worker }
1331*4dc78e53SAndroid Build Coastguard Worker
1332*4dc78e53SAndroid Build Coastguard Worker /**
1333*4dc78e53SAndroid Build Coastguard Worker * Lookup link in cache by link name
1334*4dc78e53SAndroid Build Coastguard Worker * @arg cache Link cache
1335*4dc78e53SAndroid Build Coastguard Worker * @arg name Name of link
1336*4dc78e53SAndroid Build Coastguard Worker *
1337*4dc78e53SAndroid Build Coastguard Worker * Searches through the provided cache looking for a link with matching
1338*4dc78e53SAndroid Build Coastguard Worker * link name
1339*4dc78e53SAndroid Build Coastguard Worker *
1340*4dc78e53SAndroid Build Coastguard Worker * @attention The reference counter of the returned link object will be
1341*4dc78e53SAndroid Build Coastguard Worker * incremented. Use rtnl_link_put() to release the reference.
1342*4dc78e53SAndroid Build Coastguard Worker *
1343*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_list, Get List of Links}
1344*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get()
1345*4dc78e53SAndroid Build Coastguard Worker * @return Link object or NULL if no match was found.
1346*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_by_name(struct nl_cache * cache,const char * name)1347*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache,
1348*4dc78e53SAndroid Build Coastguard Worker const char *name)
1349*4dc78e53SAndroid Build Coastguard Worker {
1350*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link;
1351*4dc78e53SAndroid Build Coastguard Worker
1352*4dc78e53SAndroid Build Coastguard Worker if (cache->c_ops != &rtnl_link_ops)
1353*4dc78e53SAndroid Build Coastguard Worker return NULL;
1354*4dc78e53SAndroid Build Coastguard Worker
1355*4dc78e53SAndroid Build Coastguard Worker nl_list_for_each_entry(link, &cache->c_items, ce_list) {
1356*4dc78e53SAndroid Build Coastguard Worker if (!strcmp(name, link->l_name)) {
1357*4dc78e53SAndroid Build Coastguard Worker nl_object_get((struct nl_object *) link);
1358*4dc78e53SAndroid Build Coastguard Worker return link;
1359*4dc78e53SAndroid Build Coastguard Worker }
1360*4dc78e53SAndroid Build Coastguard Worker }
1361*4dc78e53SAndroid Build Coastguard Worker
1362*4dc78e53SAndroid Build Coastguard Worker return NULL;
1363*4dc78e53SAndroid Build Coastguard Worker }
1364*4dc78e53SAndroid Build Coastguard Worker
1365*4dc78e53SAndroid Build Coastguard Worker /**
1366*4dc78e53SAndroid Build Coastguard Worker * Construct RTM_GETLINK netlink message
1367*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
1368*4dc78e53SAndroid Build Coastguard Worker * @arg name Name of link
1369*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting netlink message
1370*4dc78e53SAndroid Build Coastguard Worker *
1371*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_link_get_kernel()
1372*4dc78e53SAndroid Build Coastguard Worker * with the exception that it will not send the message but return it in
1373*4dc78e53SAndroid Build Coastguard Worker * the provided return pointer instead.
1374*4dc78e53SAndroid Build Coastguard Worker *
1375*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_kernel()
1376*4dc78e53SAndroid Build Coastguard Worker *
1377*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1378*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_build_get_request(int ifindex,const char * name,struct nl_msg ** result)1379*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_build_get_request(int ifindex, const char *name,
1380*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
1381*4dc78e53SAndroid Build Coastguard Worker {
1382*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
1383*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg ifi;
1384*4dc78e53SAndroid Build Coastguard Worker __u32 vf_mask = RTEXT_FILTER_VF;
1385*4dc78e53SAndroid Build Coastguard Worker
1386*4dc78e53SAndroid Build Coastguard Worker if (ifindex <= 0 && !name) {
1387*4dc78e53SAndroid Build Coastguard Worker APPBUG("ifindex or name must be specified");
1388*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
1389*4dc78e53SAndroid Build Coastguard Worker }
1390*4dc78e53SAndroid Build Coastguard Worker
1391*4dc78e53SAndroid Build Coastguard Worker memset(&ifi, 0, sizeof(ifi));
1392*4dc78e53SAndroid Build Coastguard Worker
1393*4dc78e53SAndroid Build Coastguard Worker if (!(msg = nlmsg_alloc_simple(RTM_GETLINK, 0)))
1394*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1395*4dc78e53SAndroid Build Coastguard Worker
1396*4dc78e53SAndroid Build Coastguard Worker if (ifindex > 0)
1397*4dc78e53SAndroid Build Coastguard Worker ifi.ifi_index = ifindex;
1398*4dc78e53SAndroid Build Coastguard Worker
1399*4dc78e53SAndroid Build Coastguard Worker _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
1400*4dc78e53SAndroid Build Coastguard Worker
1401*4dc78e53SAndroid Build Coastguard Worker if (name)
1402*4dc78e53SAndroid Build Coastguard Worker _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, name));
1403*4dc78e53SAndroid Build Coastguard Worker
1404*4dc78e53SAndroid Build Coastguard Worker _NL_RETURN_ON_PUT_ERR(nla_put(msg, IFLA_EXT_MASK, sizeof(vf_mask), &vf_mask));
1405*4dc78e53SAndroid Build Coastguard Worker
1406*4dc78e53SAndroid Build Coastguard Worker *result = _nl_steal_pointer(&msg);
1407*4dc78e53SAndroid Build Coastguard Worker return 0;
1408*4dc78e53SAndroid Build Coastguard Worker }
1409*4dc78e53SAndroid Build Coastguard Worker
1410*4dc78e53SAndroid Build Coastguard Worker /**
1411*4dc78e53SAndroid Build Coastguard Worker * Get a link object directly from kernel
1412*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
1413*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
1414*4dc78e53SAndroid Build Coastguard Worker * @arg name Name of link
1415*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting link object
1416*4dc78e53SAndroid Build Coastguard Worker *
1417*4dc78e53SAndroid Build Coastguard Worker * This function builds a \c RTM_GETLINK netlink message to request
1418*4dc78e53SAndroid Build Coastguard Worker * a specific link directly from the kernel. The returned answer is
1419*4dc78e53SAndroid Build Coastguard Worker * parsed into a struct rtnl_link object and returned via the result
1420*4dc78e53SAndroid Build Coastguard Worker * pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was
1421*4dc78e53SAndroid Build Coastguard Worker * found.
1422*4dc78e53SAndroid Build Coastguard Worker *
1423*4dc78e53SAndroid Build Coastguard Worker * Older kernels do not support lookup by name. In that case, libnl
1424*4dc78e53SAndroid Build Coastguard Worker * will fail with -NLE_OPNOTSUPP. Note that previous version of libnl
1425*4dc78e53SAndroid Build Coastguard Worker * failed in this case with -NLE_INVAL. You can check libnl behavior
1426*4dc78e53SAndroid Build Coastguard Worker * using NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP capability.
1427*4dc78e53SAndroid Build Coastguard Worker *
1428*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_direct_lookup, Lookup Single Link (Direct Lookup)}
1429*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1430*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_kernel(struct nl_sock * sk,int ifindex,const char * name,struct rtnl_link ** result)1431*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
1432*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link **result)
1433*4dc78e53SAndroid Build Coastguard Worker {
1434*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1435*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
1436*4dc78e53SAndroid Build Coastguard Worker int err;
1437*4dc78e53SAndroid Build Coastguard Worker int syserr;
1438*4dc78e53SAndroid Build Coastguard Worker
1439*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0)
1440*4dc78e53SAndroid Build Coastguard Worker return err;
1441*4dc78e53SAndroid Build Coastguard Worker
1442*4dc78e53SAndroid Build Coastguard Worker err = nl_send_auto(sk, msg);
1443*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
1444*4dc78e53SAndroid Build Coastguard Worker return err;
1445*4dc78e53SAndroid Build Coastguard Worker
1446*4dc78e53SAndroid Build Coastguard Worker err = nl_pickup_keep_syserr(sk, link_msg_parser, (struct nl_object **) &link, &syserr);
1447*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
1448*4dc78e53SAndroid Build Coastguard Worker if ( syserr == -EINVAL
1449*4dc78e53SAndroid Build Coastguard Worker && ifindex <= 0
1450*4dc78e53SAndroid Build Coastguard Worker && name
1451*4dc78e53SAndroid Build Coastguard Worker && *name) {
1452*4dc78e53SAndroid Build Coastguard Worker /* Older kernels do not support lookup by ifname. This was added
1453*4dc78e53SAndroid Build Coastguard Worker * by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f .
1454*4dc78e53SAndroid Build Coastguard Worker * Detect this error case and return NLE_OPNOTSUPP instead of
1455*4dc78e53SAndroid Build Coastguard Worker * NLE_INVAL. */
1456*4dc78e53SAndroid Build Coastguard Worker return -NLE_OPNOTSUPP;
1457*4dc78e53SAndroid Build Coastguard Worker }
1458*4dc78e53SAndroid Build Coastguard Worker return err;
1459*4dc78e53SAndroid Build Coastguard Worker }
1460*4dc78e53SAndroid Build Coastguard Worker
1461*4dc78e53SAndroid Build Coastguard Worker /* If an object has been returned, we also need to wait for the ACK */
1462*4dc78e53SAndroid Build Coastguard Worker if (err == 0 && link)
1463*4dc78e53SAndroid Build Coastguard Worker wait_for_ack(sk);
1464*4dc78e53SAndroid Build Coastguard Worker
1465*4dc78e53SAndroid Build Coastguard Worker *result = _nl_steal_pointer(&link);
1466*4dc78e53SAndroid Build Coastguard Worker return 0;
1467*4dc78e53SAndroid Build Coastguard Worker }
1468*4dc78e53SAndroid Build Coastguard Worker
1469*4dc78e53SAndroid Build Coastguard Worker /**
1470*4dc78e53SAndroid Build Coastguard Worker * Translate interface index to corresponding link name
1471*4dc78e53SAndroid Build Coastguard Worker * @arg cache Link cache
1472*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
1473*4dc78e53SAndroid Build Coastguard Worker * @arg dst String to store name
1474*4dc78e53SAndroid Build Coastguard Worker * @arg len Length of destination string
1475*4dc78e53SAndroid Build Coastguard Worker *
1476*4dc78e53SAndroid Build Coastguard Worker * Translates the specified interface index to the corresponding
1477*4dc78e53SAndroid Build Coastguard Worker * link name and stores the name in the destination string.
1478*4dc78e53SAndroid Build Coastguard Worker *
1479*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_translate_ifindex, Translating interface index to link name}
1480*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_name2i()
1481*4dc78e53SAndroid Build Coastguard Worker * @return Name of link or NULL if no match was found.
1482*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_i2name(struct nl_cache * cache,int ifindex,char * dst,size_t len)1483*4dc78e53SAndroid Build Coastguard Worker char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst,
1484*4dc78e53SAndroid Build Coastguard Worker size_t len)
1485*4dc78e53SAndroid Build Coastguard Worker {
1486*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1487*4dc78e53SAndroid Build Coastguard Worker
1488*4dc78e53SAndroid Build Coastguard Worker link = rtnl_link_get(cache, ifindex);
1489*4dc78e53SAndroid Build Coastguard Worker if (link) {
1490*4dc78e53SAndroid Build Coastguard Worker _nl_strncpy_trunc(dst, link->l_name, len);
1491*4dc78e53SAndroid Build Coastguard Worker return dst;
1492*4dc78e53SAndroid Build Coastguard Worker }
1493*4dc78e53SAndroid Build Coastguard Worker
1494*4dc78e53SAndroid Build Coastguard Worker return NULL;
1495*4dc78e53SAndroid Build Coastguard Worker }
1496*4dc78e53SAndroid Build Coastguard Worker
1497*4dc78e53SAndroid Build Coastguard Worker /**
1498*4dc78e53SAndroid Build Coastguard Worker * Translate link name to corresponding interface index
1499*4dc78e53SAndroid Build Coastguard Worker * @arg cache Link cache
1500*4dc78e53SAndroid Build Coastguard Worker * @arg name Name of link
1501*4dc78e53SAndroid Build Coastguard Worker *
1502*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_translate_ifindex, Translating interface index to link name}
1503*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_i2name()
1504*4dc78e53SAndroid Build Coastguard Worker * @return Interface index or 0 if no match was found.
1505*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_name2i(struct nl_cache * cache,const char * name)1506*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_name2i(struct nl_cache *cache, const char *name)
1507*4dc78e53SAndroid Build Coastguard Worker {
1508*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *link = NULL;
1509*4dc78e53SAndroid Build Coastguard Worker
1510*4dc78e53SAndroid Build Coastguard Worker link = rtnl_link_get_by_name(cache, name);
1511*4dc78e53SAndroid Build Coastguard Worker if (link)
1512*4dc78e53SAndroid Build Coastguard Worker return link->l_index;
1513*4dc78e53SAndroid Build Coastguard Worker
1514*4dc78e53SAndroid Build Coastguard Worker return 0;
1515*4dc78e53SAndroid Build Coastguard Worker }
1516*4dc78e53SAndroid Build Coastguard Worker
1517*4dc78e53SAndroid Build Coastguard Worker /** @} */
1518*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_fill_info(struct nl_msg * msg,struct rtnl_link * link)1519*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_fill_info(struct nl_msg *msg, struct rtnl_link *link)
1520*4dc78e53SAndroid Build Coastguard Worker {
1521*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_ADDR)
1522*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_ADDR(msg, IFLA_ADDRESS, link->l_addr);
1523*4dc78e53SAndroid Build Coastguard Worker
1524*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_BRD)
1525*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_ADDR(msg, IFLA_BROADCAST, link->l_bcast);
1526*4dc78e53SAndroid Build Coastguard Worker
1527*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_MTU)
1528*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_MTU, link->l_mtu);
1529*4dc78e53SAndroid Build Coastguard Worker
1530*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_TXQLEN)
1531*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_TXQLEN, link->l_txqlen);
1532*4dc78e53SAndroid Build Coastguard Worker
1533*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_WEIGHT)
1534*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_WEIGHT, link->l_weight);
1535*4dc78e53SAndroid Build Coastguard Worker
1536*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_IFNAME)
1537*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, IFLA_IFNAME, link->l_name);
1538*4dc78e53SAndroid Build Coastguard Worker
1539*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_OPERSTATE)
1540*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, IFLA_OPERSTATE, link->l_operstate);
1541*4dc78e53SAndroid Build Coastguard Worker
1542*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_CARRIER)
1543*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, IFLA_CARRIER, link->l_carrier);
1544*4dc78e53SAndroid Build Coastguard Worker
1545*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINKMODE)
1546*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U8(msg, IFLA_LINKMODE, link->l_linkmode);
1547*4dc78e53SAndroid Build Coastguard Worker
1548*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_IFALIAS)
1549*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, IFLA_IFALIAS, link->l_ifalias);
1550*4dc78e53SAndroid Build Coastguard Worker
1551*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINK)
1552*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_LINK, link->l_link);
1553*4dc78e53SAndroid Build Coastguard Worker
1554*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINK_NETNSID)
1555*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_S32(msg, IFLA_LINK_NETNSID, link->l_link_netnsid);
1556*4dc78e53SAndroid Build Coastguard Worker
1557*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_MASTER)
1558*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_MASTER, link->l_master);
1559*4dc78e53SAndroid Build Coastguard Worker
1560*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_TX_QUEUES)
1561*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_NUM_TX_QUEUES, link->l_num_tx_queues);
1562*4dc78e53SAndroid Build Coastguard Worker
1563*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_RX_QUEUES)
1564*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_NUM_RX_QUEUES, link->l_num_rx_queues);
1565*4dc78e53SAndroid Build Coastguard Worker
1566*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NS_FD)
1567*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_NET_NS_FD, link->l_ns_fd);
1568*4dc78e53SAndroid Build Coastguard Worker
1569*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NS_PID)
1570*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_NET_NS_PID, link->l_ns_pid);
1571*4dc78e53SAndroid Build Coastguard Worker
1572*4dc78e53SAndroid Build Coastguard Worker return 0;
1573*4dc78e53SAndroid Build Coastguard Worker
1574*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
1575*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
1576*4dc78e53SAndroid Build Coastguard Worker }
1577*4dc78e53SAndroid Build Coastguard Worker
build_link_msg(int cmd,struct ifinfomsg * hdr,struct rtnl_link * link,int flags,struct nl_msg ** result)1578*4dc78e53SAndroid Build Coastguard Worker static int build_link_msg(int cmd, struct ifinfomsg *hdr,
1579*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *link, int flags, struct nl_msg **result)
1580*4dc78e53SAndroid Build Coastguard Worker {
1581*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
1582*4dc78e53SAndroid Build Coastguard Worker struct nlattr *af_spec;
1583*4dc78e53SAndroid Build Coastguard Worker
1584*4dc78e53SAndroid Build Coastguard Worker msg = nlmsg_alloc_simple(cmd, flags);
1585*4dc78e53SAndroid Build Coastguard Worker if (!msg)
1586*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1587*4dc78e53SAndroid Build Coastguard Worker
1588*4dc78e53SAndroid Build Coastguard Worker if (nlmsg_append(msg, hdr, sizeof(*hdr), NLMSG_ALIGNTO) < 0)
1589*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1590*4dc78e53SAndroid Build Coastguard Worker
1591*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_fill_info(msg, link))
1592*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1593*4dc78e53SAndroid Build Coastguard Worker
1594*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_GROUP)
1595*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_U32(msg, IFLA_GROUP, link->l_group);
1596*4dc78e53SAndroid Build Coastguard Worker
1597*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & (LINK_ATTR_LINKINFO|LINK_ATTR_LINKINFO_SLAVE_KIND)) {
1598*4dc78e53SAndroid Build Coastguard Worker struct nlattr *info;
1599*4dc78e53SAndroid Build Coastguard Worker
1600*4dc78e53SAndroid Build Coastguard Worker if (!(info = nla_nest_start(msg, IFLA_LINKINFO)))
1601*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1602*4dc78e53SAndroid Build Coastguard Worker
1603*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINKINFO) {
1604*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, IFLA_INFO_KIND, link->l_info_kind);
1605*4dc78e53SAndroid Build Coastguard Worker
1606*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops) {
1607*4dc78e53SAndroid Build Coastguard Worker if (link->l_info_ops->io_put_attrs &&
1608*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops->io_put_attrs(msg, link) < 0)
1609*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1610*4dc78e53SAndroid Build Coastguard Worker }
1611*4dc78e53SAndroid Build Coastguard Worker }
1612*4dc78e53SAndroid Build Coastguard Worker
1613*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_LINKINFO_SLAVE_KIND) {
1614*4dc78e53SAndroid Build Coastguard Worker NLA_PUT_STRING(msg, IFLA_INFO_SLAVE_KIND, link->l_info_slave_kind);
1615*4dc78e53SAndroid Build Coastguard Worker }
1616*4dc78e53SAndroid Build Coastguard Worker
1617*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, info);
1618*4dc78e53SAndroid Build Coastguard Worker }
1619*4dc78e53SAndroid Build Coastguard Worker
1620*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_VF_LIST) {
1621*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_sriov_fill_vflist(msg, link) < 0)
1622*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1623*4dc78e53SAndroid Build Coastguard Worker }
1624*4dc78e53SAndroid Build Coastguard Worker
1625*4dc78e53SAndroid Build Coastguard Worker if (do_foreach_af(link, af_fill_pi, msg) < 0)
1626*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1627*4dc78e53SAndroid Build Coastguard Worker
1628*4dc78e53SAndroid Build Coastguard Worker if (!(af_spec = nla_nest_start(msg, IFLA_AF_SPEC)))
1629*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1630*4dc78e53SAndroid Build Coastguard Worker
1631*4dc78e53SAndroid Build Coastguard Worker if (do_foreach_af(link, af_fill, msg) < 0)
1632*4dc78e53SAndroid Build Coastguard Worker goto nla_put_failure;
1633*4dc78e53SAndroid Build Coastguard Worker
1634*4dc78e53SAndroid Build Coastguard Worker nla_nest_end(msg, af_spec);
1635*4dc78e53SAndroid Build Coastguard Worker
1636*4dc78e53SAndroid Build Coastguard Worker *result = _nl_steal_pointer(&msg);
1637*4dc78e53SAndroid Build Coastguard Worker return 0;
1638*4dc78e53SAndroid Build Coastguard Worker
1639*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
1640*4dc78e53SAndroid Build Coastguard Worker return -NLE_MSGSIZE;
1641*4dc78e53SAndroid Build Coastguard Worker }
1642*4dc78e53SAndroid Build Coastguard Worker
1643*4dc78e53SAndroid Build Coastguard Worker /**
1644*4dc78e53SAndroid Build Coastguard Worker * @name Add / Modify
1645*4dc78e53SAndroid Build Coastguard Worker * @{
1646*4dc78e53SAndroid Build Coastguard Worker */
1647*4dc78e53SAndroid Build Coastguard Worker
1648*4dc78e53SAndroid Build Coastguard Worker /**
1649*4dc78e53SAndroid Build Coastguard Worker * Build a netlink message requesting the addition of new virtual link
1650*4dc78e53SAndroid Build Coastguard Worker * @arg link new link to add
1651*4dc78e53SAndroid Build Coastguard Worker * @arg flags additional netlink message flags
1652*4dc78e53SAndroid Build Coastguard Worker * @arg result pointer to store resulting netlink message
1653*4dc78e53SAndroid Build Coastguard Worker *
1654*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_link_add() with
1655*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it in the
1656*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
1657*4dc78e53SAndroid Build Coastguard Worker *
1658*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_add()
1659*4dc78e53SAndroid Build Coastguard Worker *
1660*4dc78e53SAndroid Build Coastguard Worker * @note This operation is not supported on all kernel versions.
1661*4dc78e53SAndroid Build Coastguard Worker *
1662*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1663*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_build_add_request(struct rtnl_link * link,int flags,struct nl_msg ** result)1664*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_build_add_request(struct rtnl_link *link, int flags,
1665*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
1666*4dc78e53SAndroid Build Coastguard Worker {
1667*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg ifi = {
1668*4dc78e53SAndroid Build Coastguard Worker .ifi_family = link->l_family,
1669*4dc78e53SAndroid Build Coastguard Worker .ifi_index = link->l_index,
1670*4dc78e53SAndroid Build Coastguard Worker .ifi_flags = link->l_flags,
1671*4dc78e53SAndroid Build Coastguard Worker .ifi_change = link->l_flag_mask,
1672*4dc78e53SAndroid Build Coastguard Worker };
1673*4dc78e53SAndroid Build Coastguard Worker
1674*4dc78e53SAndroid Build Coastguard Worker return build_link_msg(RTM_NEWLINK, &ifi, link, flags, result);
1675*4dc78e53SAndroid Build Coastguard Worker }
1676*4dc78e53SAndroid Build Coastguard Worker
1677*4dc78e53SAndroid Build Coastguard Worker /**
1678*4dc78e53SAndroid Build Coastguard Worker * Add virtual link
1679*4dc78e53SAndroid Build Coastguard Worker * @arg sk netlink socket.
1680*4dc78e53SAndroid Build Coastguard Worker * @arg link new link to add
1681*4dc78e53SAndroid Build Coastguard Worker * @arg flags additional netlink message flags
1682*4dc78e53SAndroid Build Coastguard Worker *
1683*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_NEWLINK netlink message requesting the addition of
1684*4dc78e53SAndroid Build Coastguard Worker * a new virtual link.
1685*4dc78e53SAndroid Build Coastguard Worker *
1686*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
1687*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
1688*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
1689*4dc78e53SAndroid Build Coastguard Worker *
1690*4dc78e53SAndroid Build Coastguard Worker * @copydoc auto_ack_warning
1691*4dc78e53SAndroid Build Coastguard Worker *
1692*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1693*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_add(struct nl_sock * sk,struct rtnl_link * link,int flags)1694*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
1695*4dc78e53SAndroid Build Coastguard Worker {
1696*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
1697*4dc78e53SAndroid Build Coastguard Worker int err;
1698*4dc78e53SAndroid Build Coastguard Worker
1699*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_build_add_request(link, flags, &msg);
1700*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
1701*4dc78e53SAndroid Build Coastguard Worker return err;
1702*4dc78e53SAndroid Build Coastguard Worker
1703*4dc78e53SAndroid Build Coastguard Worker return nl_send_sync(sk, msg);
1704*4dc78e53SAndroid Build Coastguard Worker }
1705*4dc78e53SAndroid Build Coastguard Worker
1706*4dc78e53SAndroid Build Coastguard Worker /**
1707*4dc78e53SAndroid Build Coastguard Worker * Build a netlink message requesting the modification of link
1708*4dc78e53SAndroid Build Coastguard Worker * @arg orig original link to change
1709*4dc78e53SAndroid Build Coastguard Worker * @arg changes link containing the changes to be made
1710*4dc78e53SAndroid Build Coastguard Worker * @arg flags additional netlink message flags
1711*4dc78e53SAndroid Build Coastguard Worker * @arg result pointer to store resulting netlink message
1712*4dc78e53SAndroid Build Coastguard Worker *
1713*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_link_change() with
1714*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it in the
1715*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
1716*4dc78e53SAndroid Build Coastguard Worker *
1717*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_change()
1718*4dc78e53SAndroid Build Coastguard Worker *
1719*4dc78e53SAndroid Build Coastguard Worker * @note The resulting message will have message type set to RTM_NEWLINK
1720*4dc78e53SAndroid Build Coastguard Worker * which may not work with older kernels. You may have to modify it
1721*4dc78e53SAndroid Build Coastguard Worker * to RTM_SETLINK (does not allow changing link info attributes) to
1722*4dc78e53SAndroid Build Coastguard Worker * have the change request work with older kernels.
1723*4dc78e53SAndroid Build Coastguard Worker *
1724*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1725*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_build_change_request(struct rtnl_link * orig,struct rtnl_link * changes,int flags,struct nl_msg ** result)1726*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_build_change_request(struct rtnl_link *orig,
1727*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *changes, int flags,
1728*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
1729*4dc78e53SAndroid Build Coastguard Worker {
1730*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg ifi = {
1731*4dc78e53SAndroid Build Coastguard Worker .ifi_family = orig->l_family,
1732*4dc78e53SAndroid Build Coastguard Worker .ifi_index = orig->l_index,
1733*4dc78e53SAndroid Build Coastguard Worker };
1734*4dc78e53SAndroid Build Coastguard Worker int err, rt;
1735*4dc78e53SAndroid Build Coastguard Worker
1736*4dc78e53SAndroid Build Coastguard Worker if (changes->ce_mask & LINK_ATTR_FLAGS) {
1737*4dc78e53SAndroid Build Coastguard Worker ifi.ifi_flags = orig->l_flags & ~changes->l_flag_mask;
1738*4dc78e53SAndroid Build Coastguard Worker ifi.ifi_flags |= changes->l_flags;
1739*4dc78e53SAndroid Build Coastguard Worker ifi.ifi_change = changes->l_flag_mask;
1740*4dc78e53SAndroid Build Coastguard Worker }
1741*4dc78e53SAndroid Build Coastguard Worker
1742*4dc78e53SAndroid Build Coastguard Worker if (changes->l_family && changes->l_family != orig->l_family) {
1743*4dc78e53SAndroid Build Coastguard Worker APPBUG("link change: family is immutable");
1744*4dc78e53SAndroid Build Coastguard Worker return -NLE_IMMUTABLE;
1745*4dc78e53SAndroid Build Coastguard Worker }
1746*4dc78e53SAndroid Build Coastguard Worker
1747*4dc78e53SAndroid Build Coastguard Worker /* Avoid unnecessary name change requests */
1748*4dc78e53SAndroid Build Coastguard Worker if (orig->ce_mask & LINK_ATTR_IFINDEX &&
1749*4dc78e53SAndroid Build Coastguard Worker orig->ce_mask & LINK_ATTR_IFNAME &&
1750*4dc78e53SAndroid Build Coastguard Worker changes->ce_mask & LINK_ATTR_IFNAME &&
1751*4dc78e53SAndroid Build Coastguard Worker !strcmp(orig->l_name, changes->l_name))
1752*4dc78e53SAndroid Build Coastguard Worker changes->ce_mask &= ~LINK_ATTR_IFNAME;
1753*4dc78e53SAndroid Build Coastguard Worker
1754*4dc78e53SAndroid Build Coastguard Worker rt = af_request_type(orig->l_family, changes);
1755*4dc78e53SAndroid Build Coastguard Worker
1756*4dc78e53SAndroid Build Coastguard Worker if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
1757*4dc78e53SAndroid Build Coastguard Worker return err;
1758*4dc78e53SAndroid Build Coastguard Worker
1759*4dc78e53SAndroid Build Coastguard Worker return 0;
1760*4dc78e53SAndroid Build Coastguard Worker }
1761*4dc78e53SAndroid Build Coastguard Worker
1762*4dc78e53SAndroid Build Coastguard Worker /**
1763*4dc78e53SAndroid Build Coastguard Worker * Change link
1764*4dc78e53SAndroid Build Coastguard Worker * @arg sk netlink socket.
1765*4dc78e53SAndroid Build Coastguard Worker * @arg orig original link to be changed
1766*4dc78e53SAndroid Build Coastguard Worker * @arg changes link containing the changes to be made
1767*4dc78e53SAndroid Build Coastguard Worker * @arg flags additional netlink message flags
1768*4dc78e53SAndroid Build Coastguard Worker *
1769*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_NEWLINK netlink message requesting the change of
1770*4dc78e53SAndroid Build Coastguard Worker * a network link. If -EOPNOTSUPP is returned by the kernel, the
1771*4dc78e53SAndroid Build Coastguard Worker * message type will be changed to \c RTM_SETLINK and the message is
1772*4dc78e53SAndroid Build Coastguard Worker * resent to work around older kernel versions.
1773*4dc78e53SAndroid Build Coastguard Worker *
1774*4dc78e53SAndroid Build Coastguard Worker * The link to be changed is looked up based on the interface index
1775*4dc78e53SAndroid Build Coastguard Worker * supplied in the \p orig link. Optionaly the link name is used but
1776*4dc78e53SAndroid Build Coastguard Worker * only if no interface index is provided, otherwise providing an
1777*4dc78e53SAndroid Build Coastguard Worker * link name will result in the link name being changed.
1778*4dc78e53SAndroid Build Coastguard Worker *
1779*4dc78e53SAndroid Build Coastguard Worker * If no matching link exists, the function will return
1780*4dc78e53SAndroid Build Coastguard Worker * -NLE_OBJ_NOTFOUND.
1781*4dc78e53SAndroid Build Coastguard Worker *
1782*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
1783*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
1784*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
1785*4dc78e53SAndroid Build Coastguard Worker *
1786*4dc78e53SAndroid Build Coastguard Worker * @copydoc auto_ack_warning
1787*4dc78e53SAndroid Build Coastguard Worker *
1788*4dc78e53SAndroid Build Coastguard Worker * @note The link name can only be changed if the link has been put
1789*4dc78e53SAndroid Build Coastguard Worker * in opertional down state. (~IF_UP)
1790*4dc78e53SAndroid Build Coastguard Worker *
1791*4dc78e53SAndroid Build Coastguard Worker * @note On versions up to 3.4.0, \c NLE_SEQ_MISMATCH would be returned if the
1792*4dc78e53SAndroid Build Coastguard Worker * kernel does not supports \c RTM_NEWLINK. It is advised to ignore the
1793*4dc78e53SAndroid Build Coastguard Worker * error code if you cannot upgrade the library.
1794*4dc78e53SAndroid Build Coastguard Worker *
1795*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1796*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_change(struct nl_sock * sk,struct rtnl_link * orig,struct rtnl_link * changes,int flags)1797*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_change(struct nl_sock *sk, struct rtnl_link *orig,
1798*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *changes, int flags)
1799*4dc78e53SAndroid Build Coastguard Worker {
1800*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
1801*4dc78e53SAndroid Build Coastguard Worker int err;
1802*4dc78e53SAndroid Build Coastguard Worker
1803*4dc78e53SAndroid Build Coastguard Worker err = rtnl_link_build_change_request(orig, changes, flags, &msg);
1804*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
1805*4dc78e53SAndroid Build Coastguard Worker return err;
1806*4dc78e53SAndroid Build Coastguard Worker
1807*4dc78e53SAndroid Build Coastguard Worker BUG_ON(msg->nm_nlh->nlmsg_seq != NL_AUTO_SEQ);
1808*4dc78e53SAndroid Build Coastguard Worker retry:
1809*4dc78e53SAndroid Build Coastguard Worker err = nl_send_auto_complete(sk, msg);
1810*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
1811*4dc78e53SAndroid Build Coastguard Worker return err;
1812*4dc78e53SAndroid Build Coastguard Worker
1813*4dc78e53SAndroid Build Coastguard Worker err = wait_for_ack(sk);
1814*4dc78e53SAndroid Build Coastguard Worker if ( err == -NLE_OPNOTSUPP
1815*4dc78e53SAndroid Build Coastguard Worker && msg->nm_nlh->nlmsg_type == RTM_NEWLINK) {
1816*4dc78e53SAndroid Build Coastguard Worker msg->nm_nlh->nlmsg_type = RTM_SETLINK;
1817*4dc78e53SAndroid Build Coastguard Worker msg->nm_nlh->nlmsg_seq = NL_AUTO_SEQ;
1818*4dc78e53SAndroid Build Coastguard Worker goto retry;
1819*4dc78e53SAndroid Build Coastguard Worker }
1820*4dc78e53SAndroid Build Coastguard Worker
1821*4dc78e53SAndroid Build Coastguard Worker if (err < 0)
1822*4dc78e53SAndroid Build Coastguard Worker return err;
1823*4dc78e53SAndroid Build Coastguard Worker
1824*4dc78e53SAndroid Build Coastguard Worker return 0;
1825*4dc78e53SAndroid Build Coastguard Worker }
1826*4dc78e53SAndroid Build Coastguard Worker
1827*4dc78e53SAndroid Build Coastguard Worker /** @} */
1828*4dc78e53SAndroid Build Coastguard Worker
1829*4dc78e53SAndroid Build Coastguard Worker /**
1830*4dc78e53SAndroid Build Coastguard Worker * @name Delete
1831*4dc78e53SAndroid Build Coastguard Worker * @{
1832*4dc78e53SAndroid Build Coastguard Worker */
1833*4dc78e53SAndroid Build Coastguard Worker
1834*4dc78e53SAndroid Build Coastguard Worker /**
1835*4dc78e53SAndroid Build Coastguard Worker * Build a netlink message requesting the deletion of a link
1836*4dc78e53SAndroid Build Coastguard Worker * @arg link Link to delete
1837*4dc78e53SAndroid Build Coastguard Worker * @arg result Pointer to store resulting netlink message
1838*4dc78e53SAndroid Build Coastguard Worker *
1839*4dc78e53SAndroid Build Coastguard Worker * The behaviour of this function is identical to rtnl_link_delete() with
1840*4dc78e53SAndroid Build Coastguard Worker * the exception that it will not send the message but return it in the
1841*4dc78e53SAndroid Build Coastguard Worker * provided return pointer instead.
1842*4dc78e53SAndroid Build Coastguard Worker *
1843*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_delete()
1844*4dc78e53SAndroid Build Coastguard Worker *
1845*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1846*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_build_delete_request(const struct rtnl_link * link,struct nl_msg ** result)1847*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_build_delete_request(const struct rtnl_link *link,
1848*4dc78e53SAndroid Build Coastguard Worker struct nl_msg **result)
1849*4dc78e53SAndroid Build Coastguard Worker {
1850*4dc78e53SAndroid Build Coastguard Worker _nl_auto_nl_msg struct nl_msg *msg = NULL;
1851*4dc78e53SAndroid Build Coastguard Worker struct ifinfomsg ifi = {
1852*4dc78e53SAndroid Build Coastguard Worker .ifi_index = link->l_index,
1853*4dc78e53SAndroid Build Coastguard Worker };
1854*4dc78e53SAndroid Build Coastguard Worker
1855*4dc78e53SAndroid Build Coastguard Worker if (!(link->ce_mask & (LINK_ATTR_IFINDEX | LINK_ATTR_IFNAME))) {
1856*4dc78e53SAndroid Build Coastguard Worker APPBUG("ifindex or name must be specified");
1857*4dc78e53SAndroid Build Coastguard Worker return -NLE_MISSING_ATTR;
1858*4dc78e53SAndroid Build Coastguard Worker }
1859*4dc78e53SAndroid Build Coastguard Worker
1860*4dc78e53SAndroid Build Coastguard Worker if (!(msg = nlmsg_alloc_simple(RTM_DELLINK, 0)))
1861*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
1862*4dc78e53SAndroid Build Coastguard Worker
1863*4dc78e53SAndroid Build Coastguard Worker _NL_RETURN_ON_PUT_ERR(nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO));
1864*4dc78e53SAndroid Build Coastguard Worker
1865*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_IFNAME)
1866*4dc78e53SAndroid Build Coastguard Worker _NL_RETURN_ON_PUT_ERR(nla_put_string(msg, IFLA_IFNAME, link->l_name));
1867*4dc78e53SAndroid Build Coastguard Worker
1868*4dc78e53SAndroid Build Coastguard Worker *result = _nl_steal_pointer(&msg);
1869*4dc78e53SAndroid Build Coastguard Worker return 0;
1870*4dc78e53SAndroid Build Coastguard Worker }
1871*4dc78e53SAndroid Build Coastguard Worker
1872*4dc78e53SAndroid Build Coastguard Worker /**
1873*4dc78e53SAndroid Build Coastguard Worker * Delete link
1874*4dc78e53SAndroid Build Coastguard Worker * @arg sk Netlink socket
1875*4dc78e53SAndroid Build Coastguard Worker * @arg link Link to delete
1876*4dc78e53SAndroid Build Coastguard Worker *
1877*4dc78e53SAndroid Build Coastguard Worker * Builds a \c RTM_DELLINK netlink message requesting the deletion of
1878*4dc78e53SAndroid Build Coastguard Worker * a network link which has been previously added to the kernel and
1879*4dc78e53SAndroid Build Coastguard Worker * sends the message to the kernel.
1880*4dc78e53SAndroid Build Coastguard Worker *
1881*4dc78e53SAndroid Build Coastguard Worker * If no matching link exists, the function will return
1882*4dc78e53SAndroid Build Coastguard Worker * -NLE_OBJ_NOTFOUND.
1883*4dc78e53SAndroid Build Coastguard Worker *
1884*4dc78e53SAndroid Build Coastguard Worker * After sending, the function will wait for the ACK or an eventual
1885*4dc78e53SAndroid Build Coastguard Worker * error message to be received and will therefore block until the
1886*4dc78e53SAndroid Build Coastguard Worker * operation has been completed.
1887*4dc78e53SAndroid Build Coastguard Worker *
1888*4dc78e53SAndroid Build Coastguard Worker * @copydoc auto_ack_warning
1889*4dc78e53SAndroid Build Coastguard Worker *
1890*4dc78e53SAndroid Build Coastguard Worker * @note Only virtual links such as dummy interface or vlan interfaces
1891*4dc78e53SAndroid Build Coastguard Worker * can be deleted. It is not possible to delete physical interfaces
1892*4dc78e53SAndroid Build Coastguard Worker * such as ethernet interfaces or the loopback device.
1893*4dc78e53SAndroid Build Coastguard Worker *
1894*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
1895*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_delete(struct nl_sock * sk,const struct rtnl_link * link)1896*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link)
1897*4dc78e53SAndroid Build Coastguard Worker {
1898*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
1899*4dc78e53SAndroid Build Coastguard Worker int err;
1900*4dc78e53SAndroid Build Coastguard Worker
1901*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_build_delete_request(link, &msg)) < 0)
1902*4dc78e53SAndroid Build Coastguard Worker return err;
1903*4dc78e53SAndroid Build Coastguard Worker
1904*4dc78e53SAndroid Build Coastguard Worker return nl_send_sync(sk, msg);
1905*4dc78e53SAndroid Build Coastguard Worker }
1906*4dc78e53SAndroid Build Coastguard Worker
1907*4dc78e53SAndroid Build Coastguard Worker /** @} */
1908*4dc78e53SAndroid Build Coastguard Worker
1909*4dc78e53SAndroid Build Coastguard Worker /**
1910*4dc78e53SAndroid Build Coastguard Worker * @name Link Object
1911*4dc78e53SAndroid Build Coastguard Worker * @{
1912*4dc78e53SAndroid Build Coastguard Worker */
1913*4dc78e53SAndroid Build Coastguard Worker
1914*4dc78e53SAndroid Build Coastguard Worker /**
1915*4dc78e53SAndroid Build Coastguard Worker * Allocate link object
1916*4dc78e53SAndroid Build Coastguard Worker *
1917*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_put()
1918*4dc78e53SAndroid Build Coastguard Worker * @return New link object or NULL if allocation failed
1919*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_alloc(void)1920*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *rtnl_link_alloc(void)
1921*4dc78e53SAndroid Build Coastguard Worker {
1922*4dc78e53SAndroid Build Coastguard Worker return (struct rtnl_link *) nl_object_alloc(&link_obj_ops);
1923*4dc78e53SAndroid Build Coastguard Worker }
1924*4dc78e53SAndroid Build Coastguard Worker
1925*4dc78e53SAndroid Build Coastguard Worker /**
1926*4dc78e53SAndroid Build Coastguard Worker * Release a link object reference
1927*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
1928*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_put(struct rtnl_link * link)1929*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_put(struct rtnl_link *link)
1930*4dc78e53SAndroid Build Coastguard Worker {
1931*4dc78e53SAndroid Build Coastguard Worker nl_object_put((struct nl_object *) link);
1932*4dc78e53SAndroid Build Coastguard Worker }
1933*4dc78e53SAndroid Build Coastguard Worker
1934*4dc78e53SAndroid Build Coastguard Worker /**
1935*4dc78e53SAndroid Build Coastguard Worker * Set name of link object
1936*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
1937*4dc78e53SAndroid Build Coastguard Worker * @arg name New name
1938*4dc78e53SAndroid Build Coastguard Worker *
1939*4dc78e53SAndroid Build Coastguard Worker * @note To change the name of a link in the kernel, set the interface
1940*4dc78e53SAndroid Build Coastguard Worker * index to the link you wish to change, modify the link name using
1941*4dc78e53SAndroid Build Coastguard Worker * this function and pass the link object to rtnl_link_change() or
1942*4dc78e53SAndroid Build Coastguard Worker * rtnl_link_add().
1943*4dc78e53SAndroid Build Coastguard Worker *
1944*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_name, Link Name}
1945*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_name()
1946*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_ifindex()
1947*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_name(struct rtnl_link * link,const char * name)1948*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_name(struct rtnl_link *link, const char *name)
1949*4dc78e53SAndroid Build Coastguard Worker {
1950*4dc78e53SAndroid Build Coastguard Worker _nl_strncpy_trunc(link->l_name, name, sizeof(link->l_name));
1951*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_IFNAME;
1952*4dc78e53SAndroid Build Coastguard Worker }
1953*4dc78e53SAndroid Build Coastguard Worker
1954*4dc78e53SAndroid Build Coastguard Worker /**
1955*4dc78e53SAndroid Build Coastguard Worker * Return name of link object
1956*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
1957*4dc78e53SAndroid Build Coastguard Worker *
1958*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_name, Link Name}
1959*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_name()
1960*4dc78e53SAndroid Build Coastguard Worker * @return Link name or NULL if name is not specified
1961*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_name(struct rtnl_link * link)1962*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_get_name(struct rtnl_link *link)
1963*4dc78e53SAndroid Build Coastguard Worker {
1964*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_IFNAME ? link->l_name : NULL;
1965*4dc78e53SAndroid Build Coastguard Worker }
1966*4dc78e53SAndroid Build Coastguard Worker
1967*4dc78e53SAndroid Build Coastguard Worker /**
1968*4dc78e53SAndroid Build Coastguard Worker * Set the group identifier of a link object
1969*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
1970*4dc78e53SAndroid Build Coastguard Worker * @arg group Group identifier
1971*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_group(struct rtnl_link * link,uint32_t group)1972*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_group(struct rtnl_link *link, uint32_t group)
1973*4dc78e53SAndroid Build Coastguard Worker {
1974*4dc78e53SAndroid Build Coastguard Worker link->l_group = group;
1975*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_GROUP;
1976*4dc78e53SAndroid Build Coastguard Worker }
1977*4dc78e53SAndroid Build Coastguard Worker
1978*4dc78e53SAndroid Build Coastguard Worker /**
1979*4dc78e53SAndroid Build Coastguard Worker * Return the group identifier of link object
1980*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
1981*4dc78e53SAndroid Build Coastguard Worker *
1982*4dc78e53SAndroid Build Coastguard Worker * @return Group identifier or 0 if not set.
1983*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_group(struct rtnl_link * link)1984*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_link_get_group(struct rtnl_link *link)
1985*4dc78e53SAndroid Build Coastguard Worker {
1986*4dc78e53SAndroid Build Coastguard Worker return link->l_group;
1987*4dc78e53SAndroid Build Coastguard Worker }
1988*4dc78e53SAndroid Build Coastguard Worker
__assign_addr(struct rtnl_link * link,struct nl_addr ** pos,struct nl_addr * new,int flag)1989*4dc78e53SAndroid Build Coastguard Worker static inline void __assign_addr(struct rtnl_link *link, struct nl_addr **pos,
1990*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *new, int flag)
1991*4dc78e53SAndroid Build Coastguard Worker {
1992*4dc78e53SAndroid Build Coastguard Worker if (*pos)
1993*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(*pos);
1994*4dc78e53SAndroid Build Coastguard Worker
1995*4dc78e53SAndroid Build Coastguard Worker nl_addr_get(new);
1996*4dc78e53SAndroid Build Coastguard Worker *pos = new;
1997*4dc78e53SAndroid Build Coastguard Worker
1998*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= flag;
1999*4dc78e53SAndroid Build Coastguard Worker }
2000*4dc78e53SAndroid Build Coastguard Worker
2001*4dc78e53SAndroid Build Coastguard Worker /**
2002*4dc78e53SAndroid Build Coastguard Worker * Set link layer address of link object
2003*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2004*4dc78e53SAndroid Build Coastguard Worker * @arg addr New link layer address
2005*4dc78e53SAndroid Build Coastguard Worker *
2006*4dc78e53SAndroid Build Coastguard Worker * The function increments the reference counter of the address object
2007*4dc78e53SAndroid Build Coastguard Worker * and overwrites any existing link layer address previously assigned.
2008*4dc78e53SAndroid Build Coastguard Worker *
2009*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_address, Link layer address}
2010*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_addr()
2011*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_addr(struct rtnl_link * link,struct nl_addr * addr)2012*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_addr(struct rtnl_link *link, struct nl_addr *addr)
2013*4dc78e53SAndroid Build Coastguard Worker {
2014*4dc78e53SAndroid Build Coastguard Worker __assign_addr(link, &link->l_addr, addr, LINK_ATTR_ADDR);
2015*4dc78e53SAndroid Build Coastguard Worker }
2016*4dc78e53SAndroid Build Coastguard Worker
2017*4dc78e53SAndroid Build Coastguard Worker /**
2018*4dc78e53SAndroid Build Coastguard Worker * Return link layer address of link object
2019*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2020*4dc78e53SAndroid Build Coastguard Worker *
2021*4dc78e53SAndroid Build Coastguard Worker * @copydoc pointer_lifetime_warning
2022*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_address, Link Layer Address}
2023*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_addr()
2024*4dc78e53SAndroid Build Coastguard Worker * @return Link layer address or NULL if not set.
2025*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_addr(struct rtnl_link * link)2026*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *rtnl_link_get_addr(struct rtnl_link *link)
2027*4dc78e53SAndroid Build Coastguard Worker {
2028*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_ADDR ? link->l_addr : NULL;
2029*4dc78e53SAndroid Build Coastguard Worker }
2030*4dc78e53SAndroid Build Coastguard Worker
2031*4dc78e53SAndroid Build Coastguard Worker /**
2032*4dc78e53SAndroid Build Coastguard Worker * Set link layer broadcast address of link object
2033*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2034*4dc78e53SAndroid Build Coastguard Worker * @arg addr New broadcast address
2035*4dc78e53SAndroid Build Coastguard Worker *
2036*4dc78e53SAndroid Build Coastguard Worker * The function increments the reference counter of the address object
2037*4dc78e53SAndroid Build Coastguard Worker * and overwrites any existing link layer broadcast address previously
2038*4dc78e53SAndroid Build Coastguard Worker * assigned.
2039*4dc78e53SAndroid Build Coastguard Worker *
2040*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_broadcast, Link Layer Broadcast Address}
2041*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_broadcast()
2042*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_broadcast(struct rtnl_link * link,struct nl_addr * addr)2043*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_broadcast(struct rtnl_link *link, struct nl_addr *addr)
2044*4dc78e53SAndroid Build Coastguard Worker {
2045*4dc78e53SAndroid Build Coastguard Worker __assign_addr(link, &link->l_bcast, addr, LINK_ATTR_BRD);
2046*4dc78e53SAndroid Build Coastguard Worker }
2047*4dc78e53SAndroid Build Coastguard Worker
2048*4dc78e53SAndroid Build Coastguard Worker /**
2049*4dc78e53SAndroid Build Coastguard Worker * Return link layer broadcast address of link object
2050*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2051*4dc78e53SAndroid Build Coastguard Worker *
2052*4dc78e53SAndroid Build Coastguard Worker * @copydoc pointer_lifetime_warning
2053*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_address, Link Layer Address}
2054*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_broadcast()
2055*4dc78e53SAndroid Build Coastguard Worker * @return Link layer address or NULL if not set.
2056*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_broadcast(struct rtnl_link * link)2057*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *rtnl_link_get_broadcast(struct rtnl_link *link)
2058*4dc78e53SAndroid Build Coastguard Worker {
2059*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_BRD ? link->l_bcast : NULL;
2060*4dc78e53SAndroid Build Coastguard Worker }
2061*4dc78e53SAndroid Build Coastguard Worker
2062*4dc78e53SAndroid Build Coastguard Worker /**
2063*4dc78e53SAndroid Build Coastguard Worker * Set flags of link object
2064*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2065*4dc78e53SAndroid Build Coastguard Worker * @arg flags Flags
2066*4dc78e53SAndroid Build Coastguard Worker *
2067*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_flags()
2068*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_unset_flags()
2069*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_flags(struct rtnl_link * link,unsigned int flags)2070*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_flags(struct rtnl_link *link, unsigned int flags)
2071*4dc78e53SAndroid Build Coastguard Worker {
2072*4dc78e53SAndroid Build Coastguard Worker link->l_flag_mask |= flags;
2073*4dc78e53SAndroid Build Coastguard Worker link->l_flags |= flags;
2074*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_FLAGS;
2075*4dc78e53SAndroid Build Coastguard Worker }
2076*4dc78e53SAndroid Build Coastguard Worker
2077*4dc78e53SAndroid Build Coastguard Worker /**
2078*4dc78e53SAndroid Build Coastguard Worker * Unset flags of link object
2079*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2080*4dc78e53SAndroid Build Coastguard Worker * @arg flags Flags
2081*4dc78e53SAndroid Build Coastguard Worker *
2082*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_flags()
2083*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_flags()
2084*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_unset_flags(struct rtnl_link * link,unsigned int flags)2085*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_unset_flags(struct rtnl_link *link, unsigned int flags)
2086*4dc78e53SAndroid Build Coastguard Worker {
2087*4dc78e53SAndroid Build Coastguard Worker link->l_flag_mask |= flags;
2088*4dc78e53SAndroid Build Coastguard Worker link->l_flags &= ~flags;
2089*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_FLAGS;
2090*4dc78e53SAndroid Build Coastguard Worker }
2091*4dc78e53SAndroid Build Coastguard Worker
2092*4dc78e53SAndroid Build Coastguard Worker /**
2093*4dc78e53SAndroid Build Coastguard Worker * Return flags of link object
2094*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2095*4dc78e53SAndroid Build Coastguard Worker *
2096*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_flags, Link Flags}
2097*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_flags()
2098*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_unset_flags()
2099*4dc78e53SAndroid Build Coastguard Worker * @return Link flags or 0 if none have been set.
2100*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_flags(struct rtnl_link * link)2101*4dc78e53SAndroid Build Coastguard Worker unsigned int rtnl_link_get_flags(struct rtnl_link *link)
2102*4dc78e53SAndroid Build Coastguard Worker {
2103*4dc78e53SAndroid Build Coastguard Worker return link->l_flags;
2104*4dc78e53SAndroid Build Coastguard Worker }
2105*4dc78e53SAndroid Build Coastguard Worker
2106*4dc78e53SAndroid Build Coastguard Worker /**
2107*4dc78e53SAndroid Build Coastguard Worker * Set address family of link object
2108*4dc78e53SAndroid Build Coastguard Worker *
2109*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_family()
2110*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_family(struct rtnl_link * link,int family)2111*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_family(struct rtnl_link *link, int family)
2112*4dc78e53SAndroid Build Coastguard Worker {
2113*4dc78e53SAndroid Build Coastguard Worker link->l_family = family;
2114*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_FAMILY;
2115*4dc78e53SAndroid Build Coastguard Worker
2116*4dc78e53SAndroid Build Coastguard Worker if (link->l_af_ops) {
2117*4dc78e53SAndroid Build Coastguard Worker int ao_family = link->l_af_ops->ao_family;
2118*4dc78e53SAndroid Build Coastguard Worker
2119*4dc78e53SAndroid Build Coastguard Worker af_free(link, link->l_af_ops, link->l_af_data[ao_family], NULL);
2120*4dc78e53SAndroid Build Coastguard Worker link->l_af_data[ao_family] = NULL;
2121*4dc78e53SAndroid Build Coastguard Worker }
2122*4dc78e53SAndroid Build Coastguard Worker
2123*4dc78e53SAndroid Build Coastguard Worker link->l_af_ops = af_lookup_and_alloc(link, family);
2124*4dc78e53SAndroid Build Coastguard Worker }
2125*4dc78e53SAndroid Build Coastguard Worker
2126*4dc78e53SAndroid Build Coastguard Worker /**
2127*4dc78e53SAndroid Build Coastguard Worker * Return address family of link object
2128*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2129*4dc78e53SAndroid Build Coastguard Worker *
2130*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_family()
2131*4dc78e53SAndroid Build Coastguard Worker * @return Address family or \c AF_UNSPEC if not specified.
2132*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_family(struct rtnl_link * link)2133*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_family(struct rtnl_link *link)
2134*4dc78e53SAndroid Build Coastguard Worker {
2135*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_FAMILY ? link->l_family : AF_UNSPEC;
2136*4dc78e53SAndroid Build Coastguard Worker }
2137*4dc78e53SAndroid Build Coastguard Worker
2138*4dc78e53SAndroid Build Coastguard Worker /**
2139*4dc78e53SAndroid Build Coastguard Worker * Set hardware type of link object
2140*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2141*4dc78e53SAndroid Build Coastguard Worker * @arg arptype New hardware type \c (ARPHRD_*)
2142*4dc78e53SAndroid Build Coastguard Worker *
2143*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_arptype, Hardware Type}
2144*4dc78e53SAndroid Build Coastguard Worker * @copydoc read_only_attribute
2145*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_arptype()
2146*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_arptype(struct rtnl_link * link,unsigned int arptype)2147*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_arptype(struct rtnl_link *link, unsigned int arptype)
2148*4dc78e53SAndroid Build Coastguard Worker {
2149*4dc78e53SAndroid Build Coastguard Worker link->l_arptype = arptype;
2150*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_ARPTYPE;
2151*4dc78e53SAndroid Build Coastguard Worker }
2152*4dc78e53SAndroid Build Coastguard Worker
2153*4dc78e53SAndroid Build Coastguard Worker /**
2154*4dc78e53SAndroid Build Coastguard Worker * Get hardware type of link object
2155*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2156*4dc78e53SAndroid Build Coastguard Worker *
2157*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_arptype, Hardware Type}
2158*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_arptype()
2159*4dc78e53SAndroid Build Coastguard Worker * @return Hardware type \c (ARPHRD_ETHER *) or \c ARPHRD_VOID
2160*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_arptype(struct rtnl_link * link)2161*4dc78e53SAndroid Build Coastguard Worker unsigned int rtnl_link_get_arptype(struct rtnl_link *link)
2162*4dc78e53SAndroid Build Coastguard Worker {
2163*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_ARPTYPE)
2164*4dc78e53SAndroid Build Coastguard Worker return link->l_arptype;
2165*4dc78e53SAndroid Build Coastguard Worker else
2166*4dc78e53SAndroid Build Coastguard Worker return ARPHRD_VOID;
2167*4dc78e53SAndroid Build Coastguard Worker }
2168*4dc78e53SAndroid Build Coastguard Worker
2169*4dc78e53SAndroid Build Coastguard Worker /**
2170*4dc78e53SAndroid Build Coastguard Worker * Set interface index of link object
2171*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2172*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index
2173*4dc78e53SAndroid Build Coastguard Worker *
2174*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_ifindex, Interface Index}
2175*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_ifindex()
2176*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_ifindex(struct rtnl_link * link,int ifindex)2177*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_ifindex(struct rtnl_link *link, int ifindex)
2178*4dc78e53SAndroid Build Coastguard Worker {
2179*4dc78e53SAndroid Build Coastguard Worker link->l_index = ifindex;
2180*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_IFINDEX;
2181*4dc78e53SAndroid Build Coastguard Worker }
2182*4dc78e53SAndroid Build Coastguard Worker
2183*4dc78e53SAndroid Build Coastguard Worker
2184*4dc78e53SAndroid Build Coastguard Worker /**
2185*4dc78e53SAndroid Build Coastguard Worker * Return interface index of link object
2186*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2187*4dc78e53SAndroid Build Coastguard Worker *
2188*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_ifindex, Interface Index}
2189*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_ifindex()
2190*4dc78e53SAndroid Build Coastguard Worker * @return Interface index or 0 if not set.
2191*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_ifindex(struct rtnl_link * link)2192*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_ifindex(struct rtnl_link *link)
2193*4dc78e53SAndroid Build Coastguard Worker {
2194*4dc78e53SAndroid Build Coastguard Worker return link->l_index;
2195*4dc78e53SAndroid Build Coastguard Worker }
2196*4dc78e53SAndroid Build Coastguard Worker
2197*4dc78e53SAndroid Build Coastguard Worker /**
2198*4dc78e53SAndroid Build Coastguard Worker * Set Maximum Transmission Unit of link object
2199*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2200*4dc78e53SAndroid Build Coastguard Worker * @arg mtu New MTU value in number of bytes
2201*4dc78e53SAndroid Build Coastguard Worker *
2202*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_mtu, Maximum Transmission Unit}
2203*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_mtu()
2204*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_mtu(struct rtnl_link * link,unsigned int mtu)2205*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_mtu(struct rtnl_link *link, unsigned int mtu)
2206*4dc78e53SAndroid Build Coastguard Worker {
2207*4dc78e53SAndroid Build Coastguard Worker link->l_mtu = mtu;
2208*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_MTU;
2209*4dc78e53SAndroid Build Coastguard Worker }
2210*4dc78e53SAndroid Build Coastguard Worker
2211*4dc78e53SAndroid Build Coastguard Worker /**
2212*4dc78e53SAndroid Build Coastguard Worker * Return maximum transmission unit of link object
2213*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2214*4dc78e53SAndroid Build Coastguard Worker *
2215*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_mtu, Maximum Transmission Unit}
2216*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_mtu()
2217*4dc78e53SAndroid Build Coastguard Worker * @return MTU in bytes or 0 if not set
2218*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_mtu(struct rtnl_link * link)2219*4dc78e53SAndroid Build Coastguard Worker unsigned int rtnl_link_get_mtu(struct rtnl_link *link)
2220*4dc78e53SAndroid Build Coastguard Worker {
2221*4dc78e53SAndroid Build Coastguard Worker return link->l_mtu;
2222*4dc78e53SAndroid Build Coastguard Worker }
2223*4dc78e53SAndroid Build Coastguard Worker
2224*4dc78e53SAndroid Build Coastguard Worker /**
2225*4dc78e53SAndroid Build Coastguard Worker * Set transmission queue length
2226*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2227*4dc78e53SAndroid Build Coastguard Worker * @arg txqlen New queue length
2228*4dc78e53SAndroid Build Coastguard Worker *
2229*4dc78e53SAndroid Build Coastguard Worker * The unit is dependant on the link type. The most common units is number
2230*4dc78e53SAndroid Build Coastguard Worker * of packets.
2231*4dc78e53SAndroid Build Coastguard Worker *
2232*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_txqlen, Transmission Queue Length}
2233*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_txqlen(struct rtnl_link * link,unsigned int txqlen)2234*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_txqlen(struct rtnl_link *link, unsigned int txqlen)
2235*4dc78e53SAndroid Build Coastguard Worker {
2236*4dc78e53SAndroid Build Coastguard Worker link->l_txqlen = txqlen;
2237*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_TXQLEN;
2238*4dc78e53SAndroid Build Coastguard Worker }
2239*4dc78e53SAndroid Build Coastguard Worker
2240*4dc78e53SAndroid Build Coastguard Worker /**
2241*4dc78e53SAndroid Build Coastguard Worker * Return transmission queue length
2242*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2243*4dc78e53SAndroid Build Coastguard Worker *
2244*4dc78e53SAndroid Build Coastguard Worker * The unit is dependant on the link type. The most common units is number
2245*4dc78e53SAndroid Build Coastguard Worker * of packets.
2246*4dc78e53SAndroid Build Coastguard Worker *
2247*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_txqlen, Transmission Queue Length}
2248*4dc78e53SAndroid Build Coastguard Worker * @return queue length or 0 if not specified.
2249*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_txqlen(struct rtnl_link * link)2250*4dc78e53SAndroid Build Coastguard Worker unsigned int rtnl_link_get_txqlen(struct rtnl_link *link)
2251*4dc78e53SAndroid Build Coastguard Worker {
2252*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_TXQLEN ? link->l_txqlen : 0;
2253*4dc78e53SAndroid Build Coastguard Worker }
2254*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_set_link(struct rtnl_link * link,int ifindex)2255*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_link(struct rtnl_link *link, int ifindex)
2256*4dc78e53SAndroid Build Coastguard Worker {
2257*4dc78e53SAndroid Build Coastguard Worker link->l_link = ifindex;
2258*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINK;
2259*4dc78e53SAndroid Build Coastguard Worker }
2260*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_get_link(struct rtnl_link * link)2261*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_link(struct rtnl_link *link)
2262*4dc78e53SAndroid Build Coastguard Worker {
2263*4dc78e53SAndroid Build Coastguard Worker return link->l_link;
2264*4dc78e53SAndroid Build Coastguard Worker }
2265*4dc78e53SAndroid Build Coastguard Worker
2266*4dc78e53SAndroid Build Coastguard Worker /**
2267*4dc78e53SAndroid Build Coastguard Worker * Set the netnsid of the link
2268*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2269*4dc78e53SAndroid Build Coastguard Worker * @link_netnsid the netnsid to set
2270*4dc78e53SAndroid Build Coastguard Worker *
2271*4dc78e53SAndroid Build Coastguard Worker * Sets the IFLA_LINK_NETNSID attribute of the link
2272*4dc78e53SAndroid Build Coastguard Worker * @returns 0 on success
2273*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_link_netnsid(struct rtnl_link * link,int32_t link_netnsid)2274*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_set_link_netnsid(struct rtnl_link *link, int32_t link_netnsid)
2275*4dc78e53SAndroid Build Coastguard Worker {
2276*4dc78e53SAndroid Build Coastguard Worker link->l_link_netnsid = link_netnsid;
2277*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINK_NETNSID;
2278*4dc78e53SAndroid Build Coastguard Worker return 0;
2279*4dc78e53SAndroid Build Coastguard Worker }
2280*4dc78e53SAndroid Build Coastguard Worker
2281*4dc78e53SAndroid Build Coastguard Worker /**
2282*4dc78e53SAndroid Build Coastguard Worker * Get the netnsid of the link
2283*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2284*4dc78e53SAndroid Build Coastguard Worker * @out_link_netnsid the netnsid
2285*4dc78e53SAndroid Build Coastguard Worker *
2286*4dc78e53SAndroid Build Coastguard Worker * Gets the IFLA_LINK_NETNSID attribute of the link
2287*4dc78e53SAndroid Build Coastguard Worker * or returns an error if the value is unset.
2288*4dc78e53SAndroid Build Coastguard Worker *
2289*4dc78e53SAndroid Build Coastguard Worker * @returns 0 on success
2290*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_link_netnsid(const struct rtnl_link * link,int32_t * out_link_netnsid)2291*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_link_netnsid(const struct rtnl_link *link, int32_t *out_link_netnsid)
2292*4dc78e53SAndroid Build Coastguard Worker {
2293*4dc78e53SAndroid Build Coastguard Worker if (!(link->ce_mask & LINK_ATTR_LINK_NETNSID))
2294*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
2295*4dc78e53SAndroid Build Coastguard Worker
2296*4dc78e53SAndroid Build Coastguard Worker *out_link_netnsid = link->l_link_netnsid;
2297*4dc78e53SAndroid Build Coastguard Worker return 0;
2298*4dc78e53SAndroid Build Coastguard Worker }
2299*4dc78e53SAndroid Build Coastguard Worker
2300*4dc78e53SAndroid Build Coastguard Worker /**
2301*4dc78e53SAndroid Build Coastguard Worker * Set master link of link object
2302*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2303*4dc78e53SAndroid Build Coastguard Worker * @arg ifindex Interface index of master link
2304*4dc78e53SAndroid Build Coastguard Worker *
2305*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_master()
2306*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_master(struct rtnl_link * link,int ifindex)2307*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_master(struct rtnl_link *link, int ifindex)
2308*4dc78e53SAndroid Build Coastguard Worker {
2309*4dc78e53SAndroid Build Coastguard Worker link->l_master = ifindex;
2310*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_MASTER;
2311*4dc78e53SAndroid Build Coastguard Worker }
2312*4dc78e53SAndroid Build Coastguard Worker
2313*4dc78e53SAndroid Build Coastguard Worker /**
2314*4dc78e53SAndroid Build Coastguard Worker * Return master link of link object
2315*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2316*4dc78e53SAndroid Build Coastguard Worker *
2317*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_master()
2318*4dc78e53SAndroid Build Coastguard Worker * @return Interface index of master link or 0 if not specified
2319*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_master(struct rtnl_link * link)2320*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_master(struct rtnl_link *link)
2321*4dc78e53SAndroid Build Coastguard Worker {
2322*4dc78e53SAndroid Build Coastguard Worker return link->l_master;
2323*4dc78e53SAndroid Build Coastguard Worker }
2324*4dc78e53SAndroid Build Coastguard Worker
2325*4dc78e53SAndroid Build Coastguard Worker /**
2326*4dc78e53SAndroid Build Coastguard Worker * Set carrier of link object
2327*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2328*4dc78e53SAndroid Build Coastguard Worker * @arg status New carrier status
2329*4dc78e53SAndroid Build Coastguard Worker *
2330*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_carrier()
2331*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_carrier(struct rtnl_link * link,uint8_t status)2332*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_carrier(struct rtnl_link *link, uint8_t status)
2333*4dc78e53SAndroid Build Coastguard Worker {
2334*4dc78e53SAndroid Build Coastguard Worker link->l_carrier = status;
2335*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_CARRIER;
2336*4dc78e53SAndroid Build Coastguard Worker }
2337*4dc78e53SAndroid Build Coastguard Worker
2338*4dc78e53SAndroid Build Coastguard Worker /**
2339*4dc78e53SAndroid Build Coastguard Worker * Return carrier status of link object
2340*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2341*4dc78e53SAndroid Build Coastguard Worker *
2342*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_master()
2343*4dc78e53SAndroid Build Coastguard Worker * @return Carrier state.
2344*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_carrier(struct rtnl_link * link)2345*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_link_get_carrier(struct rtnl_link *link)
2346*4dc78e53SAndroid Build Coastguard Worker {
2347*4dc78e53SAndroid Build Coastguard Worker return link->l_carrier;
2348*4dc78e53SAndroid Build Coastguard Worker }
2349*4dc78e53SAndroid Build Coastguard Worker
2350*4dc78e53SAndroid Build Coastguard Worker /**
2351*4dc78e53SAndroid Build Coastguard Worker * Return carrier on/off changes of link object
2352*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2353*4dc78e53SAndroid Build Coastguard Worker * @arg carrier_changes Pointer to store number of carrier changes
2354*4dc78e53SAndroid Build Coastguard Worker *
2355*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success, negative error number otherwise
2356*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_carrier_changes(struct rtnl_link * link,uint32_t * carrier_changes)2357*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_carrier_changes(struct rtnl_link *link, uint32_t *carrier_changes)
2358*4dc78e53SAndroid Build Coastguard Worker {
2359*4dc78e53SAndroid Build Coastguard Worker if (!(link->ce_mask & LINK_ATTR_CARRIER_CHANGES))
2360*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
2361*4dc78e53SAndroid Build Coastguard Worker
2362*4dc78e53SAndroid Build Coastguard Worker if (carrier_changes)
2363*4dc78e53SAndroid Build Coastguard Worker *carrier_changes = link->l_carrier_changes;
2364*4dc78e53SAndroid Build Coastguard Worker
2365*4dc78e53SAndroid Build Coastguard Worker return 0;
2366*4dc78e53SAndroid Build Coastguard Worker }
2367*4dc78e53SAndroid Build Coastguard Worker
2368*4dc78e53SAndroid Build Coastguard Worker /**
2369*4dc78e53SAndroid Build Coastguard Worker * Set operational status of link object
2370*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2371*4dc78e53SAndroid Build Coastguard Worker * @arg status New opertional status
2372*4dc78e53SAndroid Build Coastguard Worker *
2373*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_operstate, Operational Status}}
2374*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_operstate()
2375*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_operstate(struct rtnl_link * link,uint8_t status)2376*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_operstate(struct rtnl_link *link, uint8_t status)
2377*4dc78e53SAndroid Build Coastguard Worker {
2378*4dc78e53SAndroid Build Coastguard Worker link->l_operstate = status;
2379*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_OPERSTATE;
2380*4dc78e53SAndroid Build Coastguard Worker }
2381*4dc78e53SAndroid Build Coastguard Worker
2382*4dc78e53SAndroid Build Coastguard Worker /**
2383*4dc78e53SAndroid Build Coastguard Worker * Return operational status of link object
2384*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2385*4dc78e53SAndroid Build Coastguard Worker *
2386*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_operstate, Operational Status}
2387*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_operstate()
2388*4dc78e53SAndroid Build Coastguard Worker * @return Opertional state or \c IF_OPER_UNKNOWN
2389*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_operstate(struct rtnl_link * link)2390*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_link_get_operstate(struct rtnl_link *link)
2391*4dc78e53SAndroid Build Coastguard Worker {
2392*4dc78e53SAndroid Build Coastguard Worker return link->l_operstate;
2393*4dc78e53SAndroid Build Coastguard Worker }
2394*4dc78e53SAndroid Build Coastguard Worker
2395*4dc78e53SAndroid Build Coastguard Worker /**
2396*4dc78e53SAndroid Build Coastguard Worker * Set link mode of link object
2397*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2398*4dc78e53SAndroid Build Coastguard Worker * @arg mode New link mode
2399*4dc78e53SAndroid Build Coastguard Worker *
2400*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_mode, Mode}
2401*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_linkmode()
2402*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_linkmode(struct rtnl_link * link,uint8_t mode)2403*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_linkmode(struct rtnl_link *link, uint8_t mode)
2404*4dc78e53SAndroid Build Coastguard Worker {
2405*4dc78e53SAndroid Build Coastguard Worker link->l_linkmode = mode;
2406*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKMODE;
2407*4dc78e53SAndroid Build Coastguard Worker }
2408*4dc78e53SAndroid Build Coastguard Worker
2409*4dc78e53SAndroid Build Coastguard Worker /**
2410*4dc78e53SAndroid Build Coastguard Worker * Return link mode of link object
2411*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2412*4dc78e53SAndroid Build Coastguard Worker *
2413*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_mode, Mode}
2414*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_linkmode()
2415*4dc78e53SAndroid Build Coastguard Worker * @return Link mode or \c IF_LINK_MODE_DEFAULT
2416*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_linkmode(struct rtnl_link * link)2417*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_link_get_linkmode(struct rtnl_link *link)
2418*4dc78e53SAndroid Build Coastguard Worker {
2419*4dc78e53SAndroid Build Coastguard Worker return link->l_linkmode;
2420*4dc78e53SAndroid Build Coastguard Worker }
2421*4dc78e53SAndroid Build Coastguard Worker
2422*4dc78e53SAndroid Build Coastguard Worker /**
2423*4dc78e53SAndroid Build Coastguard Worker * Return alias name of link object (SNMP IfAlias)
2424*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2425*4dc78e53SAndroid Build Coastguard Worker *
2426*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_alias, Alias}
2427*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_ifalias()
2428*4dc78e53SAndroid Build Coastguard Worker * @return Alias name or NULL if not set.
2429*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_ifalias(struct rtnl_link * link)2430*4dc78e53SAndroid Build Coastguard Worker const char *rtnl_link_get_ifalias(struct rtnl_link *link)
2431*4dc78e53SAndroid Build Coastguard Worker {
2432*4dc78e53SAndroid Build Coastguard Worker return link->l_ifalias;
2433*4dc78e53SAndroid Build Coastguard Worker }
2434*4dc78e53SAndroid Build Coastguard Worker
2435*4dc78e53SAndroid Build Coastguard Worker /**
2436*4dc78e53SAndroid Build Coastguard Worker * Set alias name of link object (SNMP IfAlias)
2437*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2438*4dc78e53SAndroid Build Coastguard Worker * @arg alias Alias name or NULL to unset
2439*4dc78e53SAndroid Build Coastguard Worker *
2440*4dc78e53SAndroid Build Coastguard Worker * Sets the alias name of the link to the specified name. The alias
2441*4dc78e53SAndroid Build Coastguard Worker * name can be unset by specyfing NULL as the alias. The name will
2442*4dc78e53SAndroid Build Coastguard Worker * be strdup()ed, so no need to provide a persistent character string.
2443*4dc78e53SAndroid Build Coastguard Worker *
2444*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_alias, Alias}
2445*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_ifalias()
2446*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_ifalias(struct rtnl_link * link,const char * alias)2447*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_ifalias(struct rtnl_link *link, const char *alias)
2448*4dc78e53SAndroid Build Coastguard Worker {
2449*4dc78e53SAndroid Build Coastguard Worker free(link->l_ifalias);
2450*4dc78e53SAndroid Build Coastguard Worker
2451*4dc78e53SAndroid Build Coastguard Worker if (alias) {
2452*4dc78e53SAndroid Build Coastguard Worker link->l_ifalias = strdup(alias);
2453*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_IFALIAS;
2454*4dc78e53SAndroid Build Coastguard Worker } else {
2455*4dc78e53SAndroid Build Coastguard Worker link->l_ifalias = NULL;
2456*4dc78e53SAndroid Build Coastguard Worker link->ce_mask &= ~LINK_ATTR_IFALIAS;
2457*4dc78e53SAndroid Build Coastguard Worker }
2458*4dc78e53SAndroid Build Coastguard Worker }
2459*4dc78e53SAndroid Build Coastguard Worker
2460*4dc78e53SAndroid Build Coastguard Worker /**
2461*4dc78e53SAndroid Build Coastguard Worker * Set queueing discipline name of link object
2462*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2463*4dc78e53SAndroid Build Coastguard Worker * @arg name Name of queueing discipline
2464*4dc78e53SAndroid Build Coastguard Worker *
2465*4dc78e53SAndroid Build Coastguard Worker * @copydoc read_only_attribute
2466*4dc78e53SAndroid Build Coastguard Worker *
2467*4dc78e53SAndroid Build Coastguard Worker * For more information on how to modify the qdisc of a link, see section
2468*4dc78e53SAndroid Build Coastguard Worker * @ref_route{route_tc, Traffic Control}.
2469*4dc78e53SAndroid Build Coastguard Worker *
2470*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_qdisc, Queueing Discipline Name}
2471*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_qdisc()
2472*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_qdisc(struct rtnl_link * link,const char * name)2473*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_qdisc(struct rtnl_link *link, const char *name)
2474*4dc78e53SAndroid Build Coastguard Worker {
2475*4dc78e53SAndroid Build Coastguard Worker _nl_strncpy_trunc(link->l_qdisc, name, sizeof(link->l_qdisc));
2476*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_QDISC;
2477*4dc78e53SAndroid Build Coastguard Worker }
2478*4dc78e53SAndroid Build Coastguard Worker
2479*4dc78e53SAndroid Build Coastguard Worker /**
2480*4dc78e53SAndroid Build Coastguard Worker * Return name of queueing discipline of link object
2481*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2482*4dc78e53SAndroid Build Coastguard Worker *
2483*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_attr_qdisc, Queueing Discipline Name}
2484*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_qdisc()
2485*4dc78e53SAndroid Build Coastguard Worker * @return Name of qdisc or NULL if not specified.
2486*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_qdisc(struct rtnl_link * link)2487*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_get_qdisc(struct rtnl_link *link)
2488*4dc78e53SAndroid Build Coastguard Worker {
2489*4dc78e53SAndroid Build Coastguard Worker return link->ce_mask & LINK_ATTR_QDISC ? link->l_qdisc : NULL;
2490*4dc78e53SAndroid Build Coastguard Worker }
2491*4dc78e53SAndroid Build Coastguard Worker
2492*4dc78e53SAndroid Build Coastguard Worker
2493*4dc78e53SAndroid Build Coastguard Worker /**
2494*4dc78e53SAndroid Build Coastguard Worker * Return number of PCI virtual functions of link object
2495*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2496*4dc78e53SAndroid Build Coastguard Worker * @arg num_vf Pointer to store number of VFs
2497*4dc78e53SAndroid Build Coastguard Worker *
2498*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or -NLE_OPNOTSUPP if not available
2499*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_num_vf(struct rtnl_link * link,uint32_t * num_vf)2500*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_num_vf(struct rtnl_link *link, uint32_t *num_vf)
2501*4dc78e53SAndroid Build Coastguard Worker {
2502*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_NUM_VF) {
2503*4dc78e53SAndroid Build Coastguard Worker *num_vf = link->l_num_vf;
2504*4dc78e53SAndroid Build Coastguard Worker return 0;
2505*4dc78e53SAndroid Build Coastguard Worker } else
2506*4dc78e53SAndroid Build Coastguard Worker return -NLE_OPNOTSUPP;
2507*4dc78e53SAndroid Build Coastguard Worker }
2508*4dc78e53SAndroid Build Coastguard Worker
2509*4dc78e53SAndroid Build Coastguard Worker /**
2510*4dc78e53SAndroid Build Coastguard Worker * Return value of link statistics counter
2511*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2512*4dc78e53SAndroid Build Coastguard Worker * @arg id Identifier of statistical counter
2513*4dc78e53SAndroid Build Coastguard Worker *
2514*4dc78e53SAndroid Build Coastguard Worker * @return Value of counter or 0 if not specified.
2515*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_stat(struct rtnl_link * link,rtnl_link_stat_id_t id)2516*4dc78e53SAndroid Build Coastguard Worker uint64_t rtnl_link_get_stat(struct rtnl_link *link, rtnl_link_stat_id_t id)
2517*4dc78e53SAndroid Build Coastguard Worker {
2518*4dc78e53SAndroid Build Coastguard Worker if (id > RTNL_LINK_STATS_MAX)
2519*4dc78e53SAndroid Build Coastguard Worker return 0;
2520*4dc78e53SAndroid Build Coastguard Worker
2521*4dc78e53SAndroid Build Coastguard Worker return link->l_stats[id];
2522*4dc78e53SAndroid Build Coastguard Worker }
2523*4dc78e53SAndroid Build Coastguard Worker
2524*4dc78e53SAndroid Build Coastguard Worker /**
2525*4dc78e53SAndroid Build Coastguard Worker * Set value of link statistics counter
2526*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2527*4dc78e53SAndroid Build Coastguard Worker * @arg id Identifier of statistical counter
2528*4dc78e53SAndroid Build Coastguard Worker * @arg value New value
2529*4dc78e53SAndroid Build Coastguard Worker *
2530*4dc78e53SAndroid Build Coastguard Worker * \note Changing the value of a statistical counter will not change the
2531*4dc78e53SAndroid Build Coastguard Worker * value in the kernel.
2532*4dc78e53SAndroid Build Coastguard Worker *
2533*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code
2534*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_stat(struct rtnl_link * link,rtnl_link_stat_id_t id,const uint64_t value)2535*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id,
2536*4dc78e53SAndroid Build Coastguard Worker const uint64_t value)
2537*4dc78e53SAndroid Build Coastguard Worker {
2538*4dc78e53SAndroid Build Coastguard Worker if (id > RTNL_LINK_STATS_MAX)
2539*4dc78e53SAndroid Build Coastguard Worker return -NLE_INVAL;
2540*4dc78e53SAndroid Build Coastguard Worker
2541*4dc78e53SAndroid Build Coastguard Worker link->l_stats[id] = value;
2542*4dc78e53SAndroid Build Coastguard Worker
2543*4dc78e53SAndroid Build Coastguard Worker return 0;
2544*4dc78e53SAndroid Build Coastguard Worker }
2545*4dc78e53SAndroid Build Coastguard Worker
2546*4dc78e53SAndroid Build Coastguard Worker /**
2547*4dc78e53SAndroid Build Coastguard Worker * Set type of link object
2548*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2549*4dc78e53SAndroid Build Coastguard Worker * @arg type Name of link type
2550*4dc78e53SAndroid Build Coastguard Worker *
2551*4dc78e53SAndroid Build Coastguard Worker * Looks up the link type module and prepares the link to store type
2552*4dc78e53SAndroid Build Coastguard Worker * specific attributes. If a type has been assigned already it will
2553*4dc78e53SAndroid Build Coastguard Worker * be released with all link type specific attributes lost.
2554*4dc78e53SAndroid Build Coastguard Worker *
2555*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_modules, Link Modules}
2556*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2557*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_type(struct rtnl_link * link,const char * type)2558*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_set_type(struct rtnl_link *link, const char *type)
2559*4dc78e53SAndroid Build Coastguard Worker {
2560*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link_info_ops *io;
2561*4dc78e53SAndroid Build Coastguard Worker _nl_auto_free char *kind = NULL;
2562*4dc78e53SAndroid Build Coastguard Worker int err;
2563*4dc78e53SAndroid Build Coastguard Worker
2564*4dc78e53SAndroid Build Coastguard Worker free(link->l_info_kind);
2565*4dc78e53SAndroid Build Coastguard Worker link->ce_mask &= ~LINK_ATTR_LINKINFO;
2566*4dc78e53SAndroid Build Coastguard Worker release_link_info(link);
2567*4dc78e53SAndroid Build Coastguard Worker
2568*4dc78e53SAndroid Build Coastguard Worker if (!type)
2569*4dc78e53SAndroid Build Coastguard Worker return 0;
2570*4dc78e53SAndroid Build Coastguard Worker
2571*4dc78e53SAndroid Build Coastguard Worker kind = strdup(type);
2572*4dc78e53SAndroid Build Coastguard Worker if (!kind)
2573*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
2574*4dc78e53SAndroid Build Coastguard Worker
2575*4dc78e53SAndroid Build Coastguard Worker io = rtnl_link_info_ops_lookup(type);
2576*4dc78e53SAndroid Build Coastguard Worker if (io) {
2577*4dc78e53SAndroid Build Coastguard Worker if (io->io_alloc && (err = io->io_alloc(link)) < 0) {
2578*4dc78e53SAndroid Build Coastguard Worker _nl_clear_free(&kind);
2579*4dc78e53SAndroid Build Coastguard Worker return err;
2580*4dc78e53SAndroid Build Coastguard Worker }
2581*4dc78e53SAndroid Build Coastguard Worker
2582*4dc78e53SAndroid Build Coastguard Worker link->l_info_ops = io;
2583*4dc78e53SAndroid Build Coastguard Worker }
2584*4dc78e53SAndroid Build Coastguard Worker
2585*4dc78e53SAndroid Build Coastguard Worker link->l_info_kind = _nl_steal_pointer(&kind);
2586*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKINFO;
2587*4dc78e53SAndroid Build Coastguard Worker
2588*4dc78e53SAndroid Build Coastguard Worker return 0;
2589*4dc78e53SAndroid Build Coastguard Worker }
2590*4dc78e53SAndroid Build Coastguard Worker
2591*4dc78e53SAndroid Build Coastguard Worker /**
2592*4dc78e53SAndroid Build Coastguard Worker * Return type of link
2593*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2594*4dc78e53SAndroid Build Coastguard Worker *
2595*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_modules, Link Modules}
2596*4dc78e53SAndroid Build Coastguard Worker * @return Name of link type or NULL if not specified.
2597*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_type(struct rtnl_link * link)2598*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_get_type(struct rtnl_link *link)
2599*4dc78e53SAndroid Build Coastguard Worker {
2600*4dc78e53SAndroid Build Coastguard Worker return link->l_info_kind;
2601*4dc78e53SAndroid Build Coastguard Worker }
2602*4dc78e53SAndroid Build Coastguard Worker
2603*4dc78e53SAndroid Build Coastguard Worker /**
2604*4dc78e53SAndroid Build Coastguard Worker * Set type of slave link object
2605*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object (slave)
2606*4dc78e53SAndroid Build Coastguard Worker * @arg type Name of link type
2607*4dc78e53SAndroid Build Coastguard Worker *
2608*4dc78e53SAndroid Build Coastguard Worker * If a slave type has been assigned already it will be released.
2609*4dc78e53SAndroid Build Coastguard Worker *
2610*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_modules, Link Modules}
2611*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2612*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_slave_type(struct rtnl_link * link,const char * type)2613*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_set_slave_type(struct rtnl_link *link, const char *type)
2614*4dc78e53SAndroid Build Coastguard Worker {
2615*4dc78e53SAndroid Build Coastguard Worker char *kind = NULL;
2616*4dc78e53SAndroid Build Coastguard Worker
2617*4dc78e53SAndroid Build Coastguard Worker if (type) {
2618*4dc78e53SAndroid Build Coastguard Worker kind = strdup(type);
2619*4dc78e53SAndroid Build Coastguard Worker if (!kind)
2620*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
2621*4dc78e53SAndroid Build Coastguard Worker }
2622*4dc78e53SAndroid Build Coastguard Worker
2623*4dc78e53SAndroid Build Coastguard Worker free(link->l_info_slave_kind);
2624*4dc78e53SAndroid Build Coastguard Worker link->l_info_slave_kind = kind;
2625*4dc78e53SAndroid Build Coastguard Worker
2626*4dc78e53SAndroid Build Coastguard Worker if (kind)
2627*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_LINKINFO_SLAVE_KIND;
2628*4dc78e53SAndroid Build Coastguard Worker else
2629*4dc78e53SAndroid Build Coastguard Worker link->ce_mask &= ~LINK_ATTR_LINKINFO_SLAVE_KIND;
2630*4dc78e53SAndroid Build Coastguard Worker return 0;
2631*4dc78e53SAndroid Build Coastguard Worker }
2632*4dc78e53SAndroid Build Coastguard Worker
2633*4dc78e53SAndroid Build Coastguard Worker /**
2634*4dc78e53SAndroid Build Coastguard Worker * Return type of enslaved link
2635*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2636*4dc78e53SAndroid Build Coastguard Worker *
2637*4dc78e53SAndroid Build Coastguard Worker * @route_doc{link_modules, Link Modules}
2638*4dc78e53SAndroid Build Coastguard Worker * @return Name of enslaved link type or NULL if not specified.
2639*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_slave_type(const struct rtnl_link * link)2640*4dc78e53SAndroid Build Coastguard Worker const char *rtnl_link_get_slave_type(const struct rtnl_link *link)
2641*4dc78e53SAndroid Build Coastguard Worker {
2642*4dc78e53SAndroid Build Coastguard Worker return link->l_info_slave_kind;
2643*4dc78e53SAndroid Build Coastguard Worker }
2644*4dc78e53SAndroid Build Coastguard Worker
2645*4dc78e53SAndroid Build Coastguard Worker
2646*4dc78e53SAndroid Build Coastguard Worker /**
2647*4dc78e53SAndroid Build Coastguard Worker * Set link promiscuity count
2648*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2649*4dc78e53SAndroid Build Coastguard Worker * @arg count New promiscuity count
2650*4dc78e53SAndroid Build Coastguard Worker *
2651*4dc78e53SAndroid Build Coastguard Worker * @copydoc read_only_attribute
2652*4dc78e53SAndroid Build Coastguard Worker *
2653*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_promiscuity()
2654*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_promiscuity(struct rtnl_link * link,uint32_t count)2655*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_promiscuity(struct rtnl_link *link, uint32_t count)
2656*4dc78e53SAndroid Build Coastguard Worker {
2657*4dc78e53SAndroid Build Coastguard Worker link->l_promiscuity = count;
2658*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_PROMISCUITY;
2659*4dc78e53SAndroid Build Coastguard Worker }
2660*4dc78e53SAndroid Build Coastguard Worker
2661*4dc78e53SAndroid Build Coastguard Worker /**
2662*4dc78e53SAndroid Build Coastguard Worker * Return link promiscuity count
2663*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2664*4dc78e53SAndroid Build Coastguard Worker *
2665*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_set_promiscuity()
2666*4dc78e53SAndroid Build Coastguard Worker * @return Link promiscuity count or 0
2667*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_promiscuity(struct rtnl_link * link)2668*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_link_get_promiscuity(struct rtnl_link *link)
2669*4dc78e53SAndroid Build Coastguard Worker {
2670*4dc78e53SAndroid Build Coastguard Worker return link->l_promiscuity;
2671*4dc78e53SAndroid Build Coastguard Worker }
2672*4dc78e53SAndroid Build Coastguard Worker
2673*4dc78e53SAndroid Build Coastguard Worker /**
2674*4dc78e53SAndroid Build Coastguard Worker * Set number of TX queues
2675*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2676*4dc78e53SAndroid Build Coastguard Worker * @arg nqueues Number of queues
2677*4dc78e53SAndroid Build Coastguard Worker *
2678*4dc78e53SAndroid Build Coastguard Worker * Sets the number of TX queues of the link object. The value is considered
2679*4dc78e53SAndroid Build Coastguard Worker * by the kernel when creating network devices that can be created via
2680*4dc78e53SAndroid Build Coastguard Worker * netlink. The value will be passed on to alloc_netdev_mqs()
2681*4dc78e53SAndroid Build Coastguard Worker *
2682*4dc78e53SAndroid Build Coastguard Worker * Therefore use of rtnl_link_set_num_tx_queues() only makes sense in
2683*4dc78e53SAndroid Build Coastguard Worker * combination with rtnl_link_add() or if the link object is used as a filter.
2684*4dc78e53SAndroid Build Coastguard Worker *
2685*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_tx_queues()
2686*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_num_tx_queues(struct rtnl_link * link,uint32_t nqueues)2687*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_num_tx_queues(struct rtnl_link *link, uint32_t nqueues)
2688*4dc78e53SAndroid Build Coastguard Worker {
2689*4dc78e53SAndroid Build Coastguard Worker link->l_num_tx_queues = nqueues;
2690*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NUM_TX_QUEUES;
2691*4dc78e53SAndroid Build Coastguard Worker }
2692*4dc78e53SAndroid Build Coastguard Worker
2693*4dc78e53SAndroid Build Coastguard Worker /**
2694*4dc78e53SAndroid Build Coastguard Worker * Return number of TX queues
2695*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2696*4dc78e53SAndroid Build Coastguard Worker *
2697*4dc78e53SAndroid Build Coastguard Worker * @return Number of TX queues or 0
2698*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_num_tx_queues(struct rtnl_link * link)2699*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_link_get_num_tx_queues(struct rtnl_link *link)
2700*4dc78e53SAndroid Build Coastguard Worker {
2701*4dc78e53SAndroid Build Coastguard Worker return link->l_num_tx_queues;
2702*4dc78e53SAndroid Build Coastguard Worker }
2703*4dc78e53SAndroid Build Coastguard Worker
2704*4dc78e53SAndroid Build Coastguard Worker /**
2705*4dc78e53SAndroid Build Coastguard Worker * Set number of RX queues
2706*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2707*4dc78e53SAndroid Build Coastguard Worker * @arg nqueues Number of queues
2708*4dc78e53SAndroid Build Coastguard Worker *
2709*4dc78e53SAndroid Build Coastguard Worker * Sets the number of RX queues of the link object. The value is considered
2710*4dc78e53SAndroid Build Coastguard Worker * by the kernel when creating network devices that can be created via
2711*4dc78e53SAndroid Build Coastguard Worker * netlink. The value will be passed on to alloc_netdev_mqs()
2712*4dc78e53SAndroid Build Coastguard Worker *
2713*4dc78e53SAndroid Build Coastguard Worker * Therefore use of rtnl_link_set_num_rx_queues() only makes sense in
2714*4dc78e53SAndroid Build Coastguard Worker * combination with rtnl_link_add() or if the link object is used as a filter.
2715*4dc78e53SAndroid Build Coastguard Worker *
2716*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_get_num_rx_queues()
2717*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_num_rx_queues(struct rtnl_link * link,uint32_t nqueues)2718*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_num_rx_queues(struct rtnl_link *link, uint32_t nqueues)
2719*4dc78e53SAndroid Build Coastguard Worker {
2720*4dc78e53SAndroid Build Coastguard Worker link->l_num_rx_queues = nqueues;
2721*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NUM_RX_QUEUES;
2722*4dc78e53SAndroid Build Coastguard Worker }
2723*4dc78e53SAndroid Build Coastguard Worker
2724*4dc78e53SAndroid Build Coastguard Worker /**
2725*4dc78e53SAndroid Build Coastguard Worker * Return number of RX queues
2726*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2727*4dc78e53SAndroid Build Coastguard Worker *
2728*4dc78e53SAndroid Build Coastguard Worker * @return Number of RX queues or 0
2729*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_num_rx_queues(struct rtnl_link * link)2730*4dc78e53SAndroid Build Coastguard Worker uint32_t rtnl_link_get_num_rx_queues(struct rtnl_link *link)
2731*4dc78e53SAndroid Build Coastguard Worker {
2732*4dc78e53SAndroid Build Coastguard Worker return link->l_num_rx_queues;
2733*4dc78e53SAndroid Build Coastguard Worker }
2734*4dc78e53SAndroid Build Coastguard Worker
2735*4dc78e53SAndroid Build Coastguard Worker /**
2736*4dc78e53SAndroid Build Coastguard Worker * Return maximum number of segments for generic segmentation offload
2737*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2738*4dc78e53SAndroid Build Coastguard Worker * @arg gso_max_segs Pointer to store maximum number GSO segments
2739*4dc78e53SAndroid Build Coastguard Worker *
2740*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success, negative error number otherwise
2741*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_gso_max_segs(struct rtnl_link * link,uint32_t * gso_max_segs)2742*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_gso_max_segs(struct rtnl_link *link, uint32_t *gso_max_segs)
2743*4dc78e53SAndroid Build Coastguard Worker {
2744*4dc78e53SAndroid Build Coastguard Worker if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SEGS))
2745*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
2746*4dc78e53SAndroid Build Coastguard Worker
2747*4dc78e53SAndroid Build Coastguard Worker if (gso_max_segs)
2748*4dc78e53SAndroid Build Coastguard Worker *gso_max_segs = link->l_gso_max_segs;
2749*4dc78e53SAndroid Build Coastguard Worker
2750*4dc78e53SAndroid Build Coastguard Worker return 0;
2751*4dc78e53SAndroid Build Coastguard Worker }
2752*4dc78e53SAndroid Build Coastguard Worker
2753*4dc78e53SAndroid Build Coastguard Worker /**
2754*4dc78e53SAndroid Build Coastguard Worker * Return maximum size for generic segmentation offload
2755*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2756*4dc78e53SAndroid Build Coastguard Worker * @arg gso_max_segs Pointer to store maximum GSO size
2757*4dc78e53SAndroid Build Coastguard Worker *
2758*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success, negative error number otherwise
2759*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_gso_max_size(struct rtnl_link * link,uint32_t * gso_max_size)2760*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_gso_max_size(struct rtnl_link *link, uint32_t *gso_max_size)
2761*4dc78e53SAndroid Build Coastguard Worker {
2762*4dc78e53SAndroid Build Coastguard Worker if (!(link->ce_mask & LINK_ATTR_GSO_MAX_SIZE))
2763*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOATTR;
2764*4dc78e53SAndroid Build Coastguard Worker
2765*4dc78e53SAndroid Build Coastguard Worker if (gso_max_size)
2766*4dc78e53SAndroid Build Coastguard Worker *gso_max_size = link->l_gso_max_size;
2767*4dc78e53SAndroid Build Coastguard Worker
2768*4dc78e53SAndroid Build Coastguard Worker return 0;
2769*4dc78e53SAndroid Build Coastguard Worker }
2770*4dc78e53SAndroid Build Coastguard Worker
2771*4dc78e53SAndroid Build Coastguard Worker /**
2772*4dc78e53SAndroid Build Coastguard Worker * Return physical port id of link object
2773*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2774*4dc78e53SAndroid Build Coastguard Worker *
2775*4dc78e53SAndroid Build Coastguard Worker * @return Physical port id or NULL if not set.
2776*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_phys_port_id(struct rtnl_link * link)2777*4dc78e53SAndroid Build Coastguard Worker struct nl_data *rtnl_link_get_phys_port_id(struct rtnl_link *link)
2778*4dc78e53SAndroid Build Coastguard Worker {
2779*4dc78e53SAndroid Build Coastguard Worker return link->l_phys_port_id;
2780*4dc78e53SAndroid Build Coastguard Worker }
2781*4dc78e53SAndroid Build Coastguard Worker
2782*4dc78e53SAndroid Build Coastguard Worker /**
2783*4dc78e53SAndroid Build Coastguard Worker * Return physical port name of link object
2784*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2785*4dc78e53SAndroid Build Coastguard Worker *
2786*4dc78e53SAndroid Build Coastguard Worker * @return Physical port name or NULL if not set.
2787*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_phys_port_name(struct rtnl_link * link)2788*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_get_phys_port_name(struct rtnl_link *link)
2789*4dc78e53SAndroid Build Coastguard Worker {
2790*4dc78e53SAndroid Build Coastguard Worker return link->l_phys_port_name;
2791*4dc78e53SAndroid Build Coastguard Worker }
2792*4dc78e53SAndroid Build Coastguard Worker
2793*4dc78e53SAndroid Build Coastguard Worker /*
2794*4dc78e53SAndroid Build Coastguard Worker * Return physical switch id of link object
2795*4dc78e53SAndroid Build Coastguard Worker * @arg link Link object
2796*4dc78e53SAndroid Build Coastguard Worker *
2797*4dc78e53SAndroid Build Coastguard Worker * @return Physical switch id or NULL if not set.
2798*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_phys_switch_id(struct rtnl_link * link)2799*4dc78e53SAndroid Build Coastguard Worker struct nl_data *rtnl_link_get_phys_switch_id(struct rtnl_link *link)
2800*4dc78e53SAndroid Build Coastguard Worker {
2801*4dc78e53SAndroid Build Coastguard Worker return link->l_phys_switch_id;
2802*4dc78e53SAndroid Build Coastguard Worker }
2803*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_set_ns_fd(struct rtnl_link * link,int fd)2804*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_ns_fd(struct rtnl_link *link, int fd)
2805*4dc78e53SAndroid Build Coastguard Worker {
2806*4dc78e53SAndroid Build Coastguard Worker link->l_ns_fd = fd;
2807*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NS_FD;
2808*4dc78e53SAndroid Build Coastguard Worker }
2809*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_get_ns_fd(struct rtnl_link * link)2810*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_get_ns_fd(struct rtnl_link *link)
2811*4dc78e53SAndroid Build Coastguard Worker {
2812*4dc78e53SAndroid Build Coastguard Worker return link->l_ns_fd;
2813*4dc78e53SAndroid Build Coastguard Worker }
2814*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_set_ns_pid(struct rtnl_link * link,pid_t pid)2815*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_ns_pid(struct rtnl_link *link, pid_t pid)
2816*4dc78e53SAndroid Build Coastguard Worker {
2817*4dc78e53SAndroid Build Coastguard Worker link->l_ns_pid = pid;
2818*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_NS_PID;
2819*4dc78e53SAndroid Build Coastguard Worker }
2820*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_get_ns_pid(struct rtnl_link * link)2821*4dc78e53SAndroid Build Coastguard Worker pid_t rtnl_link_get_ns_pid(struct rtnl_link *link)
2822*4dc78e53SAndroid Build Coastguard Worker {
2823*4dc78e53SAndroid Build Coastguard Worker return link->l_ns_pid;
2824*4dc78e53SAndroid Build Coastguard Worker }
2825*4dc78e53SAndroid Build Coastguard Worker
2826*4dc78e53SAndroid Build Coastguard Worker /** @} */
2827*4dc78e53SAndroid Build Coastguard Worker
2828*4dc78e53SAndroid Build Coastguard Worker /**
2829*4dc78e53SAndroid Build Coastguard Worker * @name Master/Slave
2830*4dc78e53SAndroid Build Coastguard Worker * @{
2831*4dc78e53SAndroid Build Coastguard Worker */
2832*4dc78e53SAndroid Build Coastguard Worker
2833*4dc78e53SAndroid Build Coastguard Worker /**
2834*4dc78e53SAndroid Build Coastguard Worker * Enslave slave link to master link
2835*4dc78e53SAndroid Build Coastguard Worker * @arg sock netlink socket
2836*4dc78e53SAndroid Build Coastguard Worker * @arg master ifindex of master link
2837*4dc78e53SAndroid Build Coastguard Worker * @arg slave ifindex of slave link
2838*4dc78e53SAndroid Build Coastguard Worker *
2839*4dc78e53SAndroid Build Coastguard Worker * This function is identical to rtnl_link_enslave() except that
2840*4dc78e53SAndroid Build Coastguard Worker * it takes interface indices instead of rtnl_link objects.
2841*4dc78e53SAndroid Build Coastguard Worker *
2842*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_enslave()
2843*4dc78e53SAndroid Build Coastguard Worker *
2844*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2845*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_enslave_ifindex(struct nl_sock * sock,int master,int slave)2846*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_enslave_ifindex(struct nl_sock *sock, int master, int slave)
2847*4dc78e53SAndroid Build Coastguard Worker {
2848*4dc78e53SAndroid Build Coastguard Worker _nl_auto_rtnl_link struct rtnl_link *link = NULL;
2849*4dc78e53SAndroid Build Coastguard Worker int err;
2850*4dc78e53SAndroid Build Coastguard Worker
2851*4dc78e53SAndroid Build Coastguard Worker if (!(link = rtnl_link_alloc()))
2852*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
2853*4dc78e53SAndroid Build Coastguard Worker
2854*4dc78e53SAndroid Build Coastguard Worker rtnl_link_set_ifindex(link, slave);
2855*4dc78e53SAndroid Build Coastguard Worker rtnl_link_set_master(link, master);
2856*4dc78e53SAndroid Build Coastguard Worker
2857*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_change(sock, link, link, 0)) < 0)
2858*4dc78e53SAndroid Build Coastguard Worker return err;
2859*4dc78e53SAndroid Build Coastguard Worker
2860*4dc78e53SAndroid Build Coastguard Worker _nl_clear_pointer(&link, rtnl_link_put);
2861*4dc78e53SAndroid Build Coastguard Worker
2862*4dc78e53SAndroid Build Coastguard Worker /*
2863*4dc78e53SAndroid Build Coastguard Worker * Due to the kernel not signaling whether this operation is
2864*4dc78e53SAndroid Build Coastguard Worker * supported or not, we will retrieve the attribute to see if the
2865*4dc78e53SAndroid Build Coastguard Worker * request was successful. If the master assigned remains unchanged
2866*4dc78e53SAndroid Build Coastguard Worker * we will return NLE_OPNOTSUPP to allow performing backwards
2867*4dc78e53SAndroid Build Coastguard Worker * compatibility of some sort.
2868*4dc78e53SAndroid Build Coastguard Worker */
2869*4dc78e53SAndroid Build Coastguard Worker if ((err = rtnl_link_get_kernel(sock, slave, NULL, &link)) < 0)
2870*4dc78e53SAndroid Build Coastguard Worker return err;
2871*4dc78e53SAndroid Build Coastguard Worker
2872*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_get_master(link) != master)
2873*4dc78e53SAndroid Build Coastguard Worker return -NLE_OPNOTSUPP;
2874*4dc78e53SAndroid Build Coastguard Worker
2875*4dc78e53SAndroid Build Coastguard Worker return 0;
2876*4dc78e53SAndroid Build Coastguard Worker }
2877*4dc78e53SAndroid Build Coastguard Worker
2878*4dc78e53SAndroid Build Coastguard Worker /**
2879*4dc78e53SAndroid Build Coastguard Worker * Enslave slave link to master link
2880*4dc78e53SAndroid Build Coastguard Worker * @arg sock netlink socket
2881*4dc78e53SAndroid Build Coastguard Worker * @arg master master link
2882*4dc78e53SAndroid Build Coastguard Worker * @arg slave slave link
2883*4dc78e53SAndroid Build Coastguard Worker *
2884*4dc78e53SAndroid Build Coastguard Worker * Constructs a RTM_NEWLINK or RTM_SETLINK message adding the slave to
2885*4dc78e53SAndroid Build Coastguard Worker * the master and sends the request via the specified netlink socket.
2886*4dc78e53SAndroid Build Coastguard Worker *
2887*4dc78e53SAndroid Build Coastguard Worker * @note The feature of enslaving/releasing via netlink has only been added
2888*4dc78e53SAndroid Build Coastguard Worker * recently to the kernel (Feb 2011). Also, the kernel does not signal
2889*4dc78e53SAndroid Build Coastguard Worker * if the operation is not supported. Therefore this function will
2890*4dc78e53SAndroid Build Coastguard Worker * verify if the master assignment has changed and will return
2891*4dc78e53SAndroid Build Coastguard Worker * -NLE_OPNOTSUPP if it did not.
2892*4dc78e53SAndroid Build Coastguard Worker *
2893*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_enslave_ifindex()
2894*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_release()
2895*4dc78e53SAndroid Build Coastguard Worker *
2896*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2897*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_enslave(struct nl_sock * sock,struct rtnl_link * master,struct rtnl_link * slave)2898*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_enslave(struct nl_sock *sock, struct rtnl_link *master,
2899*4dc78e53SAndroid Build Coastguard Worker struct rtnl_link *slave)
2900*4dc78e53SAndroid Build Coastguard Worker {
2901*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_enslave_ifindex(sock, rtnl_link_get_ifindex(master),
2902*4dc78e53SAndroid Build Coastguard Worker rtnl_link_get_ifindex(slave));
2903*4dc78e53SAndroid Build Coastguard Worker }
2904*4dc78e53SAndroid Build Coastguard Worker
2905*4dc78e53SAndroid Build Coastguard Worker /**
2906*4dc78e53SAndroid Build Coastguard Worker * Release slave link from its master
2907*4dc78e53SAndroid Build Coastguard Worker * @arg sock netlink socket
2908*4dc78e53SAndroid Build Coastguard Worker * @arg slave slave link
2909*4dc78e53SAndroid Build Coastguard Worker *
2910*4dc78e53SAndroid Build Coastguard Worker * This function is identical to rtnl_link_release() except that
2911*4dc78e53SAndroid Build Coastguard Worker * it takes an interface index instead of a rtnl_link object.
2912*4dc78e53SAndroid Build Coastguard Worker *
2913*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_release()
2914*4dc78e53SAndroid Build Coastguard Worker *
2915*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2916*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_release_ifindex(struct nl_sock * sock,int slave)2917*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_release_ifindex(struct nl_sock *sock, int slave)
2918*4dc78e53SAndroid Build Coastguard Worker {
2919*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_enslave_ifindex(sock, 0, slave);
2920*4dc78e53SAndroid Build Coastguard Worker }
2921*4dc78e53SAndroid Build Coastguard Worker
2922*4dc78e53SAndroid Build Coastguard Worker /**
2923*4dc78e53SAndroid Build Coastguard Worker * Release slave link from its master
2924*4dc78e53SAndroid Build Coastguard Worker * @arg sock netlink socket
2925*4dc78e53SAndroid Build Coastguard Worker * @arg slave slave link
2926*4dc78e53SAndroid Build Coastguard Worker *
2927*4dc78e53SAndroid Build Coastguard Worker * Constructs a RTM_NEWLINK or RTM_SETLINK message releasing the slave from
2928*4dc78e53SAndroid Build Coastguard Worker * its master and sends the request via the specified netlink socket.
2929*4dc78e53SAndroid Build Coastguard Worker *
2930*4dc78e53SAndroid Build Coastguard Worker * @note The feature of enslaving/releasing via netlink has only been added
2931*4dc78e53SAndroid Build Coastguard Worker * recently to the kernel (Feb 2011). Also, the kernel does not signal
2932*4dc78e53SAndroid Build Coastguard Worker * if the operation is not supported. Therefore this function will
2933*4dc78e53SAndroid Build Coastguard Worker * verify if the master assignment has changed and will return
2934*4dc78e53SAndroid Build Coastguard Worker * -NLE_OPNOTSUPP if it did not.
2935*4dc78e53SAndroid Build Coastguard Worker *
2936*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_release_ifindex()
2937*4dc78e53SAndroid Build Coastguard Worker * @see rtnl_link_enslave()
2938*4dc78e53SAndroid Build Coastguard Worker *
2939*4dc78e53SAndroid Build Coastguard Worker * @return 0 on success or a negative error code.
2940*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_release(struct nl_sock * sock,struct rtnl_link * slave)2941*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_release(struct nl_sock *sock, struct rtnl_link *slave)
2942*4dc78e53SAndroid Build Coastguard Worker {
2943*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_release_ifindex(sock, rtnl_link_get_ifindex(slave));
2944*4dc78e53SAndroid Build Coastguard Worker }
2945*4dc78e53SAndroid Build Coastguard Worker
2946*4dc78e53SAndroid Build Coastguard Worker /** @} */
2947*4dc78e53SAndroid Build Coastguard Worker
2948*4dc78e53SAndroid Build Coastguard Worker /**
2949*4dc78e53SAndroid Build Coastguard Worker * @name Utilities
2950*4dc78e53SAndroid Build Coastguard Worker * @{
2951*4dc78e53SAndroid Build Coastguard Worker */
2952*4dc78e53SAndroid Build Coastguard Worker
2953*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl link_flags[] = {
2954*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_LOOPBACK, loopback),
2955*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_BROADCAST, broadcast),
2956*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_POINTOPOINT, pointopoint),
2957*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_MULTICAST, multicast),
2958*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_NOARP, noarp),
2959*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_ALLMULTI, allmulti),
2960*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_PROMISC, promisc),
2961*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_MASTER, master),
2962*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_SLAVE, slave),
2963*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_DEBUG, debug),
2964*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_DYNAMIC, dynamic),
2965*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_AUTOMEDIA, automedia),
2966*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_PORTSEL, portsel),
2967*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_NOTRAILERS, notrailers),
2968*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_UP, up),
2969*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_RUNNING, running),
2970*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_LOWER_UP, lowerup),
2971*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_DORMANT, dormant),
2972*4dc78e53SAndroid Build Coastguard Worker __ADD(IFF_ECHO, echo),
2973*4dc78e53SAndroid Build Coastguard Worker };
2974*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_flags2str(int flags,char * buf,size_t len)2975*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_flags2str(int flags, char *buf, size_t len)
2976*4dc78e53SAndroid Build Coastguard Worker {
2977*4dc78e53SAndroid Build Coastguard Worker return __flags2str(flags, buf, len, link_flags,
2978*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(link_flags));
2979*4dc78e53SAndroid Build Coastguard Worker }
2980*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_str2flags(const char * name)2981*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_str2flags(const char *name)
2982*4dc78e53SAndroid Build Coastguard Worker {
2983*4dc78e53SAndroid Build Coastguard Worker return __str2flags(name, link_flags, ARRAY_SIZE(link_flags));
2984*4dc78e53SAndroid Build Coastguard Worker }
2985*4dc78e53SAndroid Build Coastguard Worker
2986*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl link_stats[] = {
2987*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_PACKETS, rx_packets),
2988*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_PACKETS, tx_packets),
2989*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_BYTES, rx_bytes),
2990*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_BYTES, tx_bytes),
2991*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_ERRORS, rx_errors),
2992*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_ERRORS, tx_errors),
2993*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_DROPPED, rx_dropped),
2994*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_DROPPED, tx_dropped),
2995*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_COMPRESSED, rx_compressed),
2996*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_COMPRESSED, tx_compressed),
2997*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_FIFO_ERR, rx_fifo_err),
2998*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_FIFO_ERR, tx_fifo_err),
2999*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_LEN_ERR, rx_len_err),
3000*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_OVER_ERR, rx_over_err),
3001*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_CRC_ERR, rx_crc_err),
3002*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_FRAME_ERR, rx_frame_err),
3003*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_MISSED_ERR, rx_missed_err),
3004*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_ABORT_ERR, tx_abort_err),
3005*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_CARRIER_ERR, tx_carrier_err),
3006*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_HBEAT_ERR, tx_hbeat_err),
3007*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_TX_WIN_ERR, tx_win_err),
3008*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_COLLISIONS, collisions),
3009*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_MULTICAST, multicast),
3010*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INPKTS, Ip6InReceives),
3011*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INHDRERRORS, Ip6InHdrErrors),
3012*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INTOOBIGERRORS, Ip6InTooBigErrors),
3013*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INNOROUTES, Ip6InNoRoutes),
3014*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INADDRERRORS, Ip6InAddrErrors),
3015*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INUNKNOWNPROTOS, Ip6InUnknownProtos),
3016*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INTRUNCATEDPKTS, Ip6InTruncatedPkts),
3017*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INDISCARDS, Ip6InDiscards),
3018*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INDELIVERS, Ip6InDelivers),
3019*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTFORWDATAGRAMS, Ip6OutForwDatagrams),
3020*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTPKTS, Ip6OutRequests),
3021*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTDISCARDS, Ip6OutDiscards),
3022*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTNOROUTES, Ip6OutNoRoutes),
3023*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_REASMTIMEOUT, Ip6ReasmTimeout),
3024*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_REASMREQDS, Ip6ReasmReqds),
3025*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_REASMOKS, Ip6ReasmOKs),
3026*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_REASMFAILS, Ip6ReasmFails),
3027*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_FRAGOKS, Ip6FragOKs),
3028*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_FRAGFAILS, Ip6FragFails),
3029*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_FRAGCREATES, Ip6FragCreates),
3030*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INMCASTPKTS, Ip6InMcastPkts),
3031*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTMCASTPKTS, Ip6OutMcastPkts),
3032*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INBCASTPKTS, Ip6InBcastPkts),
3033*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTBCASTPKTS, Ip6OutBcastPkts),
3034*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INOCTETS, Ip6InOctets),
3035*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTOCTETS, Ip6OutOctets),
3036*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INMCASTOCTETS, Ip6InMcastOctets),
3037*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTMCASTOCTETS, Ip6OutMcastOctets),
3038*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_INBCASTOCTETS, Ip6InBcastOctets),
3039*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_OUTBCASTOCTETS, Ip6OutBcastOctets),
3040*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_ICMP6_INMSGS, ICMP6_InMsgs),
3041*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_ICMP6_INERRORS, ICMP6_InErrors),
3042*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_ICMP6_OUTMSGS, ICMP6_OutMsgs),
3043*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_ICMP6_OUTERRORS, ICMP6_OutErrors),
3044*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_ICMP6_CSUMERRORS, ICMP6_InCsumErrors),
3045*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_CSUMERRORS, Ip6_InCsumErrors),
3046*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_NOECTPKTS, Ip6_InNoECTPkts),
3047*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_ECT1PKTS, Ip6_InECT1Pkts),
3048*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_ECT0PKTS, Ip6_InECT0Pkts),
3049*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_IP6_CEPKTS, Ip6_InCEPkts),
3050*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_RX_NOHANDLER, rx_nohandler),
3051*4dc78e53SAndroid Build Coastguard Worker __ADD(RTNL_LINK_REASM_OVERLAPS, ReasmOverlaps),
3052*4dc78e53SAndroid Build Coastguard Worker };
3053*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_stat2str(int st,char * buf,size_t len)3054*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_stat2str(int st, char *buf, size_t len)
3055*4dc78e53SAndroid Build Coastguard Worker {
3056*4dc78e53SAndroid Build Coastguard Worker return __type2str(st, buf, len, link_stats, ARRAY_SIZE(link_stats));
3057*4dc78e53SAndroid Build Coastguard Worker }
3058*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_str2stat(const char * name)3059*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_str2stat(const char *name)
3060*4dc78e53SAndroid Build Coastguard Worker {
3061*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, link_stats, ARRAY_SIZE(link_stats));
3062*4dc78e53SAndroid Build Coastguard Worker }
3063*4dc78e53SAndroid Build Coastguard Worker
3064*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl link_operstates[] = {
3065*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_UNKNOWN, unknown),
3066*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_NOTPRESENT, notpresent),
3067*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_DOWN, down),
3068*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_LOWERLAYERDOWN, lowerlayerdown),
3069*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_TESTING, testing),
3070*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_DORMANT, dormant),
3071*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_OPER_UP, up),
3072*4dc78e53SAndroid Build Coastguard Worker };
3073*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_operstate2str(uint8_t st,char * buf,size_t len)3074*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_operstate2str(uint8_t st, char *buf, size_t len)
3075*4dc78e53SAndroid Build Coastguard Worker {
3076*4dc78e53SAndroid Build Coastguard Worker return __type2str(st, buf, len, link_operstates,
3077*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(link_operstates));
3078*4dc78e53SAndroid Build Coastguard Worker }
3079*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_str2operstate(const char * name)3080*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_str2operstate(const char *name)
3081*4dc78e53SAndroid Build Coastguard Worker {
3082*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, link_operstates,
3083*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(link_operstates));
3084*4dc78e53SAndroid Build Coastguard Worker }
3085*4dc78e53SAndroid Build Coastguard Worker
3086*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl link_modes[] = {
3087*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_LINK_MODE_DEFAULT, default),
3088*4dc78e53SAndroid Build Coastguard Worker __ADD(IF_LINK_MODE_DORMANT, dormant),
3089*4dc78e53SAndroid Build Coastguard Worker };
3090*4dc78e53SAndroid Build Coastguard Worker
3091*4dc78e53SAndroid Build Coastguard Worker static const struct trans_tbl carrier_states[] = {
3092*4dc78e53SAndroid Build Coastguard Worker __ADD(0, down),
3093*4dc78e53SAndroid Build Coastguard Worker __ADD(1, up),
3094*4dc78e53SAndroid Build Coastguard Worker };
3095*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_mode2str(uint8_t st,char * buf,size_t len)3096*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_mode2str(uint8_t st, char *buf, size_t len)
3097*4dc78e53SAndroid Build Coastguard Worker {
3098*4dc78e53SAndroid Build Coastguard Worker return __type2str(st, buf, len, link_modes, ARRAY_SIZE(link_modes));
3099*4dc78e53SAndroid Build Coastguard Worker }
3100*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_str2mode(const char * name)3101*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_str2mode(const char *name)
3102*4dc78e53SAndroid Build Coastguard Worker {
3103*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, link_modes, ARRAY_SIZE(link_modes));
3104*4dc78e53SAndroid Build Coastguard Worker }
3105*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_carrier2str(uint8_t st,char * buf,size_t len)3106*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_carrier2str(uint8_t st, char *buf, size_t len)
3107*4dc78e53SAndroid Build Coastguard Worker {
3108*4dc78e53SAndroid Build Coastguard Worker return __type2str(st, buf, len, carrier_states,
3109*4dc78e53SAndroid Build Coastguard Worker ARRAY_SIZE(carrier_states));
3110*4dc78e53SAndroid Build Coastguard Worker }
3111*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_str2carrier(const char * name)3112*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_str2carrier(const char *name)
3113*4dc78e53SAndroid Build Coastguard Worker {
3114*4dc78e53SAndroid Build Coastguard Worker return __str2type(name, carrier_states, ARRAY_SIZE(carrier_states));
3115*4dc78e53SAndroid Build Coastguard Worker }
3116*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_has_vf_list(struct rtnl_link * link)3117*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_has_vf_list(struct rtnl_link *link) {
3118*4dc78e53SAndroid Build Coastguard Worker if (link->ce_mask & LINK_ATTR_VF_LIST)
3119*4dc78e53SAndroid Build Coastguard Worker return 1;
3120*4dc78e53SAndroid Build Coastguard Worker else
3121*4dc78e53SAndroid Build Coastguard Worker return 0;
3122*4dc78e53SAndroid Build Coastguard Worker }
3123*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_set_vf_list(struct rtnl_link * link)3124*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_vf_list(struct rtnl_link *link)
3125*4dc78e53SAndroid Build Coastguard Worker {
3126*4dc78e53SAndroid Build Coastguard Worker if (!rtnl_link_has_vf_list(link))
3127*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_VF_LIST;
3128*4dc78e53SAndroid Build Coastguard Worker }
3129*4dc78e53SAndroid Build Coastguard Worker
rtnl_link_unset_vf_list(struct rtnl_link * link)3130*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_unset_vf_list(struct rtnl_link *link)
3131*4dc78e53SAndroid Build Coastguard Worker {
3132*4dc78e53SAndroid Build Coastguard Worker if (rtnl_link_has_vf_list(link))
3133*4dc78e53SAndroid Build Coastguard Worker link->ce_mask &= ~LINK_ATTR_VF_LIST;
3134*4dc78e53SAndroid Build Coastguard Worker }
3135*4dc78e53SAndroid Build Coastguard Worker
3136*4dc78e53SAndroid Build Coastguard Worker /** @} */
3137*4dc78e53SAndroid Build Coastguard Worker
3138*4dc78e53SAndroid Build Coastguard Worker /**
3139*4dc78e53SAndroid Build Coastguard Worker * @name Deprecated Functions
3140*4dc78e53SAndroid Build Coastguard Worker */
3141*4dc78e53SAndroid Build Coastguard Worker
3142*4dc78e53SAndroid Build Coastguard Worker /**
3143*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated, use rtnl_link_set_type()
3144*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_info_type(struct rtnl_link * link,const char * type)3145*4dc78e53SAndroid Build Coastguard Worker int rtnl_link_set_info_type(struct rtnl_link *link, const char *type)
3146*4dc78e53SAndroid Build Coastguard Worker {
3147*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_set_type(link, type);
3148*4dc78e53SAndroid Build Coastguard Worker }
3149*4dc78e53SAndroid Build Coastguard Worker
3150*4dc78e53SAndroid Build Coastguard Worker /**
3151*4dc78e53SAndroid Build Coastguard Worker * @deprecated Use of this function is deprecated, use rtnl_link_get_type()
3152*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_info_type(struct rtnl_link * link)3153*4dc78e53SAndroid Build Coastguard Worker char *rtnl_link_get_info_type(struct rtnl_link *link)
3154*4dc78e53SAndroid Build Coastguard Worker {
3155*4dc78e53SAndroid Build Coastguard Worker return rtnl_link_get_type(link);
3156*4dc78e53SAndroid Build Coastguard Worker }
3157*4dc78e53SAndroid Build Coastguard Worker
3158*4dc78e53SAndroid Build Coastguard Worker /**
3159*4dc78e53SAndroid Build Coastguard Worker * @deprecated The weight attribute is unused and obsoleted in all recent kernels
3160*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_set_weight(struct rtnl_link * link,unsigned int weight)3161*4dc78e53SAndroid Build Coastguard Worker void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight)
3162*4dc78e53SAndroid Build Coastguard Worker {
3163*4dc78e53SAndroid Build Coastguard Worker link->l_weight = weight;
3164*4dc78e53SAndroid Build Coastguard Worker link->ce_mask |= LINK_ATTR_WEIGHT;
3165*4dc78e53SAndroid Build Coastguard Worker }
3166*4dc78e53SAndroid Build Coastguard Worker
3167*4dc78e53SAndroid Build Coastguard Worker /**
3168*4dc78e53SAndroid Build Coastguard Worker * @deprecated The weight attribute is unused and obsoleted in all recent kernels
3169*4dc78e53SAndroid Build Coastguard Worker */
rtnl_link_get_weight(struct rtnl_link * link)3170*4dc78e53SAndroid Build Coastguard Worker unsigned int rtnl_link_get_weight(struct rtnl_link *link)
3171*4dc78e53SAndroid Build Coastguard Worker {
3172*4dc78e53SAndroid Build Coastguard Worker return link->l_weight;
3173*4dc78e53SAndroid Build Coastguard Worker }
3174*4dc78e53SAndroid Build Coastguard Worker
3175*4dc78e53SAndroid Build Coastguard Worker /** @} */
3176*4dc78e53SAndroid Build Coastguard Worker
3177*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops link_obj_ops = {
3178*4dc78e53SAndroid Build Coastguard Worker .oo_name = "route/link",
3179*4dc78e53SAndroid Build Coastguard Worker .oo_size = sizeof(struct rtnl_link),
3180*4dc78e53SAndroid Build Coastguard Worker .oo_free_data = link_free_data,
3181*4dc78e53SAndroid Build Coastguard Worker .oo_clone = link_clone,
3182*4dc78e53SAndroid Build Coastguard Worker .oo_dump = {
3183*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_LINE] = link_dump_line,
3184*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_DETAILS] = link_dump_details,
3185*4dc78e53SAndroid Build Coastguard Worker [NL_DUMP_STATS] = link_dump_stats,
3186*4dc78e53SAndroid Build Coastguard Worker },
3187*4dc78e53SAndroid Build Coastguard Worker .oo_compare = link_compare,
3188*4dc78e53SAndroid Build Coastguard Worker .oo_keygen = link_keygen,
3189*4dc78e53SAndroid Build Coastguard Worker .oo_attrs2str = link_attrs2str,
3190*4dc78e53SAndroid Build Coastguard Worker .oo_id_attrs = LINK_ATTR_IFINDEX | LINK_ATTR_FAMILY,
3191*4dc78e53SAndroid Build Coastguard Worker };
3192*4dc78e53SAndroid Build Coastguard Worker
3193*4dc78e53SAndroid Build Coastguard Worker static struct nl_af_group link_groups[] = {
3194*4dc78e53SAndroid Build Coastguard Worker { AF_UNSPEC, RTNLGRP_LINK },
3195*4dc78e53SAndroid Build Coastguard Worker { AF_BRIDGE, RTNLGRP_LINK },
3196*4dc78e53SAndroid Build Coastguard Worker { AF_INET6, RTNLGRP_IPV6_IFINFO },
3197*4dc78e53SAndroid Build Coastguard Worker { END_OF_GROUP_LIST },
3198*4dc78e53SAndroid Build Coastguard Worker };
3199*4dc78e53SAndroid Build Coastguard Worker
3200*4dc78e53SAndroid Build Coastguard Worker static struct nl_cache_ops rtnl_link_ops = {
3201*4dc78e53SAndroid Build Coastguard Worker .co_name = "route/link",
3202*4dc78e53SAndroid Build Coastguard Worker .co_hdrsize = sizeof(struct ifinfomsg),
3203*4dc78e53SAndroid Build Coastguard Worker .co_msgtypes = {
3204*4dc78e53SAndroid Build Coastguard Worker { RTM_NEWLINK, NL_ACT_NEW, "new" },
3205*4dc78e53SAndroid Build Coastguard Worker { RTM_DELLINK, NL_ACT_DEL, "del" },
3206*4dc78e53SAndroid Build Coastguard Worker { RTM_GETLINK, NL_ACT_GET, "get" },
3207*4dc78e53SAndroid Build Coastguard Worker { RTM_SETLINK, NL_ACT_CHANGE, "set" },
3208*4dc78e53SAndroid Build Coastguard Worker END_OF_MSGTYPES_LIST,
3209*4dc78e53SAndroid Build Coastguard Worker },
3210*4dc78e53SAndroid Build Coastguard Worker .co_protocol = NETLINK_ROUTE,
3211*4dc78e53SAndroid Build Coastguard Worker .co_groups = link_groups,
3212*4dc78e53SAndroid Build Coastguard Worker .co_request_update = link_request_update,
3213*4dc78e53SAndroid Build Coastguard Worker .co_msg_parser = link_msg_parser,
3214*4dc78e53SAndroid Build Coastguard Worker .co_obj_ops = &link_obj_ops,
3215*4dc78e53SAndroid Build Coastguard Worker };
3216*4dc78e53SAndroid Build Coastguard Worker
link_init(void)3217*4dc78e53SAndroid Build Coastguard Worker static void _nl_init link_init(void)
3218*4dc78e53SAndroid Build Coastguard Worker {
3219*4dc78e53SAndroid Build Coastguard Worker nl_cache_mngt_register(&rtnl_link_ops);
3220*4dc78e53SAndroid Build Coastguard Worker }
3221*4dc78e53SAndroid Build Coastguard Worker
link_exit(void)3222*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit link_exit(void)
3223*4dc78e53SAndroid Build Coastguard Worker {
3224*4dc78e53SAndroid Build Coastguard Worker nl_cache_mngt_unregister(&rtnl_link_ops);
3225*4dc78e53SAndroid Build Coastguard Worker }
3226*4dc78e53SAndroid Build Coastguard Worker
3227*4dc78e53SAndroid Build Coastguard Worker /** @} */
3228