modules/admin-full: move pppoa related options into ATM tab
[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 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 nw = require "luci.model.network"
18 local fw = require "luci.model.firewall"
19
20 arg[1] = arg[1] or ""
21
22 local has_3g     = fs.access("/usr/bin/gcom")
23 local has_pptp   = fs.access("/usr/sbin/pptp")
24 local has_pppd   = fs.access("/usr/sbin/pppd")
25 local has_pppoe  = fs.glob("/usr/lib/pppd/*/rp-pppoe.so")()
26 local has_pppoa  = fs.glob("/usr/lib/pppd/*/pppoatm.so")()
27 local has_ipv6   = fs.access("/proc/net/ipv6_route")
28 local has_6in4   = fs.access("/lib/network/6in4.sh")
29
30 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>)."))
31 m:chain("firewall")
32 m:chain("wireless")
33
34 nw.init(m.uci)
35 fw.init(m.uci)
36
37 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
38 s.addremove = false
39
40 s:tab("general", translate("General Setup"))
41 if has_ipv6  then s:tab("ipv6", translate("IPv6 Setup")) end
42 if has_pppd  then s:tab("ppp", translate("PPP Settings")) end
43 if has_pppoa then s:tab("atm", translate("ATM Settings")) end
44 s:tab("physical", translate("Physical Settings"))
45 s:tab("firewall", translate("Firewall Settings"))
46
47 --[[
48 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
49 back.value = ""
50 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
51 ]]
52
53 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
54 p.override_scheme = true
55 p.default = "static"
56 p:value("static", translate("static"))
57 p:value("dhcp", "DHCP")
58 if has_pppd  then p:value("ppp",   "PPP")     end
59 if has_pppoe then p:value("pppoe", "PPPoE")   end
60 if has_pppoa then p:value("pppoa", "PPPoA")   end
61 if has_3g    then p:value("3g",    "UMTS/3G") end
62 if has_pptp  then p:value("pptp",  "PPTP")    end
63 p:value("none", translate("none"))
64
65 if not ( has_pppd and has_pppoe and has_pppoa and has_3g and has_pptp ) then
66         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")
67 end
68
69 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
70 br.enabled = "bridge"
71 br.rmempty = true
72
73 stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
74         translate("Enables the Spanning Tree Protocol on this bridge"))
75 stp:depends("type", "1")
76 stp.rmempty = true
77
78 ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
79 ifname_single.template = "cbi/network_ifacelist"
80 ifname_single.widget = "radio"
81 ifname_single.nobridges = true
82 ifname_single.network = arg[1]
83 ifname_single.rmempty = true
84 ifname_single:depends("type", "")
85
86 function ifname_single.cfgvalue(self, s)
87         return self.map.uci:get("network", s, "ifname")
88 end
89
90 function ifname_single.write(self, s, val)
91         local n = nw:get_network(s)
92         if n then
93                 local i
94                 for _, i in ipairs(n:get_interfaces()) do
95                         n:del_interface(i)
96                 end
97                 n:add_interface(val)
98         end
99 end
100
101
102 ifname_multi = s:taboption("physical", MultiValue, "ifname_multi", translate("Interface"))
103 ifname_multi.template = "cbi/network_ifacelist"
104 ifname_multi.nobridges = true
105 ifname_multi.network = arg[1]
106 ifname_multi.widget = "checkbox"
107 ifname_multi:depends("type", "1")
108 ifname_multi.cfgvalue = ifname_single.cfgvalue
109 ifname_multi.write = ifname_single.write
110
111
112 for _, d in ipairs(nw:get_interfaces()) do
113         if not d:is_bridge() then
114                 ifname_single:value(d:name())
115                 ifname_multi:value(d:name())
116         end
117 end
118
119
120 local fwd_to, fwd_from
121
122 fwzone = s:taboption("firewall", Value, "_fwzone",
123         translate("Create / Assign firewall-zone"),
124         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."))
125
126 fwzone.template = "cbi/firewall_zonelist"
127 fwzone.network = arg[1]
128 fwzone.rmempty = false
129
130 function fwzone.cfgvalue(self, section)
131         self.iface = section
132         local z = fw:get_zone_by_network(section)
133         return z and z:name()
134 end
135
136 function fwzone.write(self, section, value)
137         local zone = fw:get_zone(value)
138
139         if not zone and value == '-' then
140                 value = m:formvalue(self:cbid(section) .. ".newzone")
141                 if value and #value > 0 then
142                         zone = fw:add_zone(value)
143                 else
144                         fw:del_network(section)
145                 end
146         end
147
148         if zone then
149                 fw:del_network(section)
150                 zone:add_network(section)
151         end
152 end
153
154
155 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
156 ipaddr.rmempty = true
157 ipaddr:depends("proto", "static")
158
159 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
160 nm.rmempty = true
161 nm:depends("proto", "static")
162 nm:value("255.255.255.0")
163 nm:value("255.255.0.0")
164 nm:value("255.0.0.0")
165
166 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
167 gw:depends("proto", "static")
168 gw.rmempty = true
169
170 bcast = s:taboption("general", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
171 bcast:depends("proto", "static")
172
173 if has_ipv6 then
174         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"))
175         ip6addr:depends("proto", "static")
176
177         ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
178         ip6gw:depends("proto", "static")
179 end
180
181 dns = s:taboption("general", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
182         translate("You can specify multiple DNS servers separated by space here. Servers entered here will override " ..
183                 "automatically assigned ones."))
184
185 dns:depends("peerdns", "")
186
187 mtu = s:taboption("physical", Value, "mtu", "MTU")
188 mtu.isinteger = true
189
190 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
191
192
193 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
194 srv:depends("proto", "pptp")
195 srv.rmempty = true
196
197 if has_3g then
198         service = s:taboption("general", ListValue, "service", translate("Service type"))
199         service:value("", translate("-- Please choose --"))
200         service:value("umts", "UMTS/GPRS")
201         service:value("cdma", "CDMA")
202         service:value("evdo", "EV-DO")
203         service:depends("proto", "3g")
204         service.rmempty = true
205
206         apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
207         apn:depends("proto", "3g")
208
209         pincode = s:taboption("general", Value, "pincode",
210          translate("PIN code"),
211          translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
212         )
213         pincode:depends("proto", "3g")
214 end
215
216 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
217         user = s:taboption("general", Value, "username", translate("Username"))
218         user.rmempty = true
219         user:depends("proto", "pptp")
220         user:depends("proto", "pppoe")
221         user:depends("proto", "pppoa")
222         user:depends("proto", "ppp")
223         user:depends("proto", "3g")
224
225         pass = s:taboption("general", Value, "password", translate("Password"))
226         pass.rmempty = true
227         pass.password = true
228         pass:depends("proto", "pptp")
229         pass:depends("proto", "pppoe")
230         pass:depends("proto", "pppoa")
231         pass:depends("proto", "ppp")
232         pass:depends("proto", "3g")
233
234         ka = s:taboption("ppp", Value, "keepalive",
235          translate("Keep-Alive"),
236          translate("Number of failed connection tests to initiate automatic reconnect")
237         )
238         ka:depends("proto", "pptp")
239         ka:depends("proto", "pppoe")
240         ka:depends("proto", "pppoa")
241         ka:depends("proto", "ppp")
242         ka:depends("proto", "3g")
243
244         demand = s:taboption("ppp", Value, "demand",
245          translate("Automatic Disconnect"),
246          translate("Time (in seconds) after which an unused connection will be closed")
247         )
248         demand:depends("proto", "pptp")
249         demand:depends("proto", "pppoe")
250         demand:depends("proto", "pppoa")
251         demand:depends("proto", "ppp")
252         demand:depends("proto", "3g")
253 end
254
255 if has_pppoa then
256         encaps = s:taboption("atm", ListValue, "encaps", translate("PPPoA Encapsulation"))
257         encaps:depends("proto", "pppoa")
258         encaps:value("vc", "VC-Mux")
259         encaps:value("llc", "LLC")
260
261         atmdev = s:taboption("atm", Value, "atmdev", translate("ATM device number"))
262         atmdev:depends("proto", "pppoa")
263         atmdev.default = "0"
264
265         vci = s:taboption("atm", Value, "vci", translate("ATM Virtual Channel Identifier (VCI)"))
266         vci:depends("proto", "pppoa")
267         vci.default = "35"
268
269         vpi = s:taboption("atm", Value, "vpi", translate("ATM Virtual Path Identifier (VPI)"))
270         vpi:depends("proto", "pppoa")
271         vpi.default = "8"
272 end
273
274 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
275         device = s:taboption("general", Value, "device",
276          translate("Modem device"),
277          translate("The device node of your modem, e.g. /dev/ttyUSB0")
278         )
279         device:depends("proto", "ppp")
280         device:depends("proto", "3g")
281
282         defaultroute = s:taboption("ppp", Flag, "defaultroute",
283          translate("Replace default route"),
284          translate("Let pppd replace the current default route to use the PPP interface after successful connect")
285         )
286         defaultroute:depends("proto", "ppp")
287         defaultroute:depends("proto", "pppoa")
288         defaultroute:depends("proto", "pppoe")
289         defaultroute:depends("proto", "pptp")
290         defaultroute:depends("proto", "3g")
291         defaultroute.rmempty = false
292         function defaultroute.cfgvalue(...)
293                 return ( AbstractValue.cfgvalue(...) or '1' )
294         end
295
296         peerdns = s:taboption("ppp", Flag, "peerdns",
297          translate("Use peer DNS"),
298          translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
299         )
300         peerdns:depends("proto", "ppp")
301         peerdns:depends("proto", "pppoa")
302         peerdns:depends("proto", "pppoe")
303         peerdns:depends("proto", "pptp")
304         peerdns:depends("proto", "3g")
305         peerdns.rmempty = false
306         function peerdns.cfgvalue(...)
307                 return ( AbstractValue.cfgvalue(...) or '1' )
308         end
309
310         if has_ipv6 then
311                 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
312                 ipv6:depends("proto", "ppp")
313                 ipv6:depends("proto", "pppoa")
314                 ipv6:depends("proto", "pppoe")
315                 ipv6:depends("proto", "pptp")
316                 ipv6:depends("proto", "3g")
317         end
318
319         connect = s:taboption("ppp", Value, "connect",
320          translate("Connect script"),
321          translate("Let pppd run this script after establishing the PPP link")
322         )
323         connect:depends("proto", "ppp")
324         connect:depends("proto", "pppoe")
325         connect:depends("proto", "pppoa")
326         connect:depends("proto", "pptp")
327         connect:depends("proto", "3g")
328
329         disconnect = s:taboption("ppp", Value, "disconnect",
330          translate("Disconnect script"),
331          translate("Let pppd run this script before tearing down the PPP link")
332         )
333         disconnect:depends("proto", "ppp")
334         disconnect:depends("proto", "pppoe")
335         disconnect:depends("proto", "pppoa")
336         disconnect:depends("proto", "pptp")
337         disconnect:depends("proto", "3g")
338
339         pppd_options = s:taboption("ppp", Value, "pppd_options",
340          translate("Additional pppd options"),
341          translate("Specify additional command line arguments for pppd here")
342         )
343         pppd_options:depends("proto", "ppp")
344         pppd_options:depends("proto", "pppoa")
345         pppd_options:depends("proto", "pppoe")
346         pppd_options:depends("proto", "pptp")
347         pppd_options:depends("proto", "3g")
348
349         maxwait = s:taboption("ppp", Value, "maxwait",
350          translate("Setup wait time"),
351          translate("Seconds to wait for the modem to become ready before attempting to connect")
352         )
353         maxwait:depends("proto", "3g")
354 end
355
356 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
357 s2.addremove = true
358
359 s2:depends("interface", arg[1])
360 s2.defaults.interface = arg[1]
361
362 s2:tab("general", translate("General Setup"))
363 s2.defaults.proto = "static"
364
365 s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address")).rmempty = true
366
367 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
368 nm.rmempty = true
369 nm:value("255.255.255.0")
370 nm:value("255.255.0.0")
371 nm:value("255.0.0.0")
372
373 s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway")).rmempty = true
374
375 if has_ipv6 then
376         s2:tab("ipv6", translate("IPv6 Setup"))
377         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"))
378         s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
379 end
380
381 s2:tab("advanced", translate("Advanced Settings"))
382 s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
383 s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
384
385
386 m2 = Map("dhcp", "", "")
387 function m2.on_parse()
388         local has_section = false
389
390         m2.uci:foreach("dhcp", "dhcp", function(s)
391                 if s.interface == arg[1] then
392                         has_section = true
393                         return false
394                 end
395         end)
396
397         if not has_section then
398                 m2.uci:section("dhcp", "dhcp", nil, { interface = arg[1], ignore = "1" })
399                 m2.uci:save("dhcp")
400         end
401 end
402
403 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
404 s.addremove = false
405 s.anonymous = true
406 s:tab("general",  translate("General Setup"))
407 s:tab("advanced", translate("Advanced Settings"))
408
409 function s.filter(self, section)
410         return m2.uci:get("dhcp", section, "interface") == arg[1]
411 end
412
413 local ignore = s:taboption("general", Flag, "ignore",
414         translate("Ignore interface"),
415         translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
416                 "this interface."))
417
418 ignore.rmempty = false
419
420 local start = s:taboption("general", Value, "start", translate("Start"),
421         translate("Lowest leased address as offset from the network address."))
422 start.rmempty = true
423 start.default = "100"
424
425 local limit = s:taboption("general", Value, "limit", translate("Limit"),
426         translate("Maximum number of leased addresses."))
427 limit.rmempty = true
428 limit.default = "150"
429
430 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
431         translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
432 ltime.rmempty = true
433 ltime.default = "12h"
434
435 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
436         translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
437         translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
438                 "clients having static leases will be served."))
439
440 dd.rmempty = false
441 function dd.cfgvalue(self, section)
442         return Flag.cfgvalue(self, section) or "1"
443 end
444
445 s:taboption("advanced", Flag, "force", translate("Force"),
446         translate("Force DHCP on this network even if another server is detected."))
447
448 -- XXX: is this actually useful?
449 --s:taboption("advanced", Value, "name", translate("Name"),
450 --      translate("Define a name for this network."))
451
452 s:taboption("advanced", Value, "netmask",
453         translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
454         translate("Override the netmask sent to clients. Normally it is calculated " ..
455                 "from the subnet that is served."))
456
457 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
458         translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
459                 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
460
461 for i, n in ipairs(s.children) do
462         if n ~= ignore then
463                 n:depends("ignore", "")
464         end
465 end
466
467 return m, m2