2 LuCI - Lua Configuration Interface
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008-2011 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")
36 local has_ahcp = fs.access("/lib/network/ahcp.sh")
38 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>)."))
53 local net = nw:get_network(arg[1])
55 -- redirect to overview page if network does not exist anymore (e.g. after a revert)
57 luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
61 -- dhcp setup was requested, create section and reload page
62 if m:formvalue("cbid.dhcp._enable._enable") then
63 m.uci:section("dhcp", "dhcp", nil, {
71 luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
75 local ifc = net:get_interface()
77 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
80 s:tab("general", translate("General Setup"))
81 if has_ipv6 then s:tab("ipv6", translate("IPv6 Setup")) end
82 if has_pppd then s:tab("ppp", translate("PPP Settings")) end
83 if has_pppoa then s:tab("atm", translate("ATM Settings")) end
84 if has_6in4 or has_6to4 then s:tab("tunnel", translate("Tunnel Settings")) end
85 if has_relay then s:tab("relay", translate("Relay Settings")) end
86 if has_ahcp then s:tab("ahcp", translate("AHCP Settings")) end
87 s:tab("physical", translate("Physical Settings"))
88 if has_firewall then s:tab("firewall", translate("Firewall Settings")) end
90 st = s:taboption("general", DummyValue, "__status", translate("Status"))
91 st.template = "admin_network/iface_status"
95 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
97 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
100 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
101 p.override_scheme = true
103 p:value("static", translate("static"))
104 p:value("dhcp", "DHCP")
105 if has_pppd then p:value("ppp", "PPP") end
106 if has_pppoe then p:value("pppoe", "PPPoE") end
107 if has_pppoa then p:value("pppoa", "PPPoA") end
108 if has_3g then p:value("3g", "UMTS/3G") end
109 if has_pptp then p:value("pptp", "PPTP") end
110 if has_6in4 then p:value("6in4", "6in4") end
111 if has_6to4 then p:value("6to4", "6to4") end
112 if has_relay then p:value("relay", "Relay") end
113 if has_ahcp then p:value("ahcp", "AHCP") end
114 p:value("none", translate("none"))
116 if not ( has_pppd and has_pppoe and has_pppoa and has_3g and has_pptp ) then
117 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")
120 auto = s:taboption("physical", Flag, "auto", translate("Bring up on boot"))
121 auto.default = (m.uci:get("network", arg[1], "proto") == "none") and auto.disabled or auto.enabled
123 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
124 br.enabled = "bridge"
126 br:depends("proto", "static")
127 br:depends("proto", "dhcp")
128 br:depends("proto", "none")
130 stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
131 translate("Enables the Spanning Tree Protocol on this bridge"))
132 stp:depends("type", "bridge")
135 ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
136 ifname_single.template = "cbi/network_ifacelist"
137 ifname_single.widget = "radio"
138 ifname_single.nobridges = true
139 ifname_single.rmempty = false
140 ifname_single.network = arg[1]
141 ifname_single:depends({ type = "", proto = "static" })
142 ifname_single:depends({ type = "", proto = "dhcp" })
143 ifname_single:depends({ type = "", proto = "pppoe" })
144 ifname_single:depends({ type = "", proto = "pppoa" })
145 ifname_single:depends({ type = "", proto = "ahcp" })
146 ifname_single:depends({ type = "", proto = "none" })
148 function ifname_single.cfgvalue(self, s)
149 -- let the template figure out the related ifaces through the network model
153 function ifname_single.write(self, s, val)
154 local n = nw:get_network(s)
160 for _, i in ipairs(n:get_interfaces() or { n:get_interface() }) do
161 old_ifs[#old_ifs+1] = i:name()
164 for i in ut.imatch(val) do
165 new_ifs[#new_ifs+1] = i
167 -- if this is not a bridge, only assign first interface
168 if self.option == "ifname_single" then
176 for i = 1, math.max(#old_ifs, #new_ifs) do
177 if old_ifs[i] ~= new_ifs[i] then
178 for i = 1, #old_ifs do
179 n:del_interface(old_ifs[i])
181 for i = 1, #new_ifs do
182 n:add_interface(new_ifs[i])
191 ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
192 ifname_multi.template = "cbi/network_ifacelist"
193 ifname_multi.nobridges = true
194 ifname_multi.rmempty = false
195 ifname_multi.network = arg[1]
196 ifname_multi.widget = "checkbox"
197 ifname_multi:depends("type", "bridge")
198 ifname_multi.cfgvalue = ifname_single.cfgvalue
199 ifname_multi.write = ifname_single.write
203 fwzone = s:taboption("firewall", Value, "_fwzone",
204 translate("Create / Assign firewall-zone"),
205 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."))
207 fwzone.template = "cbi/firewall_zonelist"
208 fwzone.network = arg[1]
209 fwzone.rmempty = false
211 function fwzone.cfgvalue(self, section)
213 local z = fw:get_zone_by_network(section)
214 return z and z:name()
217 function fwzone.write(self, section, value)
218 local zone = fw:get_zone(value)
220 if not zone and value == '-' then
221 value = m:formvalue(self:cbid(section) .. ".newzone")
222 if value and #value > 0 then
223 zone = fw:add_zone(value)
225 fw:del_network(section)
230 fw:del_network(section)
231 zone:add_network(section)
236 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
237 ipaddr.optional = true
238 ipaddr.datatype = "ip4addr"
239 ipaddr:depends("proto", "static")
241 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
243 nm.datatype = "ip4addr"
244 nm:depends("proto", "static")
245 nm:value("255.255.255.0")
246 nm:value("255.255.0.0")
247 nm:value("255.0.0.0")
249 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
251 gw.datatype = "ip4addr"
252 gw:depends("proto", "static")
253 gw:depends("proto", "dhcp")
255 bcast = s:taboption("general", Value, "broadcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
256 bcast.optional = true
257 bcast.datatype = "ip4addr"
258 bcast:depends("proto", "static")
261 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"))
262 ip6addr.optional = true
263 ip6addr.datatype = "ip6addr"
264 ip6addr:depends("proto", "static")
265 ip6addr:depends("proto", "6in4")
267 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
268 ip6gw.optional = true
269 ip6gw.datatype = "ip6addr"
270 ip6gw:depends("proto", "static")
273 ra = s:taboption("ipv6", Flag, "accept_ra", translate("Accept Router Advertisements"))
274 ra.default = m.uci:get("network", arg[1], "proto") == "dhcp" and ra.enabled or ra.disabled
275 ra:depends("proto", "static")
276 ra:depends("proto", "dhcp")
277 ra:depends("proto", "none")
279 rs = s:taboption("ipv6", Flag, "send_rs", translate("Send Router Solicitiations"))
280 rs.default = m.uci:get("network", arg[1], "proto") ~= "dhcp" and rs.enabled or rs.disabled
281 rs:depends("proto", "static")
282 rs:depends("proto", "dhcp")
283 rs:depends("proto", "none")
286 dns = s:taboption("general", DynamicList, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
287 translate("You can specify multiple DNS servers here, press enter to add a new entry. Servers entered here will override " ..
288 "automatically assigned ones."))
292 dns.datatype = "ipaddr"
293 dns:depends({ peerdns = "", proto = "static" })
294 dns:depends({ peerdns = "", proto = "dhcp" })
295 dns:depends({ peerdns = "", proto = "pppoe" })
296 dns:depends({ peerdns = "", proto = "pppoa" })
297 dns:depends({ peerdns = "", proto = "none" })
299 mtu = s:taboption("physical", Value, "mtu", "MTU")
301 mtu.datatype = "uinteger"
302 mtu.placeholder = 1500
303 mtu:depends("proto", "static")
304 mtu:depends("proto", "dhcp")
305 mtu:depends("proto", "pppoe")
306 mtu:depends("proto", "pppoa")
307 mtu:depends("proto", "6in4")
308 mtu:depends("proto", "6to4")
309 mtu:depends("proto", "none")
311 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
312 srv:depends("proto", "pptp")
314 srv.datatype = "host"
317 peer = s:taboption("general", Value, "peeraddr", translate("Server IPv4-Address"))
318 peer.optional = false
319 peer.datatype = "ip4addr"
320 peer:depends("proto", "6in4")
323 if has_6in4 or has_6to4 then
324 ttl = s:taboption("physical", Value, "ttl", translate("TTL"))
327 ttl.datatype = "uinteger"
328 ttl:depends("proto", "6in4")
329 ttl:depends("proto", "6to4")
333 advi = s:taboption("general", Value, "adv_interface", translate("Advertise IPv6 on network"))
334 advi.widget = "checkbox"
335 advi.exclude = arg[1]
337 advi.template = "cbi/network_netlist"
339 advi.nobridges = true
340 advi:depends("proto", "6to4")
342 advn = s:taboption("general", Value, "adv_subnet", translate("Advertised network ID"), translate("Allowed range is 1 to FFFF"))
344 advn:depends("proto", "6to4")
346 function advn.write(self, section, value)
347 value = tonumber(value, 16) or 1
349 if value > 65535 then value = 65535
350 elseif value < 1 then value = 1 end
352 Value.write(self, section, "%X" % value)
357 rnet = s:taboption("general", DynamicList, "network", translate("Relay between networks"))
358 rnet.widget = "checkbox"
359 rnet.exclude = arg[1]
360 rnet.template = "cbi/network_netlist"
362 rnet.nobridges = true
363 rnet:depends("proto", "relay")
366 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
367 mac:depends("proto", "none")
368 mac:depends("proto", "static")
369 mac:depends("proto", "dhcp")
370 mac.placeholder = ifc and ifc:mac()
373 service = s:taboption("general", ListValue, "service", translate("Service type"))
374 service:value("", translate("-- Please choose --"))
375 service:value("umts", "UMTS/GPRS")
376 service:value("cdma", "CDMA")
377 service:value("evdo", "EV-DO")
378 service:depends("proto", "3g")
379 service.rmempty = true
381 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
382 apn:depends("proto", "3g")
384 pincode = s:taboption("general", Value, "pincode",
385 translate("PIN code"),
386 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
388 pincode:depends("proto", "3g")
392 tunid = s:taboption("general", Value, "tunnelid", translate("HE.net Tunnel ID"))
393 tunid.optional = true
394 tunid.datatype = "uinteger"
395 tunid:depends("proto", "6in4")
398 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp or has_6in4 then
399 user = s:taboption("general", Value, "username", translate("Username"))
401 user:depends("proto", "pptp")
402 user:depends("proto", "pppoe")
403 user:depends("proto", "pppoa")
404 user:depends("proto", "ppp")
405 user:depends("proto", "3g")
406 user:depends("proto", "6in4")
408 pass = s:taboption("general", Value, "password", translate("Password"))
411 pass:depends("proto", "pptp")
412 pass:depends("proto", "pppoe")
413 pass:depends("proto", "pppoa")
414 pass:depends("proto", "ppp")
415 pass:depends("proto", "3g")
416 pass:depends("proto", "6in4")
419 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
420 ka = s:taboption("ppp", Value, "keepalive",
421 translate("Keep-Alive"),
422 translate("Number of failed connection tests to initiate automatic reconnect")
424 ka:depends("proto", "pptp")
425 ka:depends("proto", "pppoe")
426 ka:depends("proto", "pppoa")
427 ka:depends("proto", "ppp")
428 ka:depends("proto", "3g")
430 demand = s:taboption("ppp", Value, "demand",
431 translate("Automatic Disconnect"),
432 translate("Time (in seconds) after which an unused connection will be closed")
434 demand.optional = true
435 demand.datatype = "uinteger"
436 demand:depends("proto", "pptp")
437 demand:depends("proto", "pppoe")
438 demand:depends("proto", "pppoa")
439 demand:depends("proto", "ppp")
440 demand:depends("proto", "3g")
444 encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
445 encaps:depends("proto", "pppoa")
446 encaps:value("vc", "VC-Mux")
447 encaps:value("llc", "LLC")
449 atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
450 atmdev:depends("proto", "pppoa")
452 atmdev.datatype = "uinteger"
454 vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
455 vci:depends("proto", "pppoa")
457 vci.datatype = "uinteger"
459 vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
460 vpi:depends("proto", "pppoa")
462 vpi.datatype = "uinteger"
465 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
466 device = s:taboption("general", Value, "device",
467 translate("Modem device"),
468 translate("The device node of your modem, e.g. /dev/ttyUSB0")
470 device:depends("proto", "ppp")
471 device:depends("proto", "3g")
473 defaultroute = s:taboption("ppp", Flag, "defaultroute",
474 translate("Replace default route"),
475 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
477 defaultroute:depends("proto", "ppp")
478 defaultroute:depends("proto", "pppoa")
479 defaultroute:depends("proto", "pppoe")
480 defaultroute:depends("proto", "pptp")
481 defaultroute:depends("proto", "3g")
482 defaultroute.default = defaultroute.enabled
484 peerdns = s:taboption("ppp", Flag, "peerdns",
485 translate("Use peer DNS"),
486 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
488 peerdns:depends("proto", "ppp")
489 peerdns:depends("proto", "pppoa")
490 peerdns:depends("proto", "pppoe")
491 peerdns:depends("proto", "pptp")
492 peerdns:depends("proto", "3g")
493 peerdns.default = peerdns.enabled
496 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
497 ipv6:depends("proto", "ppp")
498 ipv6:depends("proto", "pppoa")
499 ipv6:depends("proto", "pppoe")
500 ipv6:depends("proto", "pptp")
501 ipv6:depends("proto", "3g")
504 connect = s:taboption("ppp", Value, "connect",
505 translate("Connect script"),
506 translate("Let pppd run this script after establishing the PPP link")
508 connect:depends("proto", "ppp")
509 connect:depends("proto", "pppoe")
510 connect:depends("proto", "pppoa")
511 connect:depends("proto", "pptp")
512 connect:depends("proto", "3g")
514 disconnect = s:taboption("ppp", Value, "disconnect",
515 translate("Disconnect script"),
516 translate("Let pppd run this script before tearing down the PPP link")
518 disconnect:depends("proto", "ppp")
519 disconnect:depends("proto", "pppoe")
520 disconnect:depends("proto", "pppoa")
521 disconnect:depends("proto", "pptp")
522 disconnect:depends("proto", "3g")
524 pppd_options = s:taboption("ppp", Value, "pppd_options",
525 translate("Additional pppd options"),
526 translate("Specify additional command line arguments for pppd here")
528 pppd_options:depends("proto", "ppp")
529 pppd_options:depends("proto", "pppoa")
530 pppd_options:depends("proto", "pppoe")
531 pppd_options:depends("proto", "pptp")
532 pppd_options:depends("proto", "3g")
534 maxwait = s:taboption("ppp", Value, "maxwait",
535 translate("Setup wait time"),
536 translate("Seconds to wait for the modem to become ready before attempting to connect")
538 maxwait:depends("proto", "3g")
539 maxwait.default = "0"
540 maxwait.optional = true
541 maxwait.datatype = "uinteger"
545 fb = s:taboption("relay", Flag, "forward_bcast", translate("Forward broadcasts"))
546 fb.default = fb.enabled
547 fb:depends("proto", "relay")
549 fd = s:taboption("relay", Flag, "forward_dhcp", translate("Forward DHCP"))
550 fd.default = fd.enabled
551 fd:depends("proto", "relay")
553 gw = s:taboption("relay", Value, "relay_gateway", translate("Override Gateway"))
555 gw.placeholder = "0.0.0.0"
556 gw.datatype = "ip4addr"
557 gw:depends("proto", "relay")
558 function gw.cfgvalue(self, section)
559 return m.uci:get("network", section, "gateway")
561 function gw.write(self, section, value)
562 return m.uci:set("network", section, "gateway", value)
564 function gw.delete(self, section)
565 return m.uci:delete("network", section, "gateway")
568 expiry = s:taboption("relay", Value, "expiry", translate("Host expiry timeout"))
569 expiry.optional = true
570 expiry.placeholder = 30
571 expiry.datatype = "uinteger"
572 expiry:depends("proto", "relay")
574 retry = s:taboption("relay", Value, "retry", translate("ARP ping retries"))
575 retry.optional = true
576 retry.placeholder = 5
577 retry.datatype = "uinteger"
578 retry:depends("proto", "relay")
580 tableid = s:taboption("relay", Value, "table", translate("Routing table ID"))
581 tableid.optional = true
582 tableid.placeholder = 16800
583 tableid.datatype = "uinteger"
584 tableid:depends("proto", "relay")
588 mca = s:taboption("ahcp", Value, "multicast_address", translate("Multicast address"))
590 mca.placeholder = "ff02::cca6:c0f9:e182:5359"
591 mca.datatype = "ip6addr"
592 mca:depends("proto", "ahcp")
594 port = s:taboption("ahcp", Value, "port", translate("Port"))
596 port.placeholder = 5359
597 port.datatype = "port"
598 port:depends("proto", "ahcp")
600 fam = s:taboption("ahcp", ListValue, "_family", translate("Protocol family"))
601 fam:value("", translate("IPv4 and IPv6"))
602 fam:value("ipv4", translate("IPv4 only"))
603 fam:value("ipv6", translate("IPv6 only"))
604 fam:depends("proto", "ahcp")
606 function fam.cfgvalue(self, section)
607 local v4 = m.uci:get_bool("network", section, "ipv4_only")
608 local v6 = m.uci:get_bool("network", section, "ipv6_only")
617 function fam.write(self, section, value)
618 if value == "ipv4" then
619 m.uci:set("network", section, "ipv4_only", "true")
620 m.uci:delete("network", section, "ipv6_only")
621 elseif value == "ipv6" then
622 m.uci:set("network", section, "ipv6_only", "true")
623 m.uci:delete("network", section, "ipv4_only")
627 function fam.remove(self, section)
628 m.uci:delete("network", section, "ipv4_only")
629 m.uci:delete("network", section, "ipv6_only")
632 nodns = s:taboption("ahcp", Flag, "no_dns", translate("Disable DNS setup"))
633 nodns.optional = true
634 nodns.enabled = "true"
635 nodns.disabled = "false"
636 nodns.default = nodns.disabled
637 nodns:depends("proto", "ahcp")
639 ltime = s:taboption("ahcp", Value, "lease_time", translate("Lease validity time"))
640 ltime.optional = true
641 ltime.placeholder = 3666
642 ltime.datatype = "uinteger"
643 ltime:depends("proto", "ahcp")
646 if net:proto() ~= "relay" then
647 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
650 s2:depends("interface", arg[1])
651 s2.defaults.interface = arg[1]
653 s2:tab("general", translate("General Setup"))
654 s2.defaults.proto = "static"
656 ip = s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
658 ip.datatype = "ip4addr"
660 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
662 nm.datatype = "ip4addr"
663 nm:value("255.255.255.0")
664 nm:value("255.255.0.0")
665 nm:value("255.0.0.0")
667 gw = s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
669 gw.datatype = "ip4addr"
672 s2:tab("ipv6", translate("IPv6 Setup"))
674 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"))
676 ip6.datatype = "ip6addr"
678 gw6 = s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
680 gw6.datatype = "ip6addr"
683 s2:tab("advanced", translate("Advanced Settings"))
685 bcast = s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
686 bcast.optional = true
687 bcast.datatype = "ip4addr"
689 dns = s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
691 dns.datatype = "ip4addr"
696 -- Display DNS settings if dnsmasq is available
699 if has_dnsmasq and net:proto() == "static" then
700 m2 = Map("dhcp", "", "")
702 local has_section = false
704 m2.uci:foreach("dhcp", "dhcp", function(s)
705 if s.interface == arg[1] then
711 if not has_section then
713 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
715 s.cfgsections = function() return { "_enable" } end
717 x = s:option(Button, "_enable")
718 x.title = translate("No DHCP Server configured for this interface")
719 x.inputtitle = translate("Setup DHCP Server")
720 x.inputstyle = "apply"
724 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
727 s:tab("general", translate("General Setup"))
728 s:tab("advanced", translate("Advanced Settings"))
730 function s.filter(self, section)
731 return m2.uci:get("dhcp", section, "interface") == arg[1]
734 local ignore = s:taboption("general", Flag, "ignore",
735 translate("Ignore interface"),
736 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
739 local start = s:taboption("general", Value, "start", translate("Start"),
740 translate("Lowest leased address as offset from the network address."))
741 start.optional = true
742 start.datatype = "uinteger"
743 start.default = "100"
745 local limit = s:taboption("general", Value, "limit", translate("Limit"),
746 translate("Maximum number of leased addresses."))
747 limit.optional = true
748 limit.datatype = "uinteger"
749 limit.default = "150"
751 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
752 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
754 ltime.default = "12h"
756 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
757 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
758 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
759 "clients having static leases will be served."))
760 dd.default = dd.enabled
762 s:taboption("advanced", Flag, "force", translate("Force"),
763 translate("Force DHCP on this network even if another server is detected."))
765 -- XXX: is this actually useful?
766 --s:taboption("advanced", Value, "name", translate("Name"),
767 -- translate("Define a name for this network."))
769 mask = s:taboption("advanced", Value, "netmask",
770 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
771 translate("Override the netmask sent to clients. Normally it is calculated " ..
772 "from the subnet that is served."))
775 mask.datatype = "ip4addr"
777 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
778 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
779 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
781 for i, n in ipairs(s.children) do
783 n:depends("ignore", "")