110 #include <netlink-local.h> 111 #include <netlink/netlink.h> 112 #include <netlink/route/rtnl.h> 113 #include <netlink/route/addr.h> 114 #include <netlink/route/route.h> 115 #include <netlink/route/link.h> 116 #include <netlink/utils.h> 119 #define ADDR_ATTR_FAMILY 0x0001 120 #define ADDR_ATTR_PREFIXLEN 0x0002 121 #define ADDR_ATTR_FLAGS 0x0004 122 #define ADDR_ATTR_SCOPE 0x0008 123 #define ADDR_ATTR_IFINDEX 0x0010 124 #define ADDR_ATTR_LABEL 0x0020 125 #define ADDR_ATTR_CACHEINFO 0x0040 126 #define ADDR_ATTR_PEER 0x0080 127 #define ADDR_ATTR_LOCAL 0x0100 128 #define ADDR_ATTR_BROADCAST 0x0200 129 #define ADDR_ATTR_ANYCAST 0x0400 130 #define ADDR_ATTR_MULTICAST 0x0800 136 static void addr_free_data(
struct nl_object *obj)
138 struct rtnl_addr *addr = nl_object_priv(obj);
143 nl_addr_put(addr->a_peer);
144 nl_addr_put(addr->a_local);
145 nl_addr_put(addr->a_bcast);
146 nl_addr_put(addr->a_anycast);
147 nl_addr_put(addr->a_multicast);
150 static int addr_clone(
struct nl_object *_dst,
struct nl_object *_src)
152 struct rtnl_addr *dst = nl_object_priv(_dst);
153 struct rtnl_addr *src = nl_object_priv(_src);
171 if (src->a_multicast)
177 return nl_get_errno();
180 static struct nla_policy addr_policy[IFA_MAX+1] = {
182 .maxlen = IFNAMSIZ },
183 [IFA_CACHEINFO] = { .minlen =
sizeof(
struct ifa_cacheinfo) },
189 struct rtnl_addr *addr;
190 struct ifaddrmsg *ifa;
191 struct nlattr *tb[IFA_MAX+1];
192 int err = -ENOMEM, peer_prefix = 0;
194 addr = rtnl_addr_alloc();
196 err = nl_errno(ENOMEM);
201 err =
nlmsg_parse(nlh,
sizeof(*ifa), tb, IFA_MAX, addr_policy);
206 addr->a_family = ifa->ifa_family;
207 addr->a_prefixlen = ifa->ifa_prefixlen;
208 addr->a_flags = ifa->ifa_flags;
209 addr->a_scope = ifa->ifa_scope;
210 addr->a_ifindex = ifa->ifa_index;
212 addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN |
213 ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX);
216 nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ);
217 addr->ce_mask |= ADDR_ATTR_LABEL;
220 if (tb[IFA_CACHEINFO]) {
221 struct ifa_cacheinfo *ca;
224 addr->a_cacheinfo.aci_prefered = ca->ifa_prefered;
225 addr->a_cacheinfo.aci_valid = ca->ifa_valid;
226 addr->a_cacheinfo.aci_cstamp = ca->cstamp;
227 addr->a_cacheinfo.aci_tstamp = ca->tstamp;
228 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
232 addr->a_local =
nla_get_addr(tb[IFA_LOCAL], addr->a_family);
235 addr->ce_mask |= ADDR_ATTR_LOCAL;
238 if (tb[IFA_ADDRESS]) {
248 if (!tb[IFA_LOCAL] || !
nl_addr_cmp(a, addr->a_local)) {
249 nl_addr_put(addr->a_local);
251 addr->ce_mask |= ADDR_ATTR_LOCAL;
254 addr->ce_mask |= ADDR_ATTR_PEER;
259 nl_addr_set_prefixlen(peer_prefix ? addr->a_peer : addr->a_local,
262 if (tb[IFA_BROADCAST]) {
263 addr->a_bcast =
nla_get_addr(tb[IFA_BROADCAST], addr->a_family);
267 addr->ce_mask |= ADDR_ATTR_BROADCAST;
270 if (tb[IFA_ANYCAST]) {
271 addr->a_anycast =
nla_get_addr(tb[IFA_ANYCAST], addr->a_family);
272 if (!addr->a_anycast)
275 addr->ce_mask |= ADDR_ATTR_ANYCAST;
278 if (tb[IFA_MULTICAST]) {
281 if (!addr->a_multicast)
284 addr->ce_mask |= ADDR_ATTR_MULTICAST;
287 err = pp->pp_cb((
struct nl_object *) addr, pp);
299 static int addr_request_update(
struct nl_cache *cache,
struct nl_handle *handle)
304 static int addr_dump_brief(
struct nl_object *obj,
struct nl_dump_params *p)
306 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
307 struct nl_cache *link_cache;
312 if (addr->ce_mask & ADDR_ATTR_LOCAL)
318 if (addr->ce_mask & ADDR_ATTR_PEER)
319 dp_dump(p,
" peer %s",
322 dp_dump(p,
" %s ", nl_af2str(addr->a_family, buf,
sizeof(buf)));
325 dp_dump(p,
"dev %s ",
329 dp_dump(p,
"dev %d ", addr->a_ifindex);
331 dp_dump(p,
"scope %s",
332 rtnl_scope2str(addr->a_scope, buf,
sizeof(buf)));
334 rtnl_addr_flags2str(addr->a_flags, buf,
sizeof(buf));
336 dp_dump(p,
" <%s>", buf);
343 static int addr_dump_full(
struct nl_object *obj,
struct nl_dump_params *p)
345 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
346 int line = addr_dump_brief(obj, p);
349 if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST |
350 ADDR_ATTR_ANYCAST | ADDR_ATTR_MULTICAST)) {
351 dp_dump_line(p, line++,
" ");
353 if (addr->ce_mask & ADDR_ATTR_LABEL)
354 dp_dump(p,
" label %s", addr->a_label);
356 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
357 dp_dump(p,
" broadcast %s",
360 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
361 dp_dump(p,
" anycast %s",
365 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
366 dp_dump(p,
" multicast %s",
373 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
374 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
376 dp_dump_line(p, line++,
" valid-lifetime %s",
377 ci->aci_valid == 0xFFFFFFFFU ?
"forever" :
381 dp_dump(p,
" preferred-lifetime %s\n",
382 ci->aci_prefered == 0xFFFFFFFFU ?
"forever" :
386 dp_dump_line(p, line++,
" created boot-time+%s ",
390 dp_dump(p,
"last-updated boot-time+%s\n",
398 static int addr_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
400 return addr_dump_full(obj, p);
403 static int addr_dump_xml(
struct nl_object *obj,
struct nl_dump_params *p)
405 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
406 struct nl_cache *link_cache;
410 dp_dump_line(p, line++,
"<address>\n");
411 dp_dump_line(p, line++,
" <family>%s</family>\n",
412 nl_af2str(addr->a_family, buf,
sizeof(buf)));
414 if (addr->ce_mask & ADDR_ATTR_LOCAL)
415 dp_dump_line(p, line++,
" <local>%s</local>\n",
418 if (addr->ce_mask & ADDR_ATTR_PEER)
419 dp_dump_line(p, line++,
" <peer>%s</peer>\n",
422 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
423 dp_dump_line(p, line++,
" <broadcast>%s</broadcast>\n",
426 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
427 dp_dump_line(p, line++,
" <anycast>%s</anycast>\n",
430 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
431 dp_dump_line(p, line++,
" <multicast>%s</multicast>\n",
435 if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
436 dp_dump_line(p, line++,
" <prefixlen>%u</prefixlen>\n",
441 dp_dump_line(p, line++,
" <device>%s</device>\n",
445 dp_dump_line(p, line++,
" <device>%u</device>\n",
448 if (addr->ce_mask & ADDR_ATTR_SCOPE)
449 dp_dump_line(p, line++,
" <scope>%s</scope>\n",
450 rtnl_scope2str(addr->a_scope, buf,
sizeof(buf)));
452 if (addr->ce_mask & ADDR_ATTR_LABEL)
453 dp_dump_line(p, line++,
" <label>%s</label>\n", addr->a_label);
455 rtnl_addr_flags2str(addr->a_flags, buf,
sizeof(buf));
457 dp_dump_line(p, line++,
" <flags>%s</flags>\n", buf);
459 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
460 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
462 dp_dump_line(p, line++,
" <cacheinfo>\n");
464 dp_dump_line(p, line++,
" <valid>%s</valid>\n",
465 ci->aci_valid == 0xFFFFFFFFU ?
"forever" :
469 dp_dump_line(p, line++,
" <prefered>%s</prefered>\n",
470 ci->aci_prefered == 0xFFFFFFFFU ?
"forever" :
474 dp_dump_line(p, line++,
" <created>%s</created>\n",
478 dp_dump_line(p, line++,
" <last-update>%s</last-update>\n",
482 dp_dump_line(p, line++,
" </cacheinfo>\n");
485 dp_dump_line(p, line++,
"</address>\n");
490 static int addr_dump_env(
struct nl_object *obj,
struct nl_dump_params *p)
492 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
493 struct nl_cache *link_cache;
497 dp_dump_line(p, line++,
"ADDR_FAMILY=%s\n",
498 nl_af2str(addr->a_family, buf,
sizeof(buf)));
500 if (addr->ce_mask & ADDR_ATTR_LOCAL)
501 dp_dump_line(p, line++,
"ADDR_LOCAL=%s\n",
504 if (addr->ce_mask & ADDR_ATTR_PEER)
505 dp_dump_line(p, line++,
"ADDR_PEER=%s\n",
508 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
509 dp_dump_line(p, line++,
"ADDR_BROADCAST=%s\n",
512 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
513 dp_dump_line(p, line++,
"ADDR_ANYCAST=%s\n",
516 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
517 dp_dump_line(p, line++,
"ADDR_MULTICAST=%s\n",
521 if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
522 dp_dump_line(p, line++,
"ADDR_PREFIXLEN=%u\n",
526 dp_dump_line(p, line++,
"ADDR_IFINDEX=%u\n", addr->a_ifindex);
528 dp_dump_line(p, line++,
"ADDR_IFNAME=%s\n",
532 if (addr->ce_mask & ADDR_ATTR_SCOPE)
533 dp_dump_line(p, line++,
"ADDR_SCOPE=%s\n",
534 rtnl_scope2str(addr->a_scope, buf,
sizeof(buf)));
536 if (addr->ce_mask & ADDR_ATTR_LABEL)
537 dp_dump_line(p, line++,
"ADDR_LABEL=%s\n", addr->a_label);
539 rtnl_addr_flags2str(addr->a_flags, buf,
sizeof(buf));
541 dp_dump_line(p, line++,
"ADDR_FLAGS=%s\n", buf);
543 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
544 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
546 dp_dump_line(p, line++,
"ADDR_CACHEINFO_VALID=%s\n",
547 ci->aci_valid == 0xFFFFFFFFU ?
"forever" :
551 dp_dump_line(p, line++,
"ADDR_CACHEINFO_PREFERED=%s\n",
552 ci->aci_prefered == 0xFFFFFFFFU ?
"forever" :
556 dp_dump_line(p, line++,
"ADDR_CACHEINFO_CREATED=%s\n",
560 dp_dump_line(p, line++,
"ADDR_CACHEINFO_LASTUPDATE=%s\n",
568 static int addr_compare(
struct nl_object *_a,
struct nl_object *_b,
569 uint32_t attrs,
int flags)
571 struct rtnl_addr *a = (
struct rtnl_addr *) _a;
572 struct rtnl_addr *b = (
struct rtnl_addr *) _b;
575 #define ADDR_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ADDR_ATTR_##ATTR, a, b, EXPR) 577 diff |= ADDR_DIFF(IFINDEX, a->a_ifindex != b->a_ifindex);
578 diff |= ADDR_DIFF(FAMILY, a->a_family != b->a_family);
579 diff |= ADDR_DIFF(SCOPE, a->a_scope != b->a_scope);
580 diff |= ADDR_DIFF(LABEL, strcmp(a->a_label, b->a_label));
581 diff |= ADDR_DIFF(PEER,
nl_addr_cmp(a->a_peer, b->a_peer));
582 diff |= ADDR_DIFF(LOCAL,
nl_addr_cmp(a->a_local, b->a_local));
583 diff |= ADDR_DIFF(ANYCAST,
nl_addr_cmp(a->a_anycast,b->a_anycast));
584 diff |= ADDR_DIFF(MULTICAST,
nl_addr_cmp(a->a_multicast,
586 diff |= ADDR_DIFF(BROADCAST,
nl_addr_cmp(a->a_bcast, b->a_bcast));
588 if (flags & LOOSE_FLAG_COMPARISON)
589 diff |= ADDR_DIFF(FLAGS,
590 (a->a_flags ^ b->a_flags) & b->a_flag_mask);
592 diff |= ADDR_DIFF(FLAGS, a->a_flags != b->a_flags);
599 static struct trans_tbl addr_attrs[] = {
600 __ADD(ADDR_ATTR_FAMILY, family)
601 __ADD(ADDR_ATTR_PREFIXLEN, prefixlen)
602 __ADD(ADDR_ATTR_FLAGS, flags)
603 __ADD(ADDR_ATTR_SCOPE, scope)
604 __ADD(ADDR_ATTR_IFINDEX, ifindex)
605 __ADD(ADDR_ATTR_LABEL, label)
606 __ADD(ADDR_ATTR_CACHEINFO, cacheinfo)
607 __ADD(ADDR_ATTR_PEER, peer)
608 __ADD(ADDR_ATTR_LOCAL, local)
609 __ADD(ADDR_ATTR_BROADCAST, broadcast)
610 __ADD(ADDR_ATTR_ANYCAST, anycast)
611 __ADD(ADDR_ATTR_MULTICAST, multicast)
614 static char *addr_attrs2str(
int attrs,
char *buf,
size_t len)
616 return __flags2str(attrs, buf, len, addr_attrs,
617 ARRAY_SIZE(addr_attrs));
625 struct rtnl_addr *rtnl_addr_alloc(
void)
630 void rtnl_addr_put(
struct rtnl_addr *addr)
642 struct nl_cache *rtnl_addr_alloc_cache(
struct nl_handle *handle)
644 struct nl_cache *cache;
660 static struct nl_msg *build_addr_msg(
struct rtnl_addr *tmpl,
int cmd,
int flags)
663 struct ifaddrmsg am = {
664 .ifa_family = tmpl->a_family,
665 .ifa_index = tmpl->a_ifindex,
666 .ifa_prefixlen = tmpl->a_prefixlen,
669 if (tmpl->ce_mask & ADDR_ATTR_SCOPE)
670 am.ifa_scope = tmpl->a_scope;
673 if (tmpl->a_family == AF_INET &&
674 tmpl->ce_mask & ADDR_ATTR_LOCAL &&
676 am.ifa_scope = RT_SCOPE_HOST;
678 am.ifa_scope = RT_SCOPE_UNIVERSE;
683 goto nla_put_failure;
685 if (
nlmsg_append(msg, &am,
sizeof(am), NLMSG_ALIGNTO) < 0)
686 goto nla_put_failure;
688 if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
691 if (tmpl->ce_mask & ADDR_ATTR_PEER)
696 if (tmpl->ce_mask & ADDR_ATTR_LABEL)
699 if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
702 if (tmpl->ce_mask & ADDR_ATTR_ANYCAST)
739 int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY |
740 ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL;
742 if ((addr->ce_mask & required) != required) {
743 nl_error(EINVAL,
"Missing mandatory attributes, required are: " 744 "ifindex, family, prefixlen, local address.");
748 return build_addr_msg(addr, RTM_NEWADDR,
NLM_F_CREATE | flags);
765 int rtnl_addr_add(
struct nl_handle *handle,
struct rtnl_addr *addr,
int flags)
772 return nl_get_errno();
813 int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY;
815 if ((addr->ce_mask & required) != required) {
816 nl_error(EINVAL,
"Missing mandatory attributes, required are: " 821 return build_addr_msg(addr, RTM_DELADDR, flags);
846 return nl_get_errno();
863 void rtnl_addr_set_label(
struct rtnl_addr *addr,
const char *label)
865 strncpy(addr->a_label, label,
sizeof(addr->a_label) - 1);
866 addr->ce_mask |= ADDR_ATTR_LABEL;
869 char *rtnl_addr_get_label(
struct rtnl_addr *addr)
871 if (addr->ce_mask & ADDR_ATTR_LABEL)
872 return addr->a_label;
877 void rtnl_addr_set_ifindex(
struct rtnl_addr *addr,
int ifindex)
879 addr->a_ifindex = ifindex;
880 addr->ce_mask |= ADDR_ATTR_IFINDEX;
883 int rtnl_addr_get_ifindex(
struct rtnl_addr *addr)
885 if (addr->ce_mask & ADDR_ATTR_IFINDEX)
886 return addr->a_ifindex;
891 void rtnl_addr_set_family(
struct rtnl_addr *addr,
int family)
893 addr->a_family = family;
894 addr->ce_mask |= ADDR_ATTR_FAMILY;
897 int rtnl_addr_get_family(
struct rtnl_addr *addr)
899 if (addr->ce_mask & ADDR_ATTR_FAMILY)
900 return addr->a_family;
905 void rtnl_addr_set_prefixlen(
struct rtnl_addr *addr,
int prefix)
907 addr->a_prefixlen = prefix;
908 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
911 int rtnl_addr_get_prefixlen(
struct rtnl_addr *addr)
913 if (addr->ce_mask & ADDR_ATTR_PREFIXLEN)
914 return addr->a_prefixlen;
919 void rtnl_addr_set_scope(
struct rtnl_addr *addr,
int scope)
921 addr->a_scope = scope;
922 addr->ce_mask |= ADDR_ATTR_SCOPE;
925 int rtnl_addr_get_scope(
struct rtnl_addr *addr)
927 if (addr->ce_mask & ADDR_ATTR_SCOPE)
928 return addr->a_scope;
933 void rtnl_addr_set_flags(
struct rtnl_addr *addr,
unsigned int flags)
935 addr->a_flag_mask |= flags;
936 addr->a_flags |= flags;
937 addr->ce_mask |= ADDR_ATTR_FLAGS;
940 void rtnl_addr_unset_flags(
struct rtnl_addr *addr,
unsigned int flags)
942 addr->a_flag_mask |= flags;
943 addr->a_flags &= ~flags;
944 addr->ce_mask |= ADDR_ATTR_FLAGS;
947 unsigned int rtnl_addr_get_flags(
struct rtnl_addr *addr)
949 return addr->a_flags;
952 static inline int __assign_addr(
struct rtnl_addr *addr,
struct nl_addr **pos,
953 struct nl_addr *
new,
int flag)
955 if (addr->ce_mask & ADDR_ATTR_FAMILY) {
956 if (new->a_family != addr->a_family)
957 return nl_error(EINVAL,
"Address family mismatch");
959 addr->a_family =
new->a_family;
964 *pos = nl_addr_get(
new);
965 addr->ce_mask |= (flag | ADDR_ATTR_FAMILY);
970 int rtnl_addr_set_local(
struct rtnl_addr *addr,
struct nl_addr *local)
974 err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL);
978 if (!(addr->ce_mask & ADDR_ATTR_PEER)) {
980 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
986 struct nl_addr *rtnl_addr_get_local(
struct rtnl_addr *addr)
988 if (addr->ce_mask & ADDR_ATTR_LOCAL)
989 return addr->a_local;
994 int rtnl_addr_set_peer(
struct rtnl_addr *addr,
struct nl_addr *peer)
996 return __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER);
999 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
1004 struct nl_addr *rtnl_addr_get_peer(
struct rtnl_addr *addr)
1006 if (addr->ce_mask & ADDR_ATTR_PEER)
1007 return addr->a_peer;
1012 int rtnl_addr_set_broadcast(
struct rtnl_addr *addr,
struct nl_addr *bcast)
1014 return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST);
1017 struct nl_addr *rtnl_addr_get_broadcast(
struct rtnl_addr *addr)
1019 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
1020 return addr->a_bcast;
1025 int rtnl_addr_set_anycast(
struct rtnl_addr *addr,
struct nl_addr *anycast)
1027 return __assign_addr(addr, &addr->a_anycast, anycast,
1031 struct nl_addr *rtnl_addr_get_anycast(
struct rtnl_addr *addr)
1033 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
1034 return addr->a_anycast;
1039 int rtnl_addr_set_multicast(
struct rtnl_addr *addr,
struct nl_addr *multicast)
1041 return __assign_addr(addr, &addr->a_multicast, multicast,
1042 ADDR_ATTR_MULTICAST);
1045 struct nl_addr *rtnl_addr_get_multicast(
struct rtnl_addr *addr)
1047 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
1048 return addr->a_multicast;
1060 static struct trans_tbl addr_flags[] = {
1061 __ADD(IFA_F_SECONDARY, secondary)
1062 __ADD(IFA_F_DEPRECATED, deprecated)
1063 __ADD(IFA_F_TENTATIVE, tentative)
1064 __ADD(IFA_F_PERMANENT, permanent)
1067 char *rtnl_addr_flags2str(
int flags,
char *buf,
size_t size)
1069 return __flags2str(flags, buf, size, addr_flags,
1070 ARRAY_SIZE(addr_flags));
1073 int rtnl_addr_str2flags(
const char *name)
1075 return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags));
1082 .oo_size =
sizeof(
struct rtnl_addr),
1083 .oo_free_data = addr_free_data,
1084 .oo_clone = addr_clone,
1090 .oo_compare = addr_compare,
1091 .oo_attrs2str = addr_attrs2str,
1092 .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
1093 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN |
1098 { AF_INET, RTNLGRP_IPV4_IFADDR },
1099 { AF_INET6, RTNLGRP_IPV6_IFADDR },
1100 { END_OF_GROUP_LIST },
1104 .co_name =
"route/addr",
1105 .co_hdrsize =
sizeof(
struct ifaddrmsg),
1107 { RTM_NEWADDR, NL_ACT_NEW,
"new" },
1108 { RTM_DELADDR, NL_ACT_DEL,
"del" },
1109 { RTM_GETADDR, NL_ACT_GET,
"get" },
1110 END_OF_MSGTYPES_LIST,
1112 .co_protocol = NETLINK_ROUTE,
1113 .co_groups = addr_groups,
1114 .co_request_update = addr_request_update,
1115 .co_msg_parser = addr_msg_parser,
1116 .co_obj_ops = &addr_obj_ops,
1119 static void __init addr_init(
void)
1124 static void __exit addr_exit(
void)
Dump object in a brief one-liner.
struct nl_msg * rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags)
Build netlink request message to request addition of new address.
#define RTNL_LINK_NOT_FOUND
Special interface index stating the link was not found.
char * nl_addr2str(struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
void * nlmsg_data(const struct nlmsghdr *nlh)
head of message payload
uint16_t nlmsg_type
Message type (content type)
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
struct nl_msg * rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags)
Build a netlink request message to request deletion of an address.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
attribute validation policy
struct nl_addr * nl_addr_clone(struct nl_addr *addr)
Clone existing abstract address object.
int nl_wait_for_ack(struct nl_handle *handle)
Wait for ACK.
void nlmsg_free(struct nl_msg *n)
Free a netlink message.
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, struct nla_policy *policy)
parse attributes of a netlink message
#define NLA_PUT_STRING(n, attrtype, value)
Add a character string netlink attribute to a netlink message.
int nl_send_auto_complete(struct nl_handle *handle, struct nl_msg *msg)
Send netlink message and check & extend header values as needed.
void nl_cache_free(struct nl_cache *cache)
Free a cache.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
int nl_cache_refill(struct nl_handle *handle, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
int rtnl_addr_add(struct nl_handle *handle, struct rtnl_addr *addr, int flags)
Request addition of new address.
Dump all attribtes in XML format.
#define NLM_F_CREATE
Create config object if it doesn't already exist.
#define NLM_F_DUMP
Dump all entries.
void * nl_addr_get_binary_addr(struct nl_addr *addr)
Get binary address of abstract address object.
struct nl_cache * nl_cache_mngt_require(const char *name)
Demand the use of a global cache.
void * nla_data(const struct nlattr *nla)
head of payload
int nl_rtgen_request(struct nl_handle *handle, int type, int family, int flags)
Send routing netlink request message.
struct nl_addr * nla_get_addr(struct nlattr *nla, int family)
Return payload of address attribute.
int rtnl_addr_delete(struct nl_handle *handle, struct rtnl_addr *addr, int flags)
Request deletion of an address.
#define NLA_PUT_ADDR(n, attrtype, addr)
Add a address attribute to a netlink message.
unsigned int nl_addr_get_prefixlen(struct nl_addr *addr)
Get prefix length of abstract address object.
int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
Compares two abstract address objects.
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.
uint16_t type
Type of attribute or NLA_UNSPEC.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate an interface index to the corresponding link name.
Address family to netlink group association.
char * oo_name
Unique name of object type.
Dump all attributes but no statistics.
Dump all attributes including statistics.
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload into a sized buffer.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate an empty cache.
Dump all attribtues as env variables.