/** * Builds a netlink request message to do a lookup * @arg req Requested match. * @arg flags additional netlink message flags * * Builds a new netlink message requesting a change of link attributes. * The netlink message header isn't fully equipped with all relevant * fields and must be sent out via nl_send_auto_complete() or * supplemented as needed. * \a old must point to a link currently configured in the kernel * and \a tmpl must contain the attributes to be changed set via * \c rtnl_link_set_* functions. * * @return New netlink message * @note Not all attributes can be changed, see * \ref link_changeable "Changeable Attributes" for more details. */ struct nl_msg *flnl_lookup_build_request(struct flnl_request *req, int flags) { struct nl_msg *msg; struct nl_addr *addr; uint64_t fwmark; int tos, scope, table; struct fib_result_nl fr = {0}; fwmark = flnl_request_get_fwmark(req); tos = flnl_request_get_tos(req); scope = flnl_request_get_scope(req); table = flnl_request_get_table(req); fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0; fr.fl_tos = tos >= 0 ? tos : 0; fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE; fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC; addr = flnl_request_get_addr(req); if (!addr) { nl_error(EINVAL, "Request must specify the address"); return NULL; } fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr); msg = nlmsg_alloc_simple(0, flags); if (!msg) goto errout; if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0) goto errout; return msg; errout: nlmsg_free(msg); return NULL; }
/** * Builds a netlink request message to do a lookup * @arg req Requested match. * @arg flags additional netlink message flags * @arg result Result pointer * * Builds a new netlink message requesting a change of link attributes. * The netlink message header isn't fully equipped with all relevant * fields and must be sent out via nl_send_auto_complete() or * supplemented as needed. * \a old must point to a link currently configured in the kernel * and \a tmpl must contain the attributes to be changed set via * \c rtnl_link_set_* functions. * * @return 0 on success or a negative error code. */ int flnl_lookup_build_request(struct flnl_request *req, int flags, struct nl_msg **result) { struct nl_msg *msg; struct nl_addr *addr; uint64_t fwmark; int tos, scope, table; struct fib_result_nl fr = {0}; fwmark = flnl_request_get_fwmark(req); tos = flnl_request_get_tos(req); scope = flnl_request_get_scope(req); table = flnl_request_get_table(req); fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0; fr.fl_tos = tos >= 0 ? tos : 0; fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE; fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC; addr = flnl_request_get_addr(req); if (!addr) return -NLE_MISSING_ATTR; fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr); msg = nlmsg_alloc_simple(0, flags); if (!msg) return -NLE_NOMEM; if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0) goto errout; *result = msg; return 0; errout: nlmsg_free(msg); return -NLE_MSGSIZE; }