2 LuCI - Lua Configuration Interface
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 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 nw = require "luci.model.network"
18 local fw = require "luci.model.firewall"
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")
29 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>)."))
36 s = m:section(NamedSection, arg[1], "interface", translate("Common Configuration"))
39 s:tab("general", translate("General Setup"))
40 if has_ipv6 then s:tab("ipv6", translate("IPv6 Setup")) end
41 if has_pppd then s:tab("ppp", translate("PPP Settings")) end
42 s:tab("physical", translate("Physical Settings"))
43 s:tab("firewall", translate("Firewall Settings"))
46 back = s:taboption("general", DummyValue, "_overview", translate("Overview"))
48 back.titleref = luci.dispatcher.build_url("admin", "network", "network")
51 p = s:taboption("general", ListValue, "proto", translate("Protocol"))
52 p.override_scheme = true
54 p:value("static", translate("static"))
55 p:value("dhcp", "DHCP")
56 if has_pppd then p:value("ppp", "PPP") end
57 if has_pppoe then p:value("pppoe", "PPPoE") end
58 if has_pppoa then p:value("pppoa", "PPPoA") end
59 if has_3g then p:value("3g", "UMTS/3G") end
60 if has_pptp then p:value("pptp", "PPTP") end
61 p:value("none", translate("none"))
63 if not ( has_pppd and has_pppoe and has_pppoa and has_3g and has_pptp ) then
64 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 br = s:taboption("physical", Flag, "type", translate("Bridge interfaces"), translate("creates a bridge over specified interface(s)"))
71 stp = s:taboption("physical", Flag, "stp", translate("Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"),
72 translate("Enables the Spanning Tree Protocol on this bridge"))
73 stp:depends("type", "1")
76 ifname_single = s:taboption("physical", Value, "ifname_single", translate("Interface"))
77 ifname_single.template = "cbi/network_ifacelist"
78 ifname_single.widget = "radio"
79 ifname_single.nobridges = true
80 ifname_single.network = arg[1]
81 ifname_single.rmempty = true
82 ifname_single:depends("type", "")
84 function ifname_single.cfgvalue(self, s)
85 return self.map.uci:get("network", s, "ifname")
88 function ifname_single.write(self, s, val)
89 local n = nw:get_network(s)
92 for _, i in ipairs(n:get_interfaces()) do
100 ifname_multi = s:taboption("physical", MultiValue, "ifname_multi", translate("Interface"))
101 ifname_multi.template = "cbi/network_ifacelist"
102 ifname_multi.nobridges = true
103 ifname_multi.network = arg[1]
104 ifname_multi.widget = "checkbox"
105 ifname_multi:depends("type", "1")
106 ifname_multi.cfgvalue = ifname_single.cfgvalue
107 ifname_multi.write = ifname_single.write
110 for _, d in ipairs(nw:get_interfaces()) do
111 if not d:is_bridge() then
112 ifname_single:value(d:name())
113 ifname_multi:value(d:name())
118 local fwd_to, fwd_from
120 fwzone = s:taboption("firewall", Value, "_fwzone",
121 translate("Create / Assign firewall-zone"),
122 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."))
124 fwzone.template = "cbi/firewall_zonelist"
125 fwzone.network = arg[1]
126 fwzone.rmempty = false
128 function fwzone.cfgvalue(self, section)
130 local z = fw:get_zone_by_network(section)
131 return z and z:name()
134 function fwzone.write(self, section, value)
135 local zone = fw:get_zone(value)
137 if not zone and value == '-' then
138 value = m:formvalue(self:cbid(section) .. ".newzone")
139 if value and #value > 0 then
140 zone = fw:add_zone(value)
142 fw:del_network(section)
147 fw:del_network(section)
148 zone:add_network(section)
153 ipaddr = s:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
154 ipaddr.rmempty = true
155 ipaddr:depends("proto", "static")
157 nm = s:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
159 nm:depends("proto", "static")
160 nm:value("255.255.255.0")
161 nm:value("255.255.0.0")
162 nm:value("255.0.0.0")
164 gw = s:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway"))
165 gw:depends("proto", "static")
168 bcast = s:taboption("general", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
169 bcast:depends("proto", "static")
172 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"))
173 ip6addr:depends("proto", "static")
175 ip6gw = s:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
176 ip6gw:depends("proto", "static")
179 dns = s:taboption("general", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"),
180 translate("You can specify multiple DNS servers separated by space here. Servers entered here will override " ..
181 "automatically assigned ones."))
183 dns:depends("peerdns", "")
185 mtu = s:taboption("physical", Value, "mtu", "MTU")
188 mac = s:taboption("physical", Value, "macaddr", translate("<abbr title=\"Media Access Control\">MAC</abbr>-Address"))
191 srv = s:taboption("general", Value, "server", translate("<abbr title=\"Point-to-Point Tunneling Protocol\">PPTP</abbr>-Server"))
192 srv:depends("proto", "pptp")
196 service = s:taboption("general", ListValue, "service", translate("Service type"))
197 service:value("", translate("-- Please choose --"))
198 service:value("umts", "UMTS/GPRS")
199 service:value("cdma", "CDMA")
200 service:value("evdo", "EV-DO")
201 service:depends("proto", "3g")
202 service.rmempty = true
204 apn = s:taboption("general", Value, "apn", translate("Access point (APN)"))
205 apn:depends("proto", "3g")
207 pincode = s:taboption("general", Value, "pincode",
208 translate("PIN code"),
209 translate("Make sure that you provide the correct pin code here or you might lock your sim card!")
211 pincode:depends("proto", "3g")
214 if has_pppd or has_pppoe or has_pppoa or has_3g or has_pptp then
215 user = s:taboption("general", Value, "username", translate("Username"))
217 user:depends("proto", "pptp")
218 user:depends("proto", "pppoe")
219 user:depends("proto", "pppoa")
220 user:depends("proto", "ppp")
221 user:depends("proto", "3g")
223 pass = s:taboption("general", Value, "password", translate("Password"))
226 pass:depends("proto", "pptp")
227 pass:depends("proto", "pppoe")
228 pass:depends("proto", "pppoa")
229 pass:depends("proto", "ppp")
230 pass:depends("proto", "3g")
232 ka = s:taboption("ppp", Value, "keepalive",
233 translate("Keep-Alive"),
234 translate("Number of failed connection tests to initiate automatic reconnect")
236 ka:depends("proto", "pptp")
237 ka:depends("proto", "pppoe")
238 ka:depends("proto", "pppoa")
239 ka:depends("proto", "ppp")
240 ka:depends("proto", "3g")
242 demand = s:taboption("ppp", Value, "demand",
243 translate("Automatic Disconnect"),
244 translate("Time (in seconds) after which an unused connection will be closed")
246 demand:depends("proto", "pptp")
247 demand:depends("proto", "pppoe")
248 demand:depends("proto", "pppoa")
249 demand:depends("proto", "ppp")
250 demand:depends("proto", "3g")
254 encaps = s:taboption("ppp", ListValue, "encaps", translate("PPPoA Encapsulation"))
255 encaps:depends("proto", "pppoa")
256 encaps:value("", translate("-- Please choose --"))
257 encaps:value("vc", "VC")
258 encaps:value("llc", "LLC")
260 vpi = s:taboption("ppp", Value, "vpi", "VPI")
261 vpi:depends("proto", "pppoa")
263 vci = s:taboption("ppp", Value, "vci", "VCI")
264 vci:depends("proto", "pppoa")
267 if has_pptp or has_pppd or has_pppoe or has_pppoa or has_3g then
268 device = s:taboption("general", Value, "device",
269 translate("Modem device"),
270 translate("The device node of your modem, e.g. /dev/ttyUSB0")
272 device:depends("proto", "ppp")
273 device:depends("proto", "3g")
275 defaultroute = s:taboption("ppp", Flag, "defaultroute",
276 translate("Replace default route"),
277 translate("Let pppd replace the current default route to use the PPP interface after successful connect")
279 defaultroute:depends("proto", "ppp")
280 defaultroute:depends("proto", "pppoa")
281 defaultroute:depends("proto", "pppoe")
282 defaultroute:depends("proto", "pptp")
283 defaultroute:depends("proto", "3g")
284 defaultroute.rmempty = false
285 function defaultroute.cfgvalue(...)
286 return ( AbstractValue.cfgvalue(...) or '1' )
289 peerdns = s:taboption("ppp", Flag, "peerdns",
290 translate("Use peer DNS"),
291 translate("Configure the local DNS server to use the name servers adverticed by the PPP peer")
293 peerdns:depends("proto", "ppp")
294 peerdns:depends("proto", "pppoa")
295 peerdns:depends("proto", "pppoe")
296 peerdns:depends("proto", "pptp")
297 peerdns:depends("proto", "3g")
298 peerdns.rmempty = false
299 function peerdns.cfgvalue(...)
300 return ( AbstractValue.cfgvalue(...) or '1' )
304 ipv6 = s:taboption("ppp", Flag, "ipv6", translate("Enable IPv6 on PPP link") )
305 ipv6:depends("proto", "ppp")
306 ipv6:depends("proto", "pppoa")
307 ipv6:depends("proto", "pppoe")
308 ipv6:depends("proto", "pptp")
309 ipv6:depends("proto", "3g")
312 connect = s:taboption("ppp", Value, "connect",
313 translate("Connect script"),
314 translate("Let pppd run this script after establishing the PPP link")
316 connect:depends("proto", "ppp")
317 connect:depends("proto", "pppoe")
318 connect:depends("proto", "pppoa")
319 connect:depends("proto", "pptp")
320 connect:depends("proto", "3g")
322 disconnect = s:taboption("ppp", Value, "disconnect",
323 translate("Disconnect script"),
324 translate("Let pppd run this script before tearing down the PPP link")
326 disconnect:depends("proto", "ppp")
327 disconnect:depends("proto", "pppoe")
328 disconnect:depends("proto", "pppoa")
329 disconnect:depends("proto", "pptp")
330 disconnect:depends("proto", "3g")
332 pppd_options = s:taboption("ppp", Value, "pppd_options",
333 translate("Additional pppd options"),
334 translate("Specify additional command line arguments for pppd here")
336 pppd_options:depends("proto", "ppp")
337 pppd_options:depends("proto", "pppoa")
338 pppd_options:depends("proto", "pppoe")
339 pppd_options:depends("proto", "pptp")
340 pppd_options:depends("proto", "3g")
342 maxwait = s:taboption("ppp", Value, "maxwait",
343 translate("Setup wait time"),
344 translate("Seconds to wait for the modem to become ready before attempting to connect")
346 maxwait:depends("proto", "3g")
349 s2 = m:section(TypedSection, "alias", translate("IP-Aliases"))
352 s2:depends("interface", arg[1])
353 s2.defaults.interface = arg[1]
355 s2:tab("general", translate("General Setup"))
356 s2.defaults.proto = "static"
358 s2:taboption("general", Value, "ipaddr", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address")).rmempty = true
360 nm = s2:taboption("general", Value, "netmask", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"))
362 nm:value("255.255.255.0")
363 nm:value("255.255.0.0")
364 nm:value("255.0.0.0")
366 s2:taboption("general", Value, "gateway", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Gateway")).rmempty = true
369 s2:tab("ipv6", translate("IPv6 Setup"))
370 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"))
371 s2:taboption("ipv6", Value, "ip6gw", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Gateway"))
374 s2:tab("advanced", translate("Advanced Settings"))
375 s2:taboption("advanced", Value, "bcast", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Broadcast"))
376 s2:taboption("advanced", Value, "dns", translate("<abbr title=\"Domain Name System\">DNS</abbr>-Server"))
379 m2 = Map("dhcp", "", "")
380 function m2.on_parse()
381 local has_section = false
383 m2.uci:foreach("dhcp", "dhcp", function(s)
384 if s.interface == arg[1] then
390 if not has_section then
391 m2.uci:section("dhcp", "dhcp", nil, { interface = arg[1], ignore = "1" })
396 s = m2:section(TypedSection, "dhcp", translate("DHCP Server"))
398 s:tab("general", translate("General Setup"))
399 s:tab("advanced", translate("Advanced Settings"))
401 function s.filter(self, section)
402 return m2.uci:get("dhcp", section, "interface") == arg[1]
405 local ignore = s:taboption("general", Flag, "ignore",
406 translate("Ignore interface"),
407 translate("Disable <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr> for " ..
410 ignore.rmempty = false
412 local start = s:taboption("general", Value, "start", translate("Start"),
413 translate("Lowest leased address as offset from the network address."))
415 start.default = "100"
417 local limit = s:taboption("general", Value, "limit", translate("Limit"),
418 translate("Maximum number of leased addresses."))
420 limit.default = "150"
422 local ltime = s:taboption("general", Value, "leasetime", translate("Leasetime"),
423 translate("Expiry time of leased addresses, minimum is 2 Minutes (<code>2m</code>)."))
425 ltime.default = "12h"
427 local dd = s:taboption("advanced", Flag, "dynamicdhcp",
428 translate("Dynamic <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</abbr>"),
429 translate("Dynamically allocate DHCP addresses for clients. If disabled, only " ..
430 "clients having static leases will be served."))
433 function dd.cfgvalue(self, section)
434 return Flag.cfgvalue(self, section) or "1"
437 s:taboption("advanced", Flag, "force", translate("Force"),
438 translate("Force DHCP on this network even if another server is detected."))
440 -- XXX: is this actually useful?
441 --s:taboption("advanced", Value, "name", translate("Name"),
442 -- translate("Define a name for this network."))
444 s:taboption("advanced", Value, "netmask",
445 translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Netmask"),
446 translate("Override the netmask sent to clients. Normally it is calculated " ..
447 "from the subnet that is served."))
449 s:taboption("advanced", DynamicList, "dhcp_option", translate("DHCP-Options"),
450 translate("Define additional DHCP options, for example \"<code>6,192.168.2.1," ..
451 "192.168.2.2</code>\" which advertises different DNS servers to clients."))
453 for i, n in ipairs(s.children) do
455 n:depends("ignore", "")