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.rmempty = true
127 ifname_single:depends({ type = "", proto = "static" })
128 ifname_single:depends({ type = "", proto = "dhcp" })
129 ifname_single:depends({ type = "", proto = "pppoe" })
130 ifname_single:depends({ type = "", proto = "pppoa" })
131 ifname_single:depends({ type = "", proto = "ahcp" })
132 ifname_single:depends({ type = "", proto = "none" })
134 function ifname_single.cfgvalue(self, s)
135 return self.map.uci:get("network", s, "ifname")
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 ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
158 ifname_multi.template = "cbi/network_ifacelist"
159 ifname_multi.nobridges = true
160 ifname_multi.network = arg[1]
161 ifname_multi.widget = "checkbox"
162 ifname_multi:depends("type", "bridge")
163 ifname_multi.cfgvalue = ifname_single.cfgvalue
164 ifname_multi.write = ifname_single.write
168 fwzone = s:taboption("firewall", Value, "_fwzone",
169 translate("Create / Assign firewall-zone"),
170 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."))
172 fwzone.template = "cbi/firewall_zonelist"
173 fwzone.network = arg[1]
174 fwzone.rmempty = false
176 function fwzone.cfgvalue(self, section)
178 local z = fw:get_zone_by_network(section)
179 return z and z:name()
182 function fwzone.write(self, section, value)
183 local zone = fw:get_zone(value)
185 if not zone and value == '-' then
186 value = m:formvalue(self:cbid(section) .. ".newzone")
187 if value and #value > 0 then
188 zone = fw:add_zone(value)
190 fw:del_network(section)
195 fw:del_network(section)
196 zone:add_network(section)
201 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
202 ipaddr.optional = true
203 ipaddr.datatype = "ip4addr"
204 ipaddr:depends("proto", "static")
206 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
208 nm.datatype = "ip4addr"
209 nm:depends("proto", "static")
210 nm:value("255.255.255.0")
211 nm:value("255.255.0.0")
212 nm:value("255.0.0.0")
214 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
216 gw.datatype = "ip4addr"
217 gw:depends("proto", "static")
219 bcast = s:taboption("general", Value, "broadcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
220 bcast.optional = true
221 bcast.datatype = "ip4addr"
222 bcast:depends("proto", "static")
225 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"))
226 ip6addr.optional = true
227 ip6addr.datatype = "ip6addr"
228 ip6addr:depends("proto", "static")
229 ip6addr:depends("proto", "6in4")
231 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
232 ip6gw.optional = true
233 ip6gw.datatype = "ip6addr"
234 ip6gw:depends("proto", "static")
237 ra = s:taboption("ipv6", Flag, "accept_ra", translate("Accept Router Advertisements"))
238 ra.default = m.uci:get("network", arg[1], "proto") == "dhcp" and ra.enabled or ra.disabled
239 ra:depends("proto", "static")
240 ra:depends("proto", "dhcp")
241 ra:depends("proto", "none")
243 rs = s:taboption("ipv6", Flag, "send_rs", translate("Send Router Solicitiations"))
244 rs.default = m.uci:get("network", arg[1], "proto") ~= "dhcp" and rs.enabled or rs.disabled
245 rs:depends("proto", "static")
246 rs:depends("proto", "dhcp")
247 rs:depends("proto", "none")
250 dns = s:taboption("general", DynamicList, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
251 translate("You can specify multiple DNS servers here, press enter to add a new entry. Servers entered here will override " ..
252 "automatically assigned ones."))
256 dns.datatype = "ipaddr"
257 dns:depends({ peerdns = "", proto = "static" })
258 dns:depends({ peerdns = "", proto = "dhcp" })
259 dns:depends({ peerdns = "", proto = "pppoe" })
260 dns:depends({ peerdns = "", proto = "pppoa" })
261 dns:depends({ peerdns = "", proto = "none" })
263 mtu = s:taboption("physical", Value, "mtu", "MTU")
265 mtu.datatype = "uinteger"
266 mtu.placeholder = 1500
267 mtu:depends("proto", "static")
268 mtu:depends("proto", "dhcp")
269 mtu:depends("proto", "pppoe")
270 mtu:depends("proto", "pppoa")
271 mtu:depends("proto", "6in4")
272 mtu:depends("proto", "6to4")
273 mtu:depends("proto", "none")
275 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
276 srv:depends("proto", "pptp")
278 srv.datatype = "host"
281 peer = s:taboption("general", Value, "peeraddr", translate("Server IPv4-Address"))
282 peer.optional = false
283 peer.datatype = "ip4addr"
284 peer:depends("proto", "6in4")
287 if has_6in4 or has_6to4 then
288 ttl = s:taboption("physical", Value, "ttl", translate("TTL"))
291 ttl.datatype = "uinteger"
292 ttl:depends("proto", "6in4")
293 ttl:depends("proto", "6to4")
297 advi = s:taboption("general", Value, "adv_interface", translate("Advertise IPv6 on network"))
298 advi.widget = "checkbox"
299 advi.exclude = arg[1]
301 advi.template = "cbi/network_netlist"
303 advi.nobridges = true
304 advi:depends("proto", "6to4")
306 advn = s:taboption("general", Value, "adv_subnet", translate("Advertised network ID"), translate("Allowed range is 1 to FFFF"))
308 advn:depends("proto", "6to4")
310 function advn.write(self, section, value)
311 value = tonumber(value, 16) or 1
313 if value > 65535 then value = 65535
314 elseif value < 1 then value = 1 end
316 Value.write(self, section, "%X" % value)
321 rnet = s:taboption("general", Value, "network", translate("Relay between networks"))
322 rnet.widget = "checkbox"
323 rnet.exclude = arg[1]
324 rnet.template = "cbi/network_netlist"
326 rnet.nobridges = true
327 rnet:depends("proto", "relay")
330 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
331 mac:depends("proto", "none")
332 mac:depends("proto", "static")
333 mac:depends("proto", "dhcp")
334 mac.placeholder = ifc and ifc:mac():upper()
337 service = s:taboption("general", ListValue, "service", translate("Service type"))
338 service:value("", translate("-- Please choose --"))
339 service:value("umts", "UMTS/GPRS")
340 service:value("cdma", "CDMA")
341 service:value("evdo", "EV-DO")
342 service:depends("proto", "3g")
343 service.rmempty = true
345 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
346 apn:depends("proto", "3g")
348 pincode = s:taboption("general", Value, "pincode",
349 translate("PIN code"),
350 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
352 pincode:depends("proto", "3g")
356 tunid = s:taboption("general", Value, "tunnelid", translate("HE.net Tunnel ID"))
357 tunid.optional = true
358 tunid.datatype = "uinteger"
359 tunid:depends("proto", "6in4")
362 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp or has_6in4 then
363 user = s:taboption("general", Value, "username", translate("Username"))
365 user:depends("proto", "pptp")
366 user:depends("proto", "pppoe")
367 user:depends("proto", "pppoa")
368 user:depends("proto", "ppp")
369 user:depends("proto", "3g")
370 user:depends("proto", "6in4")
372 pass = s:taboption("general", Value, "password", translate("Password"))
375 pass:depends("proto", "pptp")
376 pass:depends("proto", "pppoe")
377 pass:depends("proto", "pppoa")
378 pass:depends("proto", "ppp")
379 pass:depends("proto", "3g")
380 pass:depends("proto", "6in4")
383 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
384 ka = s:taboption("ppp", Value, "keepalive",
385 translate("Keep-Alive"),
386 translate("Number of failed connection tests to initiate automatic reconnect")
388 ka:depends("proto", "pptp")
389 ka:depends("proto", "pppoe")
390 ka:depends("proto", "pppoa")
391 ka:depends("proto", "ppp")
392 ka:depends("proto", "3g")
394 demand = s:taboption("ppp", Value, "demand",
395 translate("Automatic Disconnect"),
396 translate("Time (in seconds) after which an unused connection will be closed")
398 demand.optional = true
399 demand.datatype = "uinteger"
400 demand:depends("proto", "pptp")
401 demand:depends("proto", "pppoe")
402 demand:depends("proto", "pppoa")
403 demand:depends("proto", "ppp")
404 demand:depends("proto", "3g")
408 encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
409 encaps:depends("proto", "pppoa")
410 encaps:value("vc", "VC-Mux")
411 encaps:value("llc", "LLC")
413 atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
414 atmdev:depends("proto", "pppoa")
416 atmdev.datatype = "uinteger"
418 vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
419 vci:depends("proto", "pppoa")
421 vci.datatype = "uinteger"
423 vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
424 vpi:depends("proto", "pppoa")
426 vpi.datatype = "uinteger"
429 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
430 device = s:taboption("general", Value, "device",
431 translate("Modem device"),
432 translate("The device node of your modem, e.g. /dev/ttyUSB0")
434 device:depends("proto", "ppp")
435 device:depends("proto", "3g")
437 defaultroute = s:taboption("ppp", Flag, "defaultroute",
438 translate("Replace default route"),
439 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
441 defaultroute:depends("proto", "ppp")
442 defaultroute:depends("proto", "pppoa")
443 defaultroute:depends("proto", "pppoe")
444 defaultroute:depends("proto", "pptp")
445 defaultroute:depends("proto", "3g")
446 defaultroute.default = defaultroute.enabled
448 peerdns = s:taboption("ppp", Flag, "peerdns",
449 translate("Use peer DNS"),
450 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
452 peerdns:depends("proto", "ppp")
453 peerdns:depends("proto", "pppoa")
454 peerdns:depends("proto", "pppoe")
455 peerdns:depends("proto", "pptp")
456 peerdns:depends("proto", "3g")
457 peerdns.default = peerdns.enabled
460 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
461 ipv6:depends("proto", "ppp")
462 ipv6:depends("proto", "pppoa")
463 ipv6:depends("proto", "pppoe")
464 ipv6:depends("proto", "pptp")
465 ipv6:depends("proto", "3g")
468 connect = s:taboption("ppp", Value, "connect",
469 translate("Connect script"),
470 translate("Let pppd run this script after establishing the PPP link")
472 connect:depends("proto", "ppp")
473 connect:depends("proto", "pppoe")
474 connect:depends("proto", "pppoa")
475 connect:depends("proto", "pptp")
476 connect:depends("proto", "3g")
478 disconnect = s:taboption("ppp", Value, "disconnect",
479 translate("Disconnect script"),
480 translate("Let pppd run this script before tearing down the PPP link")
482 disconnect:depends("proto", "ppp")
483 disconnect:depends("proto", "pppoe")
484 disconnect:depends("proto", "pppoa")
485 disconnect:depends("proto", "pptp")
486 disconnect:depends("proto", "3g")
488 pppd_options = s:taboption("ppp", Value, "pppd_options",
489 translate("Additional pppd options"),
490 translate("Specify additional command line arguments for pppd here")
492 pppd_options:depends("proto", "ppp")
493 pppd_options:depends("proto", "pppoa")
494 pppd_options:depends("proto", "pppoe")
495 pppd_options:depends("proto", "pptp")
496 pppd_options:depends("proto", "3g")
498 maxwait = s:taboption("ppp", Value, "maxwait",
499 translate("Setup wait time"),
500 translate("Seconds to wait for the modem to become ready before attempting to connect")
502 maxwait:depends("proto", "3g")
503 maxwait.default = "0"
504 maxwait.optional = true
505 maxwait.datatype = "uinteger"
509 fb = s:taboption("relay", Flag, "forward_bcast", translate("Forward broadcasts"))
510 fb.default = fb.enabled
511 fb:depends("proto", "relay")
513 fd = s:taboption("relay", Flag, "forward_dhcp", translate("Forward DHCP"))
514 fd.default = fd.enabled
515 fd:depends("proto", "relay")
517 gw = s:taboption("relay", Value, "relay_gateway", translate("Override Gateway"))
519 gw.placeholder = "0.0.0.0"
520 gw.datatype = "ip4addr"
521 gw:depends("proto", "relay")
522 function gw.cfgvalue(self, section)
523 return m.uci:get("network", section, "gateway")
525 function gw.write(self, section, value)
526 return m.uci:set("network", section, "gateway", value)
528 function gw.delete(self, section)
529 return m.uci:delete("network", section, "gateway")
532 expiry = s:taboption("relay", Value, "expiry", translate("Host expiry timeout"))
533 expiry.optional = true
534 expiry.placeholder = 30
535 expiry.datatype = "uinteger"
536 expiry:depends("proto", "relay")
538 retry = s:taboption("relay", Value, "retry", translate("ARP ping retries"))
539 retry.optional = true
540 retry.placeholder = 5
541 retry.datatype = "uinteger"
542 retry:depends("proto", "relay")
544 table = s:taboption("relay", Value, "table", translate("Routing table ID"))
545 table.optional = true
546 table.placeholder = 16800
547 table.datatype = "uinteger"
548 table:depends("proto", "relay")
552 mca = s:taboption("ahcp", Value, "multicast_address", translate("Multicast address"))
554 mca.placeholder = "ff02::cca6:c0f9:e182:5359"
555 mca.datatype = "ip6addr"
556 mca:depends("proto", "ahcp")
558 port = s:taboption("ahcp", Value, "port", translate("Port"))
560 port.placeholder = 5359
561 port.datatype = "port"
562 port:depends("proto", "ahcp")
564 fam = s:taboption("ahcp", ListValue, "_family", translate("Protocol family"))
565 fam:value("", translate("IPv4 and IPv6"))
566 fam:value("ipv4", translate("IPv4 only"))
567 fam:value("ipv6", translate("IPv6 only"))
568 fam:depends("proto", "ahcp")
570 function fam.cfgvalue(self, section)
571 local v4 = m.uci:get_bool("network", section, "ipv4_only")
572 local v6 = m.uci:get_bool("network", section, "ipv6_only")
581 function fam.write(self, section, value)
582 if value == "ipv4" then
583 m.uci:set("network", section, "ipv4_only", "true")
584 m.uci:delete("network", section, "ipv6_only")
585 elseif value == "ipv6" then
586 m.uci:set("network", section, "ipv6_only", "true")
587 m.uci:delete("network", section, "ipv4_only")
591 function fam.remove(self, section)
592 m.uci:delete("network", section, "ipv4_only")
593 m.uci:delete("network", section, "ipv6_only")
596 nodns = s:taboption("ahcp", Flag, "no_dns", translate("Disable DNS setup"))
597 nodns.optional = true
598 nodns.enabled = "true"
599 nodns.disabled = "false"
600 nodns.default = nodns.disabled
601 nodns:depends("proto", "ahcp")
603 ltime = s:taboption("ahcp", Value, "lease_time", translate("Lease validity time"))
604 ltime.optional = true
605 ltime.placeholder = 3666
606 ltime.datatype = "uinteger"
607 ltime:depends("proto", "ahcp")
610 if net:proto() ~= "relay" then
611 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
614 s2:depends("interface", arg[1])
615 s2.defaults.interface = arg[1]
617 s2:tab("general", translate("General Setup"))
618 s2.defaults.proto = "static"
620 ip = s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
622 ip.datatype = "ip4addr"
624 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
626 nm.datatype = "ip4addr"
627 nm:value("255.255.255.0")
628 nm:value("255.255.0.0")
629 nm:value("255.0.0.0")
631 gw = s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
633 gw.datatype = "ip4addr"
636 s2:tab("ipv6", translate("IPv6 Setup"))
638 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"))
640 ip6.datatype = "ip6addr"
642 gw6 = s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
644 gw6.datatype = "ip6addr"
647 s2:tab("advanced", translate("Advanced Settings"))
649 bcast = s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
650 bcast.optional = true
651 bcast.datatype = "ip4addr"
653 dns = s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
655 dns.datatype = "ip4addr"
660 -- Display DNS settings if dnsmasq is available
663 if has_dnsmasq and net:proto() == "static" then
664 m2 = Map("dhcp", "", "")
667 function m2.on_parse()
668 m2.uci:foreach("dhcp", "dhcp", function(s)
669 if s.interface == arg[1] then
670 section_id = s['.name']
675 if not section_id then
678 while m2.uci:get("dhcp", section_id) do
679 section_id = arg[1] .. c
685 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
688 s:tab("general", translate("General Setup"))
689 s:tab("advanced", translate("Advanced Settings"))
691 function s.cfgsections(self)
692 return { section_id }
695 local ignore = s:taboption("general", Flag, "ignore",
696 translate("Ignore interface"),
697 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
700 ignore.rmempty = false
701 ignore.default = ignore.enabled
703 function ignore.write(self, section, value)
704 if m2.uci:get("dhcp", section) ~= "dhcp" then
705 m2.uci:section("dhcp", "dhcp", section, {
709 m2.uci:set("dhcp", section, "ignore", (value == "1") and "1" or "0")
713 local start = s:taboption("general", Value, "start", translate("Start"),
714 translate("Lowest leased address as offset from the network address."))
715 start.optional = true
716 start.datatype = "uinteger"
717 start.default = "100"
719 local limit = s:taboption("general", Value, "limit", translate("Limit"),
720 translate("Maximum number of leased addresses."))
721 limit.optional = true
722 limit.datatype = "uinteger"
723 limit.default = "150"
725 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
726 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
728 ltime.default = "12h"
730 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
731 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
732 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
733 "clients having static leases will be served."))
734 dd.default = dd.enabled
736 s:taboption("advanced", Flag, "force", translate("Force"),
737 translate("Force DHCP on this network even if another server is detected."))
739 -- XXX: is this actually useful?
740 --s:taboption("advanced", Value, "name", translate("Name"),
741 -- translate("Define a name for this network."))
743 mask = s:taboption("advanced", Value, "netmask",
744 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
745 translate("Override the netmask sent to clients. Normally it is calculated " ..
746 "from the subnet that is served."))
749 mask.datatype = "ip4addr"
751 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
752 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
753 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
756 for i, n in ipairs(s.children) do
758 n:depends("ignore", "")