From patchwork Wed Apr 22 12:59:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Kolesnik X-Patchwork-Id: 463658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48F67140133 for ; Wed, 22 Apr 2015 23:00:34 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=gmail.com header.i=@gmail.com header.b=nPDFz3Ls; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 73318280445; Wed, 22 Apr 2015 14:58:48 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,FREEMAIL_FROM, HTML_MESSAGE, MIME_HTML_MOSTLY, T_DKIM_INVALID autolearn=no version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 76B60280463 for ; Wed, 22 Apr 2015 14:58:42 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .gmail. - helo: .mail-wg0-f54.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -8.5 Received: from mail-wg0-f54.google.com (mail-wg0-f54.google.com [74.125.82.54]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Wed, 22 Apr 2015 14:58:39 +0200 (CEST) Received: by wgin8 with SMTP id n8so245409656wgi.0 for ; Wed, 22 Apr 2015 05:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=JQBYynDHNVNd1M//ZXTDZlFZcI3UCFnso5QzcLzeltg=; b=nPDFz3LsePNpNdludDaFGeeRYZHBkmBA25s6rF7EKV9/AIEyBnmyRDQ6T0JaVfTRw4 FU8QlJFF5sRL71TYYIcPUEWPPtjCuN3ECGBeMqRcFScxq0rxyBk3B46JR5ZBB/OGUEnr OGvdT6M7A9FRnZ+xszblvSH4ggcOqLssvVRb6s3jb2d4S8veSG35v1OgbxGc9qmJSwyv n6Ltxk7X72yTOtMrQEvHOYuouYbd/p0+K41RQcmkZ+EFBN9GEy3cGXD3vJzRuOOsl4Pa zJl+grNdUgogdCfSaL32q7D+UFOO5QW+L/RMqp1LaLPo4q4lQf8mChcAwgHmjZaowlAA UUTA== MIME-Version: 1.0 X-Received: by 10.180.84.8 with SMTP id u8mr5769495wiy.39.1429707577675; Wed, 22 Apr 2015 05:59:37 -0700 (PDT) Received: by 10.28.86.196 with HTTP; Wed, 22 Apr 2015 05:59:37 -0700 (PDT) Date: Wed, 22 Apr 2015 15:59:37 +0300 Message-ID: From: Aleksandr Kolesnik To: jow@openwrt.org Cc: OpenWrt Development List Subject: [OpenWrt-Devel] [PATCH] luci-proto-wwan minimal support X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" Signed-off-by: Aleksandr Kolesnik --- a/contrib/package/luci/Makefile +++ b/contrib/package/luci/Makefile @@ -194,6 +194,7 @@ $(eval $(call protocol,ipv6,Support for $(eval $(call protocol,3g,Support for 3G,+PACKAGE_luci-proto-3g:comgt)) $(eval $(call protocol,hso,Support for HSO,+PACKAGE_luci-proto-hso:comgt +PACKAGE_luci-proto-hso:kmod-usb-net +PACKAGE_luci-proto-hso:kmod-usb-net-hso)) $(eval $(call protocol,relay,Support for relayd pseudo bridges,+PACKAGE_luci-proto-relay:relayd)) +$(eval $(call protocol,wwan,Support for 3G/4g wwan,+PACKAGE_luci-proto-wwan:wwan)) ### Modules ### --- a/modules/base/luasrc/model/network.lua +++ b/modules/base/luasrc/model/network.lua @@ -756,7 +756,11 @@ function protocol.ifname(self) end function protocol.proto(self) - return "none" + local p = self:_ubus("proto") + if not p then + p = "none" + end + return p end function protocol.get_i18n(self) @@ -934,7 +938,16 @@ function protocol.del_interface(self, if end function protocol.get_interface(self) - if self:is_virtual() then + if self:is_virtual() and self:proto() == "wwan" then + local ldev = self:_ubus("l3_device") + if ldev then + _tunnel[ldev] = true + return interface(ldev, self) + else + _tunnel[self:proto() .. "-" .. self.sid] = true + return interface(self:proto() .. "-" .. self.sid, self) + end + elseif self:is_virtual() then _tunnel[self:proto() .. "-" .. self.sid] = true return interface(self:proto() .. "-" .. self.sid, self) elseif self:is_bridge() then --- /dev/null +++ b/protocols/wwan/Makefile @@ -0,0 +1,2 @@ +include ../../build/config.mk +include ../../build/module.mk --- /dev/null +++ b/protocols/wwan/luasrc/model/cbi/admin_network/proto_wwan.lua @@ -0,0 +1,130 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2015 Aleksandr Kolesnik + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 +]]-- + +local map, section, net = ... + +local apn, service, pincode, username, password +local ipv6, maxwait, defaultroute, metric, peerdns, dns, + keepalive_failure, keepalive_interval, demand + +apn = section:taboption("general", Value, "apn", translate("APN")) + + +pincode = section:taboption("general", Value, "pincode", translate("PIN")) + + +username = section:taboption("general", Value, "username", translate("PAP/CHAP username")) + + +password = section:taboption("general", Value, "password", translate("PAP/CHAP password")) +password.password = true + + +if luci.model.network:has_ipv6() then + + ipv6 = section:taboption("advanced", Flag, "ipv6", + translate("Enable IPv6 negotiation on the PPP link")) + + ipv6.default = ipv6.disabled + +end + + +maxwait = section:taboption("advanced", Value, "maxwait", + translate("Modem init timeout"), + translate("Maximum amount of seconds to wait for the modem to become ready")) + +maxwait.placeholder = "20" +maxwait.datatype = "min(1)" + + +defaultroute = section:taboption("advanced", Flag, "defaultroute", + translate("Use default gateway"), + translate("If unchecked, no default route is configured")) + +defaultroute.default = defaultroute.enabled + + +metric = section:taboption("advanced", Value, "metric", + translate("Use gateway metric")) + +metric.placeholder = "0" +metric.datatype = "uinteger" +metric:depends("defaultroute", defaultroute.enabled) + + +peerdns = section:taboption("advanced", Flag, "peerdns", + translate("Use DNS servers advertised by peer"), + translate("If unchecked, the advertised DNS server addresses are ignored")) + +peerdns.default = peerdns.enabled + + +dns = section:taboption("advanced", DynamicList, "dns", + translate("Use custom DNS servers")) + +dns:depends("peerdns", "") +dns.datatype = "ipaddr" +dns.cast = "string" + + +keepalive_failure = section:taboption("advanced", Value, "_keepalive_failure", + translate("LCP echo failure threshold"), + translate("Presume peer to be dead after given amount of LCP echo failures, use 0 to ignore failures")) + +function keepalive_failure.cfgvalue(self, section) + local v = m:get(section, "keepalive") + if v and #v > 0 then + return tonumber(v:match("^(%d+)[ ,]+%d+") or v) + end +end + +function keepalive_failure.write() end +function keepalive_failure.remove() end + +keepalive_failure.placeholder = "0" +keepalive_failure.datatype = "uinteger" + + +keepalive_interval = section:taboption("advanced", Value, "_keepalive_interval", + translate("LCP echo interval"), + translate("Send LCP echo requests at the given interval in seconds, only effective in conjunction with failure threshold")) + +function keepalive_interval.cfgvalue(self, section) + local v = m:get(section, "keepalive") + if v and #v > 0 then + return tonumber(v:match("^%d+[ ,]+(%d+)")) + end +end + +function keepalive_interval.write(self, section, value) + local f = tonumber(keepalive_failure:formvalue(section)) or 0 + local i = tonumber(value) or 5 + if i < 1 then i = 1 end + if f > 0 then + m:set(section, "keepalive", "%d %d" %{ f, i }) + else + m:del(section, "keepalive") + end +end + +keepalive_interval.remove = keepalive_interval.write +keepalive_interval.placeholder = "5" +keepalive_interval.datatype = "min(1)" + + +demand = section:taboption("advanced", Value, "demand", + translate("Inactivity timeout"), + translate("Close inactive connection after the given amount of seconds, use 0 to persist connection")) + +demand.placeholder = "0" +demand.datatype = "uinteger" --- /dev/null +++ b/protocols/wwan/luasrc/model/network/proto_wwan.lua @@ -0,0 +1,57 @@ +--[[ +LuCI - Network model - WWAN protocol extension + +Copyright 2015 Aleksandr Kolesnik + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +]]-- + +local netmod = luci.model.network + +local proto = netmod:register_protocol("wwan") + +function proto.ifname(self) + return "wwan-" .. self.sid +end + +function proto.get_i18n(self) + return luci.i18n.translate("WWAN") +end + +function proto.opkg_package(self) + return "wwan" +end + +function proto.is_installed(self) + return nixio.fs.access("/lib/netifd/proto/wwan.sh") +end + +function proto.is_floating(self) + return true +end + +function proto.is_virtual(self) + return true +end + +function proto.get_interfaces(self) + return nil +end + +function proto.contains_interface(self,ifc) + return (netmod:ifnameof(ifc) == self:ifname()) +end + +netmod:register_pattern_virtual("^wwan-%%w") +