9 /^wlan[0-9]+\.sta[0-9]+$/,
15 'protolist', 0, L
.rpc
.declare({
17 method
: 'get_proto_handlers',
20 'ifstate', 1, L
.rpc
.declare({
21 object
: 'network.interface',
23 expect
: { 'interface': [ ] }
25 'devstate', 2, L
.rpc
.declare({
26 object
: 'network.device',
30 'wifistate', 0, L
.rpc
.declare({
31 object
: 'network.wireless',
35 'bwstate', 2, L
.rpc
.declare({
36 object
: 'luci2.network.bwmon',
38 expect
: { 'statistics': { } }
40 'devlist', 2, L
.rpc
.declare({
41 object
: 'luci2.network',
42 method
: 'device_list',
43 expect
: { 'devices': [ ] }
45 'swlist', 0, L
.rpc
.declare({
46 object
: 'luci2.network',
47 method
: 'switch_list',
48 expect
: { 'switches': [ ] }
52 loadProtocolHandler: function(proto
)
54 var url
= L
.globals
.resource
+ '/proto/' + proto
+ '.js';
57 var def
= $.Deferred();
63 }).then(function(data
) {
65 var protoConstructorSource
= (
66 '(function(L, $) { ' +
70 ).format(data
, window
.location
.origin
, url
);
72 var protoClass
= eval(protoConstructorSource
);
74 self
.protocolHandlers
[proto
] = new protoClass();
77 alert('Unable to instantiate proto "%s": %s'.format(url
, e
));
88 loadProtocolHandlers: function()
92 self
.loadProtocolHandler('none')
95 for (var proto
in self
.rpcCache
.protolist
)
96 deferreds
.push(self
.loadProtocolHandler(proto
));
98 return $.when
.apply($, deferreds
);
101 callSwitchInfo
: L
.rpc
.declare({
102 object
: 'luci2.network',
103 method
: 'switch_info',
104 params
: [ 'switch' ],
105 expect
: { 'info': { } }
108 callSwitchInfoCallback: function(responses
) {
109 var self
= L
.network
;
110 var swlist
= self
.rpcCache
.swlist
;
111 var swstate
= self
.rpcCache
.swstate
= { };
113 for (var i
= 0; i
< responses
.length
; i
++)
114 swstate
[swlist
[i
]] = responses
[i
];
117 loadCacheCallback: function(level
)
119 var self
= L
.network
;
120 var name
= '_fetch_cache_cb_' + level
;
122 return self
[name
] || (
123 self
[name
] = function(responses
)
125 for (var i
= 0; i
< self
.rpcCacheFunctions
.length
; i
+= 3)
126 if (!level
|| self
.rpcCacheFunctions
[i
+ 1] == level
)
127 self
.rpcCache
[self
.rpcCacheFunctions
[i
]] = responses
.shift();
133 for (var i
= 0; i
< self
.rpcCache
.swlist
.length
; i
++)
134 self
.callSwitchInfo(self
.rpcCache
.swlist
[i
]);
136 return L
.rpc
.flush().then(self
.callSwitchInfoCallback
);
139 return L
.deferrable();
144 loadCache: function(level
)
146 var self
= L
.network
;
148 return L
.uci
.load(['network', 'wireless']).then(function() {
151 for (var i
= 0; i
< self
.rpcCacheFunctions
.length
; i
+= 3)
152 if (!level
|| self
.rpcCacheFunctions
[i
+ 1] == level
)
153 self
.rpcCacheFunctions
[i
+ 2]();
155 return L
.rpc
.flush().then(self
.loadCacheCallback(level
|| 0));
159 isBlacklistedDevice: function(dev
)
161 for (var i
= 0; i
< this.deviceBlacklist
.length
; i
++)
162 if (dev
.match(this.deviceBlacklist
[i
]))
168 sortDevicesCallback: function(a
, b
)
170 if (a
.options
.kind
< b
.options
.kind
)
172 else if (a
.options
.kind
> b
.options
.kind
)
175 if (a
.options
.name
< b
.options
.name
)
177 else if (a
.options
.name
> b
.options
.name
)
183 getDeviceObject: function(ifname
)
185 var alias
= (ifname
.charAt(0) == '@');
186 return this.deviceObjects
[ifname
] || (
187 this.deviceObjects
[ifname
] = {
189 kind
: alias
? 'alias' : 'ethernet',
197 getInterfaceObject: function(name
)
199 return this.interfaceObjects
[name
] || (
200 this.interfaceObjects
[name
] = {
202 proto
: this.protocolHandlers
.none
,
208 loadDevicesCallback: function()
210 var self
= L
.network
;
213 for (var ifname
in self
.rpcCache
.devstate
)
215 if (self
.isBlacklistedDevice(ifname
))
218 var dev
= self
.rpcCache
.devstate
[ifname
];
219 var entry
= self
.getDeviceObject(ifname
);
226 entry
.kind
= 'tunnel';
230 entry
.kind
= 'bridge';
231 //entry.ports = dev['bridge-members'].sort();
236 for (var i
= 0; i
< self
.rpcCache
.devlist
.length
; i
++)
238 var dev
= self
.rpcCache
.devlist
[i
];
240 if (self
.isBlacklistedDevice(dev
.device
))
243 var entry
= self
.getDeviceObject(dev
.device
);
245 entry
.up
= dev
.is_up
;
246 entry
.type
= dev
.type
;
250 case 1: /* Ethernet */
252 entry
.kind
= 'bridge';
253 else if (dev
.is_tuntap
)
254 entry
.kind
= 'tunnel';
255 else if (dev
.is_wireless
)
260 case 768: /* IP-IP Tunnel */
261 case 769: /* IP6-IP6 Tunnel */
262 case 776: /* IPv6-in-IPv4 */
263 case 778: /* GRE over IP */
264 entry
.kind
= 'tunnel';
269 var net
= L
.uci
.sections('network');
270 for (var i
= 0; i
< net
.length
; i
++)
273 var sid
= s
['.name'];
275 if (s
['.type'] == 'device' && s
.name
)
277 var entry
= self
.getDeviceObject(s
.name
);
283 entry
.kind
= 'tunnel';
289 else if (s
['.type'] == 'interface' && !s
['.anonymous'] && s
.ifname
)
291 var ifnames
= L
.toArray(s
.ifname
);
293 for (var j
= 0; j
< ifnames
.length
; j
++)
294 self
.getDeviceObject(ifnames
[j
]);
296 if (s
['.name'] != 'loopback')
298 var entry
= self
.getDeviceObject('@%s'.format(s
['.name']));
301 entry
.kind
= 'alias';
305 else if (s
['.type'] == 'switch_vlan' && s
.device
)
307 var sw
= self
.rpcCache
.swstate
[s
.device
];
308 var vid
= parseInt(s
.vid
|| s
.vlan
);
309 var ports
= L
.toArray(s
.ports
);
311 if (!sw
|| !ports
.length
|| isNaN(vid
))
314 var ifname
= undefined;
316 for (var j
= 0; j
< ports
.length
; j
++)
318 var port
= parseInt(ports
[j
]);
319 var tag
= (ports
[j
].replace(/[^tu]/g, '') == 't');
321 if (port
== sw
.cpu_port
)
323 // XXX: need a way to map switch to netdev
325 ifname
= 'eth0.%d'.format(vid
);
336 var entry
= self
.getDeviceObject(ifname
);
345 var wifi
= L
.uci
.sections('wireless');
346 for (var i
= 0, c
= 0; i
< wifi
.length
; i
++)
350 if (s
['.type'] == 'wifi-iface')
352 var sid
= '@wifi-iface[%d]'.format(c
++);
357 var r
= parseInt(s
.device
.replace(/^[^0-9]+/, ''));
358 var n
= wificount
[s
.device
] = (wificount
[s
.device
] || 0) + 1;
359 var id
= 'radio%d.network%d'.format(r
, n
);
362 if (self
.rpcCache
.wifistate
[s
.device
])
364 var ifcs
= self
.rpcCache
.wifistate
[s
.device
].interfaces
;
365 for (var ifc
in ifcs
)
367 if (ifcs
[ifc
].section
== sid
&& ifcs
[ifc
].ifname
)
369 ifname
= ifcs
[ifc
].ifname
;
375 var entry
= self
.getDeviceObject(ifname
);
378 entry
.sid
= s
['.name'];
380 entry
.wdev
= s
.device
;
381 entry
.wmode
= s
.mode
;
382 entry
.wssid
= s
.ssid
;
383 entry
.wbssid
= s
.bssid
;
387 for (var i
= 0; i
< net
.length
; i
++)
390 var sid
= s
['.name'];
392 if (s
['.type'] == 'interface' && !s
['.anonymous'] && s
.type
== 'bridge')
394 var ifnames
= L
.toArray(s
.ifname
);
396 for (var ifname
in self
.deviceObjects
)
398 var dev
= self
.deviceObjects
[ifname
];
400 if (dev
.kind
!= 'wifi')
403 var wnets
= L
.toArray(L
.uci
.get('wireless', dev
.sid
, 'network'));
404 if ($.inArray(sid
, wnets
) > -1)
405 ifnames
.push(ifname
);
408 entry
= self
.getDeviceObject('br-%s'.format(s
['.name']));
410 entry
.kind
= 'bridge';
412 entry
.ports
= ifnames
.sort();
417 loadInterfacesCallback: function()
419 var self
= L
.network
;
420 var net
= L
.uci
.sections('network');
422 for (var i
= 0; i
< net
.length
; i
++)
425 var sid
= s
['.name'];
427 if (s
['.type'] == 'interface' && !s
['.anonymous'] && s
.proto
)
429 var entry
= self
.getInterfaceObject(s
['.name']);
430 var proto
= self
.protocolHandlers
[s
.proto
] || self
.protocolHandlers
.none
;
432 var l3dev
= undefined;
433 var l2dev
= undefined;
435 var ifnames
= L
.toArray(s
.ifname
);
437 for (var ifname
in self
.deviceObjects
)
439 var dev
= self
.deviceObjects
[ifname
];
441 if (dev
.kind
!= 'wifi')
444 var wnets
= L
.toArray(L
.uci
.get('wireless', dev
.sid
, 'network'));
445 if ($.inArray(entry
.name
, wnets
) > -1)
446 ifnames
.push(ifname
);
450 l3dev
= '%s-%s'.format(s
.proto
, entry
.name
);
451 else if (s
.type
== 'bridge')
452 l3dev
= 'br-%s'.format(entry
.name
);
456 if (!proto
.virtual
&& s
.type
== 'bridge')
457 l2dev
= 'br-%s'.format(entry
.name
);
458 else if (!proto
.virtual
)
468 for (var i
= 0; i
< self
.rpcCache
.ifstate
.length
; i
++)
470 var iface
= self
.rpcCache
.ifstate
[i
];
471 var entry
= self
.getInterfaceObject(iface
['interface']);
472 var proto
= self
.protocolHandlers
[iface
.proto
] || self
.protocolHandlers
.none
;
474 /* this is a virtual interface, either deleted from config but
475 not applied yet or set up from external tools (6rd) */
479 entry
.l2dev
= iface
.device
;
480 entry
.l3dev
= iface
.l3_device
;
490 return L
.deferrable();
493 self
.deviceObjects
= { };
494 self
.interfaceObjects
= { };
495 self
.protocolHandlers
= { };
497 return self
.loadCache()
498 .then(self
.loadProtocolHandlers
)
499 .then(self
.loadDevicesCallback
)
500 .then(self
.loadInterfacesCallback
);
505 delete this.rpcCache
;
509 refreshInterfaceStatus: function()
511 return this.loadCache(1).then(this.loadInterfacesCallback
);
514 refreshDeviceStatus: function()
516 return this.loadCache(2).then(this.loadDevicesCallback
);
519 refreshStatus: function()
521 return this.loadCache(1)
522 .then(this.loadCache(2))
523 .then(this.loadDevicesCallback
)
524 .then(this.loadInterfacesCallback
);
527 getDevices: function()
531 for (var ifname
in this.deviceObjects
)
533 devs
.push(new L
.network
.Device(this.deviceObjects
[ifname
]));
535 return devs
.sort(this.sortDevicesCallback
);
538 getDeviceByInterface: function(iface
)
540 if (iface
instanceof L
.network
.Interface
)
541 iface
= iface
.name();
543 if (this.interfaceObjects
[iface
])
544 return this.getDevice(this.interfaceObjects
[iface
].l3dev
) ||
545 this.getDevice(this.interfaceObjects
[iface
].l2dev
);
550 getDevice: function(ifname
)
552 if (this.deviceObjects
[ifname
])
553 return new L
.network
.Device(this.deviceObjects
[ifname
]);
558 createDevice: function(name
)
560 return new L
.network
.Device(this.getDeviceObject(name
));
563 getInterfaces: function()
567 for (var name
in this.interfaceObjects
)
568 if (name
!= 'loopback')
569 ifaces
.push(this.getInterface(name
));
571 ifaces
.sort(function(a
, b
) {
572 if (a
.name() < b
.name())
574 else if (a
.name() > b
.name())
583 getInterfacesByDevice: function(dev
)
587 if (dev
instanceof L
.network
.Device
)
590 for (var name
in this.interfaceObjects
)
592 var iface
= this.interfaceObjects
[name
];
593 if (iface
.l2dev
== dev
|| iface
.l3dev
== dev
)
594 ifaces
.push(this.getInterface(name
));
597 ifaces
.sort(function(a
, b
) {
598 if (a
.name() < b
.name())
600 else if (a
.name() > b
.name())
609 getInterface: function(iface
)
611 if (this.interfaceObjects
[iface
])
612 return new L
.network
.Interface(this.interfaceObjects
[iface
]);
617 getProtocols: function()
621 for (var proto
in this.protocolHandlers
)
623 var pr
= this.protocolHandlers
[proto
];
627 description
: pr
.description
,
633 return rv
.sort(function(a
, b
) {
636 else if (a
.name
> b
.name
)
643 findWANByAddr: function(ipaddr
)
645 for (var i
= 0; i
< this.rpcCache
.ifstate
.length
; i
++)
647 var ifstate
= this.rpcCache
.ifstate
[i
];
652 for (var j
= 0; j
< ifstate
.route
.length
; j
++)
653 if (ifstate
.route
[j
].mask
== 0 &&
654 ifstate
.route
[j
].target
== ipaddr
&&
655 typeof(ifstate
.route
[j
].table
) == 'undefined')
657 return this.getInterface(ifstate
['interface']);
666 return this.findWANByAddr('0.0.0.0');
671 return this.findWANByAddr('::');
674 resolveAlias: function(ifname
)
676 if (ifname
instanceof L
.network
.Device
)
677 ifname
= ifname
.name();
679 var dev
= this.deviceObjects
[ifname
];
682 while (dev
&& dev
.kind
== 'alias')
685 if (seen
[dev
.ifname
])
688 var ifc
= this.interfaceObjects
[dev
.sid
];
690 seen
[dev
.ifname
] = true;
691 dev
= ifc
? this.deviceObjects
[ifc
.l3dev
] : undefined;
694 return dev
? this.getDevice(dev
.ifname
) : undefined;
698 network_class
.Interface
= Class
.extend({
699 getStatus: function(key
)
701 var s
= L
.network
.rpcCache
.ifstate
;
703 for (var i
= 0; i
< s
.length
; i
++)
704 if (s
[i
]['interface'] == this.options
.name
)
705 return key
? s
[i
][key
] : s
[i
];
712 return L
.uci
.get('network', this.options
.name
, key
);
715 set: function(key
, val
)
717 return L
.uci
.set('network', this.options
.name
, key
, val
);
722 return this.options
.name
;
727 return (this.get('proto') || 'none');
732 return (this.getStatus('up') === true);
735 isVirtual: function()
737 return (typeof(this.options
.sid
) != 'string');
740 getProtocol: function()
742 var prname
= this.get('proto') || 'none';
743 return L
.network
.protocolHandlers
[prname
] || L
.network
.protocolHandlers
.none
;
746 getUptime: function()
748 var uptime
= this.getStatus('uptime');
749 return isNaN(uptime
) ? 0 : uptime
;
752 getDevice: function(resolveAlias
)
754 if (this.options
.l3dev
)
755 return L
.network
.getDevice(this.options
.l3dev
);
760 getPhysdev: function()
762 if (this.options
.l2dev
)
763 return L
.network
.getDevice(this.options
.l2dev
);
768 getSubdevices: function()
771 var dev
= this.options
.l2dev
?
772 L
.network
.deviceObjects
[this.options
.l2dev
] : undefined;
774 if (dev
&& dev
.kind
== 'bridge' && dev
.ports
&& dev
.ports
.length
)
775 for (var i
= 0; i
< dev
.ports
.length
; i
++)
776 rv
.push(L
.network
.getDevice(dev
.ports
[i
]));
781 getIPv4Addrs: function(mask
)
784 var addrs
= this.getStatus('ipv4-address');
787 for (var i
= 0; i
< addrs
.length
; i
++)
789 rv
.push(addrs
[i
].address
);
791 rv
.push('%s/%d'.format(addrs
[i
].address
, addrs
[i
].mask
));
796 getIPv6Addrs: function(mask
)
801 addrs
= this.getStatus('ipv6-address');
804 for (var i
= 0; i
< addrs
.length
; i
++)
806 rv
.push(addrs
[i
].address
);
808 rv
.push('%s/%d'.format(addrs
[i
].address
, addrs
[i
].mask
));
810 addrs
= this.getStatus('ipv6-prefix-assignment');
813 for (var i
= 0; i
< addrs
.length
; i
++)
815 rv
.push('%s1'.format(addrs
[i
].address
));
817 rv
.push('%s1/%d'.format(addrs
[i
].address
, addrs
[i
].mask
));
822 getDNSAddrs: function()
825 var addrs
= this.getStatus('dns-server');
828 for (var i
= 0; i
< addrs
.length
; i
++)
834 getIPv4DNS: function()
837 var dns
= this.getStatus('dns-server');
840 for (var i
= 0; i
< dns
.length
; i
++)
841 if (dns
[i
].indexOf(':') == -1)
847 getIPv6DNS: function()
850 var dns
= this.getStatus('dns-server');
853 for (var i
= 0; i
< dns
.length
; i
++)
854 if (dns
[i
].indexOf(':') > -1)
860 getIPv4Gateway: function()
862 var rt
= this.getStatus('route');
865 for (var i
= 0; i
< rt
.length
; i
++)
866 if (rt
[i
].target
== '0.0.0.0' && rt
[i
].mask
== 0)
867 return rt
[i
].nexthop
;
872 getIPv6Gateway: function()
874 var rt
= this.getStatus('route');
877 for (var i
= 0; i
< rt
.length
; i
++)
878 if (rt
[i
].target
== '::' && rt
[i
].mask
== 0)
879 return rt
[i
].nexthop
;
884 getStatistics: function()
886 var dev
= this.getDevice() || new L
.network
.Device({});
887 return dev
.getStatistics();
890 getTrafficHistory: function()
892 var dev
= this.getDevice() || new L
.network
.Device({});
893 return dev
.getTrafficHistory();
896 renderBadge: function()
898 var badge
= $('<span />')
900 .text('%s: '.format(this.name()));
902 var dev
= this.getDevice();
903 var subdevs
= this.getSubdevices();
906 for (var j
= 0; j
< subdevs
.length
; j
++)
907 badge
.append($('<img />')
908 .attr('src', subdevs
[j
].icon())
909 .attr('title', '%s (%s)'.format(subdevs
[j
].description(), subdevs
[j
].name() || '?')));
911 badge
.append($('<img />')
912 .attr('src', dev
.icon())
913 .attr('title', '%s (%s)'.format(dev
.description(), dev
.name() || '?')));
915 badge
.append($('<em />').text(L
.tr('(No devices attached)')));
920 setDevices: function(devs
)
922 var dev
= this.getPhysdev();
926 if (dev
&& dev
.isBridge())
927 old_devs
= this.getSubdevices();
931 if (old_devs
.length
!= devs
.length
)
934 for (var i
= 0; i
< old_devs
.length
; i
++)
938 if (dev
instanceof L
.network
.Device
)
941 if (!dev
|| old_devs
[i
].name() != dev
)
950 for (var i
= 0; i
< old_devs
.length
; i
++)
951 old_devs
[i
].removeFromInterface(this);
953 for (var i
= 0; i
< devs
.length
; i
++)
957 if (!(dev
instanceof L
.network
.Device
))
958 dev
= L
.network
.getDevice(dev
);
961 dev
.attachToInterface(this);
966 changeProtocol: function(proto
)
968 var pr
= L
.network
.protocolHandlers
[proto
];
973 for (var opt
in (this.get() || { }))
981 this.set(opt
, undefined);
989 this.set(opt
, pr
.protocol
);
993 this.set(opt
, undefined);
999 createFormPrepareCallback: function()
1002 var iface
= map
.options
.netIface
;
1003 var proto
= iface
.getProtocol();
1004 var device
= iface
.getDevice();
1006 map
.options
.caption
= L
.tr('Configure "%s"').format(iface
.name());
1008 var section
= map
.section(L
.cbi
.SingleSection
, iface
.name(), {
1014 caption
: L
.tr('General Settings')
1019 caption
: L
.tr('Advanced Settings')
1024 caption
: L
.tr('IPv6')
1029 caption
: L
.tr('Physical Settings')
1033 section
.taboption('general', L
.cbi
.CheckboxValue
, 'auto', {
1034 caption
: L
.tr('Start on boot'),
1039 var pr
= section
.taboption('general', L
.cbi
.ListValue
, 'proto', {
1040 caption
: L
.tr('Protocol')
1043 pr
.ucivalue = function(sid
) {
1044 return iface
.get('proto') || 'none';
1047 var ok
= section
.taboption('general', L
.cbi
.ButtonValue
, '_confirm', {
1048 caption
: L
.tr('Really switch?'),
1049 description
: L
.tr('Changing the protocol will clear all configuration for this interface!'),
1050 text
: L
.tr('Change protocol')
1053 ok
.on('click', function(ev
) {
1054 iface
.changeProtocol(pr
.formvalue(ev
.data
.sid
));
1055 iface
.createForm(mapwidget
).show();
1058 var protos
= L
.network
.getProtocols();
1060 for (var i
= 0; i
< protos
.length
; i
++)
1061 pr
.value(protos
[i
].name
, protos
[i
].description
);
1063 proto
.populateForm(section
, iface
);
1067 var br
= section
.taboption('physical', L
.cbi
.CheckboxValue
, 'type', {
1068 caption
: L
.tr('Network bridge'),
1069 description
: L
.tr('Merges multiple devices into one logical bridge'),
1076 section
.taboption('physical', L
.cbi
.DeviceList
, '__iface_multi', {
1077 caption
: L
.tr('Devices'),
1080 }).depends('type', true);
1082 section
.taboption('physical', L
.cbi
.DeviceList
, '__iface_single', {
1083 caption
: L
.tr('Device'),
1086 }).depends('type', false);
1088 var mac
= section
.taboption('physical', L
.cbi
.InputValue
, 'macaddr', {
1089 caption
: L
.tr('Override MAC'),
1091 placeholder
: device
? device
.getMACAddress() : undefined,
1095 mac
.ucivalue = function(sid
)
1098 return device
.get('macaddr');
1100 return this.callSuper('ucivalue', sid
);
1103 mac
.save = function(sid
)
1105 if (!this.changed(sid
))
1109 device
.set('macaddr', this.formvalue(sid
));
1111 this.callSuper('set', sid
);
1117 section
.taboption('physical', L
.cbi
.InputValue
, 'mtu', {
1118 caption
: L
.tr('Override MTU'),
1120 placeholder
: device
? device
.getMTU() : undefined,
1121 datatype
: 'range(1, 9000)'
1124 section
.taboption('physical', L
.cbi
.InputValue
, 'metric', {
1125 caption
: L
.tr('Override Metric'),
1128 datatype
: 'uinteger'
1131 for (var field
in section
.fields
)
1139 for (var i
= 0; i
< protos
.length
; i
++)
1140 if (protos
[i
].name
!= proto
.protocol
)
1141 section
.fields
[field
].depends('proto', protos
[i
].name
);
1145 section
.fields
[field
].depends('proto', proto
.protocol
, true);
1151 createForm: function(mapwidget
)
1156 mapwidget
= L
.cbi
.Map
;
1158 var map
= new mapwidget('network', {
1159 prepare
: self
.createFormPrepareCallback
,
1167 network_class
.Device
= Class
.extend({
1170 sta
: L
.tr('Client'),
1171 adhoc
: L
.tr('Ad-Hoc'),
1172 monitor
: L
.tr('Monitor'),
1173 wds
: L
.tr('Static WDS')
1176 getStatus: function(key
)
1178 var s
= L
.network
.rpcCache
.devstate
[this.options
.ifname
];
1181 return key
? s
[key
] : s
;
1188 var sid
= this.options
.sid
;
1189 var pkg
= (this.options
.kind
== 'wifi') ? 'wireless' : 'network';
1190 return L
.uci
.get(pkg
, sid
, key
);
1193 set: function(key
, val
)
1195 var sid
= this.options
.sid
;
1196 var pkg
= (this.options
.kind
== 'wifi') ? 'wireless' : 'network';
1197 return L
.uci
.set(pkg
, sid
, key
, val
);
1202 if (typeof(this.options
.type
) == 'undefined')
1203 this.options
.type
= 1;
1205 if (typeof(this.options
.kind
) == 'undefined')
1206 this.options
.kind
= 'ethernet';
1208 if (typeof(this.options
.networks
) == 'undefined')
1209 this.options
.networks
= [ ];
1214 return this.options
.ifname
;
1217 description: function()
1219 switch (this.options
.kind
)
1222 return L
.tr('Alias for network "%s"').format(this.options
.ifname
.substring(1));
1225 return L
.tr('Network bridge');
1228 return L
.tr('Network device');
1231 switch (this.options
.type
)
1233 case 1: /* tuntap */
1234 return L
.tr('TAP device');
1237 return L
.tr('PPP tunnel');
1239 case 768: /* IP-IP Tunnel */
1240 return L
.tr('IP-in-IP tunnel');
1242 case 769: /* IP6-IP6 Tunnel */
1243 return L
.tr('IPv6-in-IPv6 tunnel');
1245 case 776: /* IPv6-in-IPv4 */
1246 return L
.tr('IPv6-over-IPv4 tunnel');
1249 case 778: /* GRE over IP */
1250 return L
.tr('GRE-over-IP tunnel');
1253 return L
.tr('Tunnel device');
1257 return L
.tr('VLAN %d on %s').format(this.options
.vid
, this.options
.vsw
.model
);
1260 var o
= this.options
;
1261 return L
.trc('(Wifi-Mode) "(SSID)" on (radioX)', '%s "%h" on %s').format(
1262 o
.wmode
? this.wifiModeStrings
[o
.wmode
] : L
.tr('Unknown mode'),
1263 o
.wssid
|| '?', o
.wdev
1267 return L
.tr('Unknown device');
1272 var kind
= this.options
.kind
;
1274 if (kind
== 'alias')
1277 if (typeof(up
) == 'undefined')
1280 return L
.globals
.resource
+ '/icons/%s%s.png'.format(kind
, up
? '' : '_disabled');
1285 var l
= L
.network
.rpcCache
.devlist
;
1287 for (var i
= 0; i
< l
.length
; i
++)
1288 if (l
[i
].device
== this.options
.ifname
)
1289 return (l
[i
].is_up
=== true);
1296 return (this.options
.kind
== 'alias');
1299 isBridge: function()
1301 return (this.options
.kind
== 'bridge');
1304 isBridgeable: function()
1306 return (this.options
.type
== 1 && this.options
.kind
!= 'bridge');
1309 isWireless: function()
1311 return (this.options
.kind
== 'wifi');
1314 isInNetwork: function(net
)
1316 if (!(net
instanceof L
.network
.Interface
))
1317 net
= L
.network
.getInterface(net
);
1321 if (net
.options
.l3dev
== this.options
.ifname
||
1322 net
.options
.l2dev
== this.options
.ifname
)
1325 var dev
= L
.network
.deviceObjects
[net
.options
.l2dev
];
1326 if (dev
&& dev
.kind
== 'bridge' && dev
.ports
)
1327 return ($.inArray(this.options
.ifname
, dev
.ports
) > -1);
1335 var dev
= L
.network
.rpcCache
.devstate
[this.options
.ifname
];
1336 if (dev
&& !isNaN(dev
.mtu
))
1342 getMACAddress: function()
1344 if (this.options
.type
!= 1)
1347 var dev
= L
.network
.rpcCache
.devstate
[this.options
.ifname
];
1348 if (dev
&& dev
.macaddr
)
1349 return dev
.macaddr
.toUpperCase();
1354 getInterfaces: function()
1356 return L
.network
.getInterfacesByDevice(this.options
.name
);
1359 getStatistics: function()
1361 var s
= this.getStatus('statistics') || { };
1363 rx_bytes
: (s
.rx_bytes
|| 0),
1364 tx_bytes
: (s
.tx_bytes
|| 0),
1365 rx_packets
: (s
.rx_packets
|| 0),
1366 tx_packets
: (s
.tx_packets
|| 0)
1370 getTrafficHistory: function()
1372 var def
= new Array(120);
1374 for (var i
= 0; i
< 120; i
++)
1377 var h
= L
.network
.rpcCache
.bwstate
[this.options
.ifname
] || { };
1379 rx_bytes
: (h
.rx_bytes
|| def
),
1380 tx_bytes
: (h
.tx_bytes
|| def
),
1381 rx_packets
: (h
.rx_packets
|| def
),
1382 tx_packets
: (h
.tx_packets
|| def
)
1386 removeFromInterface: function(iface
)
1388 if (!(iface
instanceof L
.network
.Interface
))
1389 iface
= L
.network
.getInterface(iface
);
1394 var ifnames
= L
.toArray(iface
.get('ifname'));
1395 if ($.inArray(this.options
.ifname
, ifnames
) > -1)
1396 iface
.set('ifname', L
.filterArray(ifnames
, this.options
.ifname
));
1398 if (this.options
.kind
!= 'wifi')
1401 var networks
= L
.toArray(this.get('network'));
1402 if ($.inArray(iface
.name(), networks
) > -1)
1403 this.set('network', L
.filterArray(networks
, iface
.name()));
1406 attachToInterface: function(iface
)
1408 if (!(iface
instanceof L
.network
.Interface
))
1409 iface
= L
.network
.getInterface(iface
);
1414 if (this.options
.kind
!= 'wifi')
1416 var ifnames
= L
.toArray(iface
.get('ifname'));
1417 if ($.inArray(this.options
.ifname
, ifnames
) < 0)
1419 ifnames
.push(this.options
.ifname
);
1420 iface
.set('ifname', (ifnames
.length
> 1) ? ifnames
: ifnames
[0]);
1425 var networks
= L
.toArray(this.get('network'));
1426 if ($.inArray(iface
.name(), networks
) < 0)
1428 networks
.push(iface
.name());
1429 this.set('network', (networks
.length
> 1) ? networks
: networks
[0]);
1435 network_class
.Protocol
= network_class
.Interface
.extend({
1436 description
: '__unknown__',
1440 populateForm: function(section
, iface
)
1446 return Class
.extend(network_class
);