11#include <netlink/netlink.h>
12#include <netlink/attr.h>
13#include <netlink/route/rtnl.h>
14#include <netlink/route/link/inet6.h>
18#include "nl-priv-static-route/nl-priv-static-route.h"
20#define I6_ADDR_GEN_MODE_UNKNOWN UINT8_MAX
25 struct ifla_cacheinfo i6_cacheinfo;
26 uint32_t i6_conf[DEVCONF_MAX];
27 struct in6_addr i6_token;
29 uint8_t i6_addr_gen_mode;
32static void *inet6_alloc(
struct rtnl_link *link)
38 i6->i6_addr_gen_mode = I6_ADDR_GEN_MODE_UNKNOWN;
43static void *inet6_clone(
struct rtnl_link *link,
void *data)
47 if ((i6 = inet6_alloc(link)))
48 memcpy(i6, data,
sizeof(*i6));
53static void inet6_free(
struct rtnl_link *link,
void *data)
61 [IFLA_INET6_CONF] = { .minlen = 4 },
62 [IFLA_INET6_STATS] = { .minlen = 8 },
63 [IFLA_INET6_ICMP6STATS] = { .minlen = 8 },
64 [IFLA_INET6_TOKEN] = { .minlen =
sizeof(
struct in6_addr) },
65 [IFLA_INET6_ADDR_GEN_MODE] = { .type =
NLA_U8 },
68static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = {
106static const uint8_t map_stat_id_from_IPSTATS_MIB_v2[__IPSTATS_MIB_MAX] = {
147const uint8_t *
const _nltst_map_stat_id_from_IPSTATS_MIB_v2 = map_stat_id_from_IPSTATS_MIB_v2;
149static int inet6_parse_protinfo(
struct rtnl_link *link,
struct nlattr *attr,
153 struct nlattr *tb[IFLA_INET6_MAX+1];
159 if (tb[IFLA_INET6_CONF] &&
nla_len(tb[IFLA_INET6_CONF]) % 4)
161 if (tb[IFLA_INET6_STATS] &&
nla_len(tb[IFLA_INET6_STATS]) % 8)
163 if (tb[IFLA_INET6_ICMP6STATS] &&
nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8)
166 if (tb[IFLA_INET6_FLAGS])
169 if (tb[IFLA_INET6_CACHEINFO])
170 nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
171 sizeof(i6->i6_cacheinfo));
173 if (tb[IFLA_INET6_CONF]) {
174 i6->i6_conf_len = _NL_MIN(ARRAY_SIZE(i6->i6_conf),
176 sizeof(i6->i6_conf[0]));
178 sizeof(i6->i6_conf[0]) * i6->i6_conf_len);
181 if (tb[IFLA_INET6_TOKEN])
182 nla_memcpy(&i6->i6_token, tb[IFLA_INET6_TOKEN],
183 sizeof(
struct in6_addr));
185 if (tb[IFLA_INET6_ADDR_GEN_MODE])
186 i6->i6_addr_gen_mode =
nla_get_u8 (tb[IFLA_INET6_ADDR_GEN_MODE]);
192 if (tb[IFLA_INET6_STATS]) {
193 unsigned char *cnt =
nla_data(tb[IFLA_INET6_STATS]);
196 int len =
nla_len(tb[IFLA_INET6_STATS]) / 8;
197 const uint8_t *map_stat_id = map_stat_id_from_IPSTATS_MIB_v2;
200 (tb[IFLA_INET6_ICMP6STATS] &&
nla_len(tb[IFLA_INET6_ICMP6STATS]) < 6)) {
206 map_stat_id = map_stat_id_from_IPSTATS_MIB_v1;
209 len = _NL_MIN(__IPSTATS_MIB_MAX, len);
210 for (i = 1; i < len; i++) {
211 memcpy(&stat, &cnt[i *
sizeof(stat)],
sizeof(stat));
216 if (tb[IFLA_INET6_ICMP6STATS]) {
217#define _NL_ICMP6_MIB_MAX 6
218 unsigned char *cnt =
nla_data(tb[IFLA_INET6_ICMP6STATS]);
221 int len = _NL_MIN(_NL_ICMP6_MIB_MAX,
nla_len(tb[IFLA_INET6_ICMP6STATS]) / 8);
223 _NL_STATIC_ASSERT (__ICMP6_MIB_MAX >= _NL_ICMP6_MIB_MAX);
226 for (i = 1; i < len; i++) {
227 memcpy(&stat, &cnt[i *
sizeof(stat)],
sizeof(stat));
236static int inet6_fill_af(
struct rtnl_link *link,
struct nl_msg *msg,
void *data)
240 if (id->i6_addr_gen_mode != I6_ADDR_GEN_MODE_UNKNOWN)
241 NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, id->i6_addr_gen_mode);
250#define IF_RA_OTHERCONF 0x80
251#define IF_RA_MANAGED 0x40
252#define IF_RA_RCVD 0x20
253#define IF_RS_SENT 0x10
254#define IF_READY 0x80000000
256static const struct trans_tbl inet6_flags[] = {
257 __ADD(IF_RA_OTHERCONF, ra_otherconf),
258 __ADD(IF_RA_MANAGED, ra_managed),
259 __ADD(IF_RA_RCVD, ra_rcvd),
260 __ADD(IF_RS_SENT, rs_sent),
261 __ADD(IF_READY, ready),
264char *rtnl_link_inet6_flags2str(
int flags,
char *buf,
size_t len)
266 return __flags2str(flags, buf, len, inet6_flags,
267 ARRAY_SIZE(inet6_flags));
270int rtnl_link_inet6_str2flags(
const char *name)
272 return __str2flags(name, inet6_flags, ARRAY_SIZE(inet6_flags));
275static const struct trans_tbl inet6_devconf[] = {
276 __ADD(DEVCONF_FORWARDING, forwarding),
277 __ADD(DEVCONF_HOPLIMIT, hoplimit),
278 __ADD(DEVCONF_MTU6, mtu6),
279 __ADD(DEVCONF_ACCEPT_RA, accept_ra),
280 __ADD(DEVCONF_ACCEPT_REDIRECTS, accept_redirects),
281 __ADD(DEVCONF_AUTOCONF, autoconf),
282 __ADD(DEVCONF_DAD_TRANSMITS, dad_transmits),
283 __ADD(DEVCONF_RTR_SOLICITS, rtr_solicits),
284 __ADD(DEVCONF_RTR_SOLICIT_INTERVAL, rtr_solicit_interval),
285 __ADD(DEVCONF_RTR_SOLICIT_DELAY, rtr_solicit_delay),
286 __ADD(DEVCONF_USE_TEMPADDR, use_tempaddr),
287 __ADD(DEVCONF_TEMP_VALID_LFT, temp_valid_lft),
288 __ADD(DEVCONF_TEMP_PREFERED_LFT, temp_prefered_lft),
289 __ADD(DEVCONF_REGEN_MAX_RETRY, regen_max_retry),
290 __ADD(DEVCONF_MAX_DESYNC_FACTOR, max_desync_factor),
291 __ADD(DEVCONF_MAX_ADDRESSES, max_addresses),
292 __ADD(DEVCONF_FORCE_MLD_VERSION, force_mld_version),
293 __ADD(DEVCONF_ACCEPT_RA_DEFRTR, accept_ra_defrtr),
294 __ADD(DEVCONF_ACCEPT_RA_PINFO, accept_ra_pinfo),
295 __ADD(DEVCONF_ACCEPT_RA_RTR_PREF, accept_ra_rtr_pref),
296 __ADD(DEVCONF_RTR_PROBE_INTERVAL, rtr_probe_interval),
297 __ADD(DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, accept_ra_rt_info),
298 __ADD(DEVCONF_PROXY_NDP, proxy_ndp),
299 __ADD(DEVCONF_OPTIMISTIC_DAD, optimistic_dad),
300 __ADD(DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route),
301 __ADD(DEVCONF_MC_FORWARDING, mc_forwarding),
302 __ADD(DEVCONF_DISABLE_IPV6, disable_ipv6),
303 __ADD(DEVCONF_ACCEPT_DAD, accept_dad),
304 __ADD(DEVCONF_FORCE_TLLAO, force_tllao),
307static char *inet6_devconf2str(
int type,
char *buf,
size_t len)
309 return __type2str(type, buf, len, inet6_devconf,
310 ARRAY_SIZE(inet6_devconf));
313static const struct trans_tbl inet6_addr_gen_mode[] = {
314 __ADD(IN6_ADDR_GEN_MODE_EUI64, eui64),
315 __ADD(IN6_ADDR_GEN_MODE_NONE, none),
316 __ADD(IN6_ADDR_GEN_MODE_STABLE_PRIVACY, stable_privacy),
319const char *rtnl_link_inet6_addrgenmode2str(uint8_t mode,
char *buf,
size_t len)
321 return __type2str(mode, buf, len, inet6_addr_gen_mode,
322 ARRAY_SIZE(inet6_addr_gen_mode));
325uint8_t rtnl_link_inet6_str2addrgenmode(
const char *mode)
327 return (uint8_t) __str2type(mode, inet6_addr_gen_mode,
328 ARRAY_SIZE(inet6_addr_gen_mode));
331static void inet6_dump_details(
struct rtnl_link *link,
335 struct nl_addr *addr;
339 nl_dump_line(p,
" ipv6 max-reasm-len %s",
340 nl_size2str(i6->i6_cacheinfo.max_reasm_len, buf,
sizeof(buf)));
343 rtnl_link_inet6_flags2str(i6->i6_flags, buf,
sizeof(buf)));
345 nl_dump_line(p,
" create-stamp %.2fs reachable-time %s",
346 (
double) i6->i6_cacheinfo.tstamp / 100.,
347 nl_msec2str(i6->i6_cacheinfo.reachable_time, buf,
sizeof(buf)));
349 nl_dump(p,
" retrans-time %s\n",
350 nl_msec2str(i6->i6_cacheinfo.retrans_time, buf,
sizeof(buf)));
352 addr =
nl_addr_build(AF_INET6, &i6->i6_token,
sizeof(i6->i6_token));
357 nl_dump(p,
" link-local address mode %s\n",
358 rtnl_link_inet6_addrgenmode2str(i6->i6_addr_gen_mode,
361 nl_dump_line(p,
" devconf:\n");
362 nl_dump_line(p,
" ");
364 for (i = 0; i < (int) i6->i6_conf_len; i++) {
366 uint32_t value = i6->i6_conf[i];
370 case DEVCONF_TEMP_VALID_LFT:
371 case DEVCONF_TEMP_PREFERED_LFT:
372 nl_msec2str((uint64_t) value * 1000., buf2,
sizeof(buf2));
375 case DEVCONF_RTR_PROBE_INTERVAL:
376 case DEVCONF_RTR_SOLICIT_INTERVAL:
377 case DEVCONF_RTR_SOLICIT_DELAY:
382 snprintf(buf2,
sizeof(buf2),
"%u", value);
386 inet6_devconf2str(i, buf,
sizeof(buf));
388 offset = 23 - strlen(buf2);
392 for (x = strlen(buf); x < offset; x++)
395 _nl_strncpy_trunc(&buf[offset], buf2,
sizeof(buf) - offset);
397 nl_dump_line(p,
"%s", buf);
401 nl_dump_line(p,
" ");
411static void inet6_dump_stats(
struct rtnl_link *link,
417 nl_dump(p,
" IPv6: InPkts InOctets "
418 " InDiscards InDelivers\n");
424 nl_dump(p,
"%14.2f %3s ", octets, octetsUnit);
428 nl_dump(p,
"%18" PRIu64
" %18" PRIu64
"\n",
432 nl_dump(p,
" OutPkts OutOctets "
433 " OutDiscards OutForwards\n");
440 nl_dump(p,
"%14.2f %3s ", octets, octetsUnit);
444 nl_dump(p,
"%18" PRIu64
" %18" PRIu64
"\n",
448 nl_dump(p,
" InMcastPkts InMcastOctets "
449 " InBcastPkts InBcastOctests\n");
456 nl_dump(p,
"%14.2f %3s ", octets, octetsUnit);
464 nl_dump(p,
"%14.2f %3s\n", octets, octetsUnit);
468 nl_dump(p,
" OutMcastPkts OutMcastOctets "
469 " OutBcastPkts OutBcastOctests\n");
476 nl_dump(p,
"%14.2f %3s ", octets, octetsUnit);
484 nl_dump(p,
"%14.2f %3s\n", octets, octetsUnit);
488 nl_dump(p,
" ReasmOKs ReasmFails "
489 " ReasmReqds ReasmTimeout\n");
490 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
496 nl_dump(p,
" FragOKs FragFails "
498 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
503 nl_dump(p,
" InHdrErrors InTooBigErrors "
504 " InNoRoutes InAddrErrors\n");
505 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
511 nl_dump(p,
" InUnknownProtos InTruncatedPkts "
512 " OutNoRoutes InCsumErrors\n");
513 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
519 nl_dump(p,
" InNoECTPkts InECT1Pkts "
520 " InECT0Pkts InCEPkts\n");
521 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
527 nl_dump(p,
" ICMPv6: InMsgs InErrors "
528 " OutMsgs OutErrors InCsumErrors\n");
529 nl_dump(p,
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
" %18" PRIu64
"\n",
537static const struct nla_policy protinfo_policy = {
543 .ao_alloc = &inet6_alloc,
544 .ao_clone = &inet6_clone,
545 .ao_free = &inet6_free,
546 .ao_parse_protinfo = &inet6_parse_protinfo,
547 .ao_parse_af = &inet6_parse_protinfo,
548 .ao_fill_af = &inet6_fill_af,
551 .ao_protinfo_policy = &protinfo_policy,
564int rtnl_link_inet6_get_flags(
struct rtnl_link *link, uint32_t* out_flags)
571 *out_flags =
id->i6_flags;
585int rtnl_link_inet6_set_flags(
struct rtnl_link *link, uint32_t flags)
592 id->i6_flags = flags;
608int rtnl_link_inet6_get_token(
struct rtnl_link *link,
struct nl_addr **addr)
615 *addr =
nl_addr_build(AF_INET6, &id->i6_token,
sizeof(id->i6_token));
638int rtnl_link_inet6_set_token(
struct rtnl_link *link,
struct nl_addr *addr)
650 sizeof(id->i6_token));
667int rtnl_link_inet6_get_addr_gen_mode(
struct rtnl_link *link, uint8_t *mode)
674 if (id->i6_addr_gen_mode == I6_ADDR_GEN_MODE_UNKNOWN)
677 *mode =
id->i6_addr_gen_mode;
691int rtnl_link_inet6_set_addr_gen_mode(
struct rtnl_link *link, uint8_t mode)
698 id->i6_addr_gen_mode = mode;
715int rtnl_link_inet6_get_conf(
struct rtnl_link *link,
unsigned int cfgid,
723 if (cfgid >= id->i6_conf_len)
726 *res =
id->i6_conf[cfgid];
732static void _nl_init inet6_init(
void)
737static void _nl_exit inet6_exit(
void)
int nl_addr_iszero(const struct nl_addr *addr)
Returns true if the address consists of all zeros.
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
int nla_len(const struct nlattr *nla)
Return length of the payload .
@ NLA_NESTED
Nested attributes.
void * rtnl_link_af_alloc(struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Allocate and return data buffer for link address family modules.
int rtnl_link_af_unregister(struct rtnl_link_af_ops *ops)
Unregister operations for a link address family.
int rtnl_link_af_register(struct rtnl_link_af_ops *ops)
Register operations for a link address family.
void * rtnl_link_af_data(const struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Return data buffer for link address family modules.
int rtnl_link_set_stat(struct rtnl_link *link, rtnl_link_stat_id_t id, const uint64_t value)
Set value of link statistics counter.
@ RTNL_LINK_IP6_INBCASTOCTETS
@ RTNL_LINK_REASM_OVERLAPS
@ RTNL_LINK_IP6_INTRUNCATEDPKTS
@ RTNL_LINK_IP6_INNOROUTES
@ RTNL_LINK_IP6_OUTMCASTOCTETS
@ RTNL_LINK_IP6_INMCASTPKTS
@ RTNL_LINK_IP6_OUTBCASTOCTETS
@ RTNL_LINK_IP6_INDELIVERS
@ RTNL_LINK_IP6_REASMTIMEOUT
@ RTNL_LINK_IP6_OUTOCTETS
@ RTNL_LINK_ICMP6_INERRORS
@ RTNL_LINK_IP6_FRAGFAILS
@ RTNL_LINK_ICMP6_OUTMSGS
@ RTNL_LINK_IP6_CSUMERRORS
@ RTNL_LINK_IP6_INUNKNOWNPROTOS
@ RTNL_LINK_ICMP6_CSUMERRORS
@ RTNL_LINK_IP6_INBCASTPKTS
@ RTNL_LINK_IP6_INHDRERRORS
@ RTNL_LINK_IP6_REASMREQDS
@ RTNL_LINK_IP6_OUTFORWDATAGRAMS
@ RTNL_LINK_IP6_INDISCARDS
@ RTNL_LINK_IP6_NOECTPKTS
@ RTNL_LINK_IP6_OUTNOROUTES
@ RTNL_LINK_IP6_OUTDISCARDS
@ RTNL_LINK_IP6_FRAGCREATES
@ RTNL_LINK_ICMP6_OUTERRORS
@ RTNL_LINK_IP6_INMCASTOCTETS
@ RTNL_LINK_IP6_INADDRERRORS
@ RTNL_LINK_IP6_INTOOBIGERRORS
@ RTNL_LINK_IP6_OUTMCASTPKTS
@ RTNL_LINK_IP6_OUTBCASTPKTS
@ RTNL_LINK_IP6_REASMFAILS
char * nl_size2str(const size_t size, char *buf, const size_t len)
Convert a size toa character string.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
@ NL_DUMP_STATS
Dump all attributes including statistics.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t type
Type of attribute or NLA_UNSPEC.
Available operations to modules implementing a link address family.
const unsigned int ao_family
The address family this operations set implements.