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