1 /* 2 * lib/route/neigh.c Neighbours 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 */ 11 12 /** 13 * @ingroup rtnl 14 * @defgroup neigh Neighbours 15 * @brief 16 * 17 * The neighbour table establishes bindings between protocol addresses and 18 * link layer addresses for hosts sharing the same physical link. This 19 * module allows you to access and manipulate the content of these tables. 20 * 21 * @par Neighbour States 22 * @code 23 * NUD_INCOMPLETE 24 * NUD_REACHABLE 25 * NUD_STALE 26 * NUD_DELAY 27 * NUD_PROBE 28 * NUD_FAILED 29 * NUD_NOARP 30 * NUD_PERMANENT 31 * @endcode 32 * 33 * @par Neighbour Flags 34 * @code 35 * NTF_USE 36 * NTF_PROXY 37 * NTF_ROUTER 38 * @endcode 39 * 40 * @par Neighbour Identification 41 * A neighbour is uniquely identified by the attributes listed below, whenever 42 * you refer to an existing neighbour all of the attributes must be set. 43 * Neighbours from caches automatically have all required attributes set. 44 * - interface index (rtnl_neigh_set_ifindex()) 45 * - destination address (rtnl_neigh_set_dst()) 46 * 47 * @par Changeable Attributes 48 * \anchor neigh_changeable 49 * - state (rtnl_neigh_set_state()) 50 * - link layer address (rtnl_neigh_set_lladdr()) 51 * 52 * @par Required Caches for Dumping 53 * In order to dump neighbour attributes you must provide the following 54 * caches via nl_cache_provide() 55 * - link cache holding all links 56 * 57 * @par TODO 58 * - Document proxy settings 59 * - Document states and their influence 60 * 61 * @par 1) Retrieving information about configured neighbours 62 * @code 63 * // The first step is to retrieve a list of all available neighbour within 64 * // the kernel and put them into a cache. 65 * struct nl_cache *cache = rtnl_neigh_alloc_cache(sk); 66 * 67 * // Neighbours can then be looked up by the interface and destination 68 * // address: 69 * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr); 70 * 71 * // After successful usage, the object must be given back to the cache 72 * rtnl_neigh_put(neigh); 73 * @endcode 74 * 75 * @par 2) Adding new neighbours 76 * @code 77 * // Allocate an empty neighbour handle to be filled out with the attributes 78 * // of the new neighbour. 79 * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); 80 * 81 * // Fill out the attributes of the new neighbour 82 * rtnl_neigh_set_ifindex(neigh, ifindex); 83 * rtnl_neigh_set_dst(neigh, dst_addr); 84 * rtnl_neigh_set_state(neigh, rtnl_neigh_str2state("permanent")); 85 * 86 * // Build the netlink message and send it to the kernel, the operation will 87 * // block until the operation has been completed. Alternatively the required 88 * // netlink message can be built using rtnl_neigh_build_add_request() 89 * // to be sent out using nl_send_auto_complete(). 90 * rtnl_neigh_add(sk, neigh, NLM_F_CREATE); 91 * 92 * // Free the memory 93 * rtnl_neigh_put(neigh); 94 * @endcode 95 * 96 * @par 3) Deleting an existing neighbour 97 * @code 98 * // Allocate an empty neighbour object to be filled out with the attributes 99 * // matching the neighbour to be deleted. Alternatively a fully equipped 100 * // neighbour object out of a cache can be used instead. 101 * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); 102 * 103 * // Neighbours are uniquely identified by their interface index and 104 * // destination address, you may fill out other attributes but they 105 * // will have no influence. 106 * rtnl_neigh_set_ifindex(neigh, ifindex); 107 * rtnl_neigh_set_dst(neigh, dst_addr); 108 * 109 * // Build the netlink message and send it to the kernel, the operation will 110 * // block until the operation has been completed. Alternatively the required 111 * // netlink message can be built using rtnl_neigh_build_delete_request() 112 * // to be sent out using nl_send_auto_complete(). 113 * rtnl_neigh_delete(sk, neigh, 0); 114 * 115 * // Free the memory 116 * rtnl_neigh_put(neigh); 117 * @endcode 118 * 119 * @par 4) Changing neighbour attributes 120 * @code 121 * // Allocate an empty neighbour object to be filled out with the attributes 122 * // matching the neighbour to be changed and the new parameters. Alternatively 123 * // a fully equipped modified neighbour object out of a cache can be used. 124 * struct rtnl_neigh *neigh = rtnl_neigh_alloc(); 125 * 126 * // Identify the neighbour to be changed by its interface index and 127 * // destination address 128 * rtnl_neigh_set_ifindex(neigh, ifindex); 129 * rtnl_neigh_set_dst(neigh, dst_addr); 130 * 131 * // The link layer address may be modified, if so it is wise to change 132 * // its state to "permanent" in order to avoid having it overwritten. 133 * rtnl_neigh_set_lladdr(neigh, lladdr); 134 * 135 * // Secondly the state can be modified allowing normal neighbours to be 136 * // converted into permanent entries or to manually confirm a neighbour. 137 * rtnl_neigh_set_state(neigh, state); 138 * 139 * // Build the netlink message and send it to the kernel, the operation will 140 * // block until the operation has been completed. Alternatively the required 141 * // netlink message can be built using rtnl_neigh_build_change_request() 142 * // to be sent out using nl_send_auto_complete(). 143 * rtnl_neigh_add(sk, neigh, NLM_F_REPLACE); 144 * 145 * // Free the memory 146 * rtnl_neigh_put(neigh); 147 * @endcode 148 * @{ 149 */ 150 151 #include <netlink-private/netlink.h> 152 #include <netlink/netlink.h> 153 #include <netlink/utils.h> 154 #include <netlink/hashtable.h> 155 #include <netlink/route/rtnl.h> 156 #include <netlink/route/neighbour.h> 157 #include <netlink/route/link.h> 158 #include <netlink/hashtable.h> 159 160 /** @cond SKIP */ 161 #define NEIGH_ATTR_FLAGS 0x01 162 #define NEIGH_ATTR_STATE 0x02 163 #define NEIGH_ATTR_LLADDR 0x04 164 #define NEIGH_ATTR_DST 0x08 165 #define NEIGH_ATTR_CACHEINFO 0x10 166 #define NEIGH_ATTR_IFINDEX 0x20 167 #define NEIGH_ATTR_FAMILY 0x40 168 #define NEIGH_ATTR_TYPE 0x80 169 #define NEIGH_ATTR_PROBES 0x100 170 #define NEIGH_ATTR_MASTER 0x200 171 172 static struct nl_cache_ops rtnl_neigh_ops; 173 static struct nl_object_ops neigh_obj_ops; 174 /** @endcond */ 175 176 static void neigh_free_data(struct nl_object *c) 177 { 178 struct rtnl_neigh *neigh = nl_object_priv(c); 179 180 if (!neigh) 181 return; 182 183 nl_addr_put(neigh->n_lladdr); 184 nl_addr_put(neigh->n_dst); 185 } 186 187 static int neigh_clone(struct nl_object *_dst, struct nl_object *_src) 188 { 189 struct rtnl_neigh *dst = nl_object_priv(_dst); 190 struct rtnl_neigh *src = nl_object_priv(_src); 191 192 if (src->n_lladdr) 193 if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr))) 194 return -NLE_NOMEM; 195 196 if (src->n_dst) 197 if (!(dst->n_dst = nl_addr_clone(src->n_dst))) 198 return -NLE_NOMEM; 199 200 return 0; 201 } 202 203 static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey, 204 uint32_t table_sz) 205 { 206 struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj; 207 unsigned int nkey_sz; 208 struct nl_addr *addr = NULL; 209 struct neigh_hash_key { 210 uint32_t n_family; 211 uint32_t n_ifindex; 212 char n_addr[0]; 213 } __attribute__((packed)) *nkey; 214 #ifdef NL_DEBUG 215 char buf[INET6_ADDRSTRLEN+5]; 216 #endif 217 218 if (neigh->n_family == AF_BRIDGE) { 219 if (neigh->n_lladdr) 220 addr = neigh->n_lladdr; 221 } else if (neigh->n_dst) { 222 addr = neigh->n_dst; 223 } 224 225 nkey_sz = sizeof(*nkey); 226 if (addr) 227 nkey_sz += nl_addr_get_len(addr); 228 229 nkey = calloc(1, nkey_sz); 230 if (!nkey) { 231 *hashkey = 0; 232 return; 233 } 234 nkey->n_family = neigh->n_family; 235 if (neigh->n_family == AF_BRIDGE) 236 nkey->n_ifindex = neigh->n_master; 237 else 238 nkey->n_ifindex = neigh->n_ifindex; 239 if (addr) 240 memcpy(nkey->n_addr, 241 nl_addr_get_binary_addr(addr), 242 nl_addr_get_len(addr)); 243 244 *hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz; 245 246 NL_DBG(5, "neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n", 247 neigh, nkey->n_family, nkey->n_ifindex, 248 nl_addr2str(addr, buf, sizeof(buf)), 249 nkey_sz, *hashkey); 250 251 free(nkey); 252 253 return; 254 } 255 256 static int neigh_compare(struct nl_object *_a, struct nl_object *_b, 257 uint32_t attrs, int flags) 258 { 259 struct rtnl_neigh *a = (struct rtnl_neigh *) _a; 260 struct rtnl_neigh *b = (struct rtnl_neigh *) _b; 261 int diff = 0; 262 263 #define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR) 264 265 diff |= NEIGH_DIFF(IFINDEX, a->n_ifindex != b->n_ifindex); 266 diff |= NEIGH_DIFF(FAMILY, a->n_family != b->n_family); 267 diff |= NEIGH_DIFF(TYPE, a->n_type != b->n_type); 268 diff |= NEIGH_DIFF(LLADDR, nl_addr_cmp(a->n_lladdr, b->n_lladdr)); 269 diff |= NEIGH_DIFF(DST, nl_addr_cmp(a->n_dst, b->n_dst)); 270 diff |= NEIGH_DIFF(MASTER, a->n_master != b->n_master); 271 272 if (flags & LOOSE_COMPARISON) { 273 diff |= NEIGH_DIFF(STATE, 274 (a->n_state ^ b->n_state) & b->n_state_mask); 275 diff |= NEIGH_DIFF(FLAGS, 276 (a->n_flags ^ b->n_flags) & b->n_flag_mask); 277 } else { 278 diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state); 279 diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags); 280 } 281 282 #undef NEIGH_DIFF 283 284 return diff; 285 } 286 287 static const struct trans_tbl neigh_attrs[] = { 288 __ADD(NEIGH_ATTR_FLAGS, flags) 289 __ADD(NEIGH_ATTR_STATE, state) 290 __ADD(NEIGH_ATTR_LLADDR, lladdr) 291 __ADD(NEIGH_ATTR_DST, dst) 292 __ADD(NEIGH_ATTR_CACHEINFO, cacheinfo) 293 __ADD(NEIGH_ATTR_IFINDEX, ifindex) 294 __ADD(NEIGH_ATTR_FAMILY, family) 295 __ADD(NEIGH_ATTR_TYPE, type) 296 __ADD(NEIGH_ATTR_PROBES, probes) 297 }; 298 299 static char *neigh_attrs2str(int attrs, char *buf, size_t len) 300 { 301 return __flags2str(attrs, buf, len, neigh_attrs, 302 ARRAY_SIZE(neigh_attrs)); 303 } 304 305 static uint32_t neigh_id_attrs_get(struct nl_object *obj) 306 { 307 struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj; 308 309 if (neigh->n_family == AF_BRIDGE) 310 return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER); 311 else 312 return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY); 313 } 314 315 static struct nla_policy neigh_policy[NDA_MAX+1] = { 316 [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) }, 317 [NDA_PROBES] = { .type = NLA_U32 }, 318 }; 319 320 static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 321 struct nlmsghdr *n, struct nl_parser_param *pp) 322 { 323 struct rtnl_neigh *neigh; 324 int err; 325 326 if ((err = rtnl_neigh_parse(n, &neigh)) < 0) 327 return err; 328 329 err = pp->pp_cb((struct nl_object *) neigh, pp); 330 331 rtnl_neigh_put(neigh); 332 return err; 333 } 334 335 336 int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result) 337 { 338 struct rtnl_neigh *neigh; 339 struct nlattr *tb[NDA_MAX + 1]; 340 struct ndmsg *nm; 341 int err; 342 343 neigh = rtnl_neigh_alloc(); 344 if (!neigh) { 345 err = -NLE_NOMEM; 346 goto errout; 347 } 348 349 neigh->ce_msgtype = n->nlmsg_type; 350 nm = nlmsg_data(n); 351 352 err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy); 353 if (err < 0) 354 goto errout; 355 356 neigh->n_family = nm->ndm_family; 357 neigh->n_ifindex = nm->ndm_ifindex; 358 neigh->n_state = nm->ndm_state; 359 neigh->n_flags = nm->ndm_flags; 360 neigh->n_type = nm->ndm_type; 361 362 neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX | 363 NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS | 364 NEIGH_ATTR_TYPE); 365 366 if (tb[NDA_LLADDR]) { 367 neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC); 368 if (!neigh->n_lladdr) { 369 err = -NLE_NOMEM; 370 goto errout; 371 } 372 nl_addr_set_family(neigh->n_lladdr, 373 nl_addr_guess_family(neigh->n_lladdr)); 374 neigh->ce_mask |= NEIGH_ATTR_LLADDR; 375 } 376 377 if (tb[NDA_DST]) { 378 neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], neigh->n_family); 379 if (!neigh->n_dst) { 380 err = -NLE_NOMEM; 381 goto errout; 382 } 383 neigh->ce_mask |= NEIGH_ATTR_DST; 384 } 385 386 if (tb[NDA_CACHEINFO]) { 387 struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]); 388 389 neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed; 390 neigh->n_cacheinfo.nci_used = ci->ndm_used; 391 neigh->n_cacheinfo.nci_updated = ci->ndm_updated; 392 neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt; 393 394 neigh->ce_mask |= NEIGH_ATTR_CACHEINFO; 395 } 396 397 if (tb[NDA_PROBES]) { 398 neigh->n_probes = nla_get_u32(tb[NDA_PROBES]); 399 neigh->ce_mask |= NEIGH_ATTR_PROBES; 400 } 401 402 /* 403 * Get the bridge index for AF_BRIDGE family entries 404 */ 405 if (neigh->n_family == AF_BRIDGE) { 406 struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link"); 407 if (lcache ) { 408 struct rtnl_link *link = rtnl_link_get(lcache, 409 neigh->n_ifindex); 410 if (link) { 411 neigh->n_master = link->l_master; 412 rtnl_link_put(link); 413 neigh->ce_mask |= NEIGH_ATTR_MASTER; 414 } 415 416 nl_cache_put(lcache); 417 } 418 } 419 420 *result = neigh; 421 return 0; 422 423 errout: 424 rtnl_neigh_put(neigh); 425 return err; 426 } 427 428 static int neigh_request_update(struct nl_cache *c, struct nl_sock *h) 429 { 430 int family = c->c_iarg1; 431 432 return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP); 433 } 434 435 436 static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p) 437 { 438 char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5]; 439 struct rtnl_neigh *n = (struct rtnl_neigh *) a; 440 struct nl_cache *link_cache; 441 char state[128], flags[64]; 442 443 link_cache = nl_cache_mngt_require_safe("route/link"); 444 445 if (n->n_family != AF_BRIDGE) 446 nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst))); 447 448 if (link_cache) 449 nl_dump(p, "dev %s ", 450 rtnl_link_i2name(link_cache, n->n_ifindex, 451 state, sizeof(state))); 452 else 453 nl_dump(p, "dev %d ", n->n_ifindex); 454 455 if (n->ce_mask & NEIGH_ATTR_LLADDR) 456 nl_dump(p, "lladdr %s ", 457 nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr))); 458 459 rtnl_neigh_state2str(n->n_state, state, sizeof(state)); 460 rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags)); 461 462 if (state[0]) 463 nl_dump(p, "<%s", state); 464 if (flags[0]) 465 nl_dump(p, "%s%s", state[0] ? "," : "<", flags); 466 if (state[0] || flags[0]) 467 nl_dump(p, ">"); 468 nl_dump(p, "\n"); 469 470 if (link_cache) 471 nl_cache_put(link_cache); 472 } 473 474 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p) 475 { 476 char rtn_type[32]; 477 struct rtnl_neigh *n = (struct rtnl_neigh *) a; 478 int hz = nl_get_user_hz(); 479 480 neigh_dump_line(a, p); 481 482 nl_dump_line(p, " refcnt %u type %s confirmed %u used " 483 "%u updated %u\n", 484 n->n_cacheinfo.nci_refcnt, 485 nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)), 486 n->n_cacheinfo.nci_confirmed/hz, 487 n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz); 488 } 489 490 static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p) 491 { 492 neigh_dump_details(a, p); 493 } 494 495 /** 496 * @name Neighbour Object Allocation/Freeage 497 * @{ 498 */ 499 500 struct rtnl_neigh *rtnl_neigh_alloc(void) 501 { 502 return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops); 503 } 504 505 void rtnl_neigh_put(struct rtnl_neigh *neigh) 506 { 507 nl_object_put((struct nl_object *) neigh); 508 } 509 510 /** @} */ 511 512 /** 513 * @name Neighbour Cache Managament 514 * @{ 515 */ 516 517 /** 518 * Build a neighbour cache including all neighbours currently configured in the kernel. 519 * @arg sock Netlink socket. 520 * @arg result Pointer to store resulting cache. 521 * 522 * Allocates a new neighbour cache, initializes it properly and updates it 523 * to include all neighbours currently configured in the kernel. 524 * 525 * @return 0 on success or a negative error code. 526 */ 527 int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result) 528 { 529 return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result); 530 } 531 532 /** 533 * Look up a neighbour by interface index and destination address 534 * @arg cache neighbour cache 535 * @arg ifindex interface index the neighbour is on 536 * @arg dst destination address of the neighbour 537 * 538 * @return neighbour handle or NULL if no match was found. 539 */ 540 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, 541 struct nl_addr *dst) 542 { 543 struct rtnl_neigh *neigh; 544 545 nl_list_for_each_entry(neigh, &cache->c_items, ce_list) { 546 if (neigh->n_ifindex == ifindex && 547 !nl_addr_cmp(neigh->n_dst, dst)) { 548 nl_object_get((struct nl_object *) neigh); 549 return neigh; 550 } 551 } 552 553 return NULL; 554 } 555 556 /** @} */ 557 558 /** 559 * @name Neighbour Addition 560 * @{ 561 */ 562 563 static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags, 564 struct nl_msg **result) 565 { 566 struct nl_msg *msg; 567 struct ndmsg nhdr = { 568 .ndm_ifindex = tmpl->n_ifindex, 569 .ndm_state = NUD_PERMANENT, 570 }; 571 572 if (tmpl->n_family != AF_BRIDGE) { 573 if (!(tmpl->ce_mask & NEIGH_ATTR_DST)) 574 return -NLE_MISSING_ATTR; 575 nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst); 576 } 577 else 578 nhdr.ndm_family = AF_BRIDGE; 579 580 if (tmpl->ce_mask & NEIGH_ATTR_FLAGS) 581 nhdr.ndm_flags = tmpl->n_flags; 582 583 if (tmpl->ce_mask & NEIGH_ATTR_STATE) 584 nhdr.ndm_state = tmpl->n_state; 585 586 msg = nlmsg_alloc_simple(cmd, flags); 587 if (!msg) 588 return -NLE_NOMEM; 589 590 if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0) 591 goto nla_put_failure; 592 593 if (tmpl->n_family != AF_BRIDGE) 594 NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst); 595 596 if (tmpl->ce_mask & NEIGH_ATTR_LLADDR) 597 NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr); 598 599 *result = msg; 600 return 0; 601 602 nla_put_failure: 603 nlmsg_free(msg); 604 return -NLE_MSGSIZE; 605 } 606 607 /** 608 * Build netlink request message to add a new neighbour 609 * @arg tmpl template with data of new neighbour 610 * @arg flags additional netlink message flags 611 * @arg result Pointer to store resulting message. 612 * 613 * Builds a new netlink message requesting a addition of a new 614 * neighbour. The netlink message header isn't fully equipped with 615 * all relevant fields and must thus be sent out via nl_send_auto_complete() 616 * or supplemented as needed. \a tmpl must contain the attributes of the new 617 * neighbour set via \c rtnl_neigh_set_* functions. 618 * 619 * The following attributes must be set in the template: 620 * - Interface index (rtnl_neigh_set_ifindex()) 621 * - State (rtnl_neigh_set_state()) 622 * - Destination address (rtnl_neigh_set_dst()) 623 * - Link layer address (rtnl_neigh_set_lladdr()) 624 * 625 * @return 0 on success or a negative error code. 626 */ 627 int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags, 628 struct nl_msg **result) 629 { 630 return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result); 631 } 632 633 /** 634 * Add a new neighbour 635 * @arg sk Netlink socket. 636 * @arg tmpl template with requested changes 637 * @arg flags additional netlink message flags 638 * 639 * Builds a netlink message by calling rtnl_neigh_build_add_request(), 640 * sends the request to the kernel and waits for the next ACK to be 641 * received and thus blocks until the request has been fullfilled. 642 * 643 * The following attributes must be set in the template: 644 * - Interface index (rtnl_neigh_set_ifindex()) 645 * - State (rtnl_neigh_set_state()) 646 * - Destination address (rtnl_neigh_set_dst()) 647 * - Link layer address (rtnl_neigh_set_lladdr()) 648 * 649 * @return 0 on sucess or a negative error if an error occured. 650 */ 651 int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags) 652 { 653 int err; 654 struct nl_msg *msg; 655 656 if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0) 657 return err; 658 659 err = nl_send_auto_complete(sk, msg); 660 nlmsg_free(msg); 661 if (err < 0) 662 return err; 663 664 return wait_for_ack(sk); 665 } 666 667 /** @} */ 668 669 /** 670 * @name Neighbour Deletion 671 * @{ 672 */ 673 674 /** 675 * Build a netlink request message to delete a neighbour 676 * @arg neigh neighbour to delete 677 * @arg flags additional netlink message flags 678 * @arg result Pointer to store resulting message. 679 * 680 * Builds a new netlink message requesting a deletion of a neighbour. 681 * The netlink message header isn't fully equipped with all relevant 682 * fields and must thus be sent out via nl_send_auto_complete() 683 * or supplemented as needed. \a neigh must point to an existing 684 * neighbour. 685 * 686 * @return 0 on success or a negative error code. 687 */ 688 int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags, 689 struct nl_msg **result) 690 { 691 return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result); 692 } 693 694 /** 695 * Delete a neighbour 696 * @arg sk Netlink socket. 697 * @arg neigh neighbour to delete 698 * @arg flags additional netlink message flags 699 * 700 * Builds a netlink message by calling rtnl_neigh_build_delete_request(), 701 * sends the request to the kernel and waits for the next ACK to be 702 * received and thus blocks until the request has been fullfilled. 703 * 704 * @return 0 on sucess or a negative error if an error occured. 705 */ 706 int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh, 707 int flags) 708 { 709 struct nl_msg *msg; 710 int err; 711 712 if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0) 713 return err; 714 715 err = nl_send_auto_complete(sk, msg); 716 nlmsg_free(msg); 717 if (err < 0) 718 return err; 719 720 return wait_for_ack(sk); 721 } 722 723 /** @} */ 724 725 /** 726 * @name Neighbour States Translations 727 * @{ 728 */ 729 730 static const struct trans_tbl neigh_states[] = { 731 __ADD(NUD_INCOMPLETE, incomplete) 732 __ADD(NUD_REACHABLE, reachable) 733 __ADD(NUD_STALE, stale) 734 __ADD(NUD_DELAY, delay) 735 __ADD(NUD_PROBE, probe) 736 __ADD(NUD_FAILED, failed) 737 __ADD(NUD_NOARP, norarp) 738 __ADD(NUD_PERMANENT, permanent) 739 }; 740 741 char * rtnl_neigh_state2str(int state, char *buf, size_t len) 742 { 743 return __flags2str(state, buf, len, neigh_states, 744 ARRAY_SIZE(neigh_states)); 745 } 746 747 int rtnl_neigh_str2state(const char *name) 748 { 749 return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states)); 750 } 751 752 /** @} */ 753 754 /** 755 * @name Neighbour Flags Translations 756 * @{ 757 */ 758 759 static const struct trans_tbl neigh_flags[] = { 760 __ADD(NTF_USE, use) 761 __ADD(NTF_PROXY, proxy) 762 __ADD(NTF_ROUTER, router) 763 }; 764 765 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len) 766 { 767 return __flags2str(flags, buf, len, neigh_flags, 768 ARRAY_SIZE(neigh_flags)); 769 } 770 771 int rtnl_neigh_str2flag(const char *name) 772 { 773 return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags)); 774 } 775 776 /** @} */ 777 778 /** 779 * @name Attributes 780 * @{ 781 */ 782 783 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state) 784 { 785 neigh->n_state_mask |= state; 786 neigh->n_state |= state; 787 neigh->ce_mask |= NEIGH_ATTR_STATE; 788 } 789 790 int rtnl_neigh_get_state(struct rtnl_neigh *neigh) 791 { 792 if (neigh->ce_mask & NEIGH_ATTR_STATE) 793 return neigh->n_state; 794 else 795 return -1; 796 } 797 798 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state) 799 { 800 neigh->n_state_mask |= state; 801 neigh->n_state &= ~state; 802 neigh->ce_mask |= NEIGH_ATTR_STATE; 803 } 804 805 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags) 806 { 807 neigh->n_flag_mask |= flags; 808 neigh->n_flags |= flags; 809 neigh->ce_mask |= NEIGH_ATTR_FLAGS; 810 } 811 812 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh) 813 { 814 return neigh->n_flags; 815 } 816 817 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags) 818 { 819 neigh->n_flag_mask |= flags; 820 neigh->n_flags &= ~flags; 821 neigh->ce_mask |= NEIGH_ATTR_FLAGS; 822 } 823 824 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex) 825 { 826 neigh->n_ifindex = ifindex; 827 neigh->ce_mask |= NEIGH_ATTR_IFINDEX; 828 } 829 830 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh) 831 { 832 return neigh->n_ifindex; 833 } 834 835 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos, 836 struct nl_addr *new, int flag, int nocheck) 837 { 838 if (!nocheck) { 839 if (neigh->ce_mask & NEIGH_ATTR_FAMILY) { 840 if (new->a_family != neigh->n_family) 841 return -NLE_AF_MISMATCH; 842 } else { 843 neigh->n_family = new->a_family; 844 neigh->ce_mask |= NEIGH_ATTR_FAMILY; 845 } 846 } 847 848 if (*pos) 849 nl_addr_put(*pos); 850 851 nl_addr_get(new); 852 *pos = new; 853 854 neigh->ce_mask |= flag; 855 856 return 0; 857 } 858 859 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr) 860 { 861 __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1); 862 } 863 864 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh) 865 { 866 if (neigh->ce_mask & NEIGH_ATTR_LLADDR) 867 return neigh->n_lladdr; 868 else 869 return NULL; 870 } 871 872 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr) 873 { 874 return __assign_addr(neigh, &neigh->n_dst, addr, 875 NEIGH_ATTR_DST, 0); 876 } 877 878 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh) 879 { 880 if (neigh->ce_mask & NEIGH_ATTR_DST) 881 return neigh->n_dst; 882 else 883 return NULL; 884 } 885 886 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family) 887 { 888 neigh->n_family = family; 889 neigh->ce_mask |= NEIGH_ATTR_FAMILY; 890 } 891 892 int rtnl_neigh_get_family(struct rtnl_neigh *neigh) 893 { 894 return neigh->n_family; 895 } 896 897 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type) 898 { 899 neigh->n_type = type; 900 neigh->ce_mask = NEIGH_ATTR_TYPE; 901 } 902 903 int rtnl_neigh_get_type(struct rtnl_neigh *neigh) 904 { 905 if (neigh->ce_mask & NEIGH_ATTR_TYPE) 906 return neigh->n_type; 907 else 908 return -1; 909 } 910 911 /** @} */ 912 913 static struct nl_object_ops neigh_obj_ops = { 914 .oo_name = "route/neigh", 915 .oo_size = sizeof(struct rtnl_neigh), 916 .oo_free_data = neigh_free_data, 917 .oo_clone = neigh_clone, 918 .oo_dump = { 919 [NL_DUMP_LINE] = neigh_dump_line, 920 [NL_DUMP_DETAILS] = neigh_dump_details, 921 [NL_DUMP_STATS] = neigh_dump_stats, 922 }, 923 .oo_compare = neigh_compare, 924 .oo_keygen = neigh_keygen, 925 .oo_attrs2str = neigh_attrs2str, 926 .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY), 927 .oo_id_attrs_get = neigh_id_attrs_get 928 }; 929 930 static struct nl_af_group neigh_groups[] = { 931 { AF_UNSPEC, RTNLGRP_NEIGH }, 932 { AF_BRIDGE, RTNLGRP_NEIGH }, 933 { END_OF_GROUP_LIST }, 934 }; 935 936 static struct nl_cache_ops rtnl_neigh_ops = { 937 .co_name = "route/neigh", 938 .co_hdrsize = sizeof(struct ndmsg), 939 .co_msgtypes = { 940 { RTM_NEWNEIGH, NL_ACT_NEW, "new" }, 941 { RTM_DELNEIGH, NL_ACT_DEL, "del" }, 942 { RTM_GETNEIGH, NL_ACT_GET, "get" }, 943 END_OF_MSGTYPES_LIST, 944 }, 945 .co_protocol = NETLINK_ROUTE, 946 .co_groups = neigh_groups, 947 .co_request_update = neigh_request_update, 948 .co_msg_parser = neigh_msg_parser, 949 .co_obj_ops = &neigh_obj_ops, 950 }; 951 952 static void __init neigh_init(void) 953 { 954 nl_cache_mngt_register(&rtnl_neigh_ops); 955 } 956 957 static void __exit neigh_exit(void) 958 { 959 nl_cache_mngt_unregister(&rtnl_neigh_ops); 960 } 961 962 /** @} */ 963