OpenWrt Forum Archive

Topic: skeleton and proposal for a better configuration scheme

The content of this topic has been archived on 27 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

NOTE: If you find this interesting have a look at the wiki too:

First, thank you for answering my question on nvram policy. I have thought about a configuration scheme along the same lines that tries to be more flexible to configure than nvrams notion of wan/lan interfaces and more straight forward to understand and customize than currently.

Today I have roughly sketched the files I am attaching, note that I am quite a bash novice, but I hope you can understand what is meant and could help or throw in some more ideas.

I'd suggest to first look into the "interfaces" file then domains and firewall. They are supposed to be sourced from a init.d or helper scripts similar to Instead of invoking nvram_get directly with a logic that tends to be specific to only a subset of possible setups, the logic could iterate over whatever interfaces are defined. could become such a init.d scipt that sets up the dhcpd.


Attachment didn't seem to work.

# /etc/sysconfig/interfaces

#    The OpenWRT interface configuration.
# This file maps the various nvram settings
# into a more flexible scheme.
# You can either change your nvram settings by issuing the command
# nvram set <key>="<value>" and a subsequent "nvram commit"
# to configure OpenWRT.
# Or, you can take full advantage of OpenWRT configurability and specify
# your configuration directly in this file, save it to jffs2 and leave
# the nvram stuff untouched.
# This will allow you to freely define special interfaces for use as
# client mode wlan, WDS, DMZ etc.
# OpenWRT defaults to the following interface naming conventions:
#      vlan0 is the ethernet port labeled Internet or WAN
#      vlan1 to vlan4 are the individual ethernet ports
#      vlan5 (or better 15?) by default refers to all numbered ports
#      wlan0 is the wireless interface

iface () {
   interfaces="$interfaces $1"

# vlan0 interface configuration
# ( Factory wise labeled WAN or Internet )

iface vlan0
   vlan0_conf_method=$(nvram_get wan_proto)
   vlan0_address=$(nvram_get wan_ipaddr)
   vlan0_hwadress=$(nvram_get wan_hwaddr)
   vlan0_netmask=$(nvram_get wan_netmask)
   vlan0_gateway=$(nvram_get wan_gateway)

# PPP protocol configuration

ppp_username=$(nvram_get ppp_username)
ppp_password=$(nvram_get ppp_passwd)
ppp_redial=$(nvram_get ppp_redialperiod)
ppp_idletime=$(nvram_get ppp_idletime)

# br0 bridge configuration
# ( Factory settings bridge wlan and
#  local network together. That is not recommended
#  because direct wireless access to your private net
#  is not secure! )
# if you want it nevertheless you need to
# uncomment the following and modify
# /etc/sysconfig/dhcpd further settings for
# interfaces that are part of a bridge will
# be ignored.

# iface br0 
#    br0_conf_method=$(nvram_get lan_proto)
#    br0_ports=$(nvram_get lan_ifnames)
#    br0_stp=$(nvram_get lan_stp)
#    br0_address=$(nvram_get lan_ipaddr)
#    br0_hwadress=$(nvram_get lan_hwaddr)
#    br0_netmask =$(nvram_get lan_netmask)

# ethernet port configuration
# (by default all local ports are configured as single
# vlan5 interface, but you can define individual
# interfaces (vlan1-4) for each port by
# altering the following)

# put admcfg stuff here

# vlan5 interface configuration
# (uses your previous  nvram "lan" settings
#   as default, if br0 is not enabed)

iface vlan5
   vlan5_conf_method=$(nvram_get lan_proto)
   vlan5_address=$(nvram_get lan_ipaddr)
   vlan5_hwadress=$(nvram_get lan_hwaddr)
   vlan5_netmask=$(nvram_get lan_netmask)

# wlan0 interface configuration

iface wlan0
   wlan0_essid=$(nvram_get wl0_ssid)
   wlan0_channel=$(nvram_get wl0_channel)
   wlan0_mode=$(nvram_get wl0_mode) # master,managed,ap or sta
   wlan0_key=$(nvram_get wl0_key1) 
# /etc/sysconfig/domains

# DNS and dhcpd configuration

# The hostname of this router
HOSTNAME=$(nvram_get wan_hostame)

# Parent DNS server to use, will be overridden if another
# address is aquired by dhcp or ppp
parent_dns=$(nvram_get wan_dns)

dhcpd_enable=$(nvram_get dhcp_enable)

dhcpd_iface () {
   dhcpd_interfaces="$dhcpd_interfaces $1"

dhcpd_iface vlan5
   dhcpd_vlan5_startip=# somthing like "vlan5_address AND netmask + $(nvram_get dhcp_start)"
   dhcpd_vlan5_endip=$(nvram_get dhcp_start)+$(nvram_get dhcp_num)

dhcpd_iface wlan0
   dhcpd_wlan0_startip=# somthing like "wlan0_address AND netmask + $(nvram_get dhcp_start)"
   dhcpd_wlan0_endip=$(nvram_get dhcp_start)+$(nvram_get dhcp_num)

# if you really want to use bridging have only the following section activated:
# dhcpd_iface="br0"
#    dhcpd_br0_startip=# somthing like "br0_address AND netmask + $(nvram_get dhcp_start)"
#    dhcpd_br0_endip=$(nvram_get dhcp_start)+$(nvram_get dhcp_num)
#    dhcpd_br0_maxleases=200
#    dhcpd_br0_domain=home.lan
#    dhcpd_br0_leasetime=7200
# /etc/sysconfig/firewall
# from which the FireHOL script generates iptables rules.

version 5

    interface ppp+ red
        protection strong 10/sec 10
        server ident reject with tcp-reset

    interface wlan0 blue
        protection strong 10/sec 10
        server ssh accept

    interface vlan5 green
        policy reject
        server "dns icmp dhcp http ssh " accept

    router green2red inface vlan5 outface ppp+
        route all accept
        client ident    reject with tcp-reset

    router blue2red inface wlan0 outface ppp+
        route all accept
        client ident    reject with tcp-reset
# /etc/init.d/
#  generate dhcp server configuration file
#  according to nvram settings if  /etc/udhcpd.conf
#  is not a real fle. (is a symlink to /tmp/etc/)

# source OpenWRT settings or nvram mapping
. /etc/sysconfig/interfaces
. /etc/sysconfig/domains

if [ dhcpd_enable != 1 ]  exit

# first add some general settings
cat >> /tmp/etc/udhcpd.conf << EOF

lase_file /tmp/udhcpd.leases
pidfile /tmp/


for $if in $dhcpd_interfaces do {

cat >> /tmp/etc/udhcpd.conf << EOF

interface $if
start $dhcpd_$if_startip
end $dhcpd_$if_endip
max_leases $dhcpd_$if_maxleases
lease $dhcpd_$if_leasetime

domain $if_domain
option dns $if_address

option subnet  $if_netmask
option router $if_address



# force respawn of udhcpd ?
killall udhcpd

The NVRAM area is already allocated, with access methods already defined. We don't save any space by deleting NVRAM variables, nor do we gain anything by ignoring existing variables and duplicating them in a config file. Unfortunately the existing NVRAM variables don't lend themselves well towards multiple vlan groupings, pushing us towards a separte means of configuration.

While a nice easy to read config file would fit in with openwrt's current commandline interface and may be trivial to maintain by hand, creating a web interface that's able to display the current configuration and selectively change values becomes much more difficult. One variation I'd suggest is splitting the configuration up into smaller groups; instead of parsing one massive file you'd break it up by work loads, simplifying the parse. Example:



and the parser:

#syntax: ifup vlan0
ifup () (
  . /etc/network/interfaces/$1
  ifconfig $1 $ipaddr netmask $netmask

#just thrown in here as an example:
configure_all_interfaces () (
  cd /etc/network/interfaces
  for iface in *; do
    ifup $iface

By creating a separate file per interface, our parser nolonger has to keep track of which interface the config line refers to and each interface file can reuse the same set of variables making it simpler for a script to modify settings.

There's my $0.02

Hmm, not sure if it is really that much harder to "parse" a single file than several tiny ones. For hand editing I'd prefer one file for interfaces for example. The files arent't actually that massive as it may have looked like copied into a single post ;-) Most of the config file lines were comments anyway.

For the subset of configurations that can be represented by nvram setting the webinterface just needs to do nvram sets, as always. But if desired an expert mode could easily represent and modify the config files to I think. Depending on the webfrontend implementation the script could source the variables set in the config files directly or query a tiny bash helper script to get settings. And changing values could be as easy as
(plus a interface stanza create (cat some-lines >>) and delete (sed delete-some lines) function)

To configure the router I had to go through all the startup scripts first and had to at least partly understand how they worked before I could figure out which nvram varables where used for what and how, and be able to start changing the configuration without just guessing.

What I am trying to achieve with the config files is that new users can get an idea and overview of how to configure their router up front. Most of the variable definitions are just gathered from the existing initscripts anyway, so it shouldn't be much duplication, rather a consolidation maybe.

Another benefit I see is when OpenWRT is more generically configurable in configfiles without changing things in the initscripts themselves it can be consistent across more different hardware.  (just provide different default config file)

Especially could become more generic.  I'd also suggest to make ifup and ifdown executable shellscripts instead of shell functions.

Here is the simple parser example for the single file case.

#syntax: ifup vlan0
  .  /etc/network/interfaces 
  ifconfig $1 $(${1}_address) netmask $(${$1}_netmask )

To support bringing up all interfaces at once ("ifup -a") it would just need to do the ifconfig line for all $if in $interfaces (each iface statement in /etc/network interfaces adds the interface name to the $interfaces enumeration variable)


Has anybody had some more thoghts on this in the meantime, or maybe allready separated some of the the "this=$(nvram_get that)" lines from within the boot scripts?

I ask because AFAIK there is no cvs repository I could check, or did I miss something here?


Of course, there's a CVS repository. Click here.

Thanks for the hint Phil!

Ok, is there someone out there who is also interested to ease flexibility of configuring OpenWRT and would help me with realizing this and make the changes in cvs?

- centralizing all the nvram_gets that are currently scattered around in the scripts
  (maybe more or less as postedd above)

- make the boot/configure scripts more universal
(clean up parts that currently hardcode specific configs, especially, probably create a ifup/ifdown scripts from it that sets up the interfaces as defined in /etc/network/interfaces)

(don't worry about the firewall config I posted above, that would be a different thing)

cool, noticed has been split up into ifup/down. I too, sat down some more and worked on this. I'd need someone who could proofread what I did though. mbm could I send the modified files to you? I've made a little tarball.

- centralized nvram_get access:
  introduced: /etc/network/interfaces
   and let S10boot and S45firewall source them.
- added interface enumeration to
- made S40network handle all interfaces not just wan, lan, wifi.
- made ifup/down flexible to handle more than wan lan or wifi
- split off from ifup
- added seed for S35vlan
- added script to generate udhcpd.conf/dnsmasq.conf  from nvram variables


There is now a wiki page about flexible configuration, where you can check out and edit the scripts:

I agree with mbm.  Anything that makes it easier to make a web interface gets my vote.  I would prefer a file for each interface.  I don't think that NVRAM variables are going to work for a web interface - at the moment we are currently hamstrung by original interface configuration that the NVRAM variables are built around.  So how do we proceed?  How should NVRAM variables interact with config files?  Why should we continue to use them?  What method gives us the most amount of flexibility without creating piles of files that eat up valuable flash memory?

The discussion might have continued from here.