network.lua 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. -- Copyright 2009-2015 Jo-Philipp Wich <jow@openwrt.org>
  2. -- Licensed to the public under the Apache License 2.0.
  3. local type, next, pairs, ipairs, loadfile, table
  4. = type, next, pairs, ipairs, loadfile, table
  5. local tonumber, tostring, math = tonumber, tostring, math
  6. local require = require
  7. local nxo = require "nixio"
  8. local nfs = require "nixio.fs"
  9. local ipc = require "luci.ip"
  10. local sys = require "luci.sys"
  11. local utl = require "luci.util"
  12. local dsp = require "luci.dispatcher"
  13. local uci = require "luci.model.uci"
  14. local lng = require "luci.i18n"
  15. module "luci.model.network"
  16. IFACE_PATTERNS_VIRTUAL = { }
  17. IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^lo$" }
  18. IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" }
  19. protocol = utl.class()
  20. local _protocols = { }
  21. local _interfaces, _bridge, _switch, _tunnel
  22. local _ubusnetcache, _ubusdevcache, _ubuswificache
  23. local _uci_real, _uci_state
  24. function _filter(c, s, o, r)
  25. local val = _uci_real:get(c, s, o)
  26. if val then
  27. local l = { }
  28. if type(val) == "string" then
  29. for val in val:gmatch("%S+") do
  30. if val ~= r then
  31. l[#l+1] = val
  32. end
  33. end
  34. if #l > 0 then
  35. _uci_real:set(c, s, o, table.concat(l, " "))
  36. else
  37. _uci_real:delete(c, s, o)
  38. end
  39. elseif type(val) == "table" then
  40. for _, val in ipairs(val) do
  41. if val ~= r then
  42. l[#l+1] = val
  43. end
  44. end
  45. if #l > 0 then
  46. _uci_real:set(c, s, o, l)
  47. else
  48. _uci_real:delete(c, s, o)
  49. end
  50. end
  51. end
  52. end
  53. function _append(c, s, o, a)
  54. local val = _uci_real:get(c, s, o) or ""
  55. if type(val) == "string" then
  56. local l = { }
  57. for val in val:gmatch("%S+") do
  58. if val ~= a then
  59. l[#l+1] = val
  60. end
  61. end
  62. l[#l+1] = a
  63. _uci_real:set(c, s, o, table.concat(l, " "))
  64. elseif type(val) == "table" then
  65. local l = { }
  66. for _, val in ipairs(val) do
  67. if val ~= a then
  68. l[#l+1] = val
  69. end
  70. end
  71. l[#l+1] = a
  72. _uci_real:set(c, s, o, l)
  73. end
  74. end
  75. function _stror(s1, s2)
  76. if not s1 or #s1 == 0 then
  77. return s2 and #s2 > 0 and s2
  78. else
  79. return s1
  80. end
  81. end
  82. function _get(c, s, o)
  83. return _uci_real:get(c, s, o)
  84. end
  85. function _set(c, s, o, v)
  86. if v ~= nil then
  87. if type(v) == "boolean" then v = v and "1" or "0" end
  88. return _uci_real:set(c, s, o, v)
  89. else
  90. return _uci_real:delete(c, s, o)
  91. end
  92. end
  93. function _wifi_iface(x)
  94. local _, p
  95. for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do
  96. if x:match(p) then
  97. return true
  98. end
  99. end
  100. return false
  101. end
  102. function _wifi_state(key, val, field)
  103. local radio, radiostate, ifc, ifcstate
  104. if not next(_ubuswificache) then
  105. _ubuswificache = utl.ubus("network.wireless", "status", {}) or {}
  106. -- workaround extended section format
  107. for radio, radiostate in pairs(_ubuswificache) do
  108. for ifc, ifcstate in pairs(radiostate.interfaces) do
  109. if ifcstate.section and ifcstate.section:sub(1, 1) == '@' then
  110. local s = _uci_real:get_all('wireless.%s' % ifcstate.section)
  111. if s then
  112. ifcstate.section = s['.name']
  113. end
  114. end
  115. end
  116. end
  117. end
  118. for radio, radiostate in pairs(_ubuswificache) do
  119. for ifc, ifcstate in pairs(radiostate.interfaces) do
  120. if ifcstate[key] == val then
  121. return ifcstate[field]
  122. end
  123. end
  124. end
  125. end
  126. function _wifi_lookup(ifn)
  127. -- got a radio#.network# pseudo iface, locate the corresponding section
  128. local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$")
  129. if radio and ifnidx then
  130. local sid = nil
  131. local num = 0
  132. ifnidx = tonumber(ifnidx)
  133. _uci_real:foreach("wireless", "wifi-iface",
  134. function(s)
  135. if s.device == radio then
  136. num = num + 1
  137. if num == ifnidx then
  138. sid = s['.name']
  139. return false
  140. end
  141. end
  142. end)
  143. return sid
  144. -- looks like wifi, try to locate the section via state vars
  145. elseif _wifi_iface(ifn) then
  146. local sid = _wifi_state("ifname", ifn, "section")
  147. if not sid then
  148. _uci_state:foreach("wireless", "wifi-iface",
  149. function(s)
  150. if s.ifname == ifn then
  151. sid = s['.name']
  152. return false
  153. end
  154. end)
  155. end
  156. return sid
  157. end
  158. end
  159. function _iface_virtual(x)
  160. local _, p
  161. for _, p in ipairs(IFACE_PATTERNS_VIRTUAL) do
  162. if x:match(p) then
  163. return true
  164. end
  165. end
  166. return false
  167. end
  168. function _iface_ignore(x)
  169. local _, p
  170. for _, p in ipairs(IFACE_PATTERNS_IGNORE) do
  171. if x:match(p) then
  172. return true
  173. end
  174. end
  175. return _iface_virtual(x)
  176. end
  177. function init(cursor)
  178. _uci_real = cursor or _uci_real or uci.cursor()
  179. _uci_state = _uci_real:substate()
  180. _interfaces = { }
  181. _bridge = { }
  182. _switch = { }
  183. _tunnel = { }
  184. _ubusnetcache = { }
  185. _ubusdevcache = { }
  186. _ubuswificache = { }
  187. -- read interface information
  188. local n, i
  189. for n, i in ipairs(nxo.getifaddrs()) do
  190. local name = i.name:match("[^:]+")
  191. local prnt = name:match("^([^%.]+)%.")
  192. if _iface_virtual(name) then
  193. _tunnel[name] = true
  194. end
  195. if _tunnel[name] or not _iface_ignore(name) then
  196. _interfaces[name] = _interfaces[name] or {
  197. idx = i.ifindex or n,
  198. name = name,
  199. rawname = i.name,
  200. flags = { },
  201. ipaddrs = { },
  202. ip6addrs = { }
  203. }
  204. if prnt then
  205. _switch[name] = true
  206. _switch[prnt] = true
  207. end
  208. if i.family == "packet" then
  209. _interfaces[name].flags = i.flags
  210. _interfaces[name].stats = i.data
  211. _interfaces[name].macaddr = i.addr
  212. elseif i.family == "inet" then
  213. _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
  214. elseif i.family == "inet6" then
  215. _interfaces[name].ip6addrs[#_interfaces[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask)
  216. end
  217. end
  218. end
  219. -- read bridge informaton
  220. local b, l
  221. for l in utl.execi("brctl show") do
  222. if not l:match("STP") then
  223. local r = utl.split(l, "%s+", nil, true)
  224. if #r == 4 then
  225. b = {
  226. name = r[1],
  227. id = r[2],
  228. stp = r[3] == "yes",
  229. ifnames = { _interfaces[r[4]] }
  230. }
  231. if b.ifnames[1] then
  232. b.ifnames[1].bridge = b
  233. end
  234. _bridge[r[1]] = b
  235. elseif b then
  236. b.ifnames[#b.ifnames+1] = _interfaces[r[2]]
  237. b.ifnames[#b.ifnames].bridge = b
  238. end
  239. end
  240. end
  241. return _M
  242. end
  243. function save(self, ...)
  244. _uci_real:save(...)
  245. _uci_real:load(...)
  246. end
  247. function commit(self, ...)
  248. _uci_real:commit(...)
  249. _uci_real:load(...)
  250. end
  251. function ifnameof(self, x)
  252. if utl.instanceof(x, interface) then
  253. return x:name()
  254. elseif utl.instanceof(x, protocol) then
  255. return x:ifname()
  256. elseif type(x) == "string" then
  257. return x:match("^[^:]+")
  258. end
  259. end
  260. function get_protocol(self, protoname, netname)
  261. local v = _protocols[protoname]
  262. if v then
  263. return v(netname or "__dummy__")
  264. end
  265. end
  266. function get_protocols(self)
  267. local p = { }
  268. local _, v
  269. for _, v in ipairs(_protocols) do
  270. p[#p+1] = v("__dummy__")
  271. end
  272. return p
  273. end
  274. function register_protocol(self, protoname)
  275. local proto = utl.class(protocol)
  276. function proto.__init__(self, name)
  277. self.sid = name
  278. end
  279. function proto.proto(self)
  280. return protoname
  281. end
  282. _protocols[#_protocols+1] = proto
  283. _protocols[protoname] = proto
  284. return proto
  285. end
  286. function register_pattern_virtual(self, pat)
  287. IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat
  288. end
  289. function has_ipv6(self)
  290. return nfs.access("/proc/net/ipv6_route")
  291. end
  292. function add_network(self, n, options)
  293. local oldnet = self:get_network(n)
  294. if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then
  295. if _uci_real:section("network", "interface", n, options) then
  296. return network(n)
  297. end
  298. elseif oldnet and oldnet:is_empty() then
  299. if options then
  300. local k, v
  301. for k, v in pairs(options) do
  302. oldnet:set(k, v)
  303. end
  304. end
  305. return oldnet
  306. end
  307. end
  308. function get_network(self, n)
  309. if n and _uci_real:get("network", n) == "interface" then
  310. return network(n)
  311. end
  312. end
  313. function get_networks(self)
  314. local nets = { }
  315. local nls = { }
  316. _uci_real:foreach("network", "interface",
  317. function(s)
  318. nls[s['.name']] = network(s['.name'])
  319. end)
  320. local n
  321. for n in utl.kspairs(nls) do
  322. nets[#nets+1] = nls[n]
  323. end
  324. return nets
  325. end
  326. function del_network(self, n)
  327. local r = _uci_real:delete("network", n)
  328. if r then
  329. _uci_real:delete_all("network", "alias",
  330. function(s) return (s.interface == n) end)
  331. _uci_real:delete_all("network", "route",
  332. function(s) return (s.interface == n) end)
  333. _uci_real:delete_all("network", "route6",
  334. function(s) return (s.interface == n) end)
  335. _uci_real:foreach("wireless", "wifi-iface",
  336. function(s)
  337. local net
  338. local rest = { }
  339. for net in utl.imatch(s.network) do
  340. if net ~= n then
  341. rest[#rest+1] = net
  342. end
  343. end
  344. if #rest > 0 then
  345. _uci_real:set("wireless", s['.name'], "network",
  346. table.concat(rest, " "))
  347. else
  348. _uci_real:delete("wireless", s['.name'], "network")
  349. end
  350. end)
  351. end
  352. return r
  353. end
  354. function rename_network(self, old, new)
  355. local r
  356. if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then
  357. r = _uci_real:section("network", "interface", new, _uci_real:get_all("network", old))
  358. if r then
  359. _uci_real:foreach("network", "alias",
  360. function(s)
  361. if s.interface == old then
  362. _uci_real:set("network", s['.name'], "interface", new)
  363. end
  364. end)
  365. _uci_real:foreach("network", "route",
  366. function(s)
  367. if s.interface == old then
  368. _uci_real:set("network", s['.name'], "interface", new)
  369. end
  370. end)
  371. _uci_real:foreach("network", "route6",
  372. function(s)
  373. if s.interface == old then
  374. _uci_real:set("network", s['.name'], "interface", new)
  375. end
  376. end)
  377. _uci_real:foreach("wireless", "wifi-iface",
  378. function(s)
  379. local net
  380. local list = { }
  381. for net in utl.imatch(s.network) do
  382. if net == old then
  383. list[#list+1] = new
  384. else
  385. list[#list+1] = net
  386. end
  387. end
  388. if #list > 0 then
  389. _uci_real:set("wireless", s['.name'], "network",
  390. table.concat(list, " "))
  391. end
  392. end)
  393. _uci_real:delete("network", old)
  394. end
  395. end
  396. return r or false
  397. end
  398. function get_interface(self, i)
  399. if _interfaces[i] or _wifi_iface(i) then
  400. return interface(i)
  401. else
  402. local ifc
  403. local num = { }
  404. _uci_real:foreach("wireless", "wifi-iface",
  405. function(s)
  406. if s.device then
  407. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  408. if s['.name'] == i then
  409. ifc = interface(
  410. "%s.network%d" %{s.device, num[s.device] })
  411. return false
  412. end
  413. end
  414. end)
  415. return ifc
  416. end
  417. end
  418. function get_interfaces(self)
  419. local iface
  420. local ifaces = { }
  421. local seen = { }
  422. local nfs = { }
  423. local baseof = { }
  424. -- find normal interfaces
  425. _uci_real:foreach("network", "interface",
  426. function(s)
  427. for iface in utl.imatch(s.ifname) do
  428. if not _iface_ignore(iface) and not _wifi_iface(iface) then
  429. seen[iface] = true
  430. nfs[iface] = interface(iface)
  431. end
  432. end
  433. end)
  434. for iface in utl.kspairs(_interfaces) do
  435. if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then
  436. nfs[iface] = interface(iface)
  437. end
  438. end
  439. -- find vlan interfaces
  440. _uci_real:foreach("network", "switch_vlan",
  441. function(s)
  442. if not s.device then
  443. return
  444. end
  445. local base = baseof[s.device]
  446. if not base then
  447. if not s.device:match("^eth%d") then
  448. local l
  449. for l in utl.execi("swconfig dev %q help 2>/dev/null" % s.device) do
  450. if not base then
  451. base = l:match("^%w+: (%w+)")
  452. end
  453. end
  454. if not base or not base:match("^eth%d") then
  455. base = "eth0"
  456. end
  457. else
  458. base = s.device
  459. end
  460. baseof[s.device] = base
  461. end
  462. local vid = tonumber(s.vid or s.vlan)
  463. if vid ~= nil and vid >= 0 and vid <= 4095 then
  464. local iface = "%s.%d" %{ base, vid }
  465. if not seen[iface] then
  466. seen[iface] = true
  467. nfs[iface] = interface(iface)
  468. end
  469. end
  470. end)
  471. for iface in utl.kspairs(nfs) do
  472. ifaces[#ifaces+1] = nfs[iface]
  473. end
  474. -- find wifi interfaces
  475. local num = { }
  476. local wfs = { }
  477. _uci_real:foreach("wireless", "wifi-iface",
  478. function(s)
  479. if s.device then
  480. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  481. local i = "%s.network%d" %{ s.device, num[s.device] }
  482. wfs[i] = interface(i)
  483. end
  484. end)
  485. for iface in utl.kspairs(wfs) do
  486. ifaces[#ifaces+1] = wfs[iface]
  487. end
  488. return ifaces
  489. end
  490. function ignore_interface(self, x)
  491. return _iface_ignore(x)
  492. end
  493. function get_wifidev(self, dev)
  494. if _uci_real:get("wireless", dev) == "wifi-device" then
  495. return wifidev(dev)
  496. end
  497. end
  498. function get_wifidevs(self)
  499. local devs = { }
  500. local wfd = { }
  501. _uci_real:foreach("wireless", "wifi-device",
  502. function(s) wfd[#wfd+1] = s['.name'] end)
  503. local dev
  504. for _, dev in utl.vspairs(wfd) do
  505. devs[#devs+1] = wifidev(dev)
  506. end
  507. return devs
  508. end
  509. function get_wifinet(self, net)
  510. local wnet = _wifi_lookup(net)
  511. if wnet then
  512. return wifinet(wnet)
  513. end
  514. end
  515. function add_wifinet(self, net, options)
  516. if type(options) == "table" and options.device and
  517. _uci_real:get("wireless", options.device) == "wifi-device"
  518. then
  519. local wnet = _uci_real:section("wireless", "wifi-iface", nil, options)
  520. return wifinet(wnet)
  521. end
  522. end
  523. function del_wifinet(self, net)
  524. local wnet = _wifi_lookup(net)
  525. if wnet then
  526. _uci_real:delete("wireless", wnet)
  527. return true
  528. end
  529. return false
  530. end
  531. function get_status_by_route(self, addr, mask)
  532. local _, object
  533. for _, object in ipairs(utl.ubus()) do
  534. local net = object:match("^network%.interface%.(.+)")
  535. if net then
  536. local s = utl.ubus(object, "status", {})
  537. if s and s.route then
  538. local rt
  539. for _, rt in ipairs(s.route) do
  540. if not rt.table and rt.target == addr and rt.mask == mask then
  541. return net, s
  542. end
  543. end
  544. end
  545. end
  546. end
  547. end
  548. function get_status_by_address(self, addr)
  549. local _, object
  550. for _, object in ipairs(utl.ubus()) do
  551. local net = object:match("^network%.interface%.(.+)")
  552. if net then
  553. local s = utl.ubus(object, "status", {})
  554. if s and s['ipv4-address'] then
  555. local a
  556. for _, a in ipairs(s['ipv4-address']) do
  557. if a.address == addr then
  558. return net, s
  559. end
  560. end
  561. end
  562. if s and s['ipv6-address'] then
  563. local a
  564. for _, a in ipairs(s['ipv6-address']) do
  565. if a.address == addr then
  566. return net, s
  567. end
  568. end
  569. end
  570. end
  571. end
  572. end
  573. function get_wannet(self)
  574. local net = self:get_status_by_route("0.0.0.0", 0)
  575. return net and network(net)
  576. end
  577. function get_wandev(self)
  578. local _, stat = self:get_status_by_route("0.0.0.0", 0)
  579. return stat and interface(stat.l3_device or stat.device)
  580. end
  581. function get_wan6net(self)
  582. local net = self:get_status_by_route("::", 0)
  583. return net and network(net)
  584. end
  585. function get_wan6dev(self)
  586. local _, stat = self:get_status_by_route("::", 0)
  587. return stat and interface(stat.l3_device or stat.device)
  588. end
  589. function network(name, proto)
  590. if name then
  591. local p = proto or _uci_real:get("network", name, "proto")
  592. local c = p and _protocols[p] or protocol
  593. return c(name)
  594. end
  595. end
  596. function protocol.__init__(self, name)
  597. self.sid = name
  598. end
  599. function protocol._get(self, opt)
  600. local v = _uci_real:get("network", self.sid, opt)
  601. if type(v) == "table" then
  602. return table.concat(v, " ")
  603. end
  604. return v or ""
  605. end
  606. function protocol._ubus(self, field)
  607. if not _ubusnetcache[self.sid] then
  608. _ubusnetcache[self.sid] = utl.ubus("network.interface.%s" % self.sid,
  609. "status", { })
  610. end
  611. if _ubusnetcache[self.sid] and field then
  612. return _ubusnetcache[self.sid][field]
  613. end
  614. return _ubusnetcache[self.sid]
  615. end
  616. function protocol.get(self, opt)
  617. return _get("network", self.sid, opt)
  618. end
  619. function protocol.set(self, opt, val)
  620. return _set("network", self.sid, opt, val)
  621. end
  622. function protocol.ifname(self)
  623. local ifname
  624. if self:is_floating() then
  625. ifname = self:_ubus("l3_device")
  626. else
  627. ifname = self:_ubus("device")
  628. end
  629. if not ifname then
  630. local num = { }
  631. _uci_real:foreach("wireless", "wifi-iface",
  632. function(s)
  633. if s.device then
  634. num[s.device] = num[s.device]
  635. and num[s.device] + 1 or 1
  636. local net
  637. for net in utl.imatch(s.network) do
  638. if net == self.sid then
  639. ifname = "%s.network%d" %{ s.device, num[s.device] }
  640. return false
  641. end
  642. end
  643. end
  644. end)
  645. end
  646. return ifname
  647. end
  648. function protocol.proto(self)
  649. return "none"
  650. end
  651. function protocol.get_i18n(self)
  652. local p = self:proto()
  653. if p == "none" then
  654. return lng.translate("Unmanaged")
  655. elseif p == "static" then
  656. return lng.translate("Static address")
  657. elseif p == "dhcp" then
  658. return lng.translate("DHCP client")
  659. else
  660. return lng.translate("Unknown")
  661. end
  662. end
  663. function protocol.type(self)
  664. return self:_get("type")
  665. end
  666. function protocol.name(self)
  667. return self.sid
  668. end
  669. function protocol.uptime(self)
  670. return self:_ubus("uptime") or 0
  671. end
  672. function protocol.expires(self)
  673. local a = tonumber(_uci_state:get("network", self.sid, "lease_acquired"))
  674. local l = tonumber(_uci_state:get("network", self.sid, "lease_lifetime"))
  675. if a and l then
  676. l = l - (nxo.sysinfo().uptime - a)
  677. return l > 0 and l or 0
  678. end
  679. return -1
  680. end
  681. function protocol.metric(self)
  682. return tonumber(_uci_state:get("network", self.sid, "metric")) or 0
  683. end
  684. function protocol.ipaddr(self)
  685. local addrs = self:_ubus("ipv4-address")
  686. return addrs and #addrs > 0 and addrs[1].address
  687. end
  688. function protocol.netmask(self)
  689. local addrs = self:_ubus("ipv4-address")
  690. return addrs and #addrs > 0 and
  691. ipc.IPv4("0.0.0.0/%d" % addrs[1].mask):mask():string()
  692. end
  693. function protocol.gwaddr(self)
  694. local _, route
  695. for _, route in ipairs(self:_ubus("route") or { }) do
  696. if route.target == "0.0.0.0" and route.mask == 0 then
  697. return route.nexthop
  698. end
  699. end
  700. end
  701. function protocol.dnsaddrs(self)
  702. local dns = { }
  703. local _, addr
  704. for _, addr in ipairs(self:_ubus("dns-server") or { }) do
  705. if not addr:match(":") then
  706. dns[#dns+1] = addr
  707. end
  708. end
  709. return dns
  710. end
  711. function protocol.ip6addr(self)
  712. local addrs = self:_ubus("ipv6-address")
  713. if addrs and #addrs > 0 then
  714. return "%s/%d" %{ addrs[1].address, addrs[1].mask }
  715. else
  716. addrs = self:_ubus("ipv6-prefix-assignment")
  717. if addrs and #addrs > 0 then
  718. return "%s/%d" %{ addrs[1].address, addrs[1].mask }
  719. end
  720. end
  721. end
  722. function protocol.gw6addr(self)
  723. local _, route
  724. for _, route in ipairs(self:_ubus("route") or { }) do
  725. if route.target == "::" and route.mask == 0 then
  726. return ipc.IPv6(route.nexthop):string()
  727. end
  728. end
  729. end
  730. function protocol.dns6addrs(self)
  731. local dns = { }
  732. local _, addr
  733. for _, addr in ipairs(self:_ubus("dns-server") or { }) do
  734. if addr:match(":") then
  735. dns[#dns+1] = addr
  736. end
  737. end
  738. return dns
  739. end
  740. function protocol.is_bridge(self)
  741. return (not self:is_virtual() and self:type() == "bridge")
  742. end
  743. function protocol.opkg_package(self)
  744. return nil
  745. end
  746. function protocol.is_installed(self)
  747. return true
  748. end
  749. function protocol.is_virtual(self)
  750. return false
  751. end
  752. function protocol.is_floating(self)
  753. return false
  754. end
  755. function protocol.is_empty(self)
  756. if self:is_floating() then
  757. return false
  758. else
  759. local rv = true
  760. if (self:_get("ifname") or ""):match("%S+") then
  761. rv = false
  762. end
  763. _uci_real:foreach("wireless", "wifi-iface",
  764. function(s)
  765. local n
  766. for n in utl.imatch(s.network) do
  767. if n == self.sid then
  768. rv = false
  769. return false
  770. end
  771. end
  772. end)
  773. return rv
  774. end
  775. end
  776. function protocol.add_interface(self, ifname)
  777. ifname = _M:ifnameof(ifname)
  778. if ifname and not self:is_floating() then
  779. -- if its a wifi interface, change its network option
  780. local wif = _wifi_lookup(ifname)
  781. if wif then
  782. _append("wireless", wif, "network", self.sid)
  783. -- add iface to our iface list
  784. else
  785. _append("network", self.sid, "ifname", ifname)
  786. end
  787. end
  788. end
  789. function protocol.del_interface(self, ifname)
  790. ifname = _M:ifnameof(ifname)
  791. if ifname and not self:is_floating() then
  792. -- if its a wireless interface, clear its network option
  793. local wif = _wifi_lookup(ifname)
  794. if wif then _filter("wireless", wif, "network", self.sid) end
  795. -- remove the interface
  796. _filter("network", self.sid, "ifname", ifname)
  797. end
  798. end
  799. function protocol.get_interface(self)
  800. if self:is_virtual() then
  801. _tunnel[self:proto() .. "-" .. self.sid] = true
  802. return interface(self:proto() .. "-" .. self.sid, self)
  803. elseif self:is_bridge() then
  804. _bridge["br-" .. self.sid] = true
  805. return interface("br-" .. self.sid, self)
  806. else
  807. local ifn = nil
  808. local num = { }
  809. for ifn in utl.imatch(_uci_real:get("network", self.sid, "ifname")) do
  810. ifn = ifn:match("^[^:/]+")
  811. return ifn and interface(ifn, self)
  812. end
  813. ifn = nil
  814. _uci_real:foreach("wireless", "wifi-iface",
  815. function(s)
  816. if s.device then
  817. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  818. local net
  819. for net in utl.imatch(s.network) do
  820. if net == self.sid then
  821. ifn = "%s.network%d" %{ s.device, num[s.device] }
  822. return false
  823. end
  824. end
  825. end
  826. end)
  827. return ifn and interface(ifn, self)
  828. end
  829. end
  830. function protocol.get_interfaces(self)
  831. if self:is_bridge() or (self:is_virtual() and not self:is_floating()) then
  832. local ifaces = { }
  833. local ifn
  834. local nfs = { }
  835. for ifn in utl.imatch(self:get("ifname")) do
  836. ifn = ifn:match("^[^:/]+")
  837. nfs[ifn] = interface(ifn, self)
  838. end
  839. for ifn in utl.kspairs(nfs) do
  840. ifaces[#ifaces+1] = nfs[ifn]
  841. end
  842. local num = { }
  843. local wfs = { }
  844. _uci_real:foreach("wireless", "wifi-iface",
  845. function(s)
  846. if s.device then
  847. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  848. local net
  849. for net in utl.imatch(s.network) do
  850. if net == self.sid then
  851. ifn = "%s.network%d" %{ s.device, num[s.device] }
  852. wfs[ifn] = interface(ifn, self)
  853. end
  854. end
  855. end
  856. end)
  857. for ifn in utl.kspairs(wfs) do
  858. ifaces[#ifaces+1] = wfs[ifn]
  859. end
  860. return ifaces
  861. end
  862. end
  863. function protocol.contains_interface(self, ifname)
  864. ifname = _M:ifnameof(ifname)
  865. if not ifname then
  866. return false
  867. elseif self:is_virtual() and self:proto() .. "-" .. self.sid == ifname then
  868. return true
  869. elseif self:is_bridge() and "br-" .. self.sid == ifname then
  870. return true
  871. else
  872. local ifn
  873. for ifn in utl.imatch(self:get("ifname")) do
  874. ifn = ifn:match("[^:]+")
  875. if ifn == ifname then
  876. return true
  877. end
  878. end
  879. local wif = _wifi_lookup(ifname)
  880. if wif then
  881. local n
  882. for n in utl.imatch(_uci_real:get("wireless", wif, "network")) do
  883. if n == self.sid then
  884. return true
  885. end
  886. end
  887. end
  888. end
  889. return false
  890. end
  891. function protocol.adminlink(self)
  892. return dsp.build_url("admin", "network", "network", self.sid)
  893. end
  894. interface = utl.class()
  895. function interface.__init__(self, ifname, network)
  896. local wif = _wifi_lookup(ifname)
  897. if wif then
  898. self.wif = wifinet(wif)
  899. self.ifname = _wifi_state("section", wif, "ifname")
  900. end
  901. self.ifname = self.ifname or ifname
  902. self.dev = _interfaces[self.ifname]
  903. self.network = network
  904. end
  905. function interface._ubus(self, field)
  906. if not _ubusdevcache[self.ifname] then
  907. _ubusdevcache[self.ifname] = utl.ubus("network.device", "status",
  908. { name = self.ifname })
  909. end
  910. if _ubusdevcache[self.ifname] and field then
  911. return _ubusdevcache[self.ifname][field]
  912. end
  913. return _ubusdevcache[self.ifname]
  914. end
  915. function interface.name(self)
  916. return self.wif and self.wif:ifname() or self.ifname
  917. end
  918. function interface.mac(self)
  919. return (self:_ubus("macaddr") or "00:00:00:00:00:00"):upper()
  920. end
  921. function interface.ipaddrs(self)
  922. return self.dev and self.dev.ipaddrs or { }
  923. end
  924. function interface.ip6addrs(self)
  925. return self.dev and self.dev.ip6addrs or { }
  926. end
  927. function interface.type(self)
  928. if self.wif or _wifi_iface(self.ifname) then
  929. return "wifi"
  930. elseif _bridge[self.ifname] then
  931. return "bridge"
  932. elseif _tunnel[self.ifname] then
  933. return "tunnel"
  934. elseif self.ifname:match("%.") then
  935. return "vlan"
  936. elseif _switch[self.ifname] then
  937. return "switch"
  938. else
  939. return "ethernet"
  940. end
  941. end
  942. function interface.shortname(self)
  943. if self.wif then
  944. return "%s %q" %{
  945. self.wif:active_mode(),
  946. self.wif:active_ssid() or self.wif:active_bssid()
  947. }
  948. else
  949. return self.ifname
  950. end
  951. end
  952. function interface.get_i18n(self)
  953. if self.wif then
  954. return "%s: %s %q" %{
  955. lng.translate("Wireless Network"),
  956. self.wif:active_mode(),
  957. self.wif:active_ssid() or self.wif:active_bssid()
  958. }
  959. else
  960. return "%s: %q" %{ self:get_type_i18n(), self:name() }
  961. end
  962. end
  963. function interface.get_type_i18n(self)
  964. local x = self:type()
  965. if x == "wifi" then
  966. return lng.translate("Wireless Adapter")
  967. elseif x == "bridge" then
  968. return lng.translate("Bridge")
  969. elseif x == "switch" then
  970. return lng.translate("Ethernet Switch")
  971. elseif x == "vlan" then
  972. return lng.translate("VLAN Interface")
  973. elseif x == "tunnel" then
  974. return lng.translate("Tunnel Interface")
  975. else
  976. return lng.translate("Ethernet Adapter")
  977. end
  978. end
  979. function interface.adminlink(self)
  980. if self.wif then
  981. return self.wif:adminlink()
  982. end
  983. end
  984. function interface.ports(self)
  985. local members = self:_ubus("bridge-members")
  986. if members then
  987. local _, iface
  988. local ifaces = { }
  989. for _, iface in ipairs(members) do
  990. ifaces[#ifaces+1] = interface(iface)
  991. end
  992. end
  993. end
  994. function interface.bridge_id(self)
  995. if self.br then
  996. return self.br.id
  997. else
  998. return nil
  999. end
  1000. end
  1001. function interface.bridge_stp(self)
  1002. if self.br then
  1003. return self.br.stp
  1004. else
  1005. return false
  1006. end
  1007. end
  1008. function interface.is_up(self)
  1009. return self:_ubus("up") or false
  1010. end
  1011. function interface.is_bridge(self)
  1012. return (self:type() == "bridge")
  1013. end
  1014. function interface.is_bridgeport(self)
  1015. return self.dev and self.dev.bridge and true or false
  1016. end
  1017. function interface.tx_bytes(self)
  1018. local stat = self:_ubus("statistics")
  1019. return stat and stat.tx_bytes or 0
  1020. end
  1021. function interface.rx_bytes(self)
  1022. local stat = self:_ubus("statistics")
  1023. return stat and stat.rx_bytes or 0
  1024. end
  1025. function interface.tx_packets(self)
  1026. local stat = self:_ubus("statistics")
  1027. return stat and stat.tx_packets or 0
  1028. end
  1029. function interface.rx_packets(self)
  1030. local stat = self:_ubus("statistics")
  1031. return stat and stat.rx_packets or 0
  1032. end
  1033. function interface.get_network(self)
  1034. return self:get_networks()[1]
  1035. end
  1036. function interface.get_networks(self)
  1037. if not self.networks then
  1038. local nets = { }
  1039. local _, net
  1040. for _, net in ipairs(_M:get_networks()) do
  1041. if net:contains_interface(self.ifname) or
  1042. net:ifname() == self.ifname
  1043. then
  1044. nets[#nets+1] = net
  1045. end
  1046. end
  1047. table.sort(nets, function(a, b) return a.sid < b.sid end)
  1048. self.networks = nets
  1049. return nets
  1050. else
  1051. return self.networks
  1052. end
  1053. end
  1054. function interface.get_wifinet(self)
  1055. return self.wif
  1056. end
  1057. wifidev = utl.class()
  1058. function wifidev.__init__(self, dev)
  1059. self.sid = dev
  1060. self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
  1061. end
  1062. function wifidev.get(self, opt)
  1063. return _get("wireless", self.sid, opt)
  1064. end
  1065. function wifidev.set(self, opt, val)
  1066. return _set("wireless", self.sid, opt, val)
  1067. end
  1068. function wifidev.name(self)
  1069. return self.sid
  1070. end
  1071. function wifidev.hwmodes(self)
  1072. local l = self.iwinfo.hwmodelist
  1073. if l and next(l) then
  1074. return l
  1075. else
  1076. return { b = true, g = true }
  1077. end
  1078. end
  1079. function wifidev.get_i18n(self)
  1080. local t = "Generic"
  1081. if self.iwinfo.type == "wl" then
  1082. t = "Broadcom"
  1083. elseif self.iwinfo.type == "madwifi" then
  1084. t = "Atheros"
  1085. end
  1086. local m = ""
  1087. local l = self:hwmodes()
  1088. if l.a then m = m .. "a" end
  1089. if l.b then m = m .. "b" end
  1090. if l.g then m = m .. "g" end
  1091. if l.n then m = m .. "n" end
  1092. if l.ac then m = "ac" end
  1093. return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() }
  1094. end
  1095. function wifidev.is_up(self)
  1096. if _ubuswificache[self.sid] then
  1097. return (_ubuswificache[self.sid].up == true)
  1098. end
  1099. local up = false
  1100. _uci_state:foreach("wireless", "wifi-iface",
  1101. function(s)
  1102. if s.device == self.sid then
  1103. if s.up == "1" then
  1104. up = true
  1105. return false
  1106. end
  1107. end
  1108. end)
  1109. return up
  1110. end
  1111. function wifidev.get_wifinet(self, net)
  1112. if _uci_real:get("wireless", net) == "wifi-iface" then
  1113. return wifinet(net)
  1114. else
  1115. local wnet = _wifi_lookup(net)
  1116. if wnet then
  1117. return wifinet(wnet)
  1118. end
  1119. end
  1120. end
  1121. function wifidev.get_wifinets(self)
  1122. local nets = { }
  1123. _uci_real:foreach("wireless", "wifi-iface",
  1124. function(s)
  1125. if s.device == self.sid then
  1126. nets[#nets+1] = wifinet(s['.name'])
  1127. end
  1128. end)
  1129. return nets
  1130. end
  1131. function wifidev.add_wifinet(self, options)
  1132. options = options or { }
  1133. options.device = self.sid
  1134. local wnet = _uci_real:section("wireless", "wifi-iface", nil, options)
  1135. if wnet then
  1136. return wifinet(wnet, options)
  1137. end
  1138. end
  1139. function wifidev.del_wifinet(self, net)
  1140. if utl.instanceof(net, wifinet) then
  1141. net = net.sid
  1142. elseif _uci_real:get("wireless", net) ~= "wifi-iface" then
  1143. net = _wifi_lookup(net)
  1144. end
  1145. if net and _uci_real:get("wireless", net, "device") == self.sid then
  1146. _uci_real:delete("wireless", net)
  1147. return true
  1148. end
  1149. return false
  1150. end
  1151. wifinet = utl.class()
  1152. function wifinet.__init__(self, net, data)
  1153. self.sid = net
  1154. local num = { }
  1155. local netid
  1156. _uci_real:foreach("wireless", "wifi-iface",
  1157. function(s)
  1158. if s.device then
  1159. num[s.device] = num[s.device] and num[s.device] + 1 or 1
  1160. if s['.name'] == self.sid then
  1161. netid = "%s.network%d" %{ s.device, num[s.device] }
  1162. return false
  1163. end
  1164. end
  1165. end)
  1166. local dev = _wifi_state("section", self.sid, "ifname") or netid
  1167. self.netid = netid
  1168. self.wdev = dev
  1169. self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
  1170. self.iwdata = data or _uci_state:get_all("wireless", self.sid) or
  1171. _uci_real:get_all("wireless", self.sid) or { }
  1172. end
  1173. function wifinet.get(self, opt)
  1174. return _get("wireless", self.sid, opt)
  1175. end
  1176. function wifinet.set(self, opt, val)
  1177. return _set("wireless", self.sid, opt, val)
  1178. end
  1179. function wifinet.mode(self)
  1180. return _uci_state:get("wireless", self.sid, "mode") or "ap"
  1181. end
  1182. function wifinet.ssid(self)
  1183. return _uci_state:get("wireless", self.sid, "ssid")
  1184. end
  1185. function wifinet.bssid(self)
  1186. return _uci_state:get("wireless", self.sid, "bssid")
  1187. end
  1188. function wifinet.network(self)
  1189. return _uci_state:get("wifinet", self.sid, "network")
  1190. end
  1191. function wifinet.id(self)
  1192. return self.netid
  1193. end
  1194. function wifinet.name(self)
  1195. return self.sid
  1196. end
  1197. function wifinet.ifname(self)
  1198. local ifname = self.iwinfo.ifname
  1199. if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
  1200. ifname = self.wdev
  1201. end
  1202. return ifname
  1203. end
  1204. function wifinet.get_device(self)
  1205. if self.iwdata.device then
  1206. return wifidev(self.iwdata.device)
  1207. end
  1208. end
  1209. function wifinet.is_up(self)
  1210. local ifc = self:get_interface()
  1211. return (ifc and ifc:is_up() or false)
  1212. end
  1213. function wifinet.active_mode(self)
  1214. local m = _stror(self.iwdata.mode, self.iwinfo.mode) or "ap"
  1215. if m == "ap" then m = "Master"
  1216. elseif m == "sta" then m = "Client"
  1217. elseif m == "adhoc" then m = "Ad-Hoc"
  1218. elseif m == "mesh" then m = "Mesh"
  1219. elseif m == "monitor" then m = "Monitor"
  1220. end
  1221. return m
  1222. end
  1223. function wifinet.active_mode_i18n(self)
  1224. return lng.translate(self:active_mode())
  1225. end
  1226. function wifinet.active_ssid(self)
  1227. return _stror(self.iwdata.ssid, self.iwinfo.ssid)
  1228. end
  1229. function wifinet.active_bssid(self)
  1230. return _stror(self.iwdata.bssid, self.iwinfo.bssid) or "00:00:00:00:00:00"
  1231. end
  1232. function wifinet.active_encryption(self)
  1233. local enc = self.iwinfo and self.iwinfo.encryption
  1234. return enc and enc.description or "-"
  1235. end
  1236. function wifinet.assoclist(self)
  1237. return self.iwinfo.assoclist or { }
  1238. end
  1239. function wifinet.frequency(self)
  1240. local freq = self.iwinfo.frequency
  1241. if freq and freq > 0 then
  1242. return "%.03f" % (freq / 1000)
  1243. end
  1244. end
  1245. function wifinet.bitrate(self)
  1246. local rate = self.iwinfo.bitrate
  1247. if rate and rate > 0 then
  1248. return (rate / 1000)
  1249. end
  1250. end
  1251. function wifinet.channel(self)
  1252. return self.iwinfo.channel or
  1253. tonumber(_uci_state:get("wireless", self.iwdata.device, "channel"))
  1254. end
  1255. function wifinet.signal(self)
  1256. return self.iwinfo.signal or 0
  1257. end
  1258. function wifinet.noise(self)
  1259. return self.iwinfo.noise or 0
  1260. end
  1261. function wifinet.country(self)
  1262. return self.iwinfo.country or "00"
  1263. end
  1264. function wifinet.txpower(self)
  1265. local pwr = (self.iwinfo.txpower or 0)
  1266. return pwr + self:txpower_offset()
  1267. end
  1268. function wifinet.txpower_offset(self)
  1269. return self.iwinfo.txpower_offset or 0
  1270. end
  1271. function wifinet.signal_level(self, s, n)
  1272. if self:active_bssid() ~= "00:00:00:00:00:00" then
  1273. local signal = s or self:signal()
  1274. local noise = n or self:noise()
  1275. if signal < 0 and noise < 0 then
  1276. local snr = -1 * (noise - signal)
  1277. return math.floor(snr / 5)
  1278. else
  1279. return 0
  1280. end
  1281. else
  1282. return -1
  1283. end
  1284. end
  1285. function wifinet.signal_percent(self)
  1286. local qc = self.iwinfo.quality or 0
  1287. local qm = self.iwinfo.quality_max or 0
  1288. if qc > 0 and qm > 0 then
  1289. return math.floor((100 / qm) * qc)
  1290. else
  1291. return 0
  1292. end
  1293. end
  1294. function wifinet.shortname(self)
  1295. return "%s %q" %{
  1296. lng.translate(self:active_mode()),
  1297. self:active_ssid() or self:active_bssid()
  1298. }
  1299. end
  1300. function wifinet.get_i18n(self)
  1301. return "%s: %s %q (%s)" %{
  1302. lng.translate("Wireless Network"),
  1303. lng.translate(self:active_mode()),
  1304. self:active_ssid() or self:active_bssid(),
  1305. self:ifname()
  1306. }
  1307. end
  1308. function wifinet.adminlink(self)
  1309. return dsp.build_url("admin", "network", "wireless", self.netid)
  1310. end
  1311. function wifinet.get_network(self)
  1312. return self:get_networks()[1]
  1313. end
  1314. function wifinet.get_networks(self)
  1315. local nets = { }
  1316. local net
  1317. for net in utl.imatch(tostring(self.iwdata.network)) do
  1318. if _uci_real:get("network", net) == "interface" then
  1319. nets[#nets+1] = network(net)
  1320. end
  1321. end
  1322. table.sort(nets, function(a, b) return a.sid < b.sid end)
  1323. return nets
  1324. end
  1325. function wifinet.get_interface(self)
  1326. return interface(self:ifname())
  1327. end
  1328. -- setup base protocols
  1329. _M:register_protocol("static")
  1330. _M:register_protocol("dhcp")
  1331. _M:register_protocol("none")
  1332. -- load protocol extensions
  1333. local exts = nfs.dir(utl.libpath() .. "/model/network")
  1334. if exts then
  1335. local ext
  1336. for ext in exts do
  1337. if ext:match("%.lua$") then
  1338. require("luci.model.network." .. ext:gsub("%.lua$", ""))
  1339. end
  1340. end
  1341. end