luci-lib-ip: support specifying source address in route()
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit d73553e530
)
This commit is contained in:
parent
89e029c59f
commit
0cbc51f297
2 changed files with 42 additions and 18 deletions
|
@ -1075,22 +1075,24 @@ static int cb_dump_route(struct nl_msg *msg, void *arg)
|
|||
|
||||
bitlen = AF_BITS(rt->rtm_family);
|
||||
|
||||
if ((f->type && rt->rtm_type != f->type) ||
|
||||
(f->family && rt->rtm_family != f->family) ||
|
||||
(f->proto && rt->rtm_protocol != f->proto) ||
|
||||
(f->scope && rt->rtm_scope != f->scope) ||
|
||||
(f->iif && iif != f->iif) ||
|
||||
(f->oif && oif != f->oif) ||
|
||||
(f->table && table != f->table) ||
|
||||
diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
|
||||
f->from_exact, &f->from) ||
|
||||
diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
|
||||
f->dst_exact, &f->dst) ||
|
||||
diff_prefix(rt->rtm_family, gw, bitlen,
|
||||
false, &f->gw) ||
|
||||
diff_prefix(rt->rtm_family, src, bitlen,
|
||||
false, &f->src))
|
||||
goto out;
|
||||
if (!f->get) {
|
||||
if ((f->type && rt->rtm_type != f->type) ||
|
||||
(f->family && rt->rtm_family != f->family) ||
|
||||
(f->proto && rt->rtm_protocol != f->proto) ||
|
||||
(f->scope && rt->rtm_scope != f->scope) ||
|
||||
(f->iif && iif != f->iif) ||
|
||||
(f->oif && oif != f->oif) ||
|
||||
(f->table && table != f->table) ||
|
||||
diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
|
||||
f->from_exact, &f->from) ||
|
||||
diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
|
||||
f->dst_exact, &f->dst) ||
|
||||
diff_prefix(rt->rtm_family, gw, bitlen,
|
||||
false, &f->gw) ||
|
||||
diff_prefix(rt->rtm_family, src, bitlen,
|
||||
false, &f->src))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (s->callback)
|
||||
lua_pushvalue(s->L, 2);
|
||||
|
@ -1216,10 +1218,15 @@ static int _route_dump(lua_State *L, struct dump_filter *filter)
|
|||
|
||||
nlmsg_append(msg, &rtm, sizeof(rtm), 0);
|
||||
|
||||
if (filter->get)
|
||||
if (filter->get) {
|
||||
nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
|
||||
&filter->dst.addr.v6);
|
||||
|
||||
if (filter->src.family)
|
||||
nla_put(msg, RTA_SRC, AF_BYTES(filter->src.family),
|
||||
&filter->src.addr.v6);
|
||||
}
|
||||
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
|
||||
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
|
||||
nl_cb_err(cb, NL_CB_CUSTOM, cb_error, &s);
|
||||
|
@ -1236,17 +1243,32 @@ static int _route_dump(lua_State *L, struct dump_filter *filter)
|
|||
|
||||
out:
|
||||
nl_cb_put(cb);
|
||||
return (s.callback == 0);
|
||||
|
||||
if (s.callback)
|
||||
return 0;
|
||||
|
||||
if (!filter->get)
|
||||
return 1;
|
||||
|
||||
return (s.index > 0);
|
||||
}
|
||||
|
||||
static int route_get(lua_State *L)
|
||||
{
|
||||
struct dump_filter filter = { .get = true };
|
||||
const char *dest = luaL_checkstring(L, 1);
|
||||
const char *from = luaL_optstring(L, 2, NULL);
|
||||
|
||||
if (!parse_cidr(dest, &filter.dst))
|
||||
return _error(L, -1, "Invalid destination");
|
||||
|
||||
if (from && !parse_cidr(from, &filter.src))
|
||||
return _error(L, -1, "Invalid source");
|
||||
|
||||
if (filter.src.family != 0 &&
|
||||
filter.src.family != filter.dst.family)
|
||||
return _error(L, -1, "Different source/destination family");
|
||||
|
||||
filter.family = filter.dst.family;
|
||||
|
||||
return _route_dump(L, &filter);
|
||||
|
|
|
@ -178,6 +178,8 @@ Determine the route leading to the given destination.
|
|||
@name route
|
||||
@param address A `luci.ip.cidr` instance or a string containing
|
||||
a valid IPv4 or IPv6 range as specified by `luci.ip.new()`.
|
||||
@param source A `luci.ip.cidr` instance or a string containing
|
||||
the preferred source address for route selection (optional).
|
||||
@return <p>Table containing the fields described below.</p>
|
||||
<table id="routetable">
|
||||
<tr><th>Field</th><th>Description</th></tr>
|
||||
|
|
Loading…
Reference in a new issue