144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/fib_lookup/lookup.c FIB Lookup 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 9054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 13054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @ingroup rtnl 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @defgroup fib_lookup FIB Lookup 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @brief 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf 19054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart#include <netlink-private/netlink.h> 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netlink.h> 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/attr.h> 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/utils.h> 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/object.h> 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/rtnl.h> 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/route/route.h> 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/fib_lookup/request.h> 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/fib_lookup/lookup.h> 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */ 3044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops fib_lookup_ops; 3144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops result_obj_ops; 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf/* not exported so far */ 3444d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct fib_result_nl { 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t fl_addr; /* To be looked up*/ 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t fl_fwmark; 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char fl_tos; 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char fl_scope; 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char tb_id_in; 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char tb_id; /* Results */ 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char prefixlen; 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char nh_sel; 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char type; 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned char scope; 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */ 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf 5044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void result_free_data(struct nl_object *obj) 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct flnl_result *res = nl_object_priv(obj); 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (res && res->fr_req) 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put(OBJ_CAST(res->fr_req)); 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf 5844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int result_clone(struct nl_object *_dst, struct nl_object *_src) 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct flnl_result *dst = nl_object_priv(_dst); 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct flnl_result *src = nl_object_priv(_src); 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->fr_req) 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(dst->fr_req = (struct flnl_request *) 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_clone(OBJ_CAST(src->fr_req)))) 668a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf 7144d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 723040a1d6254465bed9e44e4d1bf279c2c50cd16aThomas Graf struct nlmsghdr *n, struct nl_parser_param *pp) 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct flnl_result *res; 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct fib_result_nl *fr; 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *addr; 778a3efffa5b3fde252675239914118664d36a2c24Thomas Graf int err = -NLE_INVAL; 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf res = flnl_result_alloc(); 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!res) 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf res->ce_msgtype = n->nlmsg_type; 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_req = flnl_request_alloc(); 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!res->fr_req) 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf fr = nlmsg_data(n); 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nl_addr_build(AF_INET, &fr->fl_addr, 4); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!addr) 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf err = flnl_request_set_addr(res->fr_req, addr); 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(addr); 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark); 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf flnl_request_set_tos(res->fr_req, fr->fl_tos); 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf flnl_request_set_scope(res->fr_req, fr->fl_scope); 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf flnl_request_set_table(res->fr_req, fr->tb_id_in); 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_table_id = fr->tb_id; 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_prefixlen = fr->prefixlen; 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_nh_sel = fr->nh_sel; 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_type = fr->type; 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_scope = fr->scope; 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_error = fr->err; 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf err = pp->pp_cb((struct nl_object *) res, pp); 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf /* REAL HACK, fib_lookup doesn't support ACK nor does it 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf * send a DONE message, enforce end of message stream 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf * after just the first message */ 117155ad439a49df034ec58ee4218834bc5b0120515Thomas Graf err = NL_STOP; 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf 11944d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf flnl_result_put(res); 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf 124d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void result_dump_line(struct nl_object *obj, struct nl_dump_params *p) 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct flnl_result *res = (struct flnl_result *) obj; 127054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart char buf[256]; 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf 129d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "table %s prefixlen %u next-hop-selector %u\n", 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_route_table2str(res->fr_table_id, buf, sizeof(buf)), 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf res->fr_prefixlen, res->fr_nh_sel); 132d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, "type %s ", 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_rtntype2str(res->fr_type, buf, sizeof(buf))); 134d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump(p, "scope %s error %s (%d)\n", 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf rtnl_scope2str(res->fr_scope, buf, sizeof(buf)), 136054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart strerror_r(-res->fr_error, buf, sizeof(buf)), res->fr_error); 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf 139d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void result_dump_details(struct nl_object *obj, struct nl_dump_params *p) 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 141d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf result_dump_line(obj, p); 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf 14444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int result_compare(struct nl_object *_a, struct nl_object *_b, 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf 15544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct flnl_result *flnl_result_alloc(void) 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct flnl_result *) nl_object_alloc(&result_obj_ops); 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf 16044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid flnl_result_put(struct flnl_result *res) 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) res); 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Cache Management 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocate lookup result cache. 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf * 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf * Allocates a new lookup result cache and initializes it properly. 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @note Free the memory after usage using nl_cache_destroy_and_free(). 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return Newly allocated cache or NULL if an error occured. 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 18044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_cache *flnl_result_alloc_cache(void) 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_cache_alloc(&fib_lookup_ops); 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Lookup 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a netlink request message to do a lookup 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg req Requested match. 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg flags additional netlink message flags 196054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @arg result Result pointer 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf * 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a new netlink message requesting a change of link attributes. 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf * The netlink message header isn't fully equipped with all relevant 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf * fields and must be sent out via nl_send_auto_complete() or 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf * supplemented as needed. 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf * \a old must point to a link currently configured in the kernel 20344d362409d5469aed47d19e7908d19bd194493aThomas Graf * and \a tmpl must contain the attributes to be changed set via 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf * \c rtnl_link_set_* functions. 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf * 206054c80d775f2ae9b8f50260bdfcb821e99c0da2aPaul Stewart * @return 0 on success or a negative error code. 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 2088a3efffa5b3fde252675239914118664d36a2c24Thomas Grafint flnl_lookup_build_request(struct flnl_request *req, int flags, 2098a3efffa5b3fde252675239914118664d36a2c24Thomas Graf struct nl_msg **result) 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *addr; 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf uint64_t fwmark; 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf int tos, scope, table; 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct fib_result_nl fr = {0}; 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf fwmark = flnl_request_get_fwmark(req); 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf tos = flnl_request_get_tos(req); 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf scope = flnl_request_get_scope(req); 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf table = flnl_request_get_table(req); 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0; 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf fr.fl_tos = tos >= 0 ? tos : 0; 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE; 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC; 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = flnl_request_get_addr(req); 2288a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if (!addr) 2298a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_MISSING_ATTR; 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr); 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf msg = nlmsg_alloc_simple(0, flags); 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!msg) 2358a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0) 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf 2408a3efffa5b3fde252675239914118664d36a2c24Thomas Graf *result = msg; 2418a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return 0; 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf 24344d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 2458a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_MSGSIZE; 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Perform FIB Lookup 2501155370f520cb64657e25153255cf7dc1424317fThomas Graf * @arg sk Netlink socket. 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg req Lookup request object. 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @arg cache Cache for result. 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf * Builds a netlink message to request a FIB lookup, waits for the 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf * reply and adds the result to the specified cache. 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf * 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf * @return 0 on success or a negative error code. 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 2591155370f520cb64657e25153255cf7dc1424317fThomas Grafint flnl_lookup(struct nl_sock *sk, struct flnl_request *req, 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *cache) 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_msg *msg; 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf int err; 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf 2658a3efffa5b3fde252675239914118664d36a2c24Thomas Graf if ((err = flnl_lookup_build_request(req, 0, &msg)) < 0) 2668a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return err; 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf 2681155370f520cb64657e25153255cf7dc1424317fThomas Graf err = nl_send_auto_complete(sk, msg); 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf nlmsg_free(msg); 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (err < 0) 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf return err; 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf 2731155370f520cb64657e25153255cf7dc1424317fThomas Graf return nl_cache_pickup(sk, cache); 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attribute Access 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf 28344d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_table_id(struct flnl_result *res) 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_table_id; 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf 28844d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_prefixlen(struct flnl_result *res) 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_prefixlen; 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf 29344d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_nexthop_sel(struct flnl_result *res) 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_nh_sel; 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf 29844d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_type(struct flnl_result *res) 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_type; 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf 30344d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_scope(struct flnl_result *res) 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_scope; 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf 30844d362409d5469aed47d19e7908d19bd194493aThomas Grafint flnl_result_get_error(struct flnl_result *res) 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf return res->fr_error; 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf 31544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_object_ops result_obj_ops = { 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "fib_lookup/result", 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct flnl_result), 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = result_free_data, 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = result_clone, 320d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf .oo_dump = { 321d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_LINE] = result_dump_line, 322d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_DETAILS] = result_dump_details, 323d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf }, 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = result_compare, 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf 32744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct nl_cache_ops fib_lookup_ops = { 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_name = "fib_lookup/fib_lookup", 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_hdrsize = sizeof(struct fib_result_nl), 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msgtypes = { 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf { 0, NL_ACT_UNSPEC, "any" }, 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf END_OF_MSGTYPES_LIST, 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf }, 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_protocol = NETLINK_FIB_LOOKUP, 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_msg_parser = result_msg_parser, 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf .co_obj_ops = &result_obj_ops, 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf 33944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __init fib_lookup_init(void) 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_register(&fib_lookup_ops); 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf 34444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void __exit fib_lookup_exit(void) 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_cache_mngt_unregister(&fib_lookup_ops); 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 350