1 /* 2 * lib/route/addr.c Addresses 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) 2003-2008 Thomas Graf <tgraf (at) suug.ch> 10 * Copyright (c) 2003-2006 Baruch Even <baruch (at) ev-en.org>, 11 * Mediatrix Telecom, inc. <ericb (at) mediatrix.com> 12 */ 13 14 /** 15 * @ingroup rtnl 16 * @defgroup rtaddr Addresses 17 * @brief 18 * 19 * @note The maximum size of an address label is IFNAMSIZ. 20 * 21 * @note The address may not contain a prefix length if the peer address 22 * has been specified already. 23 * 24 * @par 1) Address Addition 25 * @code 26 * // Allocate an empty address object to be filled out with the attributes 27 * // of the new address. 28 * struct rtnl_addr *addr = rtnl_addr_alloc(); 29 * 30 * // Fill out the mandatory attributes of the new address. Setting the 31 * // local address will automatically set the address family and the 32 * // prefix length to the correct values. 33 * rtnl_addr_set_ifindex(addr, ifindex); 34 * rtnl_addr_set_local(addr, local_addr); 35 * 36 * // The label of the address can be specified, currently only supported 37 * // by IPv4 and DECnet. 38 * rtnl_addr_set_label(addr, "mylabel"); 39 * 40 * // The peer address can be specified if necessary, in either case a peer 41 * // address will be sent to the kernel in order to fullfil the interface 42 * // requirements. If none is set, it will equal the local address. 43 * // Note: Real peer addresses are only supported by IPv4 for now. 44 * rtnl_addr_set_peer(addr, peer_addr); 45 * 46 * // In case you want to have the address have a scope other than global 47 * // it may be overwritten using rtnl_addr_set_scope(). The scope currently 48 * // cannot be set for IPv6 addresses. 49 * rtnl_addr_set_scope(addr, rtnl_str2scope("site")); 50 * 51 * // Broadcast address may be specified using the relevant 52 * // functions, the address family will be verified if one of the other 53 * // addresses has been set already. Currently only works for IPv4. 54 * rtnl_addr_set_broadcast(addr, broadcast_addr); 55 * 56 * // Build the netlink message and send it to the kernel, the operation will 57 * // block until the operation has been completed. Alternatively the required 58 * // netlink message can be built using rtnl_addr_build_add_request() to be 59 * // sent out using nl_send_auto_complete(). 60 * rtnl_addr_add(sk, addr, 0); 61 * 62 * // Free the memory 63 * rtnl_addr_put(addr); 64 * @endcode 65 * 66 * @par 2) Address Deletion 67 * @code 68 * // Allocate an empty address object to be filled out with the attributes 69 * // matching the address to be deleted. Alternatively a fully equipped 70 * // address object out of a cache can be used instead. 71 * struct rtnl_addr *addr = rtnl_addr_alloc(); 72 * 73 * // The only mandatory parameter besides the address family is the interface 74 * // index the address is on, i.e. leaving out all other parameters will 75 * // result in all addresses of the specified address family interface tuple 76 * // to be deleted. 77 * rtnl_addr_set_ifindex(addr, ifindex); 78 * 79 * // Specyfing the address family manually is only required if neither the 80 * // local nor peer address have been specified. 81 * rtnl_addr_set_family(addr, AF_INET); 82 * 83 * // Specyfing the local address is optional but the best choice to delete 84 * // specific addresses. 85 * rtnl_addr_set_local(addr, local_addr); 86 * 87 * // The label of the address can be specified, currently only supported 88 * // by IPv4 and DECnet. 89 * rtnl_addr_set_label(addr, "mylabel"); 90 * 91 * // The peer address can be specified if necessary, in either case a peer 92 * // address will be sent to the kernel in order to fullfil the interface 93 * // requirements. If none is set, it will equal the local address. 94 * // Note: Real peer addresses are only supported by IPv4 for now. 95 * rtnl_addr_set_peer(addr, peer_addr); 96 * 97 * // Build the netlink message and send it to the kernel, the operation will 98 * // block until the operation has been completed. Alternatively the required 99 * // netlink message can be built using rtnl_addr_build_delete_request() 100 * // to be sent out using nl_send_auto_complete(). 101 * rtnl_addr_delete(sk, addr, 0); 102 * 103 * // Free the memory 104 * rtnl_addr_put(addr); 105 * @endcode 106 * @{ 107 */ 108 109 #include <netlink-local.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> 116 117 /** @cond SKIP */ 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 130 131 static struct nl_cache_ops rtnl_addr_ops; 132 static struct nl_object_ops addr_obj_ops; 133 /** @endcond */ 134 135 static void addr_constructor(struct nl_object *obj) 136 { 137 struct rtnl_addr *addr = nl_object_priv(obj); 138 139 addr->a_scope = RT_SCOPE_NOWHERE; 140 } 141 142 static void addr_free_data(struct nl_object *obj) 143 { 144 struct rtnl_addr *addr = nl_object_priv(obj); 145 146 if (!addr) 147 return; 148 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); 154 } 155 156 static int addr_clone(struct nl_object *_dst, struct nl_object *_src) 157 { 158 struct rtnl_addr *dst = nl_object_priv(_dst); 159 struct rtnl_addr *src = nl_object_priv(_src); 160 161 if (src->a_peer) 162 if (!(dst->a_peer = nl_addr_clone(src->a_peer))) 163 return -NLE_NOMEM; 164 165 if (src->a_local) 166 if (!(dst->a_local = nl_addr_clone(src->a_local))) 167 return -NLE_NOMEM; 168 169 if (src->a_bcast) 170 if (!(dst->a_bcast = nl_addr_clone(src->a_bcast))) 171 return -NLE_NOMEM; 172 173 if (src->a_multicast) 174 if (!(dst->a_multicast = nl_addr_clone(src->a_multicast))) 175 return -NLE_NOMEM; 176 177 if (src->a_anycast) 178 if (!(dst->a_anycast = nl_addr_clone(src->a_anycast))) 179 return -NLE_NOMEM; 180 181 return 0; 182 } 183 184 static struct nla_policy addr_policy[IFA_MAX+1] = { 185 [IFA_LABEL] = { .type = NLA_STRING, 186 .maxlen = IFNAMSIZ }, 187 [IFA_CACHEINFO] = { .minlen = sizeof(struct ifa_cacheinfo) }, 188 }; 189 190 static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 191 struct nlmsghdr *nlh, struct nl_parser_param *pp) 192 { 193 struct rtnl_addr *addr; 194 struct ifaddrmsg *ifa; 195 struct nlattr *tb[IFA_MAX+1]; 196 int err, peer_prefix = 0, family; 197 198 addr = rtnl_addr_alloc(); 199 if (!addr) 200 return -NLE_NOMEM; 201 202 addr->ce_msgtype = nlh->nlmsg_type; 203 204 err = nlmsg_parse(nlh, sizeof(*ifa), tb, IFA_MAX, addr_policy); 205 if (err < 0) 206 goto errout; 207 208 ifa = nlmsg_data(nlh); 209 addr->a_family = family = ifa->ifa_family; 210 addr->a_prefixlen = ifa->ifa_prefixlen; 211 addr->a_flags = ifa->ifa_flags; 212 addr->a_scope = ifa->ifa_scope; 213 addr->a_ifindex = ifa->ifa_index; 214 215 addr->ce_mask = (ADDR_ATTR_FAMILY | ADDR_ATTR_PREFIXLEN | 216 ADDR_ATTR_FLAGS | ADDR_ATTR_SCOPE | ADDR_ATTR_IFINDEX); 217 218 if (tb[IFA_LABEL]) { 219 nla_strlcpy(addr->a_label, tb[IFA_LABEL], IFNAMSIZ); 220 addr->ce_mask |= ADDR_ATTR_LABEL; 221 } 222 223 if (tb[IFA_CACHEINFO]) { 224 struct ifa_cacheinfo *ca; 225 226 ca = nla_data(tb[IFA_CACHEINFO]); 227 addr->a_cacheinfo.aci_prefered = ca->ifa_prefered; 228 addr->a_cacheinfo.aci_valid = ca->ifa_valid; 229 addr->a_cacheinfo.aci_cstamp = ca->cstamp; 230 addr->a_cacheinfo.aci_tstamp = ca->tstamp; 231 addr->ce_mask |= ADDR_ATTR_CACHEINFO; 232 } 233 234 if (tb[IFA_LOCAL]) { 235 addr->a_local = nl_addr_alloc_attr(tb[IFA_LOCAL], family); 236 if (!addr->a_local) 237 goto errout_nomem; 238 addr->ce_mask |= ADDR_ATTR_LOCAL; 239 } 240 241 if (tb[IFA_ADDRESS]) { 242 struct nl_addr *a; 243 244 a = nl_addr_alloc_attr(tb[IFA_ADDRESS], family); 245 if (!a) 246 goto errout_nomem; 247 248 /* IPv6 sends the local address as IFA_ADDRESS with 249 * no IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS 250 * with IFA_ADDRESS being the peer address if they differ */ 251 if (!tb[IFA_LOCAL] || !nl_addr_cmp(a, addr->a_local)) { 252 nl_addr_put(addr->a_local); 253 addr->a_local = a; 254 addr->ce_mask |= ADDR_ATTR_LOCAL; 255 } else { 256 addr->a_peer = a; 257 addr->ce_mask |= ADDR_ATTR_PEER; 258 peer_prefix = 1; 259 } 260 } 261 262 nl_addr_set_prefixlen(peer_prefix ? addr->a_peer : addr->a_local, 263 addr->a_prefixlen); 264 265 if (tb[IFA_BROADCAST]) { 266 addr->a_bcast = nl_addr_alloc_attr(tb[IFA_BROADCAST], family); 267 if (!addr->a_bcast) 268 goto errout_nomem; 269 270 addr->ce_mask |= ADDR_ATTR_BROADCAST; 271 } 272 273 if (tb[IFA_MULTICAST]) { 274 addr->a_multicast = nl_addr_alloc_attr(tb[IFA_MULTICAST], 275 family); 276 if (!addr->a_multicast) 277 goto errout_nomem; 278 279 addr->ce_mask |= ADDR_ATTR_MULTICAST; 280 } 281 282 if (tb[IFA_ANYCAST]) { 283 addr->a_anycast = nl_addr_alloc_attr(tb[IFA_ANYCAST], 284 family); 285 if (!addr->a_anycast) 286 goto errout_nomem; 287 288 addr->ce_mask |= ADDR_ATTR_ANYCAST; 289 } 290 291 err = pp->pp_cb((struct nl_object *) addr, pp); 292 errout: 293 rtnl_addr_put(addr); 294 295 return err; 296 297 errout_nomem: 298 err = -NLE_NOMEM; 299 goto errout; 300 } 301 302 static int addr_request_update(struct nl_cache *cache, struct nl_sock *sk) 303 { 304 return nl_rtgen_request(sk, RTM_GETADDR, AF_UNSPEC, NLM_F_DUMP); 305 } 306 307 static void addr_dump_line(struct nl_object *obj, struct nl_dump_params *p) 308 { 309 struct rtnl_addr *addr = (struct rtnl_addr *) obj; 310 struct nl_cache *link_cache; 311 char buf[128]; 312 313 link_cache = nl_cache_mngt_require("route/link"); 314 315 if (addr->ce_mask & ADDR_ATTR_LOCAL) 316 nl_dump_line(p, "%s", 317 nl_addr2str(addr->a_local, buf, sizeof(buf))); 318 else 319 nl_dump_line(p, "none"); 320 321 if (addr->ce_mask & ADDR_ATTR_PEER) 322 nl_dump(p, " peer %s", 323 nl_addr2str(addr->a_peer, buf, sizeof(buf))); 324 325 nl_dump(p, " %s ", nl_af2str(addr->a_family, buf, sizeof(buf))); 326 327 if (link_cache) 328 nl_dump(p, "dev %s ", 329 rtnl_link_i2name(link_cache, addr->a_ifindex, 330 buf, sizeof(buf))); 331 else 332 nl_dump(p, "dev %d ", addr->a_ifindex); 333 334 nl_dump(p, "scope %s", 335 rtnl_scope2str(addr->a_scope, buf, sizeof(buf))); 336 337 rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf)); 338 if (buf[0]) 339 nl_dump(p, " <%s>", buf); 340 341 nl_dump(p, "\n"); 342 } 343 344 static void addr_dump_details(struct nl_object *obj, struct nl_dump_params *p) 345 { 346 struct rtnl_addr *addr = (struct rtnl_addr *) obj; 347 char buf[128]; 348 349 addr_dump_line(obj, p); 350 351 if (addr->ce_mask & (ADDR_ATTR_LABEL | ADDR_ATTR_BROADCAST | 352 ADDR_ATTR_MULTICAST)) { 353 nl_dump_line(p, " "); 354 355 if (addr->ce_mask & ADDR_ATTR_LABEL) 356 nl_dump(p, " label %s", addr->a_label); 357 358 if (addr->ce_mask & ADDR_ATTR_BROADCAST) 359 nl_dump(p, " broadcast %s", 360 nl_addr2str(addr->a_bcast, buf, sizeof(buf))); 361 362 if (addr->ce_mask & ADDR_ATTR_MULTICAST) 363 nl_dump(p, " multicast %s", 364 nl_addr2str(addr->a_multicast, buf, 365 sizeof(buf))); 366 367 if (addr->ce_mask & ADDR_ATTR_ANYCAST) 368 nl_dump(p, " anycast %s", 369 nl_addr2str(addr->a_anycast, buf, 370 sizeof(buf))); 371 372 nl_dump(p, "\n"); 373 } 374 375 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) { 376 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo; 377 378 nl_dump_line(p, " valid-lifetime %s", 379 ci->aci_valid == 0xFFFFFFFFU ? "forever" : 380 nl_msec2str(ci->aci_valid * 1000, 381 buf, sizeof(buf))); 382 383 nl_dump(p, " preferred-lifetime %s\n", 384 ci->aci_prefered == 0xFFFFFFFFU ? "forever" : 385 nl_msec2str(ci->aci_prefered * 1000, 386 buf, sizeof(buf))); 387 388 nl_dump_line(p, " created boot-time+%s ", 389 nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10, 390 buf, sizeof(buf))); 391 392 nl_dump(p, "last-updated boot-time+%s\n", 393 nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10, 394 buf, sizeof(buf))); 395 } 396 } 397 398 static void addr_dump_stats(struct nl_object *obj, struct nl_dump_params *p) 399 { 400 addr_dump_details(obj, p); 401 } 402 403 static void addr_dump_env(struct nl_object *obj, struct nl_dump_params *p) 404 { 405 struct rtnl_addr *addr = (struct rtnl_addr *) obj; 406 struct nl_cache *link_cache; 407 char buf[128]; 408 409 nl_dump_line(p, "ADDR_FAMILY=%s\n", 410 nl_af2str(addr->a_family, buf, sizeof(buf))); 411 412 if (addr->ce_mask & ADDR_ATTR_LOCAL) 413 nl_dump_line(p, "ADDR_LOCAL=%s\n", 414 nl_addr2str(addr->a_local, buf, sizeof(buf))); 415 416 if (addr->ce_mask & ADDR_ATTR_PEER) 417 nl_dump_line(p, "ADDR_PEER=%s\n", 418 nl_addr2str(addr->a_peer, buf, sizeof(buf))); 419 420 if (addr->ce_mask & ADDR_ATTR_BROADCAST) 421 nl_dump_line(p, "ADDR_BROADCAST=%s\n", 422 nl_addr2str(addr->a_bcast, buf, sizeof(buf))); 423 424 if (addr->ce_mask & ADDR_ATTR_ANYCAST) 425 nl_dump_line(p, "ADDR_ANYCAST=%s\n", 426 nl_addr2str(addr->a_anycast, buf, sizeof(buf))); 427 428 if (addr->ce_mask & ADDR_ATTR_MULTICAST) 429 nl_dump_line(p, "ADDR_MULTICAST=%s\n", 430 nl_addr2str(addr->a_multicast, buf, 431 sizeof(buf))); 432 433 if (addr->ce_mask & ADDR_ATTR_PREFIXLEN) 434 nl_dump_line(p, "ADDR_PREFIXLEN=%u\n", 435 addr->a_prefixlen); 436 link_cache = nl_cache_mngt_require("route/link"); 437 438 nl_dump_line(p, "ADDR_IFINDEX=%u\n", addr->a_ifindex); 439 if (link_cache) 440 nl_dump_line(p, "ADDR_IFNAME=%s\n", 441 rtnl_link_i2name(link_cache, addr->a_ifindex, 442 buf, sizeof(buf))); 443 444 if (addr->ce_mask & ADDR_ATTR_SCOPE) 445 nl_dump_line(p, "ADDR_SCOPE=%s\n", 446 rtnl_scope2str(addr->a_scope, buf, sizeof(buf))); 447 448 if (addr->ce_mask & ADDR_ATTR_LABEL) 449 nl_dump_line(p, "ADDR_LABEL=%s\n", addr->a_label); 450 451 rtnl_addr_flags2str(addr->a_flags, buf, sizeof(buf)); 452 if (buf[0]) 453 nl_dump_line(p, "ADDR_FLAGS=%s\n", buf); 454 455 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) { 456 struct rtnl_addr_cacheinfo *ci = &addr->a_cacheinfo; 457 458 nl_dump_line(p, "ADDR_CACHEINFO_VALID=%s\n", 459 ci->aci_valid == 0xFFFFFFFFU ? "forever" : 460 nl_msec2str(ci->aci_valid * 1000, 461 buf, sizeof(buf))); 462 463 nl_dump_line(p, "ADDR_CACHEINFO_PREFERED=%s\n", 464 ci->aci_prefered == 0xFFFFFFFFU ? "forever" : 465 nl_msec2str(ci->aci_prefered * 1000, 466 buf, sizeof(buf))); 467 468 nl_dump_line(p, "ADDR_CACHEINFO_CREATED=%s\n", 469 nl_msec2str(addr->a_cacheinfo.aci_cstamp * 10, 470 buf, sizeof(buf))); 471 472 nl_dump_line(p, "ADDR_CACHEINFO_LASTUPDATE=%s\n", 473 nl_msec2str(addr->a_cacheinfo.aci_tstamp * 10, 474 buf, sizeof(buf))); 475 } 476 } 477 478 static int addr_compare(struct nl_object *_a, struct nl_object *_b, 479 uint32_t attrs, int flags) 480 { 481 struct rtnl_addr *a = (struct rtnl_addr *) _a; 482 struct rtnl_addr *b = (struct rtnl_addr *) _b; 483 int diff = 0; 484 485 #define ADDR_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ADDR_ATTR_##ATTR, a, b, EXPR) 486 487 diff |= ADDR_DIFF(IFINDEX, a->a_ifindex != b->a_ifindex); 488 diff |= ADDR_DIFF(FAMILY, a->a_family != b->a_family); 489 diff |= ADDR_DIFF(SCOPE, a->a_scope != b->a_scope); 490 diff |= ADDR_DIFF(LABEL, strcmp(a->a_label, b->a_label)); 491 diff |= ADDR_DIFF(PEER, nl_addr_cmp(a->a_peer, b->a_peer)); 492 diff |= ADDR_DIFF(LOCAL, nl_addr_cmp(a->a_local, b->a_local)); 493 diff |= ADDR_DIFF(MULTICAST, nl_addr_cmp(a->a_multicast, 494 b->a_multicast)); 495 diff |= ADDR_DIFF(BROADCAST, nl_addr_cmp(a->a_bcast, b->a_bcast)); 496 diff |= ADDR_DIFF(ANYCAST, nl_addr_cmp(a->a_anycast, b->a_anycast)); 497 498 if (flags & LOOSE_COMPARISON) 499 diff |= ADDR_DIFF(FLAGS, 500 (a->a_flags ^ b->a_flags) & b->a_flag_mask); 501 else 502 diff |= ADDR_DIFF(FLAGS, a->a_flags != b->a_flags); 503 504 #undef ADDR_DIFF 505 506 return diff; 507 } 508 509 static struct trans_tbl addr_attrs[] = { 510 __ADD(ADDR_ATTR_FAMILY, family) 511 __ADD(ADDR_ATTR_PREFIXLEN, prefixlen) 512 __ADD(ADDR_ATTR_FLAGS, flags) 513 __ADD(ADDR_ATTR_SCOPE, scope) 514 __ADD(ADDR_ATTR_IFINDEX, ifindex) 515 __ADD(ADDR_ATTR_LABEL, label) 516 __ADD(ADDR_ATTR_CACHEINFO, cacheinfo) 517 __ADD(ADDR_ATTR_PEER, peer) 518 __ADD(ADDR_ATTR_LOCAL, local) 519 __ADD(ADDR_ATTR_BROADCAST, broadcast) 520 __ADD(ADDR_ATTR_MULTICAST, multicast) 521 }; 522 523 static char *addr_attrs2str(int attrs, char *buf, size_t len) 524 { 525 return __flags2str(attrs, buf, len, addr_attrs, 526 ARRAY_SIZE(addr_attrs)); 527 } 528 529 /** 530 * @name Allocation/Freeing 531 * @{ 532 */ 533 534 struct rtnl_addr *rtnl_addr_alloc(void) 535 { 536 return (struct rtnl_addr *) nl_object_alloc(&addr_obj_ops); 537 } 538 539 void rtnl_addr_put(struct rtnl_addr *addr) 540 { 541 nl_object_put((struct nl_object *) addr); 542 } 543 544 /** @} */ 545 546 /** 547 * @name Cache Management 548 * @{ 549 */ 550 551 int rtnl_addr_alloc_cache(struct nl_sock *sk, struct nl_cache **result) 552 { 553 return nl_cache_alloc_and_fill(&rtnl_addr_ops, sk, result); 554 } 555 556 /** @} */ 557 558 static int build_addr_msg(struct rtnl_addr *tmpl, int cmd, int flags, 559 struct nl_msg **result) 560 { 561 struct nl_msg *msg; 562 struct ifaddrmsg am = { 563 .ifa_family = tmpl->a_family, 564 .ifa_index = tmpl->a_ifindex, 565 .ifa_prefixlen = tmpl->a_prefixlen, 566 }; 567 568 if (tmpl->ce_mask & ADDR_ATTR_SCOPE) 569 am.ifa_scope = tmpl->a_scope; 570 else { 571 /* compatibility hack */ 572 if (tmpl->a_family == AF_INET && 573 tmpl->ce_mask & ADDR_ATTR_LOCAL && 574 *((char *) nl_addr_get_binary_addr(tmpl->a_local)) == 127) 575 am.ifa_scope = RT_SCOPE_HOST; 576 else 577 am.ifa_scope = RT_SCOPE_UNIVERSE; 578 } 579 580 msg = nlmsg_alloc_simple(cmd, flags); 581 if (!msg) 582 return -NLE_NOMEM; 583 584 if (nlmsg_append(msg, &am, sizeof(am), NLMSG_ALIGNTO) < 0) 585 goto nla_put_failure; 586 587 if (tmpl->ce_mask & ADDR_ATTR_LOCAL) 588 NLA_PUT_ADDR(msg, IFA_LOCAL, tmpl->a_local); 589 590 if (tmpl->ce_mask & ADDR_ATTR_PEER) 591 NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_peer); 592 else if (tmpl->ce_mask & ADDR_ATTR_LOCAL) 593 NLA_PUT_ADDR(msg, IFA_ADDRESS, tmpl->a_local); 594 595 if (tmpl->ce_mask & ADDR_ATTR_LABEL) 596 NLA_PUT_STRING(msg, IFA_LABEL, tmpl->a_label); 597 598 if (tmpl->ce_mask & ADDR_ATTR_BROADCAST) 599 NLA_PUT_ADDR(msg, IFA_BROADCAST, tmpl->a_bcast); 600 601 if (tmpl->ce_mask & ADDR_ATTR_CACHEINFO) { 602 struct ifa_cacheinfo ca = { 603 .ifa_valid = tmpl->a_cacheinfo.aci_valid, 604 .ifa_prefered = tmpl->a_cacheinfo.aci_prefered, 605 }; 606 607 NLA_PUT(msg, IFA_CACHEINFO, sizeof(ca), &ca); 608 } 609 610 611 *result = msg; 612 return 0; 613 614 nla_put_failure: 615 nlmsg_free(msg); 616 return -NLE_MSGSIZE; 617 } 618 619 /** 620 * @name Addition 621 * @{ 622 */ 623 624 /** 625 * Build netlink request message to request addition of new address 626 * @arg addr Address object representing the new address. 627 * @arg flags Additional netlink message flags. 628 * @arg result Pointer to store resulting message. 629 * 630 * Builds a new netlink message requesting the addition of a new 631 * address. The netlink message header isn't fully equipped with 632 * all relevant fields and must thus be sent out via nl_send_auto_complete() 633 * or supplemented as needed. 634 * 635 * Minimal required attributes: 636 * - interface index (rtnl_addr_set_ifindex()) 637 * - local address (rtnl_addr_set_local()) 638 * 639 * The scope will default to universe except for loopback addresses in 640 * which case a host scope is used if not specified otherwise. 641 * 642 * @note Free the memory after usage using nlmsg_free(). 643 * 644 * @return 0 on success or a negative error code. 645 */ 646 int rtnl_addr_build_add_request(struct rtnl_addr *addr, int flags, 647 struct nl_msg **result) 648 { 649 int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY | 650 ADDR_ATTR_PREFIXLEN | ADDR_ATTR_LOCAL; 651 652 if ((addr->ce_mask & required) != required) 653 return -NLE_MISSING_ATTR; 654 655 return build_addr_msg(addr, RTM_NEWADDR, NLM_F_CREATE | flags, result); 656 } 657 658 /** 659 * Request addition of new address 660 * @arg sk Netlink socket. 661 * @arg addr Address object representing the new address. 662 * @arg flags Additional netlink message flags. 663 * 664 * Builds a netlink message by calling rtnl_addr_build_add_request(), 665 * sends the request to the kernel and waits for the next ACK to be 666 * received and thus blocks until the request has been fullfilled. 667 * 668 * @see rtnl_addr_build_add_request() 669 * 670 * @return 0 on sucess or a negative error if an error occured. 671 */ 672 int rtnl_addr_add(struct nl_sock *sk, struct rtnl_addr *addr, int flags) 673 { 674 struct nl_msg *msg; 675 int err; 676 677 if ((err = rtnl_addr_build_add_request(addr, flags, &msg)) < 0) 678 return err; 679 680 err = nl_send_auto_complete(sk, msg); 681 nlmsg_free(msg); 682 if (err < 0) 683 return err; 684 685 return wait_for_ack(sk); 686 } 687 688 /** @} */ 689 690 /** 691 * @name Deletion 692 * @{ 693 */ 694 695 /** 696 * Build a netlink request message to request deletion of an address 697 * @arg addr Address object to be deleteted. 698 * @arg flags Additional netlink message flags. 699 * @arg result Pointer to store resulting message. 700 * 701 * Builds a new netlink message requesting a deletion of an address. 702 * The netlink message header isn't fully equipped with all relevant 703 * fields and must thus be sent out via nl_send_auto_complete() 704 * or supplemented as needed. 705 * 706 * Minimal required attributes: 707 * - interface index (rtnl_addr_set_ifindex()) 708 * - address family (rtnl_addr_set_family()) 709 * 710 * Optional attributes: 711 * - local address (rtnl_addr_set_local()) 712 * - label (rtnl_addr_set_label(), IPv4/DECnet only) 713 * - peer address (rtnl_addr_set_peer(), IPv4 only) 714 * 715 * @note Free the memory after usage using nlmsg_free(). 716 * 717 * @return 0 on success or a negative error code. 718 */ 719 int rtnl_addr_build_delete_request(struct rtnl_addr *addr, int flags, 720 struct nl_msg **result) 721 { 722 int required = ADDR_ATTR_IFINDEX | ADDR_ATTR_FAMILY; 723 724 if ((addr->ce_mask & required) != required) 725 return -NLE_MISSING_ATTR; 726 727 return build_addr_msg(addr, RTM_DELADDR, flags, result); 728 } 729 730 /** 731 * Request deletion of an address 732 * @arg sk Netlink socket. 733 * @arg addr Address object to be deleted. 734 * @arg flags Additional netlink message flags. 735 * 736 * Builds a netlink message by calling rtnl_addr_build_delete_request(), 737 * sends the request to the kernel and waits for the next ACK to be 738 * received and thus blocks until the request has been fullfilled. 739 * 740 * @see rtnl_addr_build_delete_request(); 741 * 742 * @return 0 on sucess or a negative error if an error occured. 743 */ 744 int rtnl_addr_delete(struct nl_sock *sk, struct rtnl_addr *addr, int flags) 745 { 746 struct nl_msg *msg; 747 int err; 748 749 if ((err = rtnl_addr_build_delete_request(addr, flags, &msg)) < 0) 750 return err; 751 752 err = nl_send_auto_complete(sk, msg); 753 nlmsg_free(msg); 754 if (err < 0) 755 return err; 756 757 return wait_for_ack(sk); 758 } 759 760 /** @} */ 761 762 /** 763 * @name Attributes 764 * @{ 765 */ 766 767 int rtnl_addr_set_label(struct rtnl_addr *addr, const char *label) 768 { 769 if (strlen(label) > sizeof(addr->a_label) - 1) 770 return -NLE_RANGE; 771 772 strcpy(addr->a_label, label); 773 addr->ce_mask |= ADDR_ATTR_LABEL; 774 775 return 0; 776 } 777 778 char *rtnl_addr_get_label(struct rtnl_addr *addr) 779 { 780 if (addr->ce_mask & ADDR_ATTR_LABEL) 781 return addr->a_label; 782 else 783 return NULL; 784 } 785 786 void rtnl_addr_set_ifindex(struct rtnl_addr *addr, int ifindex) 787 { 788 addr->a_ifindex = ifindex; 789 addr->ce_mask |= ADDR_ATTR_IFINDEX; 790 } 791 792 int rtnl_addr_get_ifindex(struct rtnl_addr *addr) 793 { 794 return addr->a_ifindex; 795 } 796 797 void rtnl_addr_set_family(struct rtnl_addr *addr, int family) 798 { 799 addr->a_family = family; 800 addr->ce_mask |= ADDR_ATTR_FAMILY; 801 } 802 803 int rtnl_addr_get_family(struct rtnl_addr *addr) 804 { 805 return addr->a_family; 806 } 807 808 void rtnl_addr_set_prefixlen(struct rtnl_addr *addr, int prefix) 809 { 810 addr->a_prefixlen = prefix; 811 addr->ce_mask |= ADDR_ATTR_PREFIXLEN; 812 } 813 814 int rtnl_addr_get_prefixlen(struct rtnl_addr *addr) 815 { 816 return addr->a_prefixlen; 817 } 818 819 void rtnl_addr_set_scope(struct rtnl_addr *addr, int scope) 820 { 821 addr->a_scope = scope; 822 addr->ce_mask |= ADDR_ATTR_SCOPE; 823 } 824 825 int rtnl_addr_get_scope(struct rtnl_addr *addr) 826 { 827 return addr->a_scope; 828 } 829 830 void rtnl_addr_set_flags(struct rtnl_addr *addr, unsigned int flags) 831 { 832 addr->a_flag_mask |= flags; 833 addr->a_flags |= flags; 834 addr->ce_mask |= ADDR_ATTR_FLAGS; 835 } 836 837 void rtnl_addr_unset_flags(struct rtnl_addr *addr, unsigned int flags) 838 { 839 addr->a_flag_mask |= flags; 840 addr->a_flags &= ~flags; 841 addr->ce_mask |= ADDR_ATTR_FLAGS; 842 } 843 844 unsigned int rtnl_addr_get_flags(struct rtnl_addr *addr) 845 { 846 return addr->a_flags; 847 } 848 849 static inline int __assign_addr(struct rtnl_addr *addr, struct nl_addr **pos, 850 struct nl_addr *new, int flag) 851 { 852 if (addr->ce_mask & ADDR_ATTR_FAMILY) { 853 if (new->a_family != addr->a_family) 854 return -NLE_AF_MISMATCH; 855 } else 856 addr->a_family = new->a_family; 857 858 if (*pos) 859 nl_addr_put(*pos); 860 861 *pos = nl_addr_get(new); 862 addr->ce_mask |= (flag | ADDR_ATTR_FAMILY); 863 864 return 0; 865 } 866 867 int rtnl_addr_set_local(struct rtnl_addr *addr, struct nl_addr *local) 868 { 869 int err; 870 871 err = __assign_addr(addr, &addr->a_local, local, ADDR_ATTR_LOCAL); 872 if (err < 0) 873 return err; 874 875 if (!(addr->ce_mask & ADDR_ATTR_PEER)) { 876 addr->a_prefixlen = nl_addr_get_prefixlen(addr->a_local); 877 addr->ce_mask |= ADDR_ATTR_PREFIXLEN; 878 } 879 880 return 0; 881 } 882 883 struct nl_addr *rtnl_addr_get_local(struct rtnl_addr *addr) 884 { 885 return addr->a_local; 886 } 887 888 int rtnl_addr_set_peer(struct rtnl_addr *addr, struct nl_addr *peer) 889 { 890 return __assign_addr(addr, &addr->a_peer, peer, ADDR_ATTR_PEER); 891 892 addr->a_prefixlen = nl_addr_get_prefixlen(addr->a_peer); 893 addr->ce_mask |= ADDR_ATTR_PREFIXLEN; 894 895 return 0; 896 } 897 898 struct nl_addr *rtnl_addr_get_peer(struct rtnl_addr *addr) 899 { 900 return addr->a_peer; 901 } 902 903 int rtnl_addr_set_broadcast(struct rtnl_addr *addr, struct nl_addr *bcast) 904 { 905 return __assign_addr(addr, &addr->a_bcast, bcast, ADDR_ATTR_BROADCAST); 906 } 907 908 struct nl_addr *rtnl_addr_get_broadcast(struct rtnl_addr *addr) 909 { 910 return addr->a_bcast; 911 } 912 913 int rtnl_addr_set_multicast(struct rtnl_addr *addr, struct nl_addr *multicast) 914 { 915 return __assign_addr(addr, &addr->a_multicast, multicast, 916 ADDR_ATTR_MULTICAST); 917 } 918 919 struct nl_addr *rtnl_addr_get_multicast(struct rtnl_addr *addr) 920 { 921 return addr->a_multicast; 922 } 923 924 int rtnl_addr_set_anycast(struct rtnl_addr *addr, struct nl_addr *anycast) 925 { 926 return __assign_addr(addr, &addr->a_anycast, anycast, 927 ADDR_ATTR_ANYCAST); 928 } 929 930 struct nl_addr *rtnl_addr_get_anycast(struct rtnl_addr *addr) 931 { 932 return addr->a_anycast; 933 } 934 935 uint32_t rtnl_addr_get_valid_lifetime(struct rtnl_addr *addr) 936 { 937 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) 938 return addr->a_cacheinfo.aci_valid; 939 else 940 return 0xFFFFFFFFU; 941 } 942 943 void rtnl_addr_set_valid_lifetime(struct rtnl_addr *addr, uint32_t lifetime) 944 { 945 addr->a_cacheinfo.aci_valid = lifetime; 946 addr->ce_mask |= ADDR_ATTR_CACHEINFO; 947 } 948 949 uint32_t rtnl_addr_get_preferred_lifetime(struct rtnl_addr *addr) 950 { 951 if (addr->ce_mask & ADDR_ATTR_CACHEINFO) 952 return addr->a_cacheinfo.aci_prefered; 953 else 954 return 0xFFFFFFFFU; 955 } 956 957 void rtnl_addr_set_preferred_lifetime(struct rtnl_addr *addr, uint32_t lifetime) 958 { 959 addr->a_cacheinfo.aci_prefered = lifetime; 960 addr->ce_mask |= ADDR_ATTR_CACHEINFO; 961 } 962 963 uint32_t rtnl_addr_get_create_time(struct rtnl_addr *addr) 964 { 965 return addr->a_cacheinfo.aci_cstamp; 966 } 967 968 uint32_t rtnl_addr_get_last_update_time(struct rtnl_addr *addr) 969 { 970 return addr->a_cacheinfo.aci_tstamp; 971 } 972 973 /** @} */ 974 975 /** 976 * @name Flags Translations 977 * @{ 978 */ 979 980 static struct trans_tbl addr_flags[] = { 981 __ADD(IFA_F_SECONDARY, secondary) 982 __ADD(IFA_F_NODAD, nodad) 983 __ADD(IFA_F_OPTIMISTIC, optimistic) 984 __ADD(IFA_F_HOMEADDRESS, homeaddress) 985 __ADD(IFA_F_DEPRECATED, deprecated) 986 __ADD(IFA_F_TENTATIVE, tentative) 987 __ADD(IFA_F_PERMANENT, permanent) 988 }; 989 990 char *rtnl_addr_flags2str(int flags, char *buf, size_t size) 991 { 992 return __flags2str(flags, buf, size, addr_flags, 993 ARRAY_SIZE(addr_flags)); 994 } 995 996 int rtnl_addr_str2flags(const char *name) 997 { 998 return __str2flags(name, addr_flags, ARRAY_SIZE(addr_flags)); 999 } 1000 1001 /** @} */ 1002 1003 static struct nl_object_ops addr_obj_ops = { 1004 .oo_name = "route/addr", 1005 .oo_size = sizeof(struct rtnl_addr), 1006 .oo_constructor = addr_constructor, 1007 .oo_free_data = addr_free_data, 1008 .oo_clone = addr_clone, 1009 .oo_dump = { 1010 [NL_DUMP_LINE] = addr_dump_line, 1011 [NL_DUMP_DETAILS] = addr_dump_details, 1012 [NL_DUMP_STATS] = addr_dump_stats, 1013 [NL_DUMP_ENV] = addr_dump_env, 1014 }, 1015 .oo_compare = addr_compare, 1016 .oo_attrs2str = addr_attrs2str, 1017 .oo_id_attrs = (ADDR_ATTR_FAMILY | ADDR_ATTR_IFINDEX | 1018 ADDR_ATTR_LOCAL | ADDR_ATTR_PREFIXLEN), 1019 }; 1020 1021 static struct nl_af_group addr_groups[] = { 1022 { AF_INET, RTNLGRP_IPV4_IFADDR }, 1023 { AF_INET6, RTNLGRP_IPV6_IFADDR }, 1024 { END_OF_GROUP_LIST }, 1025 }; 1026 1027 static struct nl_cache_ops rtnl_addr_ops = { 1028 .co_name = "route/addr", 1029 .co_hdrsize = sizeof(struct ifaddrmsg), 1030 .co_msgtypes = { 1031 { RTM_NEWADDR, NL_ACT_NEW, "new" }, 1032 { RTM_DELADDR, NL_ACT_DEL, "del" }, 1033 { RTM_GETADDR, NL_ACT_GET, "get" }, 1034 END_OF_MSGTYPES_LIST, 1035 }, 1036 .co_protocol = NETLINK_ROUTE, 1037 .co_groups = addr_groups, 1038 .co_request_update = addr_request_update, 1039 .co_msg_parser = addr_msg_parser, 1040 .co_obj_ops = &addr_obj_ops, 1041 }; 1042 1043 static void __init addr_init(void) 1044 { 1045 nl_cache_mngt_register(&rtnl_addr_ops); 1046 } 1047 1048 static void __exit addr_exit(void) 1049 { 1050 nl_cache_mngt_unregister(&rtnl_addr_ops); 1051 } 1052 1053 /** @} */ 1054