2 LuCI - Lua Configuration Interface
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
16 local fs = require "nixio.fs"
17 local ut = require "luci.util"
18 local nw = require "luci.model.network"
19 local fw = require "luci.model.firewall"
23 local has_dnsmasq = fs.access("/etc/config/dhcp")
24 local has_firewall = fs.access("/etc/config/firewall")
25 local has_radvd = fs.access("/etc/config/radvd")
27 local has_3g = fs.access("/usr/bin/gcom")
28 local has_pptp = fs.access("/usr/sbin/pptp")
29 local has_pppd = fs.access("/usr/sbin/pppd")
30 local has_pppoe = fs.glob("/usr/lib/pppd/*/rp-pppoe.so")()
31 local has_pppoa = fs.glob("/usr/lib/pppd/*/pppoatm.so")()
32 local has_ipv6 = fs.access("/proc/net/ipv6_route")
33 local has_6in4 = fs.access("/lib/network/6in4.sh")
34 local has_6to4 = fs.access("/lib/network/6to4.sh")
35 local has_relay = fs.access("/lib/network/relay.sh")
37 m = Map("network", translate("Interfaces") .. " - " .. arg[1]:upper(), translate("On this page you can configure the network interfaces. You can bridge several interfaces by ticking the \"bridge interfaces\" field and enter the names of several network interfaces separated by spaces. You can also use <abbr title=\"Virtual Local Area Network\">VLAN</abbr> notation <samp>INTERFACE.VLANNR</samp> (<abbr title=\"for example\">e.g.</abbr>: <samp>eth0.1</samp>)."))
52 local net = nw:get_network(arg[1])
54 -- redirect to overview page if network does not exist anymore (e.g. after a revert)
56 luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
60 local ifc = net:get_interfaces()[1]
62 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
65 s:tab("general", translate("General Setup"))
66 if has_ipv6 then s:tab("ipv6", translate("IPv6 Setup")) end
67 if has_pppd then s:tab("ppp", translate("PPP Settings")) end
68 if has_pppoa then s:tab("atm", translate("ATM Settings")) end
69 if has_6in4 or has_6to4 then s:tab("tunnel", translate("Tunnel Settings")) end
70 if has_relay then s:tab("relay", translate("Relay Settings")) end
71 s:tab("physical", translate("Physical Settings"))
72 if has_firewall then s:tab("firewall", translate("Firewall Settings")) end
74 st = s:taboption("general", DummyValue, "__status", translate("Status"))
75 st.template = "admin_network/iface_status"
79 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
81 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
84 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
85 p.override_scheme = true
87 p:value("static", translate("static"))
88 p:value("dhcp", "DHCP")
89 if has_pppd then p:value("ppp", "PPP") end
90 if has_pppoe then p:value("pppoe", "PPPoE") end
91 if has_pppoa then p:value("pppoa", "PPPoA") end
92 if has_3g then p:value("3g", "UMTS/3G") end
93 if has_pptp then p:value("pptp", "PPTP") end
94 if has_6in4 then p:value("6in4", "6in4") end
95 if has_6to4 then p:value("6to4", "6to4") end
96 if has_relay then p:value("relay", "Relay") end
97 p:value("none", translate("none"))
99 if not ( has_pppd and has_pppoe and has_pppoa and has_3g and has_pptp ) then
100 p.description = translate("You need to install \"comgt\" for UMTS/GPRS, \"ppp-mod-pppoe\" for PPPoE, \"ppp-mod-pppoa\" for PPPoA or \"pptp\" for PPtP support")
103 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
104 br.enabled = "bridge"
106 br:depends("proto", "static")
107 br:depends("proto", "dhcp")
108 br:depends("proto", "none")
110 stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
111 translate("Enables the Spanning Tree Protocol on this bridge"))
112 stp:depends("type", "bridge")
115 ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
116 ifname_single.template = "cbi/network_ifacelist"
117 ifname_single.widget = "radio"
118 ifname_single.nobridges = true
119 ifname_single.network = arg[1]
120 ifname_single.rmempty = true
121 ifname_single:depends({ type = "", proto = "static" })
122 ifname_single:depends({ type = "", proto = "dhcp" })
123 ifname_single:depends({ type = "", proto = "pppoe" })
124 ifname_single:depends({ type = "", proto = "pppoa" })
125 ifname_single:depends({ type = "", proto = "none" })
127 function ifname_single.cfgvalue(self, s)
128 return self.map.uci:get("network", s, "ifname")
131 function ifname_single.write(self, s, val)
132 local n = nw:get_network(s)
135 for _, i in ipairs(n:get_interfaces()) do
139 for i in ut.imatch(val) do
142 -- if this is not a bridge, only assign first interface
143 if self.option == "ifname_single" then
150 ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
151 ifname_multi.template = "cbi/network_ifacelist"
152 ifname_multi.nobridges = true
153 ifname_multi.network = arg[1]
154 ifname_multi.widget = "checkbox"
155 ifname_multi:depends("type", "bridge")
156 ifname_multi.cfgvalue = ifname_single.cfgvalue
157 ifname_multi.write = ifname_single.write
161 fwzone = s:taboption("firewall", Value, "_fwzone",
162 translate("Create / Assign firewall-zone"),
163 translate("Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>create</em> field to define a new zone and attach the interface to it."))
165 fwzone.template = "cbi/firewall_zonelist"
166 fwzone.network = arg[1]
167 fwzone.rmempty = false
169 function fwzone.cfgvalue(self, section)
171 local z = fw:get_zone_by_network(section)
172 return z and z:name()
175 function fwzone.write(self, section, value)
176 local zone = fw:get_zone(value)
178 if not zone and value == '-' then
179 value = m:formvalue(self:cbid(section) .. ".newzone")
180 if value and #value > 0 then
181 zone = fw:add_zone(value)
183 fw:del_network(section)
188 fw:del_network(section)
189 zone:add_network(section)
194 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
195 ipaddr.optional = true
196 ipaddr.datatype = "ip4addr"
197 ipaddr:depends("proto", "static")
199 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
201 nm.datatype = "ip4addr"
202 nm:depends("proto", "static")
203 nm:value("255.255.255.0")
204 nm:value("255.255.0.0")
205 nm:value("255.0.0.0")
207 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
209 gw.datatype = "ip4addr"
210 gw:depends("proto", "static")
212 bcast = s:taboption("general", Value, "broadcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
213 bcast.optional = true
214 bcast.datatype = "ip4addr"
215 bcast:depends("proto", "static")
218 ip6addr = s:taboption("ipv6", Value, "ip6addr", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Address"), translate("<abbr title=\"Classless Inter-Domain Routing\">CIDR</abbr>-Notation: address/prefix"))
219 ip6addr.optional = true
220 ip6addr.datatype = "ip6addr"
221 ip6addr:depends("proto", "static")
222 ip6addr:depends("proto", "6in4")
224 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
225 ip6gw.optional = true
226 ip6gw.datatype = "ip6addr"
227 ip6gw:depends("proto", "static")
230 ra = s:taboption("ipv6", Flag, "accept_ra", translate("Accept Router Advertisements"))
231 ra.default = m.uci:get("network", arg[1], "proto") == "dhcp" and ra.enabled or ra.disabled
232 ra:depends("proto", "static")
233 ra:depends("proto", "dhcp")
234 ra:depends("proto", "none")
236 rs = s:taboption("ipv6", Flag, "send_rs", translate("Send Router Solicitiations"))
237 rs.default = m.uci:get("network", arg[1], "proto") ~= "dhcp" and rs.enabled or rs.disabled
238 rs:depends("proto", "static")
239 rs:depends("proto", "dhcp")
240 rs:depends("proto", "none")
243 dns = s:taboption("general", DynamicList, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
244 translate("You can specify multiple DNS servers here, press enter to add a new entry. Servers entered here will override " ..
245 "automatically assigned ones."))
249 dns.datatype = "ipaddr"
250 dns:depends({ peerdns = "", proto = "static" })
251 dns:depends({ peerdns = "", proto = "dhcp" })
252 dns:depends({ peerdns = "", proto = "pppoe" })
253 dns:depends({ peerdns = "", proto = "pppoa" })
254 dns:depends({ peerdns = "", proto = "none" })
256 mtu = s:taboption("physical", Value, "mtu", "MTU")
258 mtu.datatype = "uinteger"
259 mtu.placeholder = 1500
260 mtu:depends("proto", "static")
261 mtu:depends("proto", "dhcp")
262 mtu:depends("proto", "pppoe")
263 mtu:depends("proto", "pppoa")
264 mtu:depends("proto", "6in4")
265 mtu:depends("proto", "6to4")
266 mtu:depends("proto", "none")
268 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
269 srv:depends("proto", "pptp")
271 srv.datatype = "host"
274 peer = s:taboption("general", Value, "peeraddr", translate("Server IPv4-Address"))
275 peer.optional = false
276 peer.datatype = "ip4addr"
277 peer:depends("proto", "6in4")
280 if has_6in4 or has_6to4 then
281 ttl = s:taboption("physical", Value, "ttl", translate("TTL"))
284 ttl.datatype = "uinteger"
285 ttl:depends("proto", "6in4")
286 ttl:depends("proto", "6to4")
290 advi = s:taboption("general", Value, "adv_interface", translate("Advertise IPv6 on network"))
291 advi.widget = "checkbox"
292 advi.exclude = arg[1]
294 advi.template = "cbi/network_netlist"
296 advi.nobridges = true
297 advi:depends("proto", "6to4")
299 advn = s:taboption("general", Value, "adv_subnet", translate("Advertised network ID"), translate("Allowed range is 1 to FFFF"))
301 advn:depends("proto", "6to4")
303 function advn.write(self, section, value)
304 value = tonumber(value, 16) or 1
306 if value > 65535 then value = 65535
307 elseif value < 1 then value = 1 end
309 Value.write(self, section, "%X" % value)
314 rnet = s:taboption("general", Value, "network", translate("Relay between networks"))
315 rnet.widget = "checkbox"
316 rnet.exclude = arg[1]
317 rnet.template = "cbi/network_netlist"
319 rnet.nobridges = true
320 rnet:depends("proto", "relay")
323 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
324 mac:depends("proto", "none")
325 mac:depends("proto", "static")
326 mac:depends("proto", "dhcp")
327 mac.placeholder = ifc and ifc:mac():upper()
330 service = s:taboption("general", ListValue, "service", translate("Service type"))
331 service:value("", translate("-- Please choose --"))
332 service:value("umts", "UMTS/GPRS")
333 service:value("cdma", "CDMA")
334 service:value("evdo", "EV-DO")
335 service:depends("proto", "3g")
336 service.rmempty = true
338 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
339 apn:depends("proto", "3g")
341 pincode = s:taboption("general", Value, "pincode",
342 translate("PIN code"),
343 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
345 pincode:depends("proto", "3g")
349 tunid = s:taboption("general", Value, "tunnelid", translate("HE.net Tunnel ID"))
350 tunid.optional = true
351 tunid.datatype = "uinteger"
352 tunid:depends("proto", "6in4")
355 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp or has_6in4 then
356 user = s:taboption("general", Value, "username", translate("Username"))
358 user:depends("proto", "pptp")
359 user:depends("proto", "pppoe")
360 user:depends("proto", "pppoa")
361 user:depends("proto", "ppp")
362 user:depends("proto", "3g")
363 user:depends("proto", "6in4")
365 pass = s:taboption("general", Value, "password", translate("Password"))
368 pass:depends("proto", "pptp")
369 pass:depends("proto", "pppoe")
370 pass:depends("proto", "pppoa")
371 pass:depends("proto", "ppp")
372 pass:depends("proto", "3g")
373 pass:depends("proto", "6in4")
376 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
377 ka = s:taboption("ppp", Value, "keepalive",
378 translate("Keep-Alive"),
379 translate("Number of failed connection tests to initiate automatic reconnect")
381 ka:depends("proto", "pptp")
382 ka:depends("proto", "pppoe")
383 ka:depends("proto", "pppoa")
384 ka:depends("proto", "ppp")
385 ka:depends("proto", "3g")
387 demand = s:taboption("ppp", Value, "demand",
388 translate("Automatic Disconnect"),
389 translate("Time (in seconds) after which an unused connection will be closed")
391 demand.optional = true
392 demand.datatype = "uinteger"
393 demand:depends("proto", "pptp")
394 demand:depends("proto", "pppoe")
395 demand:depends("proto", "pppoa")
396 demand:depends("proto", "ppp")
397 demand:depends("proto", "3g")
401 encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
402 encaps:depends("proto", "pppoa")
403 encaps:value("vc", "VC-Mux")
404 encaps:value("llc", "LLC")
406 atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
407 atmdev:depends("proto", "pppoa")
409 atmdev.datatype = "uinteger"
411 vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
412 vci:depends("proto", "pppoa")
414 vci.datatype = "uinteger"
416 vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
417 vpi:depends("proto", "pppoa")
419 vpi.datatype = "uinteger"
422 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
423 device = s:taboption("general", Value, "device",
424 translate("Modem device"),
425 translate("The device node of your modem, e.g. /dev/ttyUSB0")
427 device:depends("proto", "ppp")
428 device:depends("proto", "3g")
430 defaultroute = s:taboption("ppp", Flag, "defaultroute",
431 translate("Replace default route"),
432 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
434 defaultroute:depends("proto", "ppp")
435 defaultroute:depends("proto", "pppoa")
436 defaultroute:depends("proto", "pppoe")
437 defaultroute:depends("proto", "pptp")
438 defaultroute:depends("proto", "3g")
439 defaultroute.default = defaultroute.enabled
441 peerdns = s:taboption("ppp", Flag, "peerdns",
442 translate("Use peer DNS"),
443 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
445 peerdns:depends("proto", "ppp")
446 peerdns:depends("proto", "pppoa")
447 peerdns:depends("proto", "pppoe")
448 peerdns:depends("proto", "pptp")
449 peerdns:depends("proto", "3g")
450 peerdns.default = peerdns.enabled
453 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
454 ipv6:depends("proto", "ppp")
455 ipv6:depends("proto", "pppoa")
456 ipv6:depends("proto", "pppoe")
457 ipv6:depends("proto", "pptp")
458 ipv6:depends("proto", "3g")
461 connect = s:taboption("ppp", Value, "connect",
462 translate("Connect script"),
463 translate("Let pppd run this script after establishing the PPP link")
465 connect:depends("proto", "ppp")
466 connect:depends("proto", "pppoe")
467 connect:depends("proto", "pppoa")
468 connect:depends("proto", "pptp")
469 connect:depends("proto", "3g")
471 disconnect = s:taboption("ppp", Value, "disconnect",
472 translate("Disconnect script"),
473 translate("Let pppd run this script before tearing down the PPP link")
475 disconnect:depends("proto", "ppp")
476 disconnect:depends("proto", "pppoe")
477 disconnect:depends("proto", "pppoa")
478 disconnect:depends("proto", "pptp")
479 disconnect:depends("proto", "3g")
481 pppd_options = s:taboption("ppp", Value, "pppd_options",
482 translate("Additional pppd options"),
483 translate("Specify additional command line arguments for pppd here")
485 pppd_options:depends("proto", "ppp")
486 pppd_options:depends("proto", "pppoa")
487 pppd_options:depends("proto", "pppoe")
488 pppd_options:depends("proto", "pptp")
489 pppd_options:depends("proto", "3g")
491 maxwait = s:taboption("ppp", Value, "maxwait",
492 translate("Setup wait time"),
493 translate("Seconds to wait for the modem to become ready before attempting to connect")
495 maxwait:depends("proto", "3g")
496 maxwait.default = "0"
497 maxwait.optional = true
498 maxwait.datatype = "uinteger"
502 fb = s:taboption("relay", Flag, "forward_bcast", translate("Forward broadcasts"))
503 fb.default = fb.enabled
504 fb:depends("proto", "relay")
506 fd = s:taboption("relay", Flag, "forward_dhcp", translate("Forward DHCP"))
507 fd.default = fd.enabled
508 fd:depends("proto", "relay")
510 gw = s:taboption("relay", Value, "relay_gateway", translate("Override Gateway"))
512 gw.placeholder = "0.0.0.0"
513 gw.datatype = "ip4addr"
514 gw:depends("proto", "relay")
515 function gw.cfgvalue(self, section)
516 return m.uci:get("network", section, "gateway")
518 function gw.write(self, section, value)
519 return m.uci:set("network", section, "gateway", value)
521 function gw.delete(self, section)
522 return m.uci:delete("network", section, "gateway")
525 expiry = s:taboption("relay", Value, "expiry", translate("Host expiry timeout"))
526 expiry.optional = true
527 expiry.placeholder = 30
528 expiry.datatype = "uinteger"
529 expiry:depends("proto", "relay")
531 retry = s:taboption("relay", Value, "retry", translate("ARP ping retries"))
532 retry.optional = true
533 retry.placeholder = 5
534 retry.datatype = "uinteger"
535 retry:depends("proto", "relay")
537 table = s:taboption("relay", Value, "table", translate("Routing table ID"))
538 table.optional = true
539 table.placeholder = 16800
540 table.datatype = "uinteger"
541 table:depends("proto", "relay")
545 if net:proto() ~= "relay" then
546 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
549 s2:depends("interface", arg[1])
550 s2.defaults.interface = arg[1]
552 s2:tab("general", translate("General Setup"))
553 s2.defaults.proto = "static"
555 ip = s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
557 ip.datatype = "ip4addr"
559 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
561 nm.datatype = "ip4addr"
562 nm:value("255.255.255.0")
563 nm:value("255.255.0.0")
564 nm:value("255.0.0.0")
566 gw = s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
568 gw.datatype = "ip4addr"
571 s2:tab("ipv6", translate("IPv6 Setup"))
573 ip6 = s2:taboption("ipv6", Value, "ip6addr", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Address"), translate("<abbr title=\"Classless Inter-Domain Routing\">CIDR</abbr>-Notation: address/prefix"))
575 ip6.datatype = "ip6addr"
577 gw6 = s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
579 gw6.datatype = "ip6addr"
582 s2:tab("advanced", translate("Advanced Settings"))
584 bcast = s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
585 bcast.optional = true
586 bcast.datatype = "ip4addr"
588 dns = s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
590 dns.datatype = "ip4addr"
595 -- Display DNS settings if dnsmasq is available
598 if has_dnsmasq and net:proto() == "static" then
599 m2 = Map("dhcp", "", "")
600 function m2.on_parse()
601 local has_section = false
603 m2.uci:foreach("dhcp", "dhcp", function(s)
604 if s.interface == arg[1] then
610 if not has_section then
611 m2.uci:section("dhcp", "dhcp", nil, { interface = arg[1], ignore = "1" })
616 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
619 s:tab("general", translate("General Setup"))
620 s:tab("advanced", translate("Advanced Settings"))
622 function s.filter(self, section)
623 return m2.uci:get("dhcp", section, "interface") == arg[1]
626 local ignore = s:taboption("general", Flag, "ignore",
627 translate("Ignore interface"),
628 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
631 ignore.rmempty = false
633 local start = s:taboption("general", Value, "start", translate("Start"),
634 translate("Lowest leased address as offset from the network address."))
635 start.optional = true
636 start.datatype = "uinteger"
637 start.default = "100"
639 local limit = s:taboption("general", Value, "limit", translate("Limit"),
640 translate("Maximum number of leased addresses."))
641 limit.optional = true
642 limit.datatype = "uinteger"
643 limit.default = "150"
645 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
646 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
648 ltime.default = "12h"
650 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
651 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
652 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
653 "clients having static leases will be served."))
654 dd.default = dd.enabled
656 s:taboption("advanced", Flag, "force", translate("Force"),
657 translate("Force DHCP on this network even if another server is detected."))
659 -- XXX: is this actually useful?
660 --s:taboption("advanced", Value, "name", translate("Name"),
661 -- translate("Define a name for this network."))
663 mask = s:taboption("advanced", Value, "netmask",
664 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
665 translate("Override the netmask sent to clients. Normally it is calculated " ..
666 "from the subnet that is served."))
669 mask.datatype = "ip4addr"
671 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
672 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
673 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
675 for i, n in ipairs(s.children) do
677 n:depends("ignore", "")