Luci Status-->Routes routes outputting wrong (aliased) logical interface name

I have an interface modem0 defined as an aliased interface using @wan. This interface is in the wan zone, since it's just an alias to allow me to put a second private IP on my wan interface so that I can access my modem.

On the Luci Status->Routes page, instead of showing "wan" everywhere, it shows "modem0", which it shouldn't be doing (see below).

Looking at the code, there's a file called /usr/lib/lua/luci/view/admin_status/routes.htm which displays this Routes page in Luci. It makes a call to a function in a lua module luci.tools.webadmin.iface_get_network(v.dev) in order to display the logical name for the physical device name

<div class="cbi-map" id="cbi-network">
    <h2 name="content"><%:Routes%></h2>
    <div class="cbi-map-descr"><%:The following rules are currently active on this system.%></div>

    <div class="cbi-section">
        <legend>ARP</legend>
        <div class="cbi-section-node">
            <div class="table">
                <div class="tr table-titles">
                    <div class="th"><%_<abbr title="Internet Protocol Version 4">IPv4</abbr>-Address%></div>
                    <div class="th"><%_<abbr title="Media Access Control">MAC</abbr>-Address%></div>
                    <div class="th"><%:Interface%></div>
                </div>

                <%
                    for _, v in ipairs(ip.neighbors({ family = 4 })) do
                        if v.mac then
                %>
                <div class="tr cbi-rowstyle-<%=(style and 1 or 2)%>">
                    <div class="td"><%=v.dest%></div>
                    <div class="td"><%=v.mac%></div>
                    <div class="td"><%=luci.tools.webadmin.iface_get_network(v.dev) or '(' .. v.dev .. ')'%></div>
                </div>

Now, this function iface_get_network() is defined in /usr/lib/lua/luci/tools/webadmin.lua

function iface_get_network(iface)
    local link = ip.link(tostring(iface))
    if link.master then
        iface = link.master
    end

    local cur = uci.cursor()
    local dump = util.ubus("network.interface", "dump", { })
    if dump then
        local _, net
        for _, net in ipairs(dump.interface) do
            if net.l3_device == iface or net.device == iface then
                -- cross check with uci to filter out @name style aliases
                local uciname = cur:get("network", net.interface, "ifname")
                if type(uciname) == "string" and uciname:sub(1,1) ~= "@" or uciname then
                    return net.interface
                end
            end
        end
    end
end

It is clearly doing a check to see if this particular logical name is associated with an alias. But it's also apparently failing.

The conditional if type(uciname) == "string" and uciname:sub(1,1) ~= "@" or uciname looks dodgy.

uciname should be a string, so let's assume that it is, with the value of the string being @wan, so the second condition uciname:sub(1,1) ~= "@" will be false. But, since the variable is not null, the or uciname part will be true and therefore the entire condition will evaluate to true and it will still return the aliased logical name.

With this in mind, I tried to make some changes to this file to do some tests, but nothing seems to take effect. I can even return a string literal instead of `return net.interface" and the change to the code does not alter the output on the routes page.

So am I changing the right file (I recompiled and force-reinstalled the luci-base package after changing this file)?

Ok, I've answered my own question. The development wiki states that

Note that the LuCI framework caches precompiled variants of its Lua libraries in the /tmp directory, it is recommended to use uci set luci.ccache.enable=0; uci commit luci in order to disable the code caching for development purposes

Turning off the caching lets it pick up the changes and the dodgy conditional I noted above is indeed dodgy. I'll post a bug report on the github

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.