13#include "nl-default.h"
15#include <netlink/netlink.h>
16#include <netlink/attr.h>
17#include <netlink/utils.h>
18#include <netlink/object.h>
19#include <netlink/route/rtnl.h>
20#include <netlink/route/route.h>
21#include <netlink/fib_lookup/request.h>
22#include <netlink/fib_lookup/lookup.h>
24#include "nl-priv-dynamic-core/object-api.h"
25#include "nl-priv-dynamic-core/cache-api.h"
26#include "nl-priv-dynamic-core/nl-core.h"
33 struct flnl_request * fr_req;
42static struct nl_cache_ops fib_lookup_ops;
43static struct nl_object_ops result_obj_ops;
50 unsigned char fl_scope;
51 unsigned char tb_id_in;
54 unsigned char prefixlen;
62static void result_free_data(
struct nl_object *obj)
64 struct flnl_result *res = nl_object_priv(obj);
66 if (res && res->fr_req)
70static int result_clone(
struct nl_object *_dst,
struct nl_object *_src)
72 struct flnl_result *dst = nl_object_priv(_dst);
73 struct flnl_result *src = nl_object_priv(_src);
78 if (!(dst->fr_req = (
struct flnl_request *)
nl_object_clone(OBJ_CAST(src->fr_req))))
85static int result_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
86 struct nlmsghdr *n,
struct nl_parser_param *pp)
88 struct flnl_result *res;
89 struct fib_result_nl *fr;
93 res = flnl_result_alloc();
97 res->ce_msgtype = n->nlmsg_type;
99 res->fr_req = flnl_request_alloc();
107 err = flnl_request_set_addr(res->fr_req, addr);
112 flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark);
113 flnl_request_set_tos(res->fr_req, fr->fl_tos);
114 flnl_request_set_scope(res->fr_req, fr->fl_scope);
115 flnl_request_set_table(res->fr_req, fr->tb_id_in);
117 res->fr_table_id = fr->tb_id;
118 res->fr_prefixlen = fr->prefixlen;
119 res->fr_nh_sel = fr->nh_sel;
120 res->fr_type = fr->type;
121 res->fr_scope = fr->scope;
122 res->fr_error = fr->err;
124 err = pp->pp_cb((
struct nl_object *) res, pp);
134 flnl_result_put(res);
138static void result_dump_line(
struct nl_object *obj,
struct nl_dump_params *p)
140 struct flnl_result *res = (
struct flnl_result *) obj;
143 nl_dump_line(p,
"table %s prefixlen %u next-hop-selector %u\n",
144 rtnl_route_table2str(res->fr_table_id, buf,
sizeof(buf)),
145 res->fr_prefixlen, res->fr_nh_sel);
146 nl_dump_line(p,
"type %s ",
147 nl_rtntype2str(res->fr_type, buf,
sizeof(buf)));
148 nl_dump(p,
"scope %s error %s (%d)\n",
149 rtnl_scope2str(res->fr_scope, buf,
sizeof(buf)),
150 nl_strerror_l(-res->fr_error), res->fr_error);
153static void result_dump_details(
struct nl_object *obj,
struct nl_dump_params *p)
155 result_dump_line(obj, p);
158static uint64_t result_compare(
struct nl_object *_a,
struct nl_object *_b,
159 uint64_t attrs,
int flags)
169struct flnl_result *flnl_result_alloc(
void)
174void flnl_result_put(
struct flnl_result *res)
223 struct nl_msg **result)
226 struct nl_addr *addr;
228 int tos, scope, table;
229 struct fib_result_nl fr = {0};
231 fwmark = flnl_request_get_fwmark(req);
232 tos = flnl_request_get_tos(req);
233 scope = flnl_request_get_scope(req);
234 table = flnl_request_get_table(req);
236 fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0;
237 fr.fl_tos = tos >= 0 ? tos : 0;
238 fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE;
239 fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC;
241 addr = flnl_request_get_addr(req);
243 return -NLE_MISSING_ATTR;
251 if (
nlmsg_append(msg, &fr,
sizeof(fr), NLMSG_ALIGNTO) < 0)
274 struct nl_cache *cache)
297int flnl_result_get_table_id(
struct flnl_result *res)
299 return res->fr_table_id;
302int flnl_result_get_prefixlen(
struct flnl_result *res)
304 return res->fr_prefixlen;
307int flnl_result_get_nexthop_sel(
struct flnl_result *res)
309 return res->fr_nh_sel;
312int flnl_result_get_type(
struct flnl_result *res)
317int flnl_result_get_scope(
struct flnl_result *res)
319 return res->fr_scope;
322int flnl_result_get_error(
struct flnl_result *res)
324 return res->fr_error;
329static struct nl_object_ops result_obj_ops = {
330 .oo_name =
"fib_lookup/result",
331 .oo_size =
sizeof(
struct flnl_result),
332 .oo_free_data = result_free_data,
333 .oo_clone = result_clone,
338 .oo_compare = result_compare,
341static struct nl_cache_ops fib_lookup_ops = {
342 .co_name =
"fib_lookup/fib_lookup",
343 .co_hdrsize =
sizeof(
struct fib_result_nl),
345 { 0, NL_ACT_UNSPEC,
"any" },
346 END_OF_MSGTYPES_LIST,
348 .co_protocol = NETLINK_FIB_LOOKUP,
349 .co_msg_parser = result_msg_parser,
350 .co_obj_ops = &result_obj_ops,
353static void _nl_init fib_lookup_init(
void)
358static void _nl_exit fib_lookup_exit(
void)
struct nl_addr * nl_addr_build(int family, const void *buf, size_t size)
Allocate abstract address based on a binary address.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
int nl_cache_pickup_checkdup(struct nl_sock *sk, struct nl_cache *cache)
Pickup a netlink dump response and put it into a cache.
@ NL_STOP
Stop parsing altogether and discard remaining messages.
struct nl_cache * flnl_result_alloc_cache(void)
Allocate lookup result cache.
int flnl_lookup_build_request(struct flnl_request *req, int flags, struct nl_msg **result)
Builds a netlink request message to do a lookup.
int flnl_lookup(struct nl_sock *sk, struct flnl_request *req, struct nl_cache *cache)
Perform FIB Lookup.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
struct nl_object * nl_object_clone(struct nl_object *obj)
Allocate a new object and copy all data from an existing object.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.