18 #include <netlink-local.h>
19 #include <netlink/netlink.h>
20 #include <netlink/attr.h>
21 #include <netlink/utils.h>
22 #include <netlink/object.h>
23 #include <netlink/route/rtnl.h>
24 #include <netlink/route/route.h>
25 #include <netlink/fib_lookup/request.h>
26 #include <netlink/fib_lookup/lookup.h>
33 struct fib_result_nl {
37 unsigned char fl_scope;
38 unsigned char tb_id_in;
41 unsigned char prefixlen;
49 static void result_free_data(
struct nl_object *obj)
51 struct flnl_result *res = nl_object_priv(obj);
53 if (res && res->fr_req)
59 struct flnl_result *dst = nl_object_priv(_dst);
60 struct flnl_result *src = nl_object_priv(_src);
63 if (!(dst->fr_req = (
struct flnl_request *)
70 static int result_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
73 struct flnl_result *res;
74 struct fib_result_nl *fr;
78 res = flnl_result_alloc();
82 res->ce_msgtype = n->nlmsg_type;
84 res->fr_req = flnl_request_alloc();
92 err = flnl_request_set_addr(res->fr_req, addr);
97 flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark);
98 flnl_request_set_tos(res->fr_req, fr->fl_tos);
99 flnl_request_set_scope(res->fr_req, fr->fl_scope);
100 flnl_request_set_table(res->fr_req, fr->tb_id_in);
102 res->fr_table_id = fr->tb_id;
103 res->fr_prefixlen = fr->prefixlen;
104 res->fr_nh_sel = fr->nh_sel;
105 res->fr_type = fr->type;
106 res->fr_scope = fr->scope;
107 res->fr_error = fr->err;
119 flnl_result_put(res);
125 struct flnl_result *res = (
struct flnl_result *) obj;
128 nl_dump_line(p,
"table %s prefixlen %u next-hop-selector %u\n",
129 rtnl_route_table2str(res->fr_table_id, buf,
sizeof(buf)),
130 res->fr_prefixlen, res->fr_nh_sel);
131 nl_dump_line(p,
"type %s ",
132 nl_rtntype2str(res->fr_type, buf,
sizeof(buf)));
133 nl_dump(p,
"scope %s error %s (%d)\n",
134 rtnl_scope2str(res->fr_scope, buf,
sizeof(buf)),
135 strerror(-res->fr_error), res->fr_error);
140 result_dump_line(obj, p);
144 uint32_t attrs,
int flags)
154 struct flnl_result *flnl_result_alloc(
void)
159 void flnl_result_put(
struct flnl_result *res)
208 struct nl_msg **result)
211 struct nl_addr *addr;
213 int tos, scope, table;
214 struct fib_result_nl fr = {0};
216 fwmark = flnl_request_get_fwmark(req);
217 tos = flnl_request_get_tos(req);
218 scope = flnl_request_get_scope(req);
219 table = flnl_request_get_table(req);
221 fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0;
222 fr.fl_tos = tos >= 0 ? tos : 0;
223 fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE;
224 fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC;
226 addr = flnl_request_get_addr(req);
228 return -NLE_MISSING_ATTR;
236 if (
nlmsg_append(msg, &fr,
sizeof(fr), NLMSG_ALIGNTO) < 0)
259 struct nl_cache *cache)
267 err = nl_send_auto_complete(sk, msg);
282 int flnl_result_get_table_id(
struct flnl_result *res)
284 return res->fr_table_id;
287 int flnl_result_get_prefixlen(
struct flnl_result *res)
289 return res->fr_prefixlen;
292 int flnl_result_get_nexthop_sel(
struct flnl_result *res)
294 return res->fr_nh_sel;
297 int flnl_result_get_type(
struct flnl_result *res)
302 int flnl_result_get_scope(
struct flnl_result *res)
304 return res->fr_scope;
307 int flnl_result_get_error(
struct flnl_result *res)
309 return res->fr_error;
315 .
oo_name =
"fib_lookup/result",
316 .oo_size =
sizeof(
struct flnl_result),
317 .oo_free_data = result_free_data,
318 .oo_clone = result_clone,
323 .oo_compare = result_compare,
327 .
co_name =
"fib_lookup/fib_lookup",
328 .co_hdrsize =
sizeof(
struct fib_result_nl),
330 { 0, NL_ACT_UNSPEC,
"any" },
331 END_OF_MSGTYPES_LIST,
333 .co_protocol = NETLINK_FIB_LOOKUP,
334 .co_msg_parser = result_msg_parser,
335 .co_obj_ops = &result_obj_ops,
338 static void __init fib_lookup_init(
void)
343 static void __exit fib_lookup_exit(
void)