libnl  3.2.25
inet6.c
1 /*
2  * lib/route/link/inet6.c AF_INET6 link operations
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 #include <netlink-private/netlink.h>
13 #include <netlink/netlink.h>
14 #include <netlink/attr.h>
15 #include <netlink/route/rtnl.h>
16 #include <netlink-private/route/link/api.h>
17 
18 struct inet6_data
19 {
20  uint32_t i6_flags;
21  struct ifla_cacheinfo i6_cacheinfo;
22  uint32_t i6_conf[DEVCONF_MAX];
23 };
24 
25 static void *inet6_alloc(struct rtnl_link *link)
26 {
27  return calloc(1, sizeof(struct inet6_data));
28 }
29 
30 static void *inet6_clone(struct rtnl_link *link, void *data)
31 {
32  struct inet6_data *i6;
33 
34  if ((i6 = inet6_alloc(link)))
35  memcpy(i6, data, sizeof(*i6));
36 
37  return i6;
38 }
39 
40 static void inet6_free(struct rtnl_link *link, void *data)
41 {
42  free(data);
43 }
44 
45 static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
46  [IFLA_INET6_FLAGS] = { .type = NLA_U32 },
47  [IFLA_INET6_CACHEINFO] = { .minlen = sizeof(struct ifla_cacheinfo) },
48  [IFLA_INET6_CONF] = { .minlen = 4 },
49  [IFLA_INET6_STATS] = { .minlen = 8 },
50  [IFLA_INET6_ICMP6STATS] = { .minlen = 8 },
51 };
52 
53 static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = {
54  /* 14a196807482e6fc74f15fc03176d5c08880588f^:include/linux/snmp.h
55  * version before the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f.
56  * This version was valid since commit edf391ff17232f097d72441c9ad467bcb3b5db18, which
57  * predates support for parsing IFLA_PROTINFO in libnl3. Such an even older meaning of
58  * the flags is not supported in libnl3. */
59  [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */
60  [ 2] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */
61  [ 3] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */
62  [ 4] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */
63  [ 5] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */
64  [ 6] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */
65  [ 7] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */
66  [ 8] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */
67  [ 9] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */
68  [10] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */
69  [11] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */
70  [12] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */
71  [13] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */
72  [14] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */
73  [15] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */
74  [16] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */
75  [17] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */
76  [18] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */
77  [19] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */
78  [20] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */
79  [21] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */
80  [22] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */
81  [23] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */
82  [24] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */
83  [25] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */
84  [26] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */
85  [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */
86  [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */
87  [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */
88  [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */
89 };
90 
91 static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = {
92  /* d8ec26d7f8287f5788a494f56e8814210f0e64be:include/uapi/linux/snmp.h
93  * version since the API change in commit 14a196807482e6fc74f15fc03176d5c08880588f */
94  [ 1] = RTNL_LINK_IP6_INPKTS, /* IPSTATS_MIB_INPKTS */
95  [ 2] = RTNL_LINK_IP6_INOCTETS, /* IPSTATS_MIB_INOCTETS */
96  [ 3] = RTNL_LINK_IP6_INDELIVERS, /* IPSTATS_MIB_INDELIVERS */
97  [ 4] = RTNL_LINK_IP6_OUTFORWDATAGRAMS, /* IPSTATS_MIB_OUTFORWDATAGRAMS */
98  [ 5] = RTNL_LINK_IP6_OUTPKTS, /* IPSTATS_MIB_OUTPKTS */
99  [ 6] = RTNL_LINK_IP6_OUTOCTETS, /* IPSTATS_MIB_OUTOCTETS */
100  [ 7] = RTNL_LINK_IP6_INHDRERRORS, /* IPSTATS_MIB_INHDRERRORS */
101  [ 8] = RTNL_LINK_IP6_INTOOBIGERRORS, /* IPSTATS_MIB_INTOOBIGERRORS */
102  [ 9] = RTNL_LINK_IP6_INNOROUTES, /* IPSTATS_MIB_INNOROUTES */
103  [10] = RTNL_LINK_IP6_INADDRERRORS, /* IPSTATS_MIB_INADDRERRORS */
104  [11] = RTNL_LINK_IP6_INUNKNOWNPROTOS, /* IPSTATS_MIB_INUNKNOWNPROTOS */
105  [12] = RTNL_LINK_IP6_INTRUNCATEDPKTS, /* IPSTATS_MIB_INTRUNCATEDPKTS */
106  [13] = RTNL_LINK_IP6_INDISCARDS, /* IPSTATS_MIB_INDISCARDS */
107  [14] = RTNL_LINK_IP6_OUTDISCARDS, /* IPSTATS_MIB_OUTDISCARDS */
108  [15] = RTNL_LINK_IP6_OUTNOROUTES, /* IPSTATS_MIB_OUTNOROUTES */
109  [16] = RTNL_LINK_IP6_REASMTIMEOUT, /* IPSTATS_MIB_REASMTIMEOUT */
110  [17] = RTNL_LINK_IP6_REASMREQDS, /* IPSTATS_MIB_REASMREQDS */
111  [18] = RTNL_LINK_IP6_REASMOKS, /* IPSTATS_MIB_REASMOKS */
112  [19] = RTNL_LINK_IP6_REASMFAILS, /* IPSTATS_MIB_REASMFAILS */
113  [20] = RTNL_LINK_IP6_FRAGOKS, /* IPSTATS_MIB_FRAGOKS */
114  [21] = RTNL_LINK_IP6_FRAGFAILS, /* IPSTATS_MIB_FRAGFAILS */
115  [22] = RTNL_LINK_IP6_FRAGCREATES, /* IPSTATS_MIB_FRAGCREATES */
116  [23] = RTNL_LINK_IP6_INMCASTPKTS, /* IPSTATS_MIB_INMCASTPKTS */
117  [24] = RTNL_LINK_IP6_OUTMCASTPKTS, /* IPSTATS_MIB_OUTMCASTPKTS */
118  [25] = RTNL_LINK_IP6_INBCASTPKTS, /* IPSTATS_MIB_INBCASTPKTS */
119  [26] = RTNL_LINK_IP6_OUTBCASTPKTS, /* IPSTATS_MIB_OUTBCASTPKTS */
120  [27] = RTNL_LINK_IP6_INMCASTOCTETS, /* IPSTATS_MIB_INMCASTOCTETS */
121  [28] = RTNL_LINK_IP6_OUTMCASTOCTETS, /* IPSTATS_MIB_OUTMCASTOCTETS */
122  [29] = RTNL_LINK_IP6_INBCASTOCTETS, /* IPSTATS_MIB_INBCASTOCTETS */
123  [30] = RTNL_LINK_IP6_OUTBCASTOCTETS, /* IPSTATS_MIB_OUTBCASTOCTETS */
124  [31] = RTNL_LINK_IP6_CSUMERRORS, /* IPSTATS_MIB_CSUMERRORS */
125  [32] = RTNL_LINK_IP6_NOECTPKTS, /* IPSTATS_MIB_NOECTPKTS */
126  [33] = RTNL_LINK_IP6_ECT1PKTS, /* IPSTATS_MIB_ECT1PKTS */
127  [34] = RTNL_LINK_IP6_ECT0PKTS, /* IPSTATS_MIB_ECT0PKTS */
128  [35] = RTNL_LINK_IP6_CEPKTS, /* IPSTATS_MIB_CEPKTS */
129 };
130 
131 static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
132  void *data)
133 {
134  struct inet6_data *i6 = data;
135  struct nlattr *tb[IFLA_INET6_MAX+1];
136  int err;
137 
138  err = nla_parse_nested(tb, IFLA_INET6_MAX, attr, inet6_policy);
139  if (err < 0)
140  return err;
141  if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4)
142  return -EINVAL;
143  if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8)
144  return -EINVAL;
145  if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8)
146  return -EINVAL;
147 
148  if (tb[IFLA_INET6_FLAGS])
149  i6->i6_flags = nla_get_u32(tb[IFLA_INET6_FLAGS]);
150 
151  if (tb[IFLA_INET6_CACHEINFO])
152  nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
153  sizeof(i6->i6_cacheinfo));
154 
155  if (tb[IFLA_INET6_CONF])
156  nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
157  sizeof(i6->i6_conf));
158 
159  /*
160  * Due to 32bit data alignment, these addresses must be copied to an
161  * aligned location prior to access.
162  */
163  if (tb[IFLA_INET6_STATS]) {
164  unsigned char *cnt = nla_data(tb[IFLA_INET6_STATS]);
165  uint64_t stat;
166  int i;
167  int len = nla_len(tb[IFLA_INET6_STATS]) / 8;
168  const uint8_t *map_stat_id = map_stat_id_from_IPSTATS_MIB_v2;
169 
170  if (len < 32 ||
171  (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) < 6)) {
172  /* kernel commit 14a196807482e6fc74f15fc03176d5c08880588f reordered the values.
173  * The later commit 6a5dc9e598fe90160fee7de098fa319665f5253e added values
174  * IPSTATS_MIB_CSUMERRORS/ICMP6_MIB_CSUMERRORS. If the netlink is shorter
175  * then this, assume that the kernel uses the previous meaning of the
176  * enumeration. */
177  map_stat_id = map_stat_id_from_IPSTATS_MIB_v1;
178  }
179 
180  len = min_t(int, __IPSTATS_MIB_MAX, len);
181  for (i = 1; i < len; i++) {
182  memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
183  rtnl_link_set_stat(link, map_stat_id[i], stat);
184  }
185  }
186 
187  if (tb[IFLA_INET6_ICMP6STATS]) {
188  unsigned char *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]);
189  uint64_t stat;
190  int i;
191  int len = min_t(int, __ICMP6_MIB_MAX, nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8);
192 
193  for (i = 1; i < len; i++) {
194  memcpy(&stat, &cnt[i * sizeof(stat)], sizeof(stat));
196  stat);
197  }
198  }
199 
200  return 0;
201 }
202 
203 /* These live in include/net/if_inet6.h and should be moved to include/linux */
204 #define IF_RA_OTHERCONF 0x80
205 #define IF_RA_MANAGED 0x40
206 #define IF_RA_RCVD 0x20
207 #define IF_RS_SENT 0x10
208 #define IF_READY 0x80000000
209 
210 static const struct trans_tbl inet6_flags[] = {
211  __ADD(IF_RA_OTHERCONF, ra_otherconf)
212  __ADD(IF_RA_MANAGED, ra_managed)
213  __ADD(IF_RA_RCVD, ra_rcvd)
214  __ADD(IF_RS_SENT, rs_sent)
215  __ADD(IF_READY, ready)
216 };
217 
218 static char *inet6_flags2str(int flags, char *buf, size_t len)
219 {
220  return __flags2str(flags, buf, len, inet6_flags,
221  ARRAY_SIZE(inet6_flags));
222 }
223 
224 static const struct trans_tbl inet6_devconf[] = {
225  __ADD(DEVCONF_FORWARDING, forwarding)
226  __ADD(DEVCONF_HOPLIMIT, hoplimit)
227  __ADD(DEVCONF_MTU6, mtu6)
228  __ADD(DEVCONF_ACCEPT_RA, accept_ra)
229  __ADD(DEVCONF_ACCEPT_REDIRECTS, accept_redirects)
230  __ADD(DEVCONF_AUTOCONF, autoconf)
231  __ADD(DEVCONF_DAD_TRANSMITS, dad_transmits)
232  __ADD(DEVCONF_RTR_SOLICITS, rtr_solicits)
233  __ADD(DEVCONF_RTR_SOLICIT_INTERVAL, rtr_solicit_interval)
234  __ADD(DEVCONF_RTR_SOLICIT_DELAY, rtr_solicit_delay)
235  __ADD(DEVCONF_USE_TEMPADDR, use_tempaddr)
236  __ADD(DEVCONF_TEMP_VALID_LFT, temp_valid_lft)
237  __ADD(DEVCONF_TEMP_PREFERED_LFT, temp_prefered_lft)
238  __ADD(DEVCONF_REGEN_MAX_RETRY, regen_max_retry)
239  __ADD(DEVCONF_MAX_DESYNC_FACTOR, max_desync_factor)
240  __ADD(DEVCONF_MAX_ADDRESSES, max_addresses)
241  __ADD(DEVCONF_FORCE_MLD_VERSION, force_mld_version)
242  __ADD(DEVCONF_ACCEPT_RA_DEFRTR, accept_ra_defrtr)
243  __ADD(DEVCONF_ACCEPT_RA_PINFO, accept_ra_pinfo)
244  __ADD(DEVCONF_ACCEPT_RA_RTR_PREF, accept_ra_rtr_pref)
245  __ADD(DEVCONF_RTR_PROBE_INTERVAL, rtr_probe_interval)
246  __ADD(DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, accept_ra_rt_info)
247  __ADD(DEVCONF_PROXY_NDP, proxy_ndp)
248  __ADD(DEVCONF_OPTIMISTIC_DAD, optimistic_dad)
249  __ADD(DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route)
250  __ADD(DEVCONF_MC_FORWARDING, mc_forwarding)
251  __ADD(DEVCONF_DISABLE_IPV6, disable_ipv6)
252  __ADD(DEVCONF_ACCEPT_DAD, accept_dad)
253  __ADD(DEVCONF_FORCE_TLLAO, force_tllao)
254 };
255 
256 static char *inet6_devconf2str(int type, char *buf, size_t len)
257 {
258  return __type2str(type, buf, len, inet6_devconf,
259  ARRAY_SIZE(inet6_devconf));
260 }
261 
262 
263 static void inet6_dump_details(struct rtnl_link *link,
264  struct nl_dump_params *p, void *data)
265 {
266  struct inet6_data *i6 = data;
267  char buf[64], buf2[64];
268  int i, n = 0;
269 
270  nl_dump_line(p, " ipv6 max-reasm-len %s",
271  nl_size2str(i6->i6_cacheinfo.max_reasm_len, buf, sizeof(buf)));
272 
273  nl_dump(p, " <%s>\n",
274  inet6_flags2str(i6->i6_flags, buf, sizeof(buf)));
275 
276 
277  nl_dump_line(p, " create-stamp %.2fs reachable-time %s",
278  (double) i6->i6_cacheinfo.tstamp / 100.,
279  nl_msec2str(i6->i6_cacheinfo.reachable_time, buf, sizeof(buf)));
280 
281  nl_dump(p, " retrans-time %s\n",
282  nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf)));
283 
284  nl_dump_line(p, " devconf:\n");
285  nl_dump_line(p, " ");
286 
287  for (i = 0; i < DEVCONF_MAX; i++) {
288  uint32_t value = i6->i6_conf[i];
289  int x, offset;
290 
291  switch (i) {
292  case DEVCONF_TEMP_VALID_LFT:
293  case DEVCONF_TEMP_PREFERED_LFT:
294  nl_msec2str((uint64_t) value * 1000., buf2, sizeof(buf2));
295  break;
296 
297  case DEVCONF_RTR_PROBE_INTERVAL:
298  case DEVCONF_RTR_SOLICIT_INTERVAL:
299  case DEVCONF_RTR_SOLICIT_DELAY:
300  nl_msec2str(value, buf2, sizeof(buf2));
301  break;
302 
303  default:
304  snprintf(buf2, sizeof(buf2), "%u", value);
305  break;
306 
307  }
308 
309  inet6_devconf2str(i, buf, sizeof(buf));
310 
311  offset = 23 - strlen(buf2);
312  if (offset < 0)
313  offset = 0;
314 
315  for (x = strlen(buf); x < offset; x++)
316  buf[x] = ' ';
317 
318  strncpy(&buf[offset], buf2, strlen(buf2));
319 
320  nl_dump_line(p, "%s", buf);
321 
322  if (++n == 3) {
323  nl_dump(p, "\n");
324  nl_dump_line(p, " ");
325  n = 0;
326  } else
327  nl_dump(p, " ");
328  }
329 
330  if (n != 0)
331  nl_dump(p, "\n");
332 }
333 
334 static void inet6_dump_stats(struct rtnl_link *link,
335  struct nl_dump_params *p, void *data)
336 {
337  double octets;
338  char *octetsUnit;
339 
340  nl_dump(p, " IPv6: InPkts InOctets "
341  " InDiscards InDelivers\n");
342  nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INPKTS]);
343 
344  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INOCTETS],
345  &octetsUnit);
346  if (octets)
347  nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
348  else
349  nl_dump(p, "%16" PRIu64 " B ", 0);
350 
351  nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n",
352  link->l_stats[RTNL_LINK_IP6_INDISCARDS],
353  link->l_stats[RTNL_LINK_IP6_INDELIVERS]);
354 
355  nl_dump(p, " OutPkts OutOctets "
356  " OutDiscards OutForwards\n");
357 
358  nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTPKTS]);
359 
360  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTOCTETS],
361  &octetsUnit);
362  if (octets)
363  nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
364  else
365  nl_dump(p, "%16" PRIu64 " B ", 0);
366 
367  nl_dump(p, "%18" PRIu64 " %18" PRIu64 "\n",
368  link->l_stats[RTNL_LINK_IP6_OUTDISCARDS],
369  link->l_stats[RTNL_LINK_IP6_OUTFORWDATAGRAMS]);
370 
371  nl_dump(p, " InMcastPkts InMcastOctets "
372  " InBcastPkts InBcastOctests\n");
373 
374  nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INMCASTPKTS]);
375 
376  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INMCASTOCTETS],
377  &octetsUnit);
378  if (octets)
379  nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
380  else
381  nl_dump(p, "%16" PRIu64 " B ", 0);
382 
383  nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_INBCASTPKTS]);
384  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INBCASTOCTETS],
385  &octetsUnit);
386  if (octets)
387  nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
388  else
389  nl_dump(p, "%16" PRIu64 " B\n", 0);
390 
391  nl_dump(p, " OutMcastPkts OutMcastOctets "
392  " OutBcastPkts OutBcastOctests\n");
393 
394  nl_dump(p, " %18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTMCASTPKTS]);
395 
396  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTMCASTOCTETS],
397  &octetsUnit);
398  if (octets)
399  nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
400  else
401  nl_dump(p, "%16" PRIu64 " B ", 0);
402 
403  nl_dump(p, "%18" PRIu64 " ", link->l_stats[RTNL_LINK_IP6_OUTBCASTPKTS]);
404  octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTBCASTOCTETS],
405  &octetsUnit);
406  if (octets)
407  nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
408  else
409  nl_dump(p, "%16" PRIu64 " B\n", 0);
410 
411  nl_dump(p, " ReasmOKs ReasmFails "
412  " ReasmReqds ReasmTimeout\n");
413  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
414  link->l_stats[RTNL_LINK_IP6_REASMOKS],
415  link->l_stats[RTNL_LINK_IP6_REASMFAILS],
416  link->l_stats[RTNL_LINK_IP6_REASMREQDS],
417  link->l_stats[RTNL_LINK_IP6_REASMTIMEOUT]);
418 
419  nl_dump(p, " FragOKs FragFails "
420  " FragCreates\n");
421  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
422  link->l_stats[RTNL_LINK_IP6_FRAGOKS],
423  link->l_stats[RTNL_LINK_IP6_FRAGFAILS],
424  link->l_stats[RTNL_LINK_IP6_FRAGCREATES]);
425 
426  nl_dump(p, " InHdrErrors InTooBigErrors "
427  " InNoRoutes InAddrErrors\n");
428  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
429  link->l_stats[RTNL_LINK_IP6_INHDRERRORS],
430  link->l_stats[RTNL_LINK_IP6_INTOOBIGERRORS],
431  link->l_stats[RTNL_LINK_IP6_INNOROUTES],
432  link->l_stats[RTNL_LINK_IP6_INADDRERRORS]);
433 
434  nl_dump(p, " InUnknownProtos InTruncatedPkts "
435  " OutNoRoutes InCsumErrors\n");
436  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
437  link->l_stats[RTNL_LINK_IP6_INUNKNOWNPROTOS],
438  link->l_stats[RTNL_LINK_IP6_INTRUNCATEDPKTS],
439  link->l_stats[RTNL_LINK_IP6_OUTNOROUTES],
440  link->l_stats[RTNL_LINK_IP6_CSUMERRORS]);
441 
442  nl_dump(p, " InNoECTPkts InECT1Pkts "
443  " InECT0Pkts InCEPkts\n");
444  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
445  link->l_stats[RTNL_LINK_IP6_NOECTPKTS],
446  link->l_stats[RTNL_LINK_IP6_ECT1PKTS],
447  link->l_stats[RTNL_LINK_IP6_ECT0PKTS],
448  link->l_stats[RTNL_LINK_IP6_CEPKTS]);
449 
450  nl_dump(p, " ICMPv6: InMsgs InErrors "
451  " OutMsgs OutErrors InCsumErrors\n");
452  nl_dump(p, " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 " %18" PRIu64 "\n",
453  link->l_stats[RTNL_LINK_ICMP6_INMSGS],
454  link->l_stats[RTNL_LINK_ICMP6_INERRORS],
455  link->l_stats[RTNL_LINK_ICMP6_OUTMSGS],
456  link->l_stats[RTNL_LINK_ICMP6_OUTERRORS],
457  link->l_stats[RTNL_LINK_ICMP6_CSUMERRORS]);
458 }
459 
460 static const struct nla_policy protinfo_policy = {
461  .type = NLA_NESTED,
462 };
463 
464 static struct rtnl_link_af_ops inet6_ops = {
465  .ao_family = AF_INET6,
466  .ao_alloc = &inet6_alloc,
467  .ao_clone = &inet6_clone,
468  .ao_free = &inet6_free,
469  .ao_parse_protinfo = &inet6_parse_protinfo,
470  .ao_parse_af = &inet6_parse_protinfo,
471  .ao_dump[NL_DUMP_DETAILS] = &inet6_dump_details,
472  .ao_dump[NL_DUMP_STATS] = &inet6_dump_stats,
473  .ao_protinfo_policy = &protinfo_policy,
474 };
475 
476 static void __init inet6_init(void)
477 {
478  rtnl_link_af_register(&inet6_ops);
479 }
480 
481 static void __exit inet6_exit(void)
482 {
483  rtnl_link_af_unregister(&inet6_ops);
484 }
Attribute validation policy.
Definition: attr.h:60
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
Definition: utils.c:547
Dump all attributes but no statistics.
Definition: types.h:23
int nla_memcpy(void *dest, struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:353
char * nl_size2str(const size_t size, char *buf, const size_t len)
Convert a size toa character string.
Definition: utils.c:327
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
Definition: utils.c:139
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
Definition: attr.c:885
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:120
int nla_len(const struct nlattr *nla)
Return length of the payload .
Definition: attr.c:131
Nested attributes.
Definition: attr.h:46
uint16_t type
Type of attribute or NLA_UNSPEC.
Definition: attr.h:62
32 bit integer
Definition: attr.h:41
Dumping parameters.
Definition: types.h:33
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:915
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:624
Dump all attributes including statistics.
Definition: types.h:24