109 #include <netlink-private/netlink.h>
110 #include <netlink/netlink.h>
111 #include <netlink/route/rtnl.h>
112 #include <netlink/route/addr.h>
113 #include <netlink/route/route.h>
114 #include <netlink/route/link.h>
115 #include <netlink/utils.h>
118 #define ADDR_ATTR_FAMILY 0x0001
119 #define ADDR_ATTR_PREFIXLEN 0x0002
120 #define ADDR_ATTR_FLAGS 0x0004
121 #define ADDR_ATTR_SCOPE 0x0008
122 #define ADDR_ATTR_IFINDEX 0x0010
123 #define ADDR_ATTR_LABEL 0x0020
124 #define ADDR_ATTR_CACHEINFO 0x0040
125 #define ADDR_ATTR_PEER 0x0080
126 #define ADDR_ATTR_LOCAL 0x0100
127 #define ADDR_ATTR_BROADCAST 0x0200
128 #define ADDR_ATTR_MULTICAST 0x0400
129 #define ADDR_ATTR_ANYCAST 0x0800
131 static struct nl_cache_ops rtnl_addr_ops;
132 static struct nl_object_ops addr_obj_ops;
135 static void addr_constructor(
struct nl_object *obj)
137 struct rtnl_addr *addr = nl_object_priv(obj);
139 addr->a_scope = RT_SCOPE_NOWHERE;
142 static void addr_free_data(
struct nl_object *obj)
144 struct rtnl_addr *addr = nl_object_priv(obj);
149 nl_addr_put(addr->a_peer);
150 nl_addr_put(addr->a_local);
151 nl_addr_put(addr->a_bcast);
152 nl_addr_put(addr->a_multicast);
153 nl_addr_put(addr->a_anycast);
157 static int addr_clone(
struct nl_object *_dst,
struct nl_object *_src)
159 struct rtnl_addr *dst = nl_object_priv(_dst);
160 struct rtnl_addr *src = nl_object_priv(_src);
164 dst->a_link = src->a_link;
179 if (src->a_multicast)
190 static struct nla_policy addr_policy[IFA_MAX+1] = {
192 .maxlen = IFNAMSIZ },
193 [IFA_CACHEINFO] = { .minlen =
sizeof(
struct ifa_cacheinfo) },
196 static int addr_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
197 struct nlmsghdr *nlh,
struct nl_parser_param *pp)
199 struct rtnl_addr *addr;
200 struct ifaddrmsg *ifa;
201 struct nlattr *tb[IFA_MAX+1];
202 int err, peer_prefix = 0, family;
203 struct nl_cache *link_cache;
205 addr = rtnl_addr_alloc();
209 addr->ce_msgtype = nlh->nlmsg_type;
211 err =
nlmsg_parse(nlh,
sizeof(*ifa), tb, IFA_MAX, addr_policy);
216 addr->a_family = family = ifa->ifa_family;
217 addr->a_prefixlen = ifa->ifa_prefixlen;
218 addr->a_flags = ifa->ifa_flags;
219 addr->a_scope = ifa->ifa_scope;
220 addr->a_ifindex = ifa->ifa_index;
222 addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN |
223 ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX);
226 nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ);
227 addr->ce_mask |= ADDR_ATTR_LABEL;
231 if (tb[IFA_CACHEINFO]) {
232 struct ifa_cacheinfo *ca;
235 addr->a_cacheinfo.aci_prefered = ca->ifa_prefered;
236 addr->a_cacheinfo.aci_valid = ca->ifa_valid;
237 addr->a_cacheinfo.aci_cstamp = ca->cstamp;
238 addr->a_cacheinfo.aci_tstamp = ca->tstamp;
239 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
246 addr->ce_mask |= ADDR_ATTR_LOCAL;
249 if (tb[IFA_ADDRESS]) {
259 if (!tb[IFA_LOCAL] || !
nl_addr_cmp(a, addr->a_local)) {
260 nl_addr_put(addr->a_local);
262 addr->ce_mask |= ADDR_ATTR_LOCAL;
265 addr->ce_mask |= ADDR_ATTR_PEER;
270 nl_addr_set_prefixlen(peer_prefix ? addr->a_peer : addr->a_local,
274 if (tb[IFA_BROADCAST]) {
279 addr->ce_mask |= ADDR_ATTR_BROADCAST;
283 if (tb[IFA_MULTICAST]) {
286 if (!addr->a_multicast)
289 addr->ce_mask |= ADDR_ATTR_MULTICAST;
293 if (tb[IFA_ANYCAST]) {
296 if (!addr->a_anycast)
299 addr->ce_mask |= ADDR_ATTR_ANYCAST;
302 if ((link_cache = __nl_cache_mngt_require(
"route/link"))) {
306 rtnl_addr_set_link(addr, link);
313 err = pp->pp_cb((
struct nl_object *) addr, pp);
324 static int addr_request_update(
struct nl_cache *cache,
struct nl_sock *sk)
329 static void addr_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
331 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
332 struct nl_cache *link_cache;
337 if (addr->ce_mask & ADDR_ATTR_LOCAL)
338 nl_dump_line(p,
"%s",
341 nl_dump_line(p,
"none");
343 if (addr->ce_mask & ADDR_ATTR_PEER)
347 nl_dump(p,
" %s ", nl_af2str(addr->a_family, buf,
sizeof(buf)));
354 nl_dump(p,
"dev %d ", addr->a_ifindex);
357 rtnl_scope2str(addr->a_scope, buf,
sizeof(buf)));
359 rtnl_addr_flags2str(addr->a_flags, buf,
sizeof(buf));
366 nl_cache_put(link_cache);
369 static void addr_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
371 struct rtnl_addr *addr = (
struct rtnl_addr *) obj;
374 addr_dump_line(obj, p);
376 if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST |
377 ADDR_ATTR_MULTICAST)) {
378 nl_dump_line(p,
" ");
380 if (addr->ce_mask & ADDR_ATTR_LABEL)
381 nl_dump(p,
" label %s", addr->a_label);
383 if (addr->ce_mask & ADDR_ATTR_BROADCAST)
387 if (addr->ce_mask & ADDR_ATTR_MULTICAST)
392 if (addr->ce_mask & ADDR_ATTR_ANYCAST)
400 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) {
401 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo;
403 nl_dump_line(p,
" valid-lifetime %s",
404 ci->aci_valid == 0xFFFFFFFFU ?
"forever" :
408 nl_dump(p,
" preferred-lifetime %s\n",
409 ci->aci_prefered == 0xFFFFFFFFU ?
"forever" :
413 nl_dump_line(p,
" created boot-time+%s ",
417 nl_dump(p,
"last-updated boot-time+%s\n",
423 static void addr_dump_stats(
struct nl_object *obj,
struct nl_dump_params *p)
425 addr_dump_details(obj, p);
428 static int addr_compare(
struct nl_object *_a,
struct nl_object *_b,
429 uint32_t attrs,
int flags)
431 struct rtnl_addr *a = (
struct rtnl_addr *) _a;
432 struct rtnl_addr *b = (
struct rtnl_addr *) _b;
435 #define ADDR_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ADDR_ATTR_##ATTR, a, b, EXPR)
437 diff |= ADDR_DIFF(IFINDEX, a->a_ifindex != b->a_ifindex);
438 diff |= ADDR_DIFF(FAMILY, a->a_family != b->a_family);
439 diff |= ADDR_DIFF(SCOPE, a->a_scope != b->a_scope);
440 diff |= ADDR_DIFF(LABEL, strcmp(a->a_label, b->a_label));
441 diff |= ADDR_DIFF(PEER,
nl_addr_cmp(a->a_peer, b->a_peer));
442 diff |= ADDR_DIFF(LOCAL,
nl_addr_cmp(a->a_local, b->a_local));
443 diff |= ADDR_DIFF(MULTICAST,
nl_addr_cmp(a->a_multicast,
445 diff |= ADDR_DIFF(BROADCAST,
nl_addr_cmp(a->a_bcast, b->a_bcast));
446 diff |= ADDR_DIFF(ANYCAST,
nl_addr_cmp(a->a_anycast, b->a_anycast));
448 if (flags & LOOSE_COMPARISON)
449 diff |= ADDR_DIFF(FLAGS,
450 (a->a_flags ^ b->a_flags) & b->a_flag_mask);
452 diff |= ADDR_DIFF(FLAGS, a->a_flags != b->a_flags);
459 static const struct trans_tbl addr_attrs[] = {
460 __ADD(ADDR_ATTR_FAMILY, family)
461 __ADD(ADDR_ATTR_PREFIXLEN, prefixlen)
462 __ADD(ADDR_ATTR_FLAGS, flags)
463 __ADD(ADDR_ATTR_SCOPE, scope)
464 __ADD(ADDR_ATTR_IFINDEX, ifindex)
465 __ADD(ADDR_ATTR_LABEL, label)
466 __ADD(ADDR_ATTR_CACHEINFO, cacheinfo)
467 __ADD(ADDR_ATTR_PEER, peer)
468 __ADD(ADDR_ATTR_LOCAL, local)
469 __ADD(ADDR_ATTR_BROADCAST, broadcast)
470 __ADD(ADDR_ATTR_MULTICAST, multicast)
473 static
char *addr_attrs2str(
int attrs,
char *buf,
size_t len)
475 return __flags2str(attrs, buf, len, addr_attrs,
476 ARRAY_SIZE(addr_attrs));
484 struct rtnl_addr *rtnl_addr_alloc(
void)
489 void rtnl_addr_put(
struct rtnl_addr *addr)
501 int rtnl_addr_alloc_cache(
struct nl_sock *sk,
struct nl_cache **result)
521 struct nl_addr *addr)
525 if (cache->c_ops != &rtnl_addr_ops)
528 nl_list_for_each_entry(a, &cache->c_items, ce_list) {
529 if (ifindex && a->a_ifindex != ifindex)
532 if (a->ce_mask & ADDR_ATTR_LOCAL &&
544 static int build_addr_msg(
struct rtnl_addr *tmpl,
int cmd,
int flags,
545 struct nl_msg **result)
548 struct ifaddrmsg am = {
549 .ifa_family = tmpl->a_family,
550 .ifa_index = tmpl->a_ifindex,
551 .ifa_prefixlen = tmpl->a_prefixlen,
554 if (tmpl->ce_mask & ADDR_ATTR_SCOPE)
555 am.ifa_scope = tmpl->a_scope;
558 if (tmpl->a_family == AF_INET &&
559 tmpl->ce_mask & ADDR_ATTR_LOCAL &&
561 am.ifa_scope = RT_SCOPE_HOST;
563 am.ifa_scope = RT_SCOPE_UNIVERSE;
570 if (
nlmsg_append(msg, &am,
sizeof(am), NLMSG_ALIGNTO) < 0)
571 goto nla_put_failure;
573 if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
576 if (tmpl->ce_mask & ADDR_ATTR_PEER)
578 else if (tmpl->ce_mask & ADDR_ATTR_LOCAL)
581 if (tmpl->ce_mask & ADDR_ATTR_LABEL)
584 if (tmpl->ce_mask & ADDR_ATTR_BROADCAST)
587 if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) {
588 struct ifa_cacheinfo ca = {
589 .ifa_valid = tmpl->a_cacheinfo.aci_valid,
590 .ifa_prefered = tmpl->a_cacheinfo.aci_prefered,
593 NLA_PUT(msg, IFA_CACHEINFO,
sizeof(ca), &ca);
633 struct nl_msg **result)
635 uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY |
636 ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL;
638 if ((addr->ce_mask & required) != required)
639 return -NLE_MISSING_ATTR;
641 return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags, result);
671 return wait_for_ack(sk);
706 struct nl_msg **result)
708 uint32_t required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY;
710 if ((addr->ce_mask & required) != required)
711 return -NLE_MISSING_ATTR;
713 return build_addr_msg(addr, RTM_DELADDR, flags, result);
743 return wait_for_ack(sk);
753 int rtnl_addr_set_label(
struct rtnl_addr *addr,
const char *label)
755 if (strlen(label) >
sizeof(addr->a_label) - 1)
758 strcpy(addr->a_label, label);
759 addr->ce_mask |= ADDR_ATTR_LABEL;
764 char *rtnl_addr_get_label(
struct rtnl_addr *addr)
766 if (addr->ce_mask & ADDR_ATTR_LABEL)
767 return addr->a_label;
772 void rtnl_addr_set_ifindex(
struct rtnl_addr *addr,
int ifindex)
774 addr->a_ifindex = ifindex;
775 addr->ce_mask |= ADDR_ATTR_IFINDEX;
778 int rtnl_addr_get_ifindex(
struct rtnl_addr *addr)
780 return addr->a_ifindex;
783 void rtnl_addr_set_link(
struct rtnl_addr *addr,
struct rtnl_link *link)
792 addr->a_ifindex = link->l_index;
793 addr->ce_mask |= ADDR_ATTR_IFINDEX;
796 struct rtnl_link *rtnl_addr_get_link(
struct rtnl_addr *addr)
806 void rtnl_addr_set_family(
struct rtnl_addr *addr,
int family)
808 addr->a_family = family;
809 addr->ce_mask |= ADDR_ATTR_FAMILY;
812 int rtnl_addr_get_family(
struct rtnl_addr *addr)
814 return addr->a_family;
817 void rtnl_addr_set_prefixlen(
struct rtnl_addr *addr,
int prefix)
819 addr->a_prefixlen = prefix;
820 addr->ce_mask |= ADDR_ATTR_PREFIXLEN;
823 int rtnl_addr_get_prefixlen(
struct rtnl_addr *addr)
825 return addr->a_prefixlen;
828 void rtnl_addr_set_scope(
struct rtnl_addr *addr,
int scope)
830 addr->a_scope = scope;
831 addr->ce_mask |= ADDR_ATTR_SCOPE;
834 int rtnl_addr_get_scope(
struct rtnl_addr *addr)
836 return addr->a_scope;
839 void rtnl_addr_set_flags(
struct rtnl_addr *addr,
unsigned int flags)
841 addr->a_flag_mask |= flags;
842 addr->a_flags |= flags;
843 addr->ce_mask |= ADDR_ATTR_FLAGS;
846 void rtnl_addr_unset_flags(
struct rtnl_addr *addr,
unsigned int flags)
848 addr->a_flag_mask |= flags;
849 addr->a_flags &= ~flags;
850 addr->ce_mask |= ADDR_ATTR_FLAGS;
853 unsigned int rtnl_addr_get_flags(
struct rtnl_addr *addr)
855 return addr->a_flags;
858 static inline int __assign_addr(
struct rtnl_addr *addr,
struct nl_addr **pos,
859 struct nl_addr *
new,
int flag)
862 if (addr->ce_mask & ADDR_ATTR_FAMILY) {
863 if (new->a_family != addr->a_family)
864 return -NLE_AF_MISMATCH;
866 addr->a_family =
new->a_family;
871 *pos = nl_addr_get(
new);
872 addr->ce_mask |= (flag | ADDR_ATTR_FAMILY);
878 addr->ce_mask &= ~flag;
884 int rtnl_addr_set_local(
struct rtnl_addr *addr,
struct nl_addr *local)
889 if ((addr->ce_mask & ADDR_ATTR_PEER) && local &&
893 err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL);
898 if (!(addr->ce_mask & ADDR_ATTR_PEER))
904 struct nl_addr *rtnl_addr_get_local(
struct rtnl_addr *addr)
906 return addr->a_local;
909 int rtnl_addr_set_peer(
struct rtnl_addr *addr,
struct nl_addr *peer)
913 if (peer && peer->a_family != AF_INET)
914 return -NLE_AF_NOSUPPORT;
916 err = __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER);
925 struct nl_addr *rtnl_addr_get_peer(
struct rtnl_addr *addr)
930 int rtnl_addr_set_broadcast(
struct rtnl_addr *addr,
struct nl_addr *bcast)
932 if (bcast && bcast->a_family != AF_INET)
933 return -NLE_AF_NOSUPPORT;
935 return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST);
938 struct nl_addr *rtnl_addr_get_broadcast(
struct rtnl_addr *addr)
940 return addr->a_bcast;
943 int rtnl_addr_set_multicast(
struct rtnl_addr *addr,
struct nl_addr *multicast)
945 if (multicast && multicast->a_family != AF_INET6)
946 return -NLE_AF_NOSUPPORT;
948 return __assign_addr(addr, &addr->a_multicast, multicast,
949 ADDR_ATTR_MULTICAST);
952 struct nl_addr *rtnl_addr_get_multicast(
struct rtnl_addr *addr)
954 return addr->a_multicast;
957 int rtnl_addr_set_anycast(
struct rtnl_addr *addr,
struct nl_addr *anycast)
959 if (anycast && anycast->a_family != AF_INET6)
960 return -NLE_AF_NOSUPPORT;
962 return __assign_addr(addr, &addr->a_anycast, anycast,
966 struct nl_addr *rtnl_addr_get_anycast(
struct rtnl_addr *addr)
968 return addr->a_anycast;
971 uint32_t rtnl_addr_get_valid_lifetime(
struct rtnl_addr *addr)
973 if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
974 return addr->a_cacheinfo.aci_valid;
979 void rtnl_addr_set_valid_lifetime(
struct rtnl_addr *addr, uint32_t lifetime)
981 addr->a_cacheinfo.aci_valid = lifetime;
982 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
985 uint32_t rtnl_addr_get_preferred_lifetime(
struct rtnl_addr *addr)
987 if (addr->ce_mask & ADDR_ATTR_CACHEINFO)
988 return addr->a_cacheinfo.aci_prefered;
993 void rtnl_addr_set_preferred_lifetime(
struct rtnl_addr *addr, uint32_t lifetime)
995 addr->a_cacheinfo.aci_prefered = lifetime;
996 addr->ce_mask |= ADDR_ATTR_CACHEINFO;
999 uint32_t rtnl_addr_get_create_time(
struct rtnl_addr *addr)
1001 return addr->a_cacheinfo.aci_cstamp;
1004 uint32_t rtnl_addr_get_last_update_time(
struct rtnl_addr *addr)
1006 return addr->a_cacheinfo.aci_tstamp;
1016 static const struct trans_tbl addr_flags[] = {
1017 __ADD(IFA_F_SECONDARY, secondary)
1018 __ADD(IFA_F_NODAD, nodad)
1019 __ADD(IFA_F_OPTIMISTIC, optimistic)
1020 __ADD(IFA_F_HOMEADDRESS, homeaddress)
1021 __ADD(IFA_F_DEPRECATED, deprecated)
1022 __ADD(IFA_F_TENTATIVE, tentative)
1023 __ADD(IFA_F_PERMANENT, permanent)
1026 char *rtnl_addr_flags2str(
int flags,
char *buf,
size_t size)
1028 return __flags2str(flags, buf, size, addr_flags,
1029 ARRAY_SIZE(addr_flags));
1032 int rtnl_addr_str2flags(
const char *name)
1034 return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags));
1039 static struct nl_object_ops addr_obj_ops = {
1040 .oo_name =
"route/addr",
1041 .oo_size =
sizeof(
struct rtnl_addr),
1042 .oo_constructor = addr_constructor,
1043 .oo_free_data = addr_free_data,
1044 .oo_clone = addr_clone,
1050 .oo_compare = addr_compare,
1051 .oo_attrs2str = addr_attrs2str,
1052 .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX |
1053 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN),
1056 static struct nl_af_group addr_groups[] = {
1057 { AF_INET, RTNLGRP_IPV4_IFADDR },
1058 { AF_INET6, RTNLGRP_IPV6_IFADDR },
1059 { END_OF_GROUP_LIST },
1062 static struct nl_cache_ops rtnl_addr_ops = {
1063 .co_name =
"route/addr",
1064 .co_hdrsize =
sizeof(
struct ifaddrmsg),
1066 { RTM_NEWADDR, NL_ACT_NEW,
"new" },
1067 { RTM_DELADDR, NL_ACT_DEL,
"del" },
1068 { RTM_GETADDR, NL_ACT_GET,
"get" },
1069 END_OF_MSGTYPES_LIST,
1071 .co_protocol = NETLINK_ROUTE,
1072 .co_groups = addr_groups,
1073 .co_request_update = addr_request_update,
1074 .co_msg_parser = addr_msg_parser,
1075 .co_obj_ops = &addr_obj_ops,
1078 static void __init addr_init(
void)
1083 static void __exit addr_exit(
void)