bashshellfirewallopenwrtuci

Luci openWRT UCI firewall rule update without position number


Hey all I have been trying find some code that would allow me to update my firewall rule via the UCI.

The way I am currently adding the new rule is like this:

uci add firewall rule
uci set firewall.@rule[21].name='B Macbook Air'
uci set firewall.@rule[21].src='lan'
uci set firewall.@rule[21].family='ipv4'
uci set firewall.@rule[21].src_ip='192.168.1.227'
uci set firewall.@rule[21].src_mac='00:00:00:00:00:00'
uci set firewall.@rule[21].dest='wan'
uci set firewall.@rule[21].proto='all'
uci set firewall.@rule[21].target='REJECT'
uci set firewall.@rule[21].enabled='1'
uci commit firewall

This produces the correct rule inside luci (branch (git-22.347.45520-d30ab74)):

enter image description here

The way I update one of the rules' enabled or disable is this:

uci set firewall.@rule[21].name="B Macbook Air"
uci set firewall.@rule[21].enabled="1"
uci commit firewall

Which works as expected but I am wondering if there's a way too just call the firewall rules name instead of needing to know the position (ie: [21])?

Like this:

uci set firewall.@rule.name="B Macbook Air"
uci set firewall.@rule.enabled="1"
uci commit firewall

But of course the above does not work. Gives an error of

root@turris:~# uci set firewall.@rule.name="B Macbook Air"
uci: Invalid argument

Is this possible to do?


Solution

  • You can write a loop to check each rule's .name.

    The following example supposes the index numbers start from 0 and are consecutive.

    (Not sure if bash is installed by default. The example code is in sh.)

    #!/bin/sh
    
    name='Support-UDP-Traceroute'
    option=enabled
    value=1
    
    i=0
    while true; do
      rname=$( uci get "firewall.@rule[$i].name" 2> /dev/null )
      if [ $? != 0 ]; then
        # no more rules
        break
      fi
    
      if [ "$rname" = "$name" ]; then
        echo "found: $name: [$i]"
        # uci set firewall.@rule[$i].$option="$value"
        # uci commit firewall
    
        break
      fi
    
      let i++
    done
    

    Make it a function if you need to do this often. And you need to update it a bit if the index numbers are not consecutive.


    Another solution is to use uci show firewall:

    i=$( uci show firewall | grep/sed/awk/... )
    uci set firewall.@rule[$i].the_option="the_value"
    uci commit firewall
    

    This way you don't care if the index numbers are consecutive or not.