00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <netlink-local.h>
00020 #include <netlink/netlink.h>
00021 #include <netlink/utils.h>
00022 #include <netlink/route/rtnl.h>
00023 #include <netlink/route/neightbl.h>
00024 #include <netlink/route/link.h>
00025
00026
00027 #define NEIGHTBL_ATTR_FAMILY 0x001
00028 #define NEIGHTBL_ATTR_STATS 0x002
00029 #define NEIGHTBL_ATTR_NAME 0x004
00030 #define NEIGHTBL_ATTR_THRESH1 0x008
00031 #define NEIGHTBL_ATTR_THRESH2 0x010
00032 #define NEIGHTBL_ATTR_THRESH3 0x020
00033 #define NEIGHTBL_ATTR_CONFIG 0x040
00034 #define NEIGHTBL_ATTR_PARMS 0x080
00035 #define NEIGHTBL_ATTR_GC_INTERVAL 0x100
00036
00037 #define NEIGHTBLPARM_ATTR_IFINDEX 0x0001
00038 #define NEIGHTBLPARM_ATTR_REFCNT 0x0002
00039 #define NEIGHTBLPARM_ATTR_QUEUE_LEN 0x0004
00040 #define NEIGHTBLPARM_ATTR_APP_PROBES 0x0008
00041 #define NEIGHTBLPARM_ATTR_UCAST_PROBES 0x0010
00042 #define NEIGHTBLPARM_ATTR_MCAST_PROBES 0x0020
00043 #define NEIGHTBLPARM_ATTR_PROXY_QLEN 0x0040
00044 #define NEIGHTBLPARM_ATTR_REACHABLE_TIME 0x0080
00045 #define NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME 0x0100
00046 #define NEIGHTBLPARM_ATTR_RETRANS_TIME 0x0200
00047 #define NEIGHTBLPARM_ATTR_GC_STALETIME 0x0400
00048 #define NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME 0x0800
00049 #define NEIGHTBLPARM_ATTR_ANYCAST_DELAY 0x1000
00050 #define NEIGHTBLPARM_ATTR_PROXY_DELAY 0x2000
00051 #define NEIGHTBLPARM_ATTR_LOCKTIME 0x4000
00052
00053 static struct nl_cache_ops rtnl_neightbl_ops;
00054 static struct nl_object_ops neightbl_obj_ops;
00055
00056
00057 static int neightbl_compare(struct nl_object *_a, struct nl_object *_b,
00058 uint32_t attrs, int flags)
00059 {
00060 struct rtnl_neightbl *a = (struct rtnl_neightbl *) _a;
00061 struct rtnl_neightbl *b = (struct rtnl_neightbl *) _b;
00062 int diff = 0;
00063
00064 #define NT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGHTBL_ATTR_##ATTR, a, b, EXPR)
00065
00066 diff |= NT_DIFF(FAMILY, a->nt_family != b->nt_family);
00067 diff |= NT_DIFF(NAME, strcmp(a->nt_name, b->nt_name));
00068 diff |= NT_DIFF(THRESH1, a->nt_gc_thresh1 != b->nt_gc_thresh1);
00069 diff |= NT_DIFF(THRESH2, a->nt_gc_thresh2 != b->nt_gc_thresh2);
00070 diff |= NT_DIFF(THRESH3, a->nt_gc_thresh3 != b->nt_gc_thresh3);
00071 diff |= NT_DIFF(GC_INTERVAL, a->nt_gc_interval != b->nt_gc_interval);
00072
00073 #undef NT_DIFF
00074
00075 if (!(a->ce_mask & NEIGHTBL_ATTR_PARMS) &&
00076 !(b->ce_mask & NEIGHTBL_ATTR_PARMS))
00077 return diff;
00078
00079
00080
00081
00082 #if 0
00083 #define REQ(F) (fp->ntp_mask & NEIGHTBLPARM_ATTR_##F)
00084 #define AVAIL(F) (op->ntp_mask & NEIGHTBLPARM_ATTR_##F)
00085 #define _C(F, N) (REQ(F) && (!AVAIL(F) || (op->N != fp->N)))
00086 if (_C(IFINDEX, ntp_ifindex) ||
00087 _C(QUEUE_LEN, ntp_queue_len) ||
00088 _C(APP_PROBES, ntp_app_probes) ||
00089 _C(UCAST_PROBES, ntp_ucast_probes) ||
00090 _C(MCAST_PROBES, ntp_mcast_probes) ||
00091 _C(PROXY_QLEN, ntp_proxy_qlen) ||
00092 _C(LOCKTIME, ntp_locktime) ||
00093 _C(RETRANS_TIME, ntp_retrans_time) ||
00094 _C(BASE_REACHABLE_TIME, ntp_base_reachable_time) ||
00095 _C(GC_STALETIME, ntp_gc_stale_time) ||
00096 _C(DELAY_PROBE_TIME, ntp_probe_delay) ||
00097 _C(ANYCAST_DELAY, ntp_anycast_delay) ||
00098 _C(PROXY_DELAY, ntp_proxy_delay))
00099 return 0;
00100 #undef REQ
00101 #undef AVAIL
00102 #undef _C
00103 #endif
00104
00105 return diff;
00106 }
00107
00108
00109 static struct nla_policy neightbl_policy[NDTA_MAX+1] = {
00110 [NDTA_NAME] = { .type = NLA_STRING,
00111 .maxlen = NTBLNAMSIZ },
00112 [NDTA_THRESH1] = { .type = NLA_U32 },
00113 [NDTA_THRESH2] = { .type = NLA_U32 },
00114 [NDTA_THRESH3] = { .type = NLA_U32 },
00115 [NDTA_GC_INTERVAL] = { .type = NLA_U32 },
00116 [NDTA_CONFIG] = { .minlen = sizeof(struct ndt_config) },
00117 [NDTA_STATS] = { .minlen = sizeof(struct ndt_stats) },
00118 [NDTA_PARMS] = { .type = NLA_NESTED },
00119 };
00120
00121 static int neightbl_msg_parser(struct nl_cache_ops *ops,
00122 struct sockaddr_nl *who, struct nlmsghdr *n,
00123 struct nl_parser_param *pp)
00124 {
00125 struct rtnl_neightbl *ntbl;
00126 struct nlattr *tb[NDTA_MAX + 1];
00127 struct rtgenmsg *rtmsg;
00128 int err;
00129
00130 ntbl = rtnl_neightbl_alloc();
00131 if (!ntbl) {
00132 err = nl_errno(ENOMEM);
00133 goto errout;
00134 }
00135
00136 ntbl->ce_msgtype = n->nlmsg_type;
00137 rtmsg = nlmsg_data(n);
00138
00139 err = nlmsg_parse(n, sizeof(*rtmsg), tb, NDTA_MAX, neightbl_policy);
00140 if (err < 0)
00141 goto errout;
00142
00143 ntbl->nt_family = rtmsg->rtgen_family;
00144
00145 if (tb[NDTA_NAME] == NULL) {
00146 err = nl_error(EINVAL, "NDTA_NAME is missing");
00147 goto errout;
00148 }
00149
00150 nla_strlcpy(ntbl->nt_name, tb[NDTA_NAME], NTBLNAMSIZ);
00151 ntbl->ce_mask |= NEIGHTBL_ATTR_NAME;
00152
00153 if (tb[NDTA_THRESH1]) {
00154 ntbl->nt_gc_thresh1 = nla_get_u32(tb[NDTA_THRESH1]);
00155 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH1;
00156 }
00157
00158 if (tb[NDTA_THRESH2]) {
00159 ntbl->nt_gc_thresh2 = nla_get_u32(tb[NDTA_THRESH2]);
00160 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH2;
00161 }
00162
00163 if (tb[NDTA_THRESH3]) {
00164 ntbl->nt_gc_thresh3 = nla_get_u32(tb[NDTA_THRESH3]);
00165 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH3;
00166 }
00167
00168 if (tb[NDTA_GC_INTERVAL]) {
00169 ntbl->nt_gc_interval = nla_get_u32(tb[NDTA_GC_INTERVAL]);
00170 ntbl->ce_mask |= NEIGHTBL_ATTR_GC_INTERVAL;
00171 }
00172
00173 if (tb[NDTA_CONFIG]) {
00174 nla_memcpy(&ntbl->nt_config, tb[NDTA_CONFIG],
00175 sizeof(ntbl->nt_config));
00176 ntbl->ce_mask |= NEIGHTBL_ATTR_CONFIG;
00177 }
00178
00179 if (tb[NDTA_STATS]) {
00180 nla_memcpy(&ntbl->nt_stats, tb[NDTA_STATS],
00181 sizeof(ntbl->nt_stats));
00182 ntbl->ce_mask |= NEIGHTBL_ATTR_STATS;
00183 }
00184
00185 if (tb[NDTA_PARMS]) {
00186 struct nlattr *tbp[NDTPA_MAX + 1];
00187 struct rtnl_neightbl_parms *p = &ntbl->nt_parms;
00188
00189 err = nla_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS], NULL);
00190 if (err < 0)
00191 goto errout;
00192
00193 #define COPY_ENTRY(name, var) \
00194 if (tbp[NDTPA_ ##name]) { \
00195 p->ntp_ ##var = nla_get_u32(tbp[NDTPA_ ##name]); \
00196 p->ntp_mask |= NEIGHTBLPARM_ATTR_ ##name; \
00197 }
00198
00199 COPY_ENTRY(IFINDEX, ifindex);
00200 COPY_ENTRY(REFCNT, refcnt);
00201 COPY_ENTRY(QUEUE_LEN, queue_len);
00202 COPY_ENTRY(APP_PROBES, app_probes);
00203 COPY_ENTRY(UCAST_PROBES, ucast_probes);
00204 COPY_ENTRY(MCAST_PROBES, mcast_probes);
00205 COPY_ENTRY(PROXY_QLEN, proxy_qlen);
00206 COPY_ENTRY(PROXY_DELAY, proxy_delay);
00207 COPY_ENTRY(ANYCAST_DELAY, anycast_delay);
00208 COPY_ENTRY(LOCKTIME, locktime);
00209 COPY_ENTRY(REACHABLE_TIME, reachable_time);
00210 COPY_ENTRY(BASE_REACHABLE_TIME, base_reachable_time);
00211 COPY_ENTRY(RETRANS_TIME, retrans_time);
00212 COPY_ENTRY(GC_STALETIME, gc_stale_time);
00213 COPY_ENTRY(DELAY_PROBE_TIME, probe_delay);
00214 #undef COPY_ENTRY
00215
00216 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00217 }
00218
00219 err = pp->pp_cb((struct nl_object *) ntbl, pp);
00220 if (err < 0)
00221 goto errout;
00222
00223 err = P_ACCEPT;
00224 errout:
00225 rtnl_neightbl_put(ntbl);
00226 return err;
00227 }
00228
00229 static int neightbl_request_update(struct nl_cache *c, struct nl_handle *h)
00230 {
00231 return nl_rtgen_request(h, RTM_GETNEIGHTBL, AF_UNSPEC, NLM_F_DUMP);
00232 }
00233
00234
00235 static int neightbl_dump_brief(struct nl_object *arg, struct nl_dump_params *p)
00236 {
00237 int line = 1;
00238 struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
00239
00240 dp_dump(p, "%s", ntbl->nt_name);
00241
00242 if (ntbl->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX) {
00243 struct nl_cache *link_cache;
00244
00245 link_cache = nl_cache_mngt_require("route/link");
00246
00247 if (link_cache) {
00248 char buf[32];
00249 dp_dump(p, "<%s> ",
00250 rtnl_link_i2name(link_cache,
00251 ntbl->nt_parms.ntp_ifindex,
00252 buf, sizeof(buf)));
00253 } else
00254 dp_dump(p, "<%u> ", ntbl->nt_parms.ntp_ifindex);
00255 } else
00256 dp_dump(p, " ");
00257
00258 if (ntbl->ce_mask & NEIGHTBL_ATTR_CONFIG)
00259 dp_dump(p, "entries %u ", ntbl->nt_config.ndtc_entries);
00260
00261 if (ntbl->ce_mask & NEIGHTBL_ATTR_PARMS) {
00262 char rt[32], rt2[32];
00263 struct rtnl_neightbl_parms *pa = &ntbl->nt_parms;
00264
00265 dp_dump(p, "reachable-time %s retransmit-time %s",
00266 nl_msec2str(pa->ntp_reachable_time, rt, sizeof(rt)),
00267 nl_msec2str(pa->ntp_retrans_time, rt2, sizeof(rt2)));
00268 }
00269
00270 dp_dump(p, "\n");
00271
00272 return line;
00273 }
00274
00275 static int neightbl_dump_full(struct nl_object *arg, struct nl_dump_params *p)
00276 {
00277 char x[32], y[32], z[32];
00278 struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
00279
00280 int line = neightbl_dump_brief(arg, p);
00281
00282 if (ntbl->ce_mask & NEIGHTBL_ATTR_CONFIG) {
00283 dp_new_line(p, line++);
00284 dp_dump(p, " key-len %u entry-size %u last-flush %s\n",
00285 ntbl->nt_config.ndtc_key_len,
00286 ntbl->nt_config.ndtc_entry_size,
00287 nl_msec2str(ntbl->nt_config.ndtc_last_flush,
00288 x, sizeof(x)));
00289
00290 dp_new_line(p, line++);
00291 dp_dump(p, " gc threshold %u/%u/%u interval %s " \
00292 "chain-position %u\n",
00293 ntbl->nt_gc_thresh1, ntbl->nt_gc_thresh2,
00294 ntbl->nt_gc_thresh3,
00295 nl_msec2str(ntbl->nt_gc_interval, x, sizeof(x)),
00296 ntbl->nt_config.ndtc_hash_chain_gc);
00297
00298 dp_new_line(p, line++);
00299 dp_dump(p, " hash-rand 0x%08X/0x%08X last-rand %s\n",
00300 ntbl->nt_config.ndtc_hash_rnd,
00301 ntbl->nt_config.ndtc_hash_mask,
00302 nl_msec2str(ntbl->nt_config.ndtc_last_rand,
00303 x, sizeof(x)));
00304 }
00305
00306 if (ntbl->ce_mask & NEIGHTBL_ATTR_PARMS) {
00307 struct rtnl_neightbl_parms *pa = &ntbl->nt_parms;
00308
00309 dp_new_line(p, line++);
00310 dp_dump(p, " refcnt %u pending-queue-limit %u " \
00311 "proxy-delayed-queue-limit %u\n",
00312 pa->ntp_refcnt,
00313 pa->ntp_queue_len,
00314 pa->ntp_proxy_qlen);
00315
00316 dp_new_line(p, line++);
00317 dp_dump(p, " num-userspace-probes %u num-unicast-probes " \
00318 "%u num-multicast-probes %u\n",
00319 pa->ntp_app_probes,
00320 pa->ntp_ucast_probes,
00321 pa->ntp_mcast_probes);
00322
00323 dp_new_line(p, line++);
00324 dp_dump(p, " min-age %s base-reachable-time %s " \
00325 "stale-check-interval %s\n",
00326 nl_msec2str(pa->ntp_locktime, x, sizeof(x)),
00327 nl_msec2str(pa->ntp_base_reachable_time,
00328 y, sizeof(y)),
00329 nl_msec2str(pa->ntp_gc_stale_time, z, sizeof(z)));
00330
00331 dp_new_line(p, line++);
00332 dp_dump(p, " initial-probe-delay %s answer-delay %s " \
00333 "proxy-answer-delay %s\n",
00334 nl_msec2str(pa->ntp_probe_delay, x, sizeof(x)),
00335 nl_msec2str(pa->ntp_anycast_delay, y, sizeof(y)),
00336 nl_msec2str(pa->ntp_proxy_delay, z, sizeof(z)));
00337 }
00338
00339 return line;
00340 }
00341
00342 static int neightbl_dump_stats(struct nl_object *arg, struct nl_dump_params *p)
00343 {
00344 struct rtnl_neightbl *ntbl = (struct rtnl_neightbl *) arg;
00345 int line = neightbl_dump_full(arg, p);
00346
00347 if (!(ntbl->ce_mask & NEIGHTBL_ATTR_STATS))
00348 return line;
00349
00350 dp_new_line(p, line++);
00351 dp_dump(p, " lookups %lld hits %lld failed %lld " \
00352 "allocations %lld destroys %lld\n",
00353 ntbl->nt_stats.ndts_lookups,
00354 ntbl->nt_stats.ndts_hits,
00355 ntbl->nt_stats.ndts_res_failed,
00356 ntbl->nt_stats.ndts_allocs,
00357 ntbl->nt_stats.ndts_destroys);
00358
00359 dp_new_line(p, line++);
00360 dp_dump(p, " hash-grows %lld forced-gc-runs %lld " \
00361 "periodic-gc-runs %lld\n",
00362 ntbl->nt_stats.ndts_hash_grows,
00363 ntbl->nt_stats.ndts_forced_gc_runs,
00364 ntbl->nt_stats.ndts_periodic_gc_runs);
00365
00366 dp_dump(p, " rcv-unicast-probes %lld rcv-multicast-probes %lld\n",
00367 ntbl->nt_stats.ndts_rcv_probes_ucast,
00368 ntbl->nt_stats.ndts_rcv_probes_mcast);
00369
00370 return line;
00371 }
00372
00373
00374
00375
00376
00377
00378 struct rtnl_neightbl *rtnl_neightbl_alloc(void)
00379 {
00380 return (struct rtnl_neightbl *) nl_object_alloc(&neightbl_obj_ops);
00381 }
00382
00383 void rtnl_neightbl_put(struct rtnl_neightbl *neightbl)
00384 {
00385 nl_object_put((struct nl_object *) neightbl);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 struct nl_cache * rtnl_neightbl_alloc_cache(struct nl_handle *handle)
00408 {
00409 struct nl_cache * cache;
00410
00411 cache = nl_cache_alloc(&rtnl_neightbl_ops);
00412 if (cache == NULL)
00413 return NULL;
00414
00415 if (handle && nl_cache_refill(handle, cache) < 0) {
00416 nl_cache_free(cache);
00417 return NULL;
00418 }
00419
00420 return cache;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *cache,
00437 const char *name, int ifindex)
00438 {
00439 struct rtnl_neightbl *nt;
00440
00441 if (cache->c_ops != &rtnl_neightbl_ops)
00442 return NULL;
00443
00444 nl_list_for_each_entry(nt, &cache->c_items, ce_list) {
00445 if (!strcasecmp(nt->nt_name, name) &&
00446 ((!ifindex && !nt->nt_parms.ntp_ifindex) ||
00447 (ifindex && ifindex == nt->nt_parms.ntp_ifindex))) {
00448 nl_object_get((struct nl_object *) nt);
00449 return nt;
00450 }
00451 }
00452
00453 return NULL;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 struct nl_msg * rtnl_neightbl_build_change_request(struct rtnl_neightbl *old,
00479 struct rtnl_neightbl *tmpl)
00480 {
00481 struct nl_msg *m;
00482 struct ndtmsg ndt = {
00483 .ndtm_family = old->nt_family,
00484 };
00485
00486 m = nlmsg_alloc_simple(RTM_SETNEIGHTBL, 0);
00487 nlmsg_append(m, &ndt, sizeof(ndt), NLMSG_ALIGNTO);
00488
00489 nla_put_string(m, NDTA_NAME, old->nt_name);
00490
00491 if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH1)
00492 nla_put_u32(m, NDTA_THRESH1, tmpl->nt_gc_thresh1);
00493
00494 if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
00495 nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
00496
00497 if (tmpl->ce_mask & NEIGHTBL_ATTR_THRESH2)
00498 nla_put_u32(m, NDTA_THRESH2, tmpl->nt_gc_thresh2);
00499
00500 if (tmpl->ce_mask & NEIGHTBL_ATTR_GC_INTERVAL)
00501 nla_put_u64(m, NDTA_GC_INTERVAL,
00502 tmpl->nt_gc_interval);
00503
00504 if (tmpl->ce_mask & NEIGHTBL_ATTR_PARMS) {
00505 struct rtnl_neightbl_parms *p = &tmpl->nt_parms;
00506 struct nl_msg *parms = nlmsg_alloc();
00507
00508 if (old->nt_parms.ntp_mask & NEIGHTBLPARM_ATTR_IFINDEX)
00509 nla_put_u32(parms, NDTPA_IFINDEX,
00510 old->nt_parms.ntp_ifindex);
00511
00512
00513 if (p->ntp_mask & NEIGHTBLPARM_ATTR_QUEUE_LEN)
00514 nla_put_u32(parms, NDTPA_QUEUE_LEN, p->ntp_queue_len);
00515
00516 if (p->ntp_mask & NEIGHTBLPARM_ATTR_APP_PROBES)
00517 nla_put_u32(parms, NDTPA_APP_PROBES, p->ntp_app_probes);
00518
00519 if (p->ntp_mask & NEIGHTBLPARM_ATTR_UCAST_PROBES)
00520 nla_put_u32(parms, NDTPA_UCAST_PROBES,
00521 p->ntp_ucast_probes);
00522
00523 if (p->ntp_mask & NEIGHTBLPARM_ATTR_MCAST_PROBES)
00524 nla_put_u32(parms, NDTPA_MCAST_PROBES,
00525 p->ntp_mcast_probes);
00526
00527 if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_QLEN)
00528 nla_put_u32(parms, NDTPA_PROXY_QLEN,
00529 p->ntp_proxy_qlen);
00530
00531 if (p->ntp_mask & NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME)
00532 nla_put_u64(parms, NDTPA_BASE_REACHABLE_TIME,
00533 p->ntp_base_reachable_time);
00534
00535 if (p->ntp_mask & NEIGHTBLPARM_ATTR_RETRANS_TIME)
00536 nla_put_u64(parms, NDTPA_RETRANS_TIME,
00537 p->ntp_retrans_time);
00538
00539 if (p->ntp_mask & NEIGHTBLPARM_ATTR_GC_STALETIME)
00540 nla_put_u64(parms, NDTPA_GC_STALETIME,
00541 p->ntp_gc_stale_time);
00542
00543 if (p->ntp_mask & NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME)
00544 nla_put_u64(parms, NDTPA_DELAY_PROBE_TIME,
00545 p->ntp_proxy_delay);
00546
00547 if (p->ntp_mask & NEIGHTBLPARM_ATTR_ANYCAST_DELAY)
00548 nla_put_u64(parms, NDTPA_ANYCAST_DELAY,
00549 p->ntp_anycast_delay);
00550
00551 if (p->ntp_mask & NEIGHTBLPARM_ATTR_PROXY_DELAY)
00552 nla_put_u64(parms, NDTPA_PROXY_DELAY,
00553 p->ntp_proxy_delay);
00554
00555 if (p->ntp_mask & NEIGHTBLPARM_ATTR_LOCKTIME)
00556 nla_put_u64(parms, NDTPA_LOCKTIME, p->ntp_locktime);
00557
00558 nla_put_nested(m, NDTA_PARMS, parms);
00559 nlmsg_free(parms);
00560 }
00561
00562 return m;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 int rtnl_neightbl_change(struct nl_handle *handle, struct rtnl_neightbl *old,
00579 struct rtnl_neightbl *tmpl)
00580 {
00581 int err;
00582 struct nl_msg *msg;
00583
00584 msg = rtnl_neightbl_build_change_request(old, tmpl);
00585 err = nl_send_auto_complete(handle, msg);
00586 if (err < 0)
00587 return err;
00588
00589 nlmsg_free(msg);
00590 return nl_wait_for_ack(handle);
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600 void rtnl_neightbl_set_family(struct rtnl_neightbl *ntbl, int family)
00601 {
00602 ntbl->nt_family = family;
00603 ntbl->ce_mask |= NEIGHTBL_ATTR_FAMILY;
00604 }
00605
00606 void rtnl_neightbl_set_gc_interval(struct rtnl_neightbl *ntbl, uint64_t ms)
00607 {
00608 ntbl->nt_gc_interval = ms;
00609 ntbl->ce_mask |= NEIGHTBL_ATTR_GC_INTERVAL;
00610 }
00611
00612 void rtnl_neightbl_set_gc_tresh1(struct rtnl_neightbl *ntbl, int thresh)
00613 {
00614 ntbl->nt_gc_thresh1 = thresh;
00615 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH1;
00616 }
00617
00618 void rtnl_neightbl_set_gc_tresh2(struct rtnl_neightbl *ntbl, int thresh)
00619 {
00620 ntbl->nt_gc_thresh2 = thresh;
00621 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH2;
00622 }
00623
00624 void rtnl_neightbl_set_gc_tresh3(struct rtnl_neightbl *ntbl, int thresh)
00625 {
00626 ntbl->nt_gc_thresh3 = thresh;
00627 ntbl->ce_mask |= NEIGHTBL_ATTR_THRESH3;
00628 }
00629
00630 void rtnl_neightbl_set_name(struct rtnl_neightbl *ntbl, const char *name)
00631 {
00632 strncpy(ntbl->nt_name, name, sizeof(ntbl->nt_name) - 1);
00633 ntbl->ce_mask |= NEIGHTBL_ATTR_NAME;
00634 }
00635
00636 void rtnl_neightbl_set_dev(struct rtnl_neightbl *ntbl, int ifindex)
00637 {
00638 ntbl->nt_parms.ntp_ifindex = ifindex;
00639 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_IFINDEX;
00640 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00641 }
00642
00643
00644
00645
00646
00647
00648 void rtnl_neightbl_set_queue_len(struct rtnl_neightbl *ntbl, int len)
00649 {
00650 ntbl->nt_parms.ntp_queue_len = len;
00651 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_QUEUE_LEN;
00652 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00653 }
00654
00655
00656
00657
00658
00659
00660 void rtnl_neightbl_set_proxy_queue_len(struct rtnl_neightbl *ntbl, int len)
00661 {
00662 ntbl->nt_parms.ntp_proxy_qlen = len;
00663 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_PROXY_QLEN;
00664 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00665 }
00666
00667
00668
00669
00670
00671
00672 void rtnl_neightbl_set_app_probes(struct rtnl_neightbl *ntbl, int probes)
00673 {
00674 ntbl->nt_parms.ntp_app_probes = probes;
00675 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_APP_PROBES;
00676 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00677 }
00678
00679
00680
00681
00682
00683
00684 void rtnl_neightbl_set_ucast_probes(struct rtnl_neightbl *ntbl, int probes)
00685 {
00686 ntbl->nt_parms.ntp_ucast_probes = probes;
00687 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_UCAST_PROBES;
00688 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00689 }
00690
00691
00692
00693
00694
00695
00696 void rtnl_neightbl_set_mcast_probes(struct rtnl_neightbl *ntbl, int probes)
00697 {
00698 ntbl->nt_parms.ntp_mcast_probes = probes;
00699 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_MCAST_PROBES;
00700 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00701 }
00702
00703
00704
00705
00706
00707
00708 void rtnl_neightbl_set_base_reachable_time(struct rtnl_neightbl *ntbl,
00709 uint64_t ms)
00710 {
00711 ntbl->nt_parms.ntp_base_reachable_time = ms;
00712 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_BASE_REACHABLE_TIME;
00713 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00714 }
00715
00716
00717
00718
00719
00720
00721 void rtnl_neightbl_set_retrans_time(struct rtnl_neightbl *ntbl, uint64_t ms)
00722 {
00723 ntbl->nt_parms.ntp_retrans_time = ms;
00724 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_RETRANS_TIME;
00725 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00726 }
00727
00728
00729
00730
00731
00732
00733 void rtnl_neightbl_set_gc_stale_time(struct rtnl_neightbl *ntbl, uint64_t ms)
00734 {
00735 ntbl->nt_parms.ntp_gc_stale_time = ms;
00736 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_GC_STALETIME;
00737 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00738 }
00739
00740
00741
00742
00743
00744
00745 void rtnl_neightbl_set_delay_probe_time(struct rtnl_neightbl *ntbl, uint64_t ms)
00746 {
00747 ntbl->nt_parms.ntp_probe_delay = ms;
00748 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_DELAY_PROBE_TIME;
00749 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00750 }
00751
00752
00753
00754
00755
00756
00757 void rtnl_neightbl_set_anycast_delay(struct rtnl_neightbl *ntbl, uint64_t ms)
00758 {
00759 ntbl->nt_parms.ntp_anycast_delay = ms;
00760 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_ANYCAST_DELAY;
00761 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00762 }
00763
00764
00765
00766
00767
00768
00769 void rtnl_neightbl_set_proxy_delay(struct rtnl_neightbl *ntbl, uint64_t ms)
00770 {
00771 ntbl->nt_parms.ntp_proxy_delay = ms;
00772 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_PROXY_DELAY;
00773 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00774 }
00775
00776
00777
00778
00779
00780
00781 void rtnl_neightbl_set_locktime(struct rtnl_neightbl *ntbl, uint64_t ms)
00782 {
00783 ntbl->nt_parms.ntp_locktime = ms;
00784 ntbl->nt_parms.ntp_mask |= NEIGHTBLPARM_ATTR_LOCKTIME;
00785 ntbl->ce_mask |= NEIGHTBL_ATTR_PARMS;
00786 }
00787
00788
00789
00790 static struct nl_object_ops neightbl_obj_ops = {
00791 .oo_name = "route/neightbl",
00792 .oo_size = sizeof(struct rtnl_neightbl),
00793 .oo_dump[NL_DUMP_BRIEF] = neightbl_dump_brief,
00794 .oo_dump[NL_DUMP_FULL] = neightbl_dump_full,
00795 .oo_dump[NL_DUMP_STATS] = neightbl_dump_stats,
00796 .oo_compare = neightbl_compare,
00797 };
00798
00799 static struct nl_cache_ops rtnl_neightbl_ops = {
00800 .co_name = "route/neightbl",
00801 .co_hdrsize = sizeof(struct rtgenmsg),
00802 .co_msgtypes = {
00803 { RTM_NEWNEIGHTBL, NL_ACT_NEW, "new" },
00804 { RTM_SETNEIGHTBL, NL_ACT_SET, "set" },
00805 { RTM_GETNEIGHTBL, NL_ACT_GET, "get" },
00806 END_OF_MSGTYPES_LIST,
00807 },
00808 .co_protocol = NETLINK_ROUTE,
00809 .co_request_update = neightbl_request_update,
00810 .co_msg_parser = neightbl_msg_parser,
00811 .co_obj_ops = &neightbl_obj_ops,
00812 };
00813
00814 static void __init neightbl_init(void)
00815 {
00816 nl_cache_mngt_register(&rtnl_neightbl_ops);
00817 }
00818
00819 static void __exit neightbl_exit(void)
00820 {
00821 nl_cache_mngt_unregister(&rtnl_neightbl_ops);
00822 }
00823
00824