3aef9d71f88267b6b151b969611be556dcfaee59
[project/luci.git] / modules / admin-full / luasrc / model / cbi / admin_network / ifaces.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008-2011 Jo-Philipp Wich <xm@subsignal.org>
6
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
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id$
14 ]]--
15
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"
20
21 arg[1] = arg[1] or ""
22
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")
26
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")
37
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>)."))
39 m:chain("wireless")
40
41 if has_firewall then
42 m:chain("firewall")
43 end
44
45 if has_radvd then
46 m:chain("radvd")
47 end
48
49 nw.init(m.uci)
50 fw.init(m.uci)
51
52
53 local net = nw:get_network(arg[1])
54
55 -- redirect to overview page if network does not exist anymore (e.g. after a revert)
56 if not net then
57 luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
58 return
59 end
60
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, {
64 interface = arg[1],
65 start = "100",
66 limit = "150",
67 leasetime = "12h"
68 })
69
70 m.uci:save("dhcp")
71 luci.http.redirect(luci.dispatcher.build_url("admin/network/network", arg[1]))
72 return
73 end
74
75 local ifc = net:get_interfaces()[1]
76
77 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
78 s.addremove = false
79
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
89
90 st = s:taboption("general", DummyValue, "__status", translate("Status"))
91 st.template = "admin_network/iface_status"
92 st.network = arg[1]
93
94 --[[
95 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
96 back.value = ""
97 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
98 ]]
99
100 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
101 p.override_scheme = true
102 p.default = "static"
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"))
115
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")
118 end
119
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
122
123 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
124 br.enabled = "bridge"
125 br.rmempty = true
126 br:depends("proto", "static")
127 br:depends("proto", "dhcp")
128 br:depends("proto", "none")
129
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")
133 stp.rmempty = true
134
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.network = arg[1]
140 ifname_single:depends({ type = "", proto = "static" })
141 ifname_single:depends({ type = "", proto = "dhcp" })
142 ifname_single:depends({ type = "", proto = "pppoe" })
143 ifname_single:depends({ type = "", proto = "pppoa" })
144 ifname_single:depends({ type = "", proto = "ahcp" })
145 ifname_single:depends({ type = "", proto = "none" })
146
147 function ifname_single.cfgvalue(self, s)
148 -- let the template figure out the related ifaces through the network model
149 return nil
150 end
151
152 function ifname_single.write(self, s, val)
153 local n = nw:get_network(s)
154 if n then
155 local i
156 for _, i in ipairs(n:get_interfaces()) do
157 n:del_interface(i)
158 end
159
160 for i in ut.imatch(val) do
161 n:add_interface(i)
162
163 -- if this is not a bridge, only assign first interface
164 if self.option == "ifname_single" then
165 break
166 end
167 end
168 end
169 end
170
171 function ifname_single.remove(self, s)
172 self:write(s, "")
173 end
174
175
176 ifname_multi = s:taboption("physical", Value, "ifname_multi", translate("Interface"))
177 ifname_multi.template = "cbi/network_ifacelist"
178 ifname_multi.nobridges = true
179 ifname_multi.network = arg[1]
180 ifname_multi.widget = "checkbox"
181 ifname_multi:depends("type", "bridge")
182 ifname_multi.cfgvalue = ifname_single.cfgvalue
183 ifname_multi.write = ifname_single.write
184 ifname_multi.remove = ifname_single.remove
185
186
187 if has_firewall then
188 fwzone = s:taboption("firewall", Value, "_fwzone",
189 translate("Create / Assign firewall-zone"),
190 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."))
191
192 fwzone.template = "cbi/firewall_zonelist"
193 fwzone.network = arg[1]
194 fwzone.rmempty = false
195
196 function fwzone.cfgvalue(self, section)
197 self.iface = section
198 local z = fw:get_zone_by_network(section)
199 return z and z:name()
200 end
201
202 function fwzone.write(self, section, value)
203 local zone = fw:get_zone(value)
204
205 if not zone and value == '-' then
206 value = m:formvalue(self:cbid(section) .. ".newzone")
207 if value and #value > 0 then
208 zone = fw:add_zone(value)
209 else
210 fw:del_network(section)
211 end
212 end
213
214 if zone then
215 fw:del_network(section)
216 zone:add_network(section)
217 end
218 end
219 end
220
221 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
222 ipaddr.optional = true
223 ipaddr.datatype = "ip4addr"
224 ipaddr:depends("proto", "static")
225
226 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
227 nm.optional = true
228 nm.datatype = "ip4addr"
229 nm:depends("proto", "static")
230 nm:value("255.255.255.0")
231 nm:value("255.255.0.0")
232 nm:value("255.0.0.0")
233
234 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
235 gw.optional = true
236 gw.datatype = "ip4addr"
237 gw:depends("proto", "static")
238
239 bcast = s:taboption("general", Value, "broadcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
240 bcast.optional = true
241 bcast.datatype = "ip4addr"
242 bcast:depends("proto", "static")
243
244 if has_ipv6 then
245 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"))
246 ip6addr.optional = true
247 ip6addr.datatype = "ip6addr"
248 ip6addr:depends("proto", "static")
249 ip6addr:depends("proto", "6in4")
250
251 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
252 ip6gw.optional = true
253 ip6gw.datatype = "ip6addr"
254 ip6gw:depends("proto", "static")
255
256
257 ra = s:taboption("ipv6", Flag, "accept_ra", translate("Accept Router Advertisements"))
258 ra.default = m.uci:get("network", arg[1], "proto") == "dhcp" and ra.enabled or ra.disabled
259 ra:depends("proto", "static")
260 ra:depends("proto", "dhcp")
261 ra:depends("proto", "none")
262
263 rs = s:taboption("ipv6", Flag, "send_rs", translate("Send Router Solicitiations"))
264 rs.default = m.uci:get("network", arg[1], "proto") ~= "dhcp" and rs.enabled or rs.disabled
265 rs:depends("proto", "static")
266 rs:depends("proto", "dhcp")
267 rs:depends("proto", "none")
268 end
269
270 dns = s:taboption("general", DynamicList, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
271 translate("You can specify multiple DNS servers here, press enter to add a new entry. Servers entered here will override " ..
272 "automatically assigned ones."))
273
274 dns.optional = true
275 dns.cast = "string"
276 dns.datatype = "ipaddr"
277 dns:depends({ peerdns = "", proto = "static" })
278 dns:depends({ peerdns = "", proto = "dhcp" })
279 dns:depends({ peerdns = "", proto = "pppoe" })
280 dns:depends({ peerdns = "", proto = "pppoa" })
281 dns:depends({ peerdns = "", proto = "none" })
282
283 mtu = s:taboption("physical", Value, "mtu", "MTU")
284 mtu.optional = true
285 mtu.datatype = "uinteger"
286 mtu.placeholder = 1500
287 mtu:depends("proto", "static")
288 mtu:depends("proto", "dhcp")
289 mtu:depends("proto", "pppoe")
290 mtu:depends("proto", "pppoa")
291 mtu:depends("proto", "6in4")
292 mtu:depends("proto", "6to4")
293 mtu:depends("proto", "none")
294
295 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
296 srv:depends("proto", "pptp")
297 srv.optional = false
298 srv.datatype = "host"
299
300 if has_6in4 then
301 peer = s:taboption("general", Value, "peeraddr", translate("Server IPv4-Address"))
302 peer.optional = false
303 peer.datatype = "ip4addr"
304 peer:depends("proto", "6in4")
305 end
306
307 if has_6in4 or has_6to4 then
308 ttl = s:taboption("physical", Value, "ttl", translate("TTL"))
309 ttl.default = "64"
310 ttl.optional = true
311 ttl.datatype = "uinteger"
312 ttl:depends("proto", "6in4")
313 ttl:depends("proto", "6to4")
314 end
315
316 if has_6to4 then
317 advi = s:taboption("general", Value, "adv_interface", translate("Advertise IPv6 on network"))
318 advi.widget = "checkbox"
319 advi.exclude = arg[1]
320 advi.default = "lan"
321 advi.template = "cbi/network_netlist"
322 advi.nocreate = true
323 advi.nobridges = true
324 advi:depends("proto", "6to4")
325
326 advn = s:taboption("general", Value, "adv_subnet", translate("Advertised network ID"), translate("Allowed range is 1 to FFFF"))
327 advn.default = "1"
328 advn:depends("proto", "6to4")
329
330 function advn.write(self, section, value)
331 value = tonumber(value, 16) or 1
332
333 if value > 65535 then value = 65535
334 elseif value < 1 then value = 1 end
335
336 Value.write(self, section, "%X" % value)
337 end
338 end
339
340 if has_relay then
341 rnet = s:taboption("general", Value, "network", translate("Relay between networks"))
342 rnet.widget = "checkbox"
343 rnet.exclude = arg[1]
344 rnet.template = "cbi/network_netlist"
345 rnet.nocreate = true
346 rnet.nobridges = true
347 rnet:depends("proto", "relay")
348 end
349
350 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
351 mac:depends("proto", "none")
352 mac:depends("proto", "static")
353 mac:depends("proto", "dhcp")
354 mac.placeholder = ifc and ifc:mac():upper()
355
356 if has_3g then
357 service = s:taboption("general", ListValue, "service", translate("Service type"))
358 service:value("", translate("-- Please choose --"))
359 service:value("umts", "UMTS/GPRS")
360 service:value("cdma", "CDMA")
361 service:value("evdo", "EV-DO")
362 service:depends("proto", "3g")
363 service.rmempty = true
364
365 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
366 apn:depends("proto", "3g")
367
368 pincode = s:taboption("general", Value, "pincode",
369 translate("PIN code"),
370 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
371 )
372 pincode:depends("proto", "3g")
373 end
374
375 if has_6in4 then
376 tunid = s:taboption("general", Value, "tunnelid", translate("HE.net Tunnel ID"))
377 tunid.optional = true
378 tunid.datatype = "uinteger"
379 tunid:depends("proto", "6in4")
380 end
381
382 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp or has_6in4 then
383 user = s:taboption("general", Value, "username", translate("Username"))
384 user.rmempty = true
385 user:depends("proto", "pptp")
386 user:depends("proto", "pppoe")
387 user:depends("proto", "pppoa")
388 user:depends("proto", "ppp")
389 user:depends("proto", "3g")
390 user:depends("proto", "6in4")
391
392 pass = s:taboption("general", Value, "password", translate("Password"))
393 pass.rmempty = true
394 pass.password = true
395 pass:depends("proto", "pptp")
396 pass:depends("proto", "pppoe")
397 pass:depends("proto", "pppoa")
398 pass:depends("proto", "ppp")
399 pass:depends("proto", "3g")
400 pass:depends("proto", "6in4")
401 end
402
403 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
404 ka = s:taboption("ppp", Value, "keepalive",
405 translate("Keep-Alive"),
406 translate("Number of failed connection tests to initiate automatic reconnect")
407 )
408 ka:depends("proto", "pptp")
409 ka:depends("proto", "pppoe")
410 ka:depends("proto", "pppoa")
411 ka:depends("proto", "ppp")
412 ka:depends("proto", "3g")
413
414 demand = s:taboption("ppp", Value, "demand",
415 translate("Automatic Disconnect"),
416 translate("Time (in seconds) after which an unused connection will be closed")
417 )
418 demand.optional = true
419 demand.datatype = "uinteger"
420 demand:depends("proto", "pptp")
421 demand:depends("proto", "pppoe")
422 demand:depends("proto", "pppoa")
423 demand:depends("proto", "ppp")
424 demand:depends("proto", "3g")
425 end
426
427 if has_pppoa then
428 encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
429 encaps:depends("proto", "pppoa")
430 encaps:value("vc", "VC-Mux")
431 encaps:value("llc", "LLC")
432
433 atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
434 atmdev:depends("proto", "pppoa")
435 atmdev.default = "0"
436 atmdev.datatype = "uinteger"
437
438 vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
439 vci:depends("proto", "pppoa")
440 vci.default = "35"
441 vci.datatype = "uinteger"
442
443 vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
444 vpi:depends("proto", "pppoa")
445 vpi.default = "8"
446 vpi.datatype = "uinteger"
447 end
448
449 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
450 device = s:taboption("general", Value, "device",
451 translate("Modem device"),
452 translate("The device node of your modem, e.g. /dev/ttyUSB0")
453 )
454 device:depends("proto", "ppp")
455 device:depends("proto", "3g")
456
457 defaultroute = s:taboption("ppp", Flag, "defaultroute",
458 translate("Replace default route"),
459 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
460 )
461 defaultroute:depends("proto", "ppp")
462 defaultroute:depends("proto", "pppoa")
463 defaultroute:depends("proto", "pppoe")
464 defaultroute:depends("proto", "pptp")
465 defaultroute:depends("proto", "3g")
466 defaultroute.default = defaultroute.enabled
467
468 peerdns = s:taboption("ppp", Flag, "peerdns",
469 translate("Use peer DNS"),
470 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
471 )
472 peerdns:depends("proto", "ppp")
473 peerdns:depends("proto", "pppoa")
474 peerdns:depends("proto", "pppoe")
475 peerdns:depends("proto", "pptp")
476 peerdns:depends("proto", "3g")
477 peerdns.default = peerdns.enabled
478
479 if has_ipv6 then
480 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
481 ipv6:depends("proto", "ppp")
482 ipv6:depends("proto", "pppoa")
483 ipv6:depends("proto", "pppoe")
484 ipv6:depends("proto", "pptp")
485 ipv6:depends("proto", "3g")
486 end
487
488 connect = s:taboption("ppp", Value, "connect",
489 translate("Connect script"),
490 translate("Let pppd run this script after establishing the PPP link")
491 )
492 connect:depends("proto", "ppp")
493 connect:depends("proto", "pppoe")
494 connect:depends("proto", "pppoa")
495 connect:depends("proto", "pptp")
496 connect:depends("proto", "3g")
497
498 disconnect = s:taboption("ppp", Value, "disconnect",
499 translate("Disconnect script"),
500 translate("Let pppd run this script before tearing down the PPP link")
501 )
502 disconnect:depends("proto", "ppp")
503 disconnect:depends("proto", "pppoe")
504 disconnect:depends("proto", "pppoa")
505 disconnect:depends("proto", "pptp")
506 disconnect:depends("proto", "3g")
507
508 pppd_options = s:taboption("ppp", Value, "pppd_options",
509 translate("Additional pppd options"),
510 translate("Specify additional command line arguments for pppd here")
511 )
512 pppd_options:depends("proto", "ppp")
513 pppd_options:depends("proto", "pppoa")
514 pppd_options:depends("proto", "pppoe")
515 pppd_options:depends("proto", "pptp")
516 pppd_options:depends("proto", "3g")
517
518 maxwait = s:taboption("ppp", Value, "maxwait",
519 translate("Setup wait time"),
520 translate("Seconds to wait for the modem to become ready before attempting to connect")
521 )
522 maxwait:depends("proto", "3g")
523 maxwait.default = "0"
524 maxwait.optional = true
525 maxwait.datatype = "uinteger"
526 end
527
528 if has_relay then
529 fb = s:taboption("relay", Flag, "forward_bcast", translate("Forward broadcasts"))
530 fb.default = fb.enabled
531 fb:depends("proto", "relay")
532
533 fd = s:taboption("relay", Flag, "forward_dhcp", translate("Forward DHCP"))
534 fd.default = fd.enabled
535 fd:depends("proto", "relay")
536
537 gw = s:taboption("relay", Value, "relay_gateway", translate("Override Gateway"))
538 gw.optional = true
539 gw.placeholder = "0.0.0.0"
540 gw.datatype = "ip4addr"
541 gw:depends("proto", "relay")
542 function gw.cfgvalue(self, section)
543 return m.uci:get("network", section, "gateway")
544 end
545 function gw.write(self, section, value)
546 return m.uci:set("network", section, "gateway", value)
547 end
548 function gw.delete(self, section)
549 return m.uci:delete("network", section, "gateway")
550 end
551
552 expiry = s:taboption("relay", Value, "expiry", translate("Host expiry timeout"))
553 expiry.optional = true
554 expiry.placeholder = 30
555 expiry.datatype = "uinteger"
556 expiry:depends("proto", "relay")
557
558 retry = s:taboption("relay", Value, "retry", translate("ARP ping retries"))
559 retry.optional = true
560 retry.placeholder = 5
561 retry.datatype = "uinteger"
562 retry:depends("proto", "relay")
563
564 table = s:taboption("relay", Value, "table", translate("Routing table ID"))
565 table.optional = true
566 table.placeholder = 16800
567 table.datatype = "uinteger"
568 table:depends("proto", "relay")
569 end
570
571 if has_ahcp then
572 mca = s:taboption("ahcp", Value, "multicast_address", translate("Multicast address"))
573 mca.optional = true
574 mca.placeholder = "ff02::cca6:c0f9:e182:5359"
575 mca.datatype = "ip6addr"
576 mca:depends("proto", "ahcp")
577
578 port = s:taboption("ahcp", Value, "port", translate("Port"))
579 port.optional = true
580 port.placeholder = 5359
581 port.datatype = "port"
582 port:depends("proto", "ahcp")
583
584 fam = s:taboption("ahcp", ListValue, "_family", translate("Protocol family"))
585 fam:value("", translate("IPv4 and IPv6"))
586 fam:value("ipv4", translate("IPv4 only"))
587 fam:value("ipv6", translate("IPv6 only"))
588 fam:depends("proto", "ahcp")
589
590 function fam.cfgvalue(self, section)
591 local v4 = m.uci:get_bool("network", section, "ipv4_only")
592 local v6 = m.uci:get_bool("network", section, "ipv6_only")
593 if v4 then
594 return "ipv4"
595 elseif v6 then
596 return "ipv6"
597 end
598 return ""
599 end
600
601 function fam.write(self, section, value)
602 if value == "ipv4" then
603 m.uci:set("network", section, "ipv4_only", "true")
604 m.uci:delete("network", section, "ipv6_only")
605 elseif value == "ipv6" then
606 m.uci:set("network", section, "ipv6_only", "true")
607 m.uci:delete("network", section, "ipv4_only")
608 end
609 end
610
611 function fam.remove(self, section)
612 m.uci:delete("network", section, "ipv4_only")
613 m.uci:delete("network", section, "ipv6_only")
614 end
615
616 nodns = s:taboption("ahcp", Flag, "no_dns", translate("Disable DNS setup"))
617 nodns.optional = true
618 nodns.enabled = "true"
619 nodns.disabled = "false"
620 nodns.default = nodns.disabled
621 nodns:depends("proto", "ahcp")
622
623 ltime = s:taboption("ahcp", Value, "lease_time", translate("Lease validity time"))
624 ltime.optional = true
625 ltime.placeholder = 3666
626 ltime.datatype = "uinteger"
627 ltime:depends("proto", "ahcp")
628 end
629
630 if net:proto() ~= "relay" then
631 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
632 s2.addremove = true
633
634 s2:depends("interface", arg[1])
635 s2.defaults.interface = arg[1]
636
637 s2:tab("general", translate("General Setup"))
638 s2.defaults.proto = "static"
639
640 ip = s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
641 ip.optional = true
642 ip.datatype = "ip4addr"
643
644 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
645 nm.optional = true
646 nm.datatype = "ip4addr"
647 nm:value("255.255.255.0")
648 nm:value("255.255.0.0")
649 nm:value("255.0.0.0")
650
651 gw = s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
652 gw.optional = true
653 gw.datatype = "ip4addr"
654
655 if has_ipv6 then
656 s2:tab("ipv6", translate("IPv6 Setup"))
657
658 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"))
659 ip6.optional = true
660 ip6.datatype = "ip6addr"
661
662 gw6 = s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
663 gw6.optional = true
664 gw6.datatype = "ip6addr"
665 end
666
667 s2:tab("advanced", translate("Advanced Settings"))
668
669 bcast = s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
670 bcast.optional = true
671 bcast.datatype = "ip4addr"
672
673 dns = s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
674 dns.optional = true
675 dns.datatype = "ip4addr"
676 end
677
678
679 --
680 -- Display DNS settings if dnsmasq is available
681 --
682
683 if has_dnsmasq and net:proto() == "static" then
684 m2 = Map("dhcp", "", "")
685
686 local has_section = false
687
688 m2.uci:foreach("dhcp", "dhcp", function(s)
689 if s.interface == arg[1] then
690 has_section = true
691 return false
692 end
693 end)
694
695 if not has_section then
696
697 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
698 s.anonymous = true
699 s.cfgsections = function() return { "_enable" } end
700
701 x = s:option(Button, "_enable")
702 x.title = translate("No DHCP Server configured for this interface")
703 x.inputtitle = translate("Setup DHCP Server")
704 x.inputstyle = "apply"
705
706 else
707
708 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
709 s.addremove = false
710 s.anonymous = true
711 s:tab("general", translate("General Setup"))
712 s:tab("advanced", translate("Advanced Settings"))
713
714 function s.filter(self, section)
715 return m2.uci:get("dhcp", section, "interface") == arg[1]
716 end
717
718 local ignore = s:taboption("general", Flag, "ignore",
719 translate("Ignore interface"),
720 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
721 "this interface."))
722
723 local start = s:taboption("general", Value, "start", translate("Start"),
724 translate("Lowest leased address as offset from the network address."))
725 start.optional = true
726 start.datatype = "uinteger"
727 start.default = "100"
728
729 local limit = s:taboption("general", Value, "limit", translate("Limit"),
730 translate("Maximum number of leased addresses."))
731 limit.optional = true
732 limit.datatype = "uinteger"
733 limit.default = "150"
734
735 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
736 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
737 ltime.rmempty = true
738 ltime.default = "12h"
739
740 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
741 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
742 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
743 "clients having static leases will be served."))
744 dd.default = dd.enabled
745
746 s:taboption("advanced", Flag, "force", translate("Force"),
747 translate("Force DHCP on this network even if another server is detected."))
748
749 -- XXX: is this actually useful?
750 --s:taboption("advanced", Value, "name", translate("Name"),
751 -- translate("Define a name for this network."))
752
753 mask = s:taboption("advanced", Value, "netmask",
754 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
755 translate("Override the netmask sent to clients. Normally it is calculated " ..
756 "from the subnet that is served."))
757
758 mask.optional = true
759 mask.datatype = "ip4addr"
760
761 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
762 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
763 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
764
765 for i, n in ipairs(s.children) do
766 if n ~= ignore then
767 n:depends("ignore", "")
768 end
769 end
770
771 end
772 end
773
774 return m, m2