Advertisement
Guest User

Untitled

a guest
Jan 6th, 2017
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 35.03 KB | None | 0 0
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Copyright 2010-2011 Jo-Philipp Wich <jow@openwrt.org>
  3. -- Licensed to the public under the Apache License 2.0.
  4.  
  5. m = Map("network", translate("Switch"), translate("The network ports on this dev                                                                                                                                                             ice can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</                                                                                                                                                             abbr>s in which computers can communicate directly with each other. <abbr title=                                                                                                                                                             \"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different                                                                                                                                                              network segments. Often there is by default one Uplink port for a connection to                                                                                                                                                              the next greater network like the internet and other ports for a local network.                                                                                                                                                             "))
  6.  
  7. local fs = require "nixio.fs"
  8. local switches = { }
  9.  
  10. m.uci:foreach("network", "switch",
  11.         function(x)
  12.                 local sid         = x['.name']
  13.                 local switch_name = x.name or sid
  14.                 local has_vlan    = nil
  15.                 local has_learn   = nil
  16.                 local has_vlan4k  = nil
  17.                 local has_jumbo3  = nil
  18.                 local has_mirror  = nil
  19.                 local min_vid     = 0
  20.                 local max_vid     = 16
  21.                 local num_vlans   = 16
  22.                 local cpu_port    = tonumber(fs.readfile("/proc/switch/eth0/cpup                                                                                                                                                             ort") or 5)
  23.                 local num_ports   = cpu_port + 1
  24.  
  25.                 local switch_title
  26.                 local enable_vlan4k = false
  27.  
  28.                 -- Parse some common switch properties from swconfig help output                                                                                                                                                             .
  29.                 local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch                                                                                                                                                             _name)
  30.                 if swc then
  31.  
  32.                         local is_port_attr = false
  33.                         local is_vlan_attr = false
  34.  
  35.                         while true do
  36.                                 local line = swc:read("*l")
  37.                                 if not line then break end
  38.  
  39.                                 if line:match("^%s+%-%-vlan") then
  40.                                         is_vlan_attr = true
  41.  
  42.                                 elseif line:match("^%s+%-%-port") then
  43.                                         is_vlan_attr = false
  44.                                         is_port_attr = true
  45.  
  46.                                 elseif line:match("cpu @") then
  47.                                         switch_title = line:match("^switch%d: %w                                                                                                                                                             +%((.-)%)")
  48.                                         num_ports, cpu_port, num_vlans =
  49.                                                 line:match("ports: (%d+) %(cpu @                                                                                                                                                              (%d+)%), vlans: (%d+)")
  50.  
  51.                                         num_ports  = tonumber(num_ports) or  6
  52.                                         num_vlans  = tonumber(num_vlans) or 16
  53.                                         cpu_port   = tonumber(cpu_port)  or  5
  54.                                         min_vid    = 1
  55.  
  56.                                 elseif line:match(": pvid") or line:match(": tag                                                                                                                                                             ") or line:match(": vid") then
  57.                                         if is_vlan_attr then has_vlan4k = line:m                                                                                                                                                             atch(": (%w+)") end
  58.  
  59.                                 elseif line:match(": enable_vlan4k") then
  60.                                         enable_vlan4k = true
  61.  
  62.                                 elseif line:match(": enable_vlan") then
  63.                                         has_vlan = "enable_vlan"
  64.  
  65.                                 elseif line:match(": enable_learning") then
  66.                                         has_learn = "enable_learning"
  67.  
  68.                                 elseif line:match(": enable_mirror_rx") then
  69.                                         has_mirror = "enable_mirror_rx"
  70.  
  71.                                 elseif line:match(": max_length") then
  72.                                         has_jumbo3 = "max_length"
  73.                                 end
  74.                         end
  75.  
  76.                         swc:close()
  77.                 end
  78.  
  79.  
  80.                 -- Switch properties
  81.                 s = m:section(NamedSection, x['.name'], "switch",
  82.                         switch_title and translatef("Switch %q (%s)", switch_nam                                                                                                                                                             e, switch_title)
  83.                                               or translatef("Switch %q", switch_                                                                                                                                                             name))
  84.  
  85.                 s.addremove = false
  86.  
  87.                 if has_vlan then
  88.                         s:option(Flag, has_vlan, translate("Enable VLAN function                                                                                                                                                             ality"))
  89.                 end
  90.  
  91.                 if has_learn then
  92.                         x = s:option(Flag, has_learn, translate("Enable learning                                                                                                                                                              and aging"))
  93.                         x.default = x.enabled
  94.                 end
  95.  
  96.                 if has_jumbo3 then
  97.                         x = s:option(Flag, has_jumbo3, translate("Enable Jumbo F                                                                                                                                                             rame passthrough"))
  98.                         x.enabled = "3"
  99.                         x.rmempty = true
  100.                 end
  101.  
  102.                 -- Does this switch support port mirroring?
  103.                 if has_mirror then
  104.                         s:option(Flag, "enable_mirror_rx", translate("Enable mir                                                                                                                                                             roring of incoming packets"))
  105.                         s:option(Flag, "enable_mirror_tx", translate("Enable mir                                                                                                                                                             roring of outgoing packets"))
  106.  
  107.                         local sp = s:option(ListValue, "mirror_source_port", tra                                                                                                                                                             nslate("Mirror source port"))
  108.                         local mp = s:option(ListValue, "mirror_monitor_port", tr                                                                                                                                                             anslate("Mirror monitor port"))
  109.  
  110.                         sp:depends("enable_mirror_tx", "1")
  111.                         sp:depends("enable_mirror_rx", "1")
  112.  
  113.                         mp:depends("enable_mirror_tx", "1")
  114.                         mp:depends("enable_mirror_rx", "1")
  115.  
  116.                         local pt
  117.                         for pt = 0, num_ports - 1 do
  118.                                 local name
  119.  
  120.                                 name = (pt == cpu_port) and translate("CPU") or                                                                                                                                                              translatef("Port %d", pt)
  121.  
  122.                                 sp:value(pt, name)
  123.                                 mp:value(pt, name)
  124.                         end
  125.                 end
  126.  
  127.                 -- VLAN table
  128.                 s = m:section(TypedSection, "switch_vlan",
  129.                         switch_title and translatef("VLANs on %q (%s)", switch_n                                                                                                                                                             ame, switch_title)
  130.                                                   or translatef("VLANs on %q", s                                                                                                                                                             witch_name))
  131.  
  132.                 s.template = "cbi/tblsection"
  133.                 s.addremove = true
  134.                 s.anonymous = true
  135.  
  136.                 -- Filter by switch
  137.                 s.filter = function(self, section)
  138.                         local device = m:get(section, "device")
  139.                         return (device and device == switch_name)
  140.                 end
  141.  
  142.                 -- Override cfgsections callback to enforce row ordering by vlan                                                                                                                                                              id.
  143.                 s.cfgsections = function(self)
  144.                         local osections = TypedSection.cfgsections(self)
  145.                         local sections = { }
  146.                         local section
  147.  
  148.                         for _, section in luci.util.spairs(
  149.                                 osections,
  150.                                 function(a, b)
  151.                                         return (tonumber(m:get(osections[a], has                                                                                                                                                             _vlan4k or "vlan")) or 9999)
  152.                                                 <  (tonumber(m:get(osections[b],                                                                                                                                                              has_vlan4k or "vlan")) or 9999)
  153.                                 end
  154.                         ) do
  155.                                 sections[#sections+1] = section
  156.                         end
  157.  
  158.                         return sections
  159.                 end
  160.  
  161.                 -- When creating a new vlan, preset it with the highest found vi                                                                                                                                                             d + 1.
  162.                 s.create = function(self, section, origin)
  163.                         -- Filter by switch
  164.                         if m:get(origin, "device") ~= switch_name then
  165.                                 return
  166.                         end
  167.  
  168.                         local sid = TypedSection.create(self, section)
  169.  
  170.                         local max_nr = 0
  171.                         local max_id = 0
  172.  
  173.                         m.uci:foreach("network", "switch_vlan",
  174.                                 function(s)
  175.                                         if s.device == switch_name then
  176.                                                 local nr = tonumber(s.vlan)
  177.                                                 local id = has_vlan4k and tonumb                                                                                                                                                             er(s[has_vlan4k])
  178.                                                 if nr ~= nil and nr > max_nr the                                                                                                                                                             n max_nr = nr end
  179.                                                 if id ~= nil and id > max_id the                                                                                                                                                             n max_id = id end
  180.                                         end
  181.                                 end)
  182.  
  183.                         m:set(sid, "device", switch_name)
  184.                         m:set(sid, "vlan", max_nr + 1)
  185.  
  186.                         if has_vlan4k then
  187.                                 m:set(sid, has_vlan4k, max_id + 1)
  188.                         end
  189.  
  190.                         return sid
  191.                 end
  192.  
  193.  
  194.                 local port_opts = { }
  195.                 local untagged  = { }
  196.  
  197.                 -- Parse current tagging state from the "ports" option.
  198.                 local portvalue = function(self, section)
  199.                         local pt
  200.                         for pt in (m:get(section, "ports") or ""):gmatch("%w+")                                                                                                                                                              do
  201.                                 local pc, tu = pt:match("^(%d+)([tu]*)")
  202.                                 if pc == self.option then return (#tu > 0) and t                                                                                                                                                             u or "u" end
  203.                         end
  204.                         return ""
  205.                 end
  206.  
  207.                 -- Validate port tagging. Ensure that a port is only untagged on                                                                                                                                                             ce,
  208.                 -- bail out if not.
  209.                 local portvalidate = function(self, value, section)
  210.                         -- ensure that the ports appears untagged only once
  211.                         if value == "u" then
  212.                                 if not untagged[self.option] then
  213.                                         untagged[self.option] = true
  214.                                 elseif min_vid > 0 or tonumber(self.option) ~= c                                                                                                                                                             pu_port then -- enable multiple untagged cpu ports due to weird broadcom default                                                                                                                                                              setup
  215.                                         return nil,
  216.                                                 translatef("Port %d is untagged                                                                                                                                                              in multiple VLANs!", tonumber(self.option) + 1)
  217.                                 end
  218.                         end
  219.                         return value
  220.                 end
  221.  
  222.  
  223.                 local vid = s:option(Value, has_vlan4k or "vlan", "VLAN ID", "<d                                                                                                                                                             iv id='portstatus-%s'></div>" % switch_name)
  224.                 local mx_vid = has_vlan4k and 4094 or (num_vlans - 1)
  225.  
  226.                 vid.rmempty = false
  227.                 vid.forcewrite = true
  228.                 vid.vlan_used = { }
  229.                 vid.datatype = "and(uinteger,range("..min_vid..","..mx_vid.."))"
  230.  
  231.                 -- Validate user provided VLAN ID, make sure its within the boun                                                                                                                                                             ds
  232.                 -- allowed by the switch.
  233.                 vid.validate = function(self, value, section)
  234.                         local v = tonumber(value)
  235.                         local m = has_vlan4k and 4094 or (num_vlans - 1)
  236.                         if v ~= nil and v >= min_vid and v <= m then
  237.                                 if not self.vlan_used[v] then
  238.                                         self.vlan_used[v] = true
  239.                                         return value
  240.                                 else
  241.                                         return nil,
  242.                                                 translatef("Invalid VLAN ID give                                                                                                                                                             n! Only unique IDs are allowed")
  243.                                 end
  244.                         else
  245.                                 return nil,
  246.                                         translatef("Invalid VLAN ID given! Only                                                                                                                                                              IDs between %d and %d are allowed.", min_vid, m)
  247.                         end
  248.                 end
  249.  
  250.                 -- When writing the "vid" or "vlan" option, serialize the port s                                                                                                                                                             tates
  251.                 -- as well and write them as "ports" option to uci.
  252.                 vid.write = function(self, section, value)
  253.                         local o
  254.                         local p = { }
  255.  
  256.                         for _, o in ipairs(port_opts) do
  257.                                 local v = o:formvalue(section)
  258.                                 if v == "t" then
  259.                                         p[#p+1] = o.option .. v
  260.                                 elseif v == "u" then
  261.                                         p[#p+1] = o.option
  262.                                 end
  263.                         end
  264.  
  265.                         if enable_vlan4k then
  266.                                 m:set(sid, "enable_vlan4k", "1")
  267.                         end
  268.  
  269.                         m:set(section, "ports", table.concat(p, " "))
  270.                         return Value.write(self, section, value)
  271.                 end
  272.  
  273.                 -- Fallback to "vlan" option if "vid" option is supported but un                                                                                                                                                             set.
  274.                 vid.cfgvalue = function(self, section)
  275.                         return m:get(section, has_vlan4k or "vlan")
  276.                                 or m:get(section, "vlan")
  277.                 end
  278.  
  279.                 -- Build per-port off/untagged/tagged choice lists.
  280.                 local pt
  281.                 for pt = 0, num_ports - 1 do
  282.                         local title
  283.                         if pt == cpu_port then
  284.                                 title = translate("CPU")
  285.                         else
  286.                                 title = translatef("Port %d", pt)
  287.                         end
  288.  
  289.                         local po = s:option(ListValue, tostring(pt), title)
  290.  
  291.                         po:value("",  translate("off"))
  292.                         po:value("u", translate("untagged"))
  293.                         po:value("t", translate("tagged"))
  294.  
  295.                         po.cfgvalue = portvalue
  296.                         po.validate = portvalidate
  297.                         po.write    = function() end
  298.  
  299.                         port_opts[#port_opts+1] = po
  300.                 end
  301.  
  302.                 switches[#switches+1] = switch_name
  303.         end
  304. )
  305.  
  306. -- Switch status template
  307. s = m:section(SimpleSection)
  308. s.template = "admin_network/switch_status"
  309. s.switches = switches
  310.  
  311. return m
  312. root@turris:/# cat /usr/lib/lua/luci/model/cbi/admin_network/vlan.lua
  313. -- Copyright 2008 Steven Barth <steven@midlink.org>
  314. -- Copyright 2010-2011 Jo-Philipp Wich <jow@openwrt.org>
  315. -- Licensed to the public under the Apache License 2.0.
  316.  
  317. m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
  318.  
  319. local fs = require "nixio.fs"
  320. local switches = { }
  321.  
  322. m.uci:foreach("network", "switch",
  323.         function(x)
  324.                 local sid         = x['.name']
  325.                 local switch_name = x.name or sid
  326.                 local has_vlan    = nil
  327.                 local has_learn   = nil
  328.                 local has_vlan4k  = nil
  329.                 local has_jumbo3  = nil
  330.                 local has_mirror  = nil
  331.                 local min_vid     = 0
  332.                 local max_vid     = 16
  333.                 local num_vlans   = 16
  334.                 local cpu_port    = tonumber(fs.readfile("/proc/switch/eth0/cpuport") or 5)
  335.                 local num_ports   = cpu_port + 1
  336.  
  337.                 local switch_title
  338.                 local enable_vlan4k = false
  339.  
  340.                 -- Parse some common switch properties from swconfig help output.
  341.                 local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch_name)
  342.                 if swc then
  343.  
  344.                         local is_port_attr = false
  345.                         local is_vlan_attr = false
  346.  
  347.                         while true do
  348.                                 local line = swc:read("*l")
  349.                                 if not line then break end
  350.  
  351.                                 if line:match("^%s+%-%-vlan") then
  352.                                         is_vlan_attr = true
  353.  
  354.                                 elseif line:match("^%s+%-%-port") then
  355.                                         is_vlan_attr = false
  356.                                         is_port_attr = true
  357.  
  358.                                 elseif line:match("cpu @") then
  359.                                         switch_title = line:match("^switch%d: %w+%((.-)%)")
  360.                                         num_ports, cpu_port, num_vlans =
  361.                                                 line:match("ports: (%d+) %(cpu @ (%d+)%), vlans: (%d+)")
  362.  
  363.                                         num_ports  = tonumber(num_ports) or  6
  364.                                         num_vlans  = tonumber(num_vlans) or 16
  365.                                         cpu_port   = tonumber(cpu_port)  or  5
  366.                                         min_vid    = 1
  367.  
  368.                                 elseif line:match(": pvid") or line:match(": tag") or line:match(": vid") then
  369.                                         if is_vlan_attr then has_vlan4k = line:match(": (%w+)") end
  370.  
  371.                                 elseif line:match(": enable_vlan4k") then
  372.                                         enable_vlan4k = true
  373.  
  374.                                 elseif line:match(": enable_vlan") then
  375.                                         has_vlan = "enable_vlan"
  376.  
  377.                                 elseif line:match(": enable_learning") then
  378.                                         has_learn = "enable_learning"
  379.  
  380.                                 elseif line:match(": enable_mirror_rx") then
  381.                                         has_mirror = "enable_mirror_rx"
  382.  
  383.                                 elseif line:match(": max_length") then
  384.                                         has_jumbo3 = "max_length"
  385.                                 end
  386.                         end
  387.  
  388.                         swc:close()
  389.                 end
  390.  
  391.  
  392.                 -- Switch properties
  393.                 s = m:section(NamedSection, x['.name'], "switch",
  394.                         switch_title and translatef("Switch %q (%s)", switch_name, switch_title)
  395.                                               or translatef("Switch %q", switch_name))
  396.  
  397.                 s.addremove = false
  398.  
  399.                 if has_vlan then
  400.                         s:option(Flag, has_vlan, translate("Enable VLAN functionality"))
  401.                 end
  402.  
  403.                 if has_learn then
  404.                         x = s:option(Flag, has_learn, translate("Enable learning and aging"))
  405.                         x.default = x.enabled
  406.                 end
  407.  
  408.                 if has_jumbo3 then
  409.                         x = s:option(Flag, has_jumbo3, translate("Enable Jumbo Frame passthrough"))
  410.                         x.enabled = "3"
  411.                         x.rmempty = true
  412.                 end
  413.  
  414.                 -- Does this switch support port mirroring?
  415.                 if has_mirror then
  416.                         s:option(Flag, "enable_mirror_rx", translate("Enable mirroring of incoming packets"))
  417.                         s:option(Flag, "enable_mirror_tx", translate("Enable mirroring of outgoing packets"))
  418.  
  419.                         local sp = s:option(ListValue, "mirror_source_port", translate("Mirror source port"))
  420.                         local mp = s:option(ListValue, "mirror_monitor_port", translate("Mirror monitor port"))
  421.  
  422.                         sp:depends("enable_mirror_tx", "1")
  423.                         sp:depends("enable_mirror_rx", "1")
  424.  
  425.                         mp:depends("enable_mirror_tx", "1")
  426.                         mp:depends("enable_mirror_rx", "1")
  427.  
  428.                         local pt
  429.                         for pt = 0, num_ports - 1 do
  430.                                 local name
  431.  
  432.                                 name = (pt == cpu_port) and translate("CPU") or translatef("Port %d", pt)
  433.  
  434.                                 sp:value(pt, name)
  435.                                 mp:value(pt, name)
  436.                         end
  437.                 end
  438.  
  439.                 -- VLAN table
  440.                 s = m:section(TypedSection, "switch_vlan",
  441.                         switch_title and translatef("VLANs on %q (%s)", switch_name, switch_title)
  442.                                                   or translatef("VLANs on %q", switch_name))
  443.  
  444.                 s.template = "cbi/tblsection"
  445.                 s.addremove = true
  446.                 s.anonymous = true
  447.  
  448.                 -- Filter by switch
  449.                 s.filter = function(self, section)
  450.                         local device = m:get(section, "device")
  451.                         return (device and device == switch_name)
  452.                 end
  453.  
  454.                 -- Override cfgsections callback to enforce row ordering by vlan id.
  455.                 s.cfgsections = function(self)
  456.                         local osections = TypedSection.cfgsections(self)
  457.                         local sections = { }
  458.                         local section
  459.  
  460.                         for _, section in luci.util.spairs(
  461.                                 osections,
  462.                                 function(a, b)
  463.                                         return (tonumber(m:get(osections[a], has_vlan4k or "vlan")) or 9999)
  464.                                                 <  (tonumber(m:get(osections[b], has_vlan4k or "vlan")) or 9999)
  465.                                 end
  466.                         ) do
  467.                                 sections[#sections+1] = section
  468.                         end
  469.  
  470.                         return sections
  471.                 end
  472.  
  473.                 -- When creating a new vlan, preset it with the highest found vid + 1.
  474.                 s.create = function(self, section, origin)
  475.                         -- Filter by switch
  476.                         if m:get(origin, "device") ~= switch_name then
  477.                                 return
  478.                         end
  479.  
  480.                         local sid = TypedSection.create(self, section)
  481.  
  482.                         local max_nr = 0
  483.                         local max_id = 0
  484.  
  485.                         m.uci:foreach("network", "switch_vlan",
  486.                                 function(s)
  487.                                         if s.device == switch_name then
  488.                                                 local nr = tonumber(s.vlan)
  489.                                                 local id = has_vlan4k and tonumber(s[has_vlan4k])
  490.                                                 if nr ~= nil and nr > max_nr then max_nr = nr end
  491.                                                 if id ~= nil and id > max_id then max_id = id end
  492.                                         end
  493.                                 end)
  494.  
  495.                         m:set(sid, "device", switch_name)
  496.                         m:set(sid, "vlan", max_nr + 1)
  497.  
  498.                         if has_vlan4k then
  499.                                 m:set(sid, has_vlan4k, max_id + 1)
  500.                         end
  501.  
  502.                         return sid
  503.                 end
  504.  
  505.  
  506.                 local port_opts = { }
  507.                 local untagged  = { }
  508.  
  509.                 -- Parse current tagging state from the "ports" option.
  510.                 local portvalue = function(self, section)
  511.                         local pt
  512.                         for pt in (m:get(section, "ports") or ""):gmatch("%w+") do
  513.                                 local pc, tu = pt:match("^(%d+)([tu]*)")
  514.                                 if pc == self.option then return (#tu > 0) and tu or "u" end
  515.                         end
  516.                         return ""
  517.                 end
  518.  
  519.                 -- Validate port tagging. Ensure that a port is only untagged once,
  520.                 -- bail out if not.
  521.                 local portvalidate = function(self, value, section)
  522.                         -- ensure that the ports appears untagged only once
  523.                         if value == "u" then
  524.                                 if not untagged[self.option] then
  525.                                         untagged[self.option] = true
  526.                                 elseif min_vid > 0 or tonumber(self.option) ~= cpu_port then -- enable multiple untagged cpu ports due to weird broadcom default setup
  527.                                         return nil,
  528.                                                 translatef("Port %d is untagged in multiple VLANs!", tonumber(self.option) + 1)
  529.                                 end
  530.                         end
  531.                         return value
  532.                 end
  533.  
  534.  
  535.                 local vid = s:option(Value, has_vlan4k or "vlan", "VLAN ID", "<div id='portstatus-%s'></div>" % switch_name)
  536.                 local mx_vid = has_vlan4k and 4094 or (num_vlans - 1)
  537.  
  538.                 vid.rmempty = false
  539.                 vid.forcewrite = true
  540.                 vid.vlan_used = { }
  541.                 vid.datatype = "and(uinteger,range("..min_vid..","..mx_vid.."))"
  542.  
  543.                 -- Validate user provided VLAN ID, make sure its within the bounds
  544.                 -- allowed by the switch.
  545.                 vid.validate = function(self, value, section)
  546.                         local v = tonumber(value)
  547.                         local m = has_vlan4k and 4094 or (num_vlans - 1)
  548.                         if v ~= nil and v >= min_vid and v <= m then
  549.                                 if not self.vlan_used[v] then
  550.                                         self.vlan_used[v] = true
  551.                                         return value
  552.                                 else
  553.                                         return nil,
  554.                                                 translatef("Invalid VLAN ID given! Only unique IDs are allowed")
  555.                                 end
  556.                         else
  557.                                 return nil,
  558.                                         translatef("Invalid VLAN ID given! Only IDs between %d and %d are allowed.", min_vid, m)
  559.                         end
  560.                 end
  561.  
  562.                 -- When writing the "vid" or "vlan" option, serialize the port states
  563.                 -- as well and write them as "ports" option to uci.
  564.                 vid.write = function(self, section, value)
  565.                         local o
  566.                         local p = { }
  567.  
  568.                         for _, o in ipairs(port_opts) do
  569.                                 local v = o:formvalue(section)
  570.                                 if v == "t" then
  571.                                         p[#p+1] = o.option .. v
  572.                                 elseif v == "u" then
  573.                                         p[#p+1] = o.option
  574.                                 end
  575.                         end
  576.  
  577.                         if enable_vlan4k then
  578.                                 m:set(sid, "enable_vlan4k", "1")
  579.                         end
  580.  
  581.                         m:set(section, "ports", table.concat(p, " "))
  582.                         return Value.write(self, section, value)
  583.                 end
  584.  
  585.                 -- Fallback to "vlan" option if "vid" option is supported but unset.
  586.                 vid.cfgvalue = function(self, section)
  587.                         return m:get(section, has_vlan4k or "vlan")
  588.                                 or m:get(section, "vlan")
  589.                 end
  590.  
  591.                 -- Build per-port off/untagged/tagged choice lists.
  592.                 local pt
  593.                 for pt = 0, num_ports - 1 do
  594.                         local title
  595.                         if pt == cpu_port then
  596.                                 title = translate("CPU")
  597.                         else
  598.                                 title = translatef("Port %d", pt)
  599.                         end
  600.  
  601.                         local po = s:option(ListValue, tostring(pt), title)
  602.  
  603.                         po:value("",  translate("off"))
  604.                         po:value("u", translate("untagged"))
  605.                         po:value("t", translate("tagged"))
  606.  
  607.                         po.cfgvalue = portvalue
  608.                         po.validate = portvalidate
  609.                         po.write    = function() end
  610.  
  611.                         port_opts[#port_opts+1] = po
  612.                 end
  613.  
  614.                 switches[#switches+1] = switch_name
  615.         end
  616. )
  617.  
  618. -- Switch status template
  619. s = m:section(SimpleSection)
  620. s.template = "admin_network/switch_status"
  621. s.switches = switches
  622.  
  623. return m
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement