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 local ifc = net:get_interfaces()[1]
63 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
66 s:tab("general", translate("General Setup"))
67 if has_ipv6 then s:tab("ipv6", translate("IPv6 Setup")) end
68 if has_pppd then s:tab("ppp", translate("PPP Settings")) end
69 if has_pppoa then s:tab("atm", translate("ATM Settings")) end
70 if has_6in4 or has_6to4 then s:tab("tunnel", translate("Tunnel Settings")) end
71 if has_relay then s:tab("relay", translate("Relay Settings")) end
72 if has_ahcp then s:tab("ahcp", translate("AHCP Settings")) end
73 s:tab("physical", translate("Physical Settings"))
74 if has_firewall then s:tab("firewall", translate("Firewall Settings")) end
76 st = s:taboption("general", DummyValue, "__status", translate("Status"))
77 st.template = "admin_network/iface_status"
81 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
83 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
86 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
87 p.override_scheme = true
89 p:value("static", translate("static"))
90 p:value("dhcp", "DHCP")
91 if has_pppd then p:value("ppp", "PPP") end
92 if has_pppoe then p:value("pppoe", "PPPoE") end
93 if has_pppoa then p:value("pppoa", "PPPoA") end
94 if has_3g then p:value("3g", "UMTS/3G") end
95 if has_pptp then p:value("pptp", "PPTP") end
96 if has_6in4 then p:value("6in4", "6in4") end
97 if has_6to4 then p:value("6to4", "6to4") end
98 if has_relay then p:value("relay", "Relay") end
99 if has_ahcp then p:value("ahcp", "AHCP") end
100 p:value("none", translate("none"))
102 if not ( has_pppd and has_pppoe and has_pppoa and has_3g and has_pptp ) then
103 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")
106 auto = s:taboption("physical", Flag, "auto", translate("Bring up on boot"))
107 auto.default = (m.uci:get("network", arg[1], "proto") == "none") and auto.disabled or auto.enabled
109 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
110 br.enabled = "bridge"
112 br:depends("proto", "static")
113 br:depends("proto", "dhcp")
114 br:depends("proto", "none")
116 stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
117 translate("Enables the Spanning Tree Protocol on this bridge"))
118 stp:depends("type", "bridge")
121 ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
122 ifname_single.template = "cbi/network_ifacelist"
123 ifname_single.widget = "radio"
124 ifname_single.nobridges = true
125 ifname_single.network = arg[1]
126 ifname_single:depends({ type = "", proto = "static" })
127 ifname_single:depends({ type = "", proto = "dhcp" })
128 ifname_single:depends({ type = "", proto = "pppoe" })
129 ifname_single:depends({ type = "", proto = "pppoa" })
130 ifname_single:depends({ type = "", proto = "ahcp" })
131 ifname_single:depends({ type = "", proto = "none" })
133 function ifname_single.cfgvalue(self, s)
134 -- let the template figure out the related ifaces through the network model
138 function ifname_single.write(self, s, val)
139 local n = nw:get_network(s)
142 for _, i in ipairs(n:get_interfaces()) do
146 for i in ut.imatch(val) do
149 -- if this is not a bridge, only assign first interface
150 if self.option == "ifname_single" then
157 function ifname_single.remove(self, s)
162 ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
163 ifname_multi.template = "cbi/network_ifacelist"
164 ifname_multi.nobridges = true
165 ifname_multi.network = arg[1]
166 ifname_multi.widget = "checkbox"
167 ifname_multi:depends("type", "bridge")
168 ifname_multi.cfgvalue = ifname_single.cfgvalue
169 ifname_multi.write = ifname_single.write
170 ifname_multi.remove = ifname_single.remove
174 fwzone = s:taboption("firewall", Value, "_fwzone",
175 translate("Create / Assign firewall-zone"),
176 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."))
178 fwzone.template = "cbi/firewall_zonelist"
179 fwzone.network = arg[1]
180 fwzone.rmempty = false
182 function fwzone.cfgvalue(self, section)
184 local z = fw:get_zone_by_network(section)
185 return z and z:name()
188 function fwzone.write(self, section, value)
189 local zone = fw:get_zone(value)
191 if not zone and value == '-' then
192 value = m:formvalue(self:cbid(section) .. ".newzone")
193 if value and #value > 0 then
194 zone = fw:add_zone(value)
196 fw:del_network(section)
201 fw:del_network(section)
202 zone:add_network(section)
207 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
208 ipaddr.optional = true
209 ipaddr.datatype = "ip4addr"
210 ipaddr:depends("proto", "static")
212 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
214 nm.datatype = "ip4addr"
215 nm:depends("proto", "static")
216 nm:value("255.255.255.0")
217 nm:value("255.255.0.0")
218 nm:value("255.0.0.0")
220 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
222 gw.datatype = "ip4addr"
223 gw:depends("proto", "static")
225 bcast = s:taboption("general", Value, "broadcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
226 bcast.optional = true
227 bcast.datatype = "ip4addr"
228 bcast:depends("proto", "static")
231 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"))
232 ip6addr.optional = true
233 ip6addr.datatype = "ip6addr"
234 ip6addr:depends("proto", "static")
235 ip6addr:depends("proto", "6in4")
237 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
238 ip6gw.optional = true
239 ip6gw.datatype = "ip6addr"
240 ip6gw:depends("proto", "static")
243 ra = s:taboption("ipv6", Flag, "accept_ra", translate("Accept Router Advertisements"))
244 ra.default = m.uci:get("network", arg[1], "proto") == "dhcp" and ra.enabled or ra.disabled
245 ra:depends("proto", "static")
246 ra:depends("proto", "dhcp")
247 ra:depends("proto", "none")
249 rs = s:taboption("ipv6", Flag, "send_rs", translate("Send Router Solicitiations"))
250 rs.default = m.uci:get("network", arg[1], "proto") ~= "dhcp" and rs.enabled or rs.disabled
251 rs:depends("proto", "static")
252 rs:depends("proto", "dhcp")
253 rs:depends("proto", "none")
256 dns = s:taboption("general", DynamicList, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
257 translate("You can specify multiple DNS servers here, press enter to add a new entry. Servers entered here will override " ..
258 "automatically assigned ones."))
262 dns.datatype = "ipaddr"
263 dns:depends({ peerdns = "", proto = "static" })
264 dns:depends({ peerdns = "", proto = "dhcp" })
265 dns:depends({ peerdns = "", proto = "pppoe" })
266 dns:depends({ peerdns = "", proto = "pppoa" })
267 dns:depends({ peerdns = "", proto = "none" })
269 mtu = s:taboption("physical", Value, "mtu", "MTU")
271 mtu.datatype = "uinteger"
272 mtu.placeholder = 1500
273 mtu:depends("proto", "static")
274 mtu:depends("proto", "dhcp")
275 mtu:depends("proto", "pppoe")
276 mtu:depends("proto", "pppoa")
277 mtu:depends("proto", "6in4")
278 mtu:depends("proto", "6to4")
279 mtu:depends("proto", "none")
281 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
282 srv:depends("proto", "pptp")
284 srv.datatype = "host"
287 peer = s:taboption("general", Value, "peeraddr", translate("Server IPv4-Address"))
288 peer.optional = false
289 peer.datatype = "ip4addr"
290 peer:depends("proto", "6in4")
293 if has_6in4 or has_6to4 then
294 ttl = s:taboption("physical", Value, "ttl", translate("TTL"))
297 ttl.datatype = "uinteger"
298 ttl:depends("proto", "6in4")
299 ttl:depends("proto", "6to4")
303 advi = s:taboption("general", Value, "adv_interface", translate("Advertise IPv6 on network"))
304 advi.widget = "checkbox"
305 advi.exclude = arg[1]
307 advi.template = "cbi/network_netlist"
309 advi.nobridges = true
310 advi:depends("proto", "6to4")
312 advn = s:taboption("general", Value, "adv_subnet", translate("Advertised network ID"), translate("Allowed range is 1 to FFFF"))
314 advn:depends("proto", "6to4")
316 function advn.write(self, section, value)
317 value = tonumber(value, 16) or 1
319 if value > 65535 then value = 65535
320 elseif value < 1 then value = 1 end
322 Value.write(self, section, "%X" % value)
327 rnet = s:taboption("general", Value, "network", translate("Relay between networks"))
328 rnet.widget = "checkbox"
329 rnet.exclude = arg[1]
330 rnet.template = "cbi/network_netlist"
332 rnet.nobridges = true
333 rnet:depends("proto", "relay")
336 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
337 mac:depends("proto", "none")
338 mac:depends("proto", "static")
339 mac:depends("proto", "dhcp")
340 mac.placeholder = ifc and ifc:mac():upper()
343 service = s:taboption("general", ListValue, "service", translate("Service type"))
344 service:value("", translate("-- Please choose --"))
345 service:value("umts", "UMTS/GPRS")
346 service:value("cdma", "CDMA")
347 service:value("evdo", "EV-DO")
348 service:depends("proto", "3g")
349 service.rmempty = true
351 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
352 apn:depends("proto", "3g")
354 pincode = s:taboption("general", Value, "pincode",
355 translate("PIN code"),
356 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
358 pincode:depends("proto", "3g")
362 tunid = s:taboption("general", Value, "tunnelid", translate("HE.net Tunnel ID"))
363 tunid.optional = true
364 tunid.datatype = "uinteger"
365 tunid:depends("proto", "6in4")
368 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp or has_6in4 then
369 user = s:taboption("general", Value, "username", translate("Username"))
371 user:depends("proto", "pptp")
372 user:depends("proto", "pppoe")
373 user:depends("proto", "pppoa")
374 user:depends("proto", "ppp")
375 user:depends("proto", "3g")
376 user:depends("proto", "6in4")
378 pass = s:taboption("general", Value, "password", translate("Password"))
381 pass:depends("proto", "pptp")
382 pass:depends("proto", "pppoe")
383 pass:depends("proto", "pppoa")
384 pass:depends("proto", "ppp")
385 pass:depends("proto", "3g")
386 pass:depends("proto", "6in4")
389 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
390 ka = s:taboption("ppp", Value, "keepalive",
391 translate("Keep-Alive"),
392 translate("Number of failed connection tests to initiate automatic reconnect")
394 ka:depends("proto", "pptp")
395 ka:depends("proto", "pppoe")
396 ka:depends("proto", "pppoa")
397 ka:depends("proto", "ppp")
398 ka:depends("proto", "3g")
400 demand = s:taboption("ppp", Value, "demand",
401 translate("Automatic Disconnect"),
402 translate("Time (in seconds) after which an unused connection will be closed")
404 demand.optional = true
405 demand.datatype = "uinteger"
406 demand:depends("proto", "pptp")
407 demand:depends("proto", "pppoe")
408 demand:depends("proto", "pppoa")
409 demand:depends("proto", "ppp")
410 demand:depends("proto", "3g")
414 encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
415 encaps:depends("proto", "pppoa")
416 encaps:value("vc", "VC-Mux")
417 encaps:value("llc", "LLC")
419 atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
420 atmdev:depends("proto", "pppoa")
422 atmdev.datatype = "uinteger"
424 vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
425 vci:depends("proto", "pppoa")
427 vci.datatype = "uinteger"
429 vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
430 vpi:depends("proto", "pppoa")
432 vpi.datatype = "uinteger"
435 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
436 device = s:taboption("general", Value, "device",
437 translate("Modem device"),
438 translate("The device node of your modem, e.g. /dev/ttyUSB0")
440 device:depends("proto", "ppp")
441 device:depends("proto", "3g")
443 defaultroute = s:taboption("ppp", Flag, "defaultroute",
444 translate("Replace default route"),
445 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
447 defaultroute:depends("proto", "ppp")
448 defaultroute:depends("proto", "pppoa")
449 defaultroute:depends("proto", "pppoe")
450 defaultroute:depends("proto", "pptp")
451 defaultroute:depends("proto", "3g")
452 defaultroute.default = defaultroute.enabled
454 peerdns = s:taboption("ppp", Flag, "peerdns",
455 translate("Use peer DNS"),
456 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
458 peerdns:depends("proto", "ppp")
459 peerdns:depends("proto", "pppoa")
460 peerdns:depends("proto", "pppoe")
461 peerdns:depends("proto", "pptp")
462 peerdns:depends("proto", "3g")
463 peerdns.default = peerdns.enabled
466 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
467 ipv6:depends("proto", "ppp")
468 ipv6:depends("proto", "pppoa")
469 ipv6:depends("proto", "pppoe")
470 ipv6:depends("proto", "pptp")
471 ipv6:depends("proto", "3g")
474 connect = s:taboption("ppp", Value, "connect",
475 translate("Connect script"),
476 translate("Let pppd run this script after establishing the PPP link")
478 connect:depends("proto", "ppp")
479 connect:depends("proto", "pppoe")
480 connect:depends("proto", "pppoa")
481 connect:depends("proto", "pptp")
482 connect:depends("proto", "3g")
484 disconnect = s:taboption("ppp", Value, "disconnect",
485 translate("Disconnect script"),
486 translate("Let pppd run this script before tearing down the PPP link")
488 disconnect:depends("proto", "ppp")
489 disconnect:depends("proto", "pppoe")
490 disconnect:depends("proto", "pppoa")
491 disconnect:depends("proto", "pptp")
492 disconnect:depends("proto", "3g")
494 pppd_options = s:taboption("ppp", Value, "pppd_options",
495 translate("Additional pppd options"),
496 translate("Specify additional command line arguments for pppd here")
498 pppd_options:depends("proto", "ppp")
499 pppd_options:depends("proto", "pppoa")
500 pppd_options:depends("proto", "pppoe")
501 pppd_options:depends("proto", "pptp")
502 pppd_options:depends("proto", "3g")
504 maxwait = s:taboption("ppp", Value, "maxwait",
505 translate("Setup wait time"),
506 translate("Seconds to wait for the modem to become ready before attempting to connect")
508 maxwait:depends("proto", "3g")
509 maxwait.default = "0"
510 maxwait.optional = true
511 maxwait.datatype = "uinteger"
515 fb = s:taboption("relay", Flag, "forward_bcast", translate("Forward broadcasts"))
516 fb.default = fb.enabled
517 fb:depends("proto", "relay")
519 fd = s:taboption("relay", Flag, "forward_dhcp", translate("Forward DHCP"))
520 fd.default = fd.enabled
521 fd:depends("proto", "relay")
523 gw = s:taboption("relay", Value, "relay_gateway", translate("Override Gateway"))
525 gw.placeholder = "0.0.0.0"
526 gw.datatype = "ip4addr"
527 gw:depends("proto", "relay")
528 function gw.cfgvalue(self, section)
529 return m.uci:get("network", section, "gateway")
531 function gw.write(self, section, value)
532 return m.uci:set("network", section, "gateway", value)
534 function gw.delete(self, section)
535 return m.uci:delete("network", section, "gateway")
538 expiry = s:taboption("relay", Value, "expiry", translate("Host expiry timeout"))
539 expiry.optional = true
540 expiry.placeholder = 30
541 expiry.datatype = "uinteger"
542 expiry:depends("proto", "relay")
544 retry = s:taboption("relay", Value, "retry", translate("ARP ping retries"))
545 retry.optional = true
546 retry.placeholder = 5
547 retry.datatype = "uinteger"
548 retry:depends("proto", "relay")
550 table = s:taboption("relay", Value, "table", translate("Routing table ID"))
551 table.optional = true
552 table.placeholder = 16800
553 table.datatype = "uinteger"
554 table:depends("proto", "relay")
558 mca = s:taboption("ahcp", Value, "multicast_address", translate("Multicast address"))
560 mca.placeholder = "ff02::cca6:c0f9:e182:5359"
561 mca.datatype = "ip6addr"
562 mca:depends("proto", "ahcp")
564 port = s:taboption("ahcp", Value, "port", translate("Port"))
566 port.placeholder = 5359
567 port.datatype = "port"
568 port:depends("proto", "ahcp")
570 fam = s:taboption("ahcp", ListValue, "_family", translate("Protocol family"))
571 fam:value("", translate("IPv4 and IPv6"))
572 fam:value("ipv4", translate("IPv4 only"))
573 fam:value("ipv6", translate("IPv6 only"))
574 fam:depends("proto", "ahcp")
576 function fam.cfgvalue(self, section)
577 local v4 = m.uci:get_bool("network", section, "ipv4_only")
578 local v6 = m.uci:get_bool("network", section, "ipv6_only")
587 function fam.write(self, section, value)
588 if value == "ipv4" then
589 m.uci:set("network", section, "ipv4_only", "true")
590 m.uci:delete("network", section, "ipv6_only")
591 elseif value == "ipv6" then
592 m.uci:set("network", section, "ipv6_only", "true")
593 m.uci:delete("network", section, "ipv4_only")
597 function fam.remove(self, section)
598 m.uci:delete("network", section, "ipv4_only")
599 m.uci:delete("network", section, "ipv6_only")
602 nodns = s:taboption("ahcp", Flag, "no_dns", translate("Disable DNS setup"))
603 nodns.optional = true
604 nodns.enabled = "true"
605 nodns.disabled = "false"
606 nodns.default = nodns.disabled
607 nodns:depends("proto", "ahcp")
609 ltime = s:taboption("ahcp", Value, "lease_time", translate("Lease validity time"))
610 ltime.optional = true
611 ltime.placeholder = 3666
612 ltime.datatype = "uinteger"
613 ltime:depends("proto", "ahcp")
616 if net:proto() ~= "relay" then
617 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
620 s2:depends("interface", arg[1])
621 s2.defaults.interface = arg[1]
623 s2:tab("general", translate("General Setup"))
624 s2.defaults.proto = "static"
626 ip = s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
628 ip.datatype = "ip4addr"
630 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
632 nm.datatype = "ip4addr"
633 nm:value("255.255.255.0")
634 nm:value("255.255.0.0")
635 nm:value("255.0.0.0")
637 gw = s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
639 gw.datatype = "ip4addr"
642 s2:tab("ipv6", translate("IPv6 Setup"))
644 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"))
646 ip6.datatype = "ip6addr"
648 gw6 = s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
650 gw6.datatype = "ip6addr"
653 s2:tab("advanced", translate("Advanced Settings"))
655 bcast = s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
656 bcast.optional = true
657 bcast.datatype = "ip4addr"
659 dns = s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
661 dns.datatype = "ip4addr"
666 -- Display DNS settings if dnsmasq is available
669 if has_dnsmasq and net:proto() == "static" then
670 m2 = Map("dhcp", "", "")
673 function m2.on_parse()
674 m2.uci:foreach("dhcp", "dhcp", function(s)
675 if s.interface == arg[1] then
676 section_id = s['.name']
681 if not section_id then
684 while m2.uci:get("dhcp", section_id) do
685 section_id = arg[1] .. c
691 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
694 s:tab("general", translate("General Setup"))
695 s:tab("advanced", translate("Advanced Settings"))
697 function s.cfgsections(self)
698 return { section_id }
701 local ignore = s:taboption("general", Flag, "ignore",
702 translate("Ignore interface"),
703 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
706 ignore.rmempty = false
707 ignore.default = ignore.enabled
709 function ignore.write(self, section, value)
710 if m2.uci:get("dhcp", section) ~= "dhcp" then
711 m2.uci:section("dhcp", "dhcp", section, {
715 m2.uci:set("dhcp", section, "ignore", (value == "1") and "1" or "0")
719 local start = s:taboption("general", Value, "start", translate("Start"),
720 translate("Lowest leased address as offset from the network address."))
721 start.optional = true
722 start.datatype = "uinteger"
723 start.default = "100"
725 local limit = s:taboption("general", Value, "limit", translate("Limit"),
726 translate("Maximum number of leased addresses."))
727 limit.optional = true
728 limit.datatype = "uinteger"
729 limit.default = "150"
731 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
732 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
734 ltime.default = "12h"
736 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
737 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
738 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
739 "clients having static leases will be served."))
740 dd.default = dd.enabled
742 s:taboption("advanced", Flag, "force", translate("Force"),
743 translate("Force DHCP on this network even if another server is detected."))
745 -- XXX: is this actually useful?
746 --s:taboption("advanced", Value, "name", translate("Name"),
747 -- translate("Define a name for this network."))
749 mask = s:taboption("advanced", Value, "netmask",
750 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
751 translate("Override the netmask sent to clients. Normally it is calculated " ..
752 "from the subnet that is served."))
755 mask.datatype = "ip4addr"
757 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
758 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
759 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
762 for i, n in ipairs(s.children) do
764 n:depends("ignore", "")