103#include "nl-default.h"
105#include <netlink/netlink.h>
106#include <netlink/route/rtnl.h>
107#include <netlink/route/addr.h>
108#include <netlink/route/route.h>
109#include <netlink/route/link.h>
110#include <netlink/utils.h>
113#include "nl-priv-dynamic-core/nl-core.h"
114#include "nl-priv-dynamic-core/cache-api.h"
117struct rtnl_addr_cacheinfo {
119 uint32_t aci_prefered;
140 struct nl_addr *a_peer;
141 struct nl_addr *a_local;
142 struct nl_addr *a_bcast;
143 struct nl_addr *a_anycast;
144 struct nl_addr *a_multicast;
146 struct rtnl_addr_cacheinfo a_cacheinfo;
148 char a_label[IFNAMSIZ];
149 uint32_t a_flag_mask;
153#define ADDR_ATTR_FAMILY 0x0001
154#define ADDR_ATTR_PREFIXLEN 0x0002
155#define ADDR_ATTR_FLAGS 0x0004
156#define ADDR_ATTR_SCOPE 0x0008
157#define ADDR_ATTR_IFINDEX 0x0010
158#define ADDR_ATTR_LABEL 0x0020
159#define ADDR_ATTR_CACHEINFO 0x0040
160#define ADDR_ATTR_PEER 0x0080
161#define ADDR_ATTR_LOCAL 0x0100
162#define ADDR_ATTR_BROADCAST 0x0200
163#define ADDR_ATTR_MULTICAST 0x0400
164#define ADDR_ATTR_ANYCAST 0x0800
166static struct nl_cache_ops rtnl_addr_ops;
167static struct nl_object_ops addr_obj_ops;
170static void addr_constructor(
struct nl_object *obj)
172 struct rtnl_addr *addr = nl_object_priv(obj);
174 addr->a_scope = RT_SCOPE_NOWHERE;
177static void addr_free_data(
struct nl_object *obj)
179 struct rtnl_addr *addr = nl_object_priv(obj);
192static int addr_clone(
struct nl_object *_dst,
struct nl_object *_src)
194 struct rtnl_addr *dst = nl_object_priv(_dst);
195 struct rtnl_addr *src = nl_object_priv(_src);
200 dst->a_anycast = NULL;
201 dst->a_multicast = NULL;
206 dst->a_link = src->a_link;
221 if (src->a_multicast)
234 .maxlen = IFNAMSIZ },
235 [
IFA_CACHEINFO] = { .minlen =
sizeof(
struct ifa_cacheinfo) },
238static int addr_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
239 struct nlmsghdr *nlh,
struct nl_parser_param *pp)
241 struct rtnl_addr *addr;
242 struct ifaddrmsg *ifa;
243 struct nlattr *tb[IFA_MAX+1];
245 struct nl_cache *link_cache;
246 struct nl_addr *plen_addr = NULL;
248 addr = rtnl_addr_alloc();
252 addr->ce_msgtype = nlh->nlmsg_type;
254 err =
nlmsg_parse(nlh,
sizeof(*ifa), tb, IFA_MAX, addr_policy);
259 addr->a_family = family = ifa->ifa_family;
260 addr->a_prefixlen = ifa->ifa_prefixlen;
261 addr->a_scope = ifa->ifa_scope;
262 addr->a_flags = tb[IFA_FLAGS] ?
nla_get_u32(tb[IFA_FLAGS]) :
264 addr->a_ifindex = ifa->ifa_index;
266 addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN |
267 ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX);
270 nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ);
271 addr->ce_mask |= ADDR_ATTR_LABEL;
275 if (tb[IFA_CACHEINFO]) {
276 struct ifa_cacheinfo *ca;
279 addr->a_cacheinfo.aci_prefered = ca->ifa_prefered;
280 addr->a_cacheinfo.aci_valid = ca->ifa_valid;
281 addr->a_cacheinfo.aci_cstamp = ca->cstamp;
282 addr->a_cacheinfo.aci_tstamp = ca->tstamp;
283 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
286 if (family == AF_INET) {
297 addr->ce_mask |= ADDR_ATTR_LOCAL;
316 addr->ce_mask |= ADDR_ATTR_PEER;
318 plen_addr = addr->a_local;
324 addr->ce_mask |= ADDR_ATTR_LOCAL;
325 plen_addr = addr->a_local;
328 if (tb[IFA_ADDRESS]) {
338 if (!tb[IFA_LOCAL] || !
nl_addr_cmp(a, addr->a_local)) {
341 addr->ce_mask |= ADDR_ATTR_LOCAL;
344 addr->ce_mask |= ADDR_ATTR_PEER;
355 if (tb[IFA_BROADCAST]) {
360 addr->ce_mask |= ADDR_ATTR_BROADCAST;
364 if (tb[IFA_MULTICAST]) {
367 if (!addr->a_multicast)
370 addr->ce_mask |= ADDR_ATTR_MULTICAST;
374 if (tb[IFA_ANYCAST]) {
377 if (!addr->a_anycast)
380 addr->ce_mask |= ADDR_ATTR_ANYCAST;
383 if ((link_cache = __nl_cache_mngt_require(
"route/link"))) {
387 rtnl_addr_set_link(addr, link);
394 err = pp->pp_cb((
struct nl_object *) addr, pp);
405static int addr_request_update(
struct nl_cache *cache,
struct nl_sock *sk)
410static void addr_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
412 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
413 struct nl_cache *link_cache;
418 if (addr->ce_mask & ADDR_ATTR_LOCAL)
419 nl_dump_line(p,
"%s",
422 nl_dump_line(p,
"none");
424 if (addr->ce_mask & ADDR_ATTR_PEER)
428 nl_dump(p,
" %s ", nl_af2str(addr->a_family, buf,
sizeof(buf)));
435 nl_dump(p,
"dev %d ", addr->a_ifindex);
438 rtnl_scope2str(addr->a_scope, buf,
sizeof(buf)));
440 rtnl_addr_flags2str(addr->a_flags, buf,
sizeof(buf));
447 nl_cache_put(link_cache);
450static void addr_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
452 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
455 addr_dump_line(obj, p);
457 if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST |
458 ADDR_ATTR_MULTICAST)) {
459 nl_dump_line(p,
" ");
461 if (addr->ce_mask & ADDR_ATTR_LABEL)
462 nl_dump(p,
" label %s", addr->a_label);
464 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
468 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
473 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
481 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
482 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
484 nl_dump_line(p,
" valid-lifetime %s",
485 ci->aci_valid == 0xFFFFFFFFU ?
"forever" :
489 nl_dump(p,
" preferred-lifetime %s\n",
490 ci->aci_prefered == 0xFFFFFFFFU ?
"forever" :
494 nl_dump_line(p,
" created boot-time+%s ",
498 nl_dump(p,
"last-updated boot-time+%s\n",
504static void addr_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
506 addr_dump_details(obj, p);
509static uint32_t addr_id_attrs_get(
struct nl_object *obj)
511 struct rtnl_addr *addr = (
struct rtnl_addr *)obj;
514 switch (addr->a_family) {
516 rv = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
517 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN);
519 rv |= ADDR_ATTR_PEER;
522 return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
525 return (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
526 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN);
530static uint64_t addr_compare(
struct nl_object *_a,
struct nl_object *_b,
531 uint64_t attrs,
int flags)
533 struct rtnl_addr *a = (
struct rtnl_addr *) _a;
534 struct rtnl_addr *b = (
struct rtnl_addr *) _b;
537#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
538 diff |= _DIFF(ADDR_ATTR_IFINDEX, a->a_ifindex != b->a_ifindex);
539 diff |= _DIFF(ADDR_ATTR_FAMILY, a->a_family != b->a_family);
540 diff |= _DIFF(ADDR_ATTR_SCOPE, a->a_scope != b->a_scope);
541 diff |= _DIFF(ADDR_ATTR_LABEL, strcmp(a->a_label, b->a_label));
542 if (attrs & ADDR_ATTR_PEER) {
543 if ((flags & ID_COMPARISON) && a->a_family == AF_INET &&
544 b->a_family == AF_INET && a->a_peer && b->a_peer &&
545 a->a_prefixlen == b->a_prefixlen) {
549 diff |= _DIFF(ADDR_ATTR_PEER,
552 diff |= _DIFF(ADDR_ATTR_PEER,
555 diff |= _DIFF(ADDR_ATTR_LOCAL,
nl_addr_cmp(a->a_local, b->a_local));
556 diff |= _DIFF(ADDR_ATTR_MULTICAST,
558 diff |= _DIFF(ADDR_ATTR_BROADCAST,
nl_addr_cmp(a->a_bcast, b->a_bcast));
559 diff |= _DIFF(ADDR_ATTR_ANYCAST,
561 diff |= _DIFF(ADDR_ATTR_CACHEINFO,
562 memcmp(&a->a_cacheinfo, &b->a_cacheinfo,
563 sizeof(a->a_cacheinfo)));
565 if (flags & LOOSE_COMPARISON)
566 diff |= _DIFF(ADDR_ATTR_FLAGS,
567 (a->a_flags ^ b->a_flags) & b->a_flag_mask);
569 diff |= _DIFF(ADDR_ATTR_FLAGS, a->a_flags != b->a_flags);
575static const struct trans_tbl addr_attrs[] = {
576 __ADD(ADDR_ATTR_FAMILY, family),
577 __ADD(ADDR_ATTR_PREFIXLEN, prefixlen),
578 __ADD(ADDR_ATTR_FLAGS, flags),
579 __ADD(ADDR_ATTR_SCOPE, scope),
580 __ADD(ADDR_ATTR_IFINDEX, ifindex),
581 __ADD(ADDR_ATTR_LABEL, label),
582 __ADD(ADDR_ATTR_CACHEINFO, cacheinfo),
583 __ADD(ADDR_ATTR_PEER, peer),
584 __ADD(ADDR_ATTR_LOCAL, local),
585 __ADD(ADDR_ATTR_BROADCAST, broadcast),
586 __ADD(ADDR_ATTR_MULTICAST, multicast),
589static char *addr_attrs2str(
int attrs,
char *buf,
size_t len)
591 return __flags2str(attrs, buf, len, addr_attrs,
592 ARRAY_SIZE(addr_attrs));
600struct rtnl_addr *rtnl_addr_alloc(
void)
605void rtnl_addr_put(
struct rtnl_addr *addr)
617int rtnl_addr_alloc_cache(
struct nl_sock *sk,
struct nl_cache **result)
637 struct nl_addr *addr)
641 if (cache->c_ops != &rtnl_addr_ops)
644 nl_list_for_each_entry(a, &cache->c_items, ce_list) {
645 if (ifindex != 0 && a->a_ifindex != ((
unsigned)ifindex))
648 if (a->ce_mask & ADDR_ATTR_LOCAL &&
660static int build_addr_msg(
struct rtnl_addr *tmpl,
int cmd,
int flags,
661 struct nl_msg **result)
664 struct ifaddrmsg am = {
665 .ifa_family = tmpl->a_family,
666 .ifa_index = tmpl->a_ifindex,
667 .ifa_prefixlen = tmpl->a_prefixlen,
668 .ifa_flags = tmpl->a_flags,
671 if (tmpl->ce_mask & ADDR_ATTR_SCOPE)
672 am.ifa_scope = tmpl->a_scope;
675 if (tmpl->a_family == AF_INET &&
676 tmpl->ce_mask & ADDR_ATTR_LOCAL &&
678 am.ifa_scope = RT_SCOPE_HOST;
680 am.ifa_scope = RT_SCOPE_UNIVERSE;
687 if (
nlmsg_append(msg, &am,
sizeof(am), NLMSG_ALIGNTO) < 0)
688 goto nla_put_failure;
690 if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
693 if (tmpl->ce_mask & ADDR_ATTR_PEER)
695 else if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
698 if (tmpl->ce_mask & ADDR_ATTR_LABEL)
701 if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
704 if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) {
705 struct ifa_cacheinfo ca = {
706 .ifa_valid = tmpl->a_cacheinfo.aci_valid,
707 .ifa_prefered = tmpl->a_cacheinfo.aci_prefered,
710 NLA_PUT(msg, IFA_CACHEINFO,
sizeof(ca), &ca);
713 if (tmpl->a_flags & ~0xFF) {
763 struct nl_msg **result)
765 uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY |
766 ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL;
768 if ((addr->ce_mask & required) != required)
769 return -NLE_MISSING_ATTR;
771 return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags, result);
801 return wait_for_ack(sk);
836 struct nl_msg **result)
838 uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY;
840 if ((addr->ce_mask & required) != required)
841 return -NLE_MISSING_ATTR;
843 return build_addr_msg(addr, RTM_DELADDR, flags, result);
873 return wait_for_ack(sk);
883int rtnl_addr_set_label(
struct rtnl_addr *addr,
const char *label)
885 if (strlen(label) >
sizeof(addr->a_label) - 1)
888 strcpy(addr->a_label, label);
889 addr->ce_mask |= ADDR_ATTR_LABEL;
894char *rtnl_addr_get_label(
struct rtnl_addr *addr)
896 if (addr->ce_mask & ADDR_ATTR_LABEL)
897 return addr->a_label;
902void rtnl_addr_set_ifindex(
struct rtnl_addr *addr,
int ifindex)
904 addr->a_ifindex = ifindex;
905 addr->ce_mask |= ADDR_ATTR_IFINDEX;
908int rtnl_addr_get_ifindex(
struct rtnl_addr *addr)
910 return addr->a_ifindex;
913void rtnl_addr_set_link(
struct rtnl_addr *addr,
struct rtnl_link *link)
922 addr->a_ifindex = link->l_index;
923 addr->ce_mask |= ADDR_ATTR_IFINDEX;
926struct rtnl_link *rtnl_addr_get_link(
struct rtnl_addr *addr)
936void rtnl_addr_set_family(
struct rtnl_addr *addr,
int family)
938 addr->a_family = family;
939 addr->ce_mask |= ADDR_ATTR_FAMILY;
942int rtnl_addr_get_family(
struct rtnl_addr *addr)
944 return addr->a_family;
965 addr->a_prefixlen = prefixlen;
968 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
970 addr->ce_mask &= ~ADDR_ATTR_PREFIXLEN;
978 else if (addr->a_local)
982int rtnl_addr_get_prefixlen(
struct rtnl_addr *addr)
984 return addr->a_prefixlen;
987void rtnl_addr_set_scope(
struct rtnl_addr *addr,
int scope)
989 addr->a_scope = scope;
990 addr->ce_mask |= ADDR_ATTR_SCOPE;
993int rtnl_addr_get_scope(
struct rtnl_addr *addr)
995 return addr->a_scope;
998void rtnl_addr_set_flags(
struct rtnl_addr *addr,
unsigned int flags)
1000 addr->a_flag_mask |= flags;
1001 addr->a_flags |= flags;
1002 addr->ce_mask |= ADDR_ATTR_FLAGS;
1005void rtnl_addr_unset_flags(
struct rtnl_addr *addr,
unsigned int flags)
1007 addr->a_flag_mask |= flags;
1008 addr->a_flags &= ~flags;
1009 addr->ce_mask |= ADDR_ATTR_FLAGS;
1012unsigned int rtnl_addr_get_flags(
struct rtnl_addr *addr)
1014 return addr->a_flags;
1017static inline int __assign_addr(
struct rtnl_addr *addr,
struct nl_addr **pos,
1018 struct nl_addr *
new,
int flag)
1021 if (addr->ce_mask & ADDR_ATTR_FAMILY) {
1022 if (new->a_family != addr->a_family)
1023 return -NLE_AF_MISMATCH;
1025 addr->a_family =
new->a_family;
1031 addr->ce_mask |= (flag | ADDR_ATTR_FAMILY);
1037 addr->ce_mask &= ~flag;
1043int rtnl_addr_set_local(
struct rtnl_addr *addr,
struct nl_addr *local)
1048 if ((addr->ce_mask & ADDR_ATTR_PEER) && local &&
1052 err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL);
1057 if (!(addr->ce_mask & ADDR_ATTR_PEER))
1063struct nl_addr *rtnl_addr_get_local(
struct rtnl_addr *addr)
1065 return addr->a_local;
1068int rtnl_addr_set_peer(
struct rtnl_addr *addr,
struct nl_addr *peer)
1072 if (peer && peer->a_family != AF_INET)
1073 return -NLE_AF_NOSUPPORT;
1075 err = __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER);
1084struct nl_addr *rtnl_addr_get_peer(
struct rtnl_addr *addr)
1086 return addr->a_peer;
1089int rtnl_addr_set_broadcast(
struct rtnl_addr *addr,
struct nl_addr *bcast)
1091 if (bcast && bcast->a_family != AF_INET)
1092 return -NLE_AF_NOSUPPORT;
1094 return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST);
1097struct nl_addr *rtnl_addr_get_broadcast(
struct rtnl_addr *addr)
1099 return addr->a_bcast;
1102int rtnl_addr_set_multicast(
struct rtnl_addr *addr,
struct nl_addr *multicast)
1104 if (multicast && multicast->a_family != AF_INET6)
1105 return -NLE_AF_NOSUPPORT;
1107 return __assign_addr(addr, &addr->a_multicast, multicast,
1108 ADDR_ATTR_MULTICAST);
1111struct nl_addr *rtnl_addr_get_multicast(
struct rtnl_addr *addr)
1113 return addr->a_multicast;
1116int rtnl_addr_set_anycast(
struct rtnl_addr *addr,
struct nl_addr *anycast)
1118 if (anycast && anycast->a_family != AF_INET6)
1119 return -NLE_AF_NOSUPPORT;
1121 return __assign_addr(addr, &addr->a_anycast, anycast,
1125struct nl_addr *rtnl_addr_get_anycast(
struct rtnl_addr *addr)
1127 return addr->a_anycast;
1130uint32_t rtnl_addr_get_valid_lifetime(
struct rtnl_addr *addr)
1132 if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
1133 return addr->a_cacheinfo.aci_valid;
1138void rtnl_addr_set_valid_lifetime(
struct rtnl_addr *addr, uint32_t lifetime)
1140 addr->a_cacheinfo.aci_valid = lifetime;
1141 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
1144uint32_t rtnl_addr_get_preferred_lifetime(
struct rtnl_addr *addr)
1146 if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
1147 return addr->a_cacheinfo.aci_prefered;
1152void rtnl_addr_set_preferred_lifetime(
struct rtnl_addr *addr, uint32_t lifetime)
1154 addr->a_cacheinfo.aci_prefered = lifetime;
1155 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
1158uint32_t rtnl_addr_get_create_time(
struct rtnl_addr *addr)
1160 return addr->a_cacheinfo.aci_cstamp;
1163uint32_t rtnl_addr_get_last_update_time(
struct rtnl_addr *addr)
1165 return addr->a_cacheinfo.aci_tstamp;
1175static const struct trans_tbl addr_flags[] = {
1176 __ADD(IFA_F_SECONDARY, secondary),
1177 __ADD(IFA_F_NODAD, nodad),
1178 __ADD(IFA_F_OPTIMISTIC, optimistic),
1179 __ADD(IFA_F_DADFAILED, dadfailed),
1180 __ADD(IFA_F_HOMEADDRESS, homeaddress),
1181 __ADD(IFA_F_DEPRECATED, deprecated),
1182 __ADD(IFA_F_TENTATIVE, tentative),
1183 __ADD(IFA_F_PERMANENT, permanent),
1184 __ADD(IFA_F_MANAGETEMPADDR, mngtmpaddr),
1185 __ADD(IFA_F_NOPREFIXROUTE, noprefixroute),
1188char *rtnl_addr_flags2str(
int flags,
char *buf,
size_t size)
1190 return __flags2str(flags, buf, size, addr_flags,
1191 ARRAY_SIZE(addr_flags));
1194int rtnl_addr_str2flags(
const char *name)
1196 return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags));
1201static struct nl_object_ops addr_obj_ops = {
1202 .oo_name =
"route/addr",
1203 .oo_size =
sizeof(
struct rtnl_addr),
1204 .oo_constructor = addr_constructor,
1205 .oo_free_data = addr_free_data,
1206 .oo_clone = addr_clone,
1212 .oo_compare = addr_compare,
1213 .oo_attrs2str = addr_attrs2str,
1214 .oo_id_attrs_get = addr_id_attrs_get,
1215 .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
1216 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN),
1219static struct nl_af_group addr_groups[] = {
1220 { AF_INET, RTNLGRP_IPV4_IFADDR },
1221 { AF_INET6, RTNLGRP_IPV6_IFADDR },
1222 { END_OF_GROUP_LIST },
1225static struct nl_cache_ops rtnl_addr_ops = {
1226 .co_name =
"route/addr",
1227 .co_hdrsize =
sizeof(
struct ifaddrmsg),
1229 { RTM_NEWADDR, NL_ACT_NEW,
"new" },
1230 { RTM_DELADDR, NL_ACT_DEL,
"del" },
1231 { RTM_GETADDR, NL_ACT_GET,
"get" },
1232 END_OF_MSGTYPES_LIST,
1234 .co_protocol = NETLINK_ROUTE,
1235 .co_groups = addr_groups,
1236 .co_request_update = addr_request_update,
1237 .co_msg_parser = addr_msg_parser,
1238 .co_obj_ops = &addr_obj_ops,
1241static void _nl_init addr_init(
void)
1246static void _nl_exit addr_exit(
void)
void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
Set the prefix length of an abstract address.
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b)
Compare the prefix of two abstract addresses.
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_prefixlen(const struct nl_addr *addr)
Return prefix length 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_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
#define NLA_PUT_STRING(msg, attrtype, value)
Add string attribute to netlink message.
@ NLA_STRING
NUL terminated character string.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_sock *sock, struct nl_cache **result)
Allocate new cache and fill it.
struct rtnl_link * rtnl_link_get(struct nl_cache *cache, int ifindex)
Lookup link in cache by interface index.
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
void rtnl_link_put(struct rtnl_link *link)
Release a link object reference.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
int rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags, struct nl_msg **result)
Build a netlink request message to request deletion of an address.
int rtnl_addr_delete(struct nl_sock *sk, struct rtnl_addr *addr, int flags)
Request deletion of an address.
struct rtnl_addr * rtnl_addr_get(struct nl_cache *cache, int ifindex, struct nl_addr *addr)
Search address in cache.
int rtnl_addr_add(struct nl_sock *sk, struct rtnl_addr *addr, int flags)
Request addition of new address.
int rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags, struct nl_msg **result)
Build netlink request message to request addition of new address.
void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefixlen)
Set the prefix length / netmask.
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
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_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t type
Type of attribute or NLA_UNSPEC.