diff options
author | Ian Leonard <antonlacon@gmail.com> | 2014-08-10 01:09:06 -0700 |
---|---|---|
committer | Ian Leonard <antonlacon@gmail.com> | 2014-08-10 01:09:06 -0700 |
commit | f5a1d1bba66d293486dc74bbc1de767dc7054013 (patch) | |
tree | 7685a0f8f7e195e22d93ab8ea8825a92d117e229 /net | |
parent | d55f37ea1a920beea420a50f4104a3d4109b095a (diff) | |
parent | 048e700bfc72247e425bd5ace12d90bbc39f8599 (diff) |
Merge branch 'master' into license-updates
Signed-off-by: Ian Leonard <antonlacon@gmail.com>
Conflicts:
devel/patch/Makefile
multimedia/minidlna/Makefile
Diffstat (limited to 'net')
62 files changed, 3741 insertions, 215 deletions
diff --git a/net/dhcpcd/Makefile b/net/dhcpcd/Makefile new file mode 100644 index 000000000..9add73476 --- /dev/null +++ b/net/dhcpcd/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=dhcpcd +PKG_VERSION:=6.4.3 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=ftp://roy.marples.name/pub/dhcpcd \ + http://roy.marples.name/downloads/dhcpcd +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_MD5SUM:=b22005c131e7108ecf598b6a4ac091eb + +PKG_LICENSE:=BSD-2c +PKG_LICENSE_FILES:= + +PKG_MAINTAINER:=Roy Marples <roy@marples.name> + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/dhcpcd + SECTION:=net + CATEGORY:=Network + TITLE:=DHCPv4/IPv4LL/IPv6RS/DHCPv6 quad stack client + URL:=http://roy.marples.name/projects/dhcpcd +endef + +define Package/dhcpcd/description + DHCPv4, IPv6RS and DHCPv6 client with IPv4LL support + dhcpcd is a one stop network management daemon which includes + * RFC compliant DHCPv4 and DHCPv6 clients + * DHCPv6 Prefix Delegation support + * IPv4LL (aka ZeroConf) support + * ARP address conflict resolution + * Link carrier detection + * Wireless SSID profiles + * ARP ping profiles +endef + +CONFIGURE_ARGS+= --prefix=/ --sbindir=/sbin \ + --libexecdir=/lib/dhcpcd --dbdir=/var/dhcpcd + +define Package/dhcpcd/install + $(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/dhcpcd/dhcpcd-hooks + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/dhcpcd $(1)/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/lib/dhcpcd/dhcpcd-run-hooks \ + $(1)/lib/dhcpcd/ + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/lib/dhcpcd/dhcpcd-hooks/* \ + $(1)/lib/dhcpcd/dhcpcd-hooks/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/dhcpcd.init $(1)/etc/init.d/dhcpcd + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/dhcpcd.conf $(1)/etc/dhcpcd.conf +endef + +$(eval $(call BuildPackage,dhcpcd)) diff --git a/net/dhcpcd/files/dhcpcd.init b/net/dhcpcd/files/dhcpcd.init new file mode 100755 index 000000000..2fad41dd4 --- /dev/null +++ b/net/dhcpcd/files/dhcpcd.init @@ -0,0 +1,24 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +START=30 +STOP=85 +USE_PROCD=1 + +start_service() +{ + procd_open_instance + procd_set_param command /sbin/dhcpcd -B + procd_set_param respawn + procd_close_instance +} + +reload_service() +{ + /sbin/dhcpcd -n +} diff --git a/net/ethtool/Makefile b/net/ethtool/Makefile index 1f2cea167..7fa772aed 100644 --- a/net/ethtool/Makefile +++ b/net/ethtool/Makefile @@ -8,13 +8,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ethtool -PKG_VERSION:=3.14 +PKG_VERSION:=3.15 PKG_RELEASE:=1 PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net> PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@KERNEL/software/network/ethtool -PKG_MD5SUM:=d46b809ddd672b51d7e23787ae9122e0 +PKG_MD5SUM:=e7bf0c355d2bf6ee281ebc713c5fb987 + +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILE:=COPYING PKG_FIXUP:=autoreconf PKG_INSTALL:=1 diff --git a/net/ethtool/patches/100-ixp4xx.patch b/net/ethtool/patches/100-ixp4xx.patch deleted file mode 100644 index 48c011920..000000000 --- a/net/ethtool/patches/100-ixp4xx.patch +++ /dev/null @@ -1,166 +0,0 @@ ---- a/Makefile.am -+++ b/Makefile.am -@@ -13,7 +13,7 @@ ethtool_SOURCES += \ - fec_8xx.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \ - pcnet32.c realtek.c tg3.c marvell.c vioc.c \ - smsc911x.c at76c50x-usb.c sfc.c stmmac.c \ -- sfpid.c sfpdiag.c ixgbevf.c -+ sfpid.c sfpdiag.c ixgbevf.c ixp4xx.c - endif - - TESTS = test-cmdline test-features ---- a/ethtool.c -+++ b/ethtool.c -@@ -894,6 +894,7 @@ static const struct { - { "ixgb", ixgb_dump_regs }, - { "ixgbe", ixgbe_dump_regs }, - { "ixgbevf", ixgbevf_dump_regs }, -+ { "ixp4xx", ixp4xx_dump_regs }, - { "natsemi", natsemi_dump_regs }, - { "e100", e100_dump_regs }, - { "amd8111e", amd8111e_dump_regs }, ---- a/internal.h -+++ b/internal.h -@@ -243,6 +243,9 @@ int st_gmac_dump_regs(struct ethtool_drv - /* Et131x ethernet controller */ - int et131x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); - -+/* Intel IXP4xx internal MAC */ -+int ixp4xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs); -+ - /* Rx flow classification */ - int rxclass_parse_ruleopts(struct cmd_context *ctx, - struct ethtool_rx_flow_spec *fsp); ---- /dev/null -+++ b/ixp4xx.c -@@ -0,0 +1,130 @@ -+/* -+ * Copyright (c) 2006 Christian Hohnstaed <chohnstaedt@innominate.com> -+ * This file is released under the GPLv2 -+ */ -+ -+#include <stdio.h> -+#include "internal.h" -+ -+#ifndef BIT -+#define BIT(x) (1<<x) -+#endif -+ -+#define TX_CNTRL1_TX_EN BIT(0) -+#define TX_CNTRL1_DUPLEX BIT(1) -+#define TX_CNTRL1_RETRY BIT(2) -+#define TX_CNTRL1_PAD_EN BIT(3) -+#define TX_CNTRL1_FCS_EN BIT(4) -+#define TX_CNTRL1_2DEFER BIT(5) -+#define TX_CNTRL1_RMII BIT(6) -+ -+/* TX Control Register 2 */ -+#define TX_CNTRL2_RETRIES_MASK 0xf -+ -+/* RX Control Register 1 */ -+#define RX_CNTRL1_RX_EN BIT(0) -+#define RX_CNTRL1_PADSTRIP_EN BIT(1) -+#define RX_CNTRL1_CRC_EN BIT(2) -+#define RX_CNTRL1_PAUSE_EN BIT(3) -+#define RX_CNTRL1_LOOP_EN BIT(4) -+#define RX_CNTRL1_ADDR_FLTR_EN BIT(5) -+#define RX_CNTRL1_RX_RUNT_EN BIT(6) -+#define RX_CNTRL1_BCAST_DIS BIT(7) -+ -+/* Core Control Register */ -+#define CORE_RESET BIT(0) -+#define CORE_RX_FIFO_FLUSH BIT(1) -+#define CORE_TX_FIFO_FLUSH BIT(2) -+#define CORE_SEND_JAM BIT(3) -+#define CORE_MDC_EN BIT(4) -+ -+#define MAC "%02x:%02x:%02x:%02x:%02x:%02x" -+#define MAC_DATA(d) (d)[0], (d)[1], (d)[2], (d)[3], (d)[4], (d)[5] -+ -+int ixp4xx_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs) -+{ -+ u8 *data = regs->data; -+ -+ fprintf(stdout, -+ "TXctrl: 0x%02x:0x%02x\n" -+ " Enable: %s\n" -+ " Duplex: %s\n" -+ " Retry: %s (%d)\n" -+ " Padding: %s\n" -+ " Frame check: %s\n" -+ " TX deferral: %s\n" -+ " Connection: %s\n" -+ "\n", -+ data[0], data[1], -+ data[0] & TX_CNTRL1_TX_EN ? "yes" : "no", -+ data[0] & TX_CNTRL1_DUPLEX ? "half" : "full", -+ data[0] & TX_CNTRL1_RETRY ? "enabled" : "disabled", -+ data[1] & TX_CNTRL2_RETRIES_MASK, -+ data[0] & TX_CNTRL1_PAD_EN ? "enabled" : "disabled", -+ data[0] & TX_CNTRL1_FCS_EN ? "enabled" : "disabled", -+ data[0] & TX_CNTRL1_2DEFER ? "two-part" : "one-part", -+ data[0] & TX_CNTRL1_RMII ? "RMII" : "Full MII" -+ ); -+ -+ fprintf(stdout, -+ "RXctrl: 0x%02x\n" -+ " Enable: %s\n" -+ " Pad strip: %s\n" -+ " CRC check: %s\n" -+ " Pause: %s\n" -+ " Loop: %s\n" -+ " Promiscous: %s\n" -+ " Runt frames: %s\n" -+ " Broadcast: %s\n" -+ "\n", -+ data[2], -+ data[2] & RX_CNTRL1_RX_EN ? "yes" : "no", -+ data[2] & RX_CNTRL1_PADSTRIP_EN ? "enabled" : "disabled", -+ data[2] & RX_CNTRL1_CRC_EN ? "enabled" : "disabled", -+ data[2] & RX_CNTRL1_PAUSE_EN ? "enabled" : "disabled", -+ data[2] & RX_CNTRL1_LOOP_EN ? "enabled" : "disabled", -+ data[2] & RX_CNTRL1_ADDR_FLTR_EN ? "disabled" : "enabled", -+ data[2] & RX_CNTRL1_RX_RUNT_EN ? "forward" : "discard", -+ data[2] & RX_CNTRL1_BCAST_DIS ? "disabled" : "enabled" -+ ); -+ fprintf(stdout, -+ "Core control: 0x%02x\n" -+ " Core state: %s\n" -+ " RX fifo: %s\n" -+ " TX fifo: %s\n" -+ " Send jam: %s\n" -+ " MDC clock %s\n" -+ "\n", -+ data[32], -+ data[32] & CORE_RESET ? "reset" : "normal operation", -+ data[32] & CORE_RX_FIFO_FLUSH ? "flush" : "ok", -+ data[32] & CORE_TX_FIFO_FLUSH ? "flush" : "ok", -+ data[32] & CORE_SEND_JAM ? "yes" : "no", -+ data[32] & CORE_MDC_EN ? "output" : "input" -+ ); -+ fprintf(stdout, -+ "MAC addresses: \n" -+ " Multicast mask: " MAC "\n" -+ " Multicast address: " MAC "\n" -+ " Unicast address: " MAC "\n" -+ "\n", -+ MAC_DATA(data+13), MAC_DATA(data+19), MAC_DATA(data+26) -+ ); -+ fprintf(stdout, -+ "Random seed: 0x%02x\n" -+ "Threshold empty: %3d\n" -+ "Threshold full: %3d\n" -+ "TX buffer size: %3d\n" -+ "TX deferral: %3d\n" -+ "RX deferral: %3d\n" -+ "TX two deferral 1: %3d\n" -+ "TX two deferral 2: %3d\n" -+ "Slot time: %3d\n" -+ "Internal clock: %3d\n" -+ "\n", -+ data[4], data[5], data[6], data[7], data[8], data[9], -+ data[10], data[11], data[12], data[25] -+ ); -+ -+ return 0; -+} diff --git a/net/fastd/Makefile b/net/fastd/Makefile index 0629cd7b6..e2fca698e 100644 --- a/net/fastd/Makefile +++ b/net/fastd/Makefile @@ -16,6 +16,9 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/75 PKG_MD5SUM:=34f6bdebd0410a1fba7c8fd06fff7a05 +PKG_LICENSE:=BSD-2-Clause +PKG_LICENSE_FILE:=COPYRIGHT + PKG_CONFIG_DEPENDS:=\ CONFIG_FASTD_ENABLE_METHOD_CIPHER_TEST \ CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC \ diff --git a/net/freeradius2/Makefile b/net/freeradius2/Makefile index 194913d17..4eddb26b2 100644 --- a/net/freeradius2/Makefile +++ b/net/freeradius2/Makefile @@ -18,6 +18,7 @@ PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org> PKG_BUILD_DIR:=$(BUILD_DIR)/freeradius-server-$(PKG_VERSION) PKG_FIXUP:=autoreconf +PKG_CHECK_FORMAT_SECURITY:=0 PKG_CONFIG_DEPENDS := \ FREERADIUS_OPENSSL \ @@ -415,14 +416,14 @@ PKG_DICTIONARIES:= \ microsoft \ wispr \ -#ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius2-mod-ldap),) -# CONFIGURE_ARGS+= \ -# --with-rlm_ldap-include-dir="$(STAGING_DIR)/usr/include" \ -# --with-rlm_ldap-lib-dir="$(STAGING_DIR)/usr/lib" -# CONFIGURE_LIBS+= -lcrypto -lssl -#else +ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius2-mod-ldap),) + CONFIGURE_ARGS+= \ + --with-rlm_ldap-include-dir="$(STAGING_DIR)/usr/include" \ + --with-rlm_ldap-lib-dir="$(STAGING_DIR)/usr/lib" + CONFIGURE_LIBS+= -lcrypto -lssl +else CONFIGURE_ARGS+= --without-rlm_ldap -#endif +endif #ifneq ($(SDK)$(CONFIG_PACKAGE_freeradius2-mod-sql-mysql),) # CONFIGURE_ARGS+= \ @@ -612,7 +613,7 @@ $(eval $(call BuildPlugin,freeradius2-mod-exec,rlm_exec,modules/exec modules/ech $(eval $(call BuildPlugin,freeradius2-mod-attr-rewrite,rlm_attr_rewrite,modules/attr_rewrite,modules,)) $(eval $(call BuildPlugin,freeradius2-mod-files,rlm_files,acct_users preproxy_users users modules/files,modules,)) $(eval $(call BuildPlugin,freeradius2-mod-passwd,rlm_passwd,modules/passwd,modules,)) -#$(eval $(call BuildPlugin,freeradius2-mod-ldap,rlm_ldap,ldap.attrmap modules/ldap,modules,)) +$(eval $(call BuildPlugin,freeradius2-mod-ldap,rlm_ldap,ldap.attrmap modules/ldap,modules,)) $(eval $(call BuildPlugin,freeradius2-mod-mschap,rlm_mschap,modules/mschap,modules,)) $(eval $(call BuildPlugin,freeradius2-mod-pap,rlm_pap,modules/pap,modules,)) $(eval $(call BuildPlugin,freeradius2-mod-preprocess,rlm_preprocess,hints huntgroups modules/preprocess,modules,)) diff --git a/net/horst/Makefile b/net/horst/Makefile new file mode 100644 index 000000000..e746abea7 --- /dev/null +++ b/net/horst/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=horst +PKG_VERSION:=4.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-git.tar.gz +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_URL:=git://br1.einfach.org/horst +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=version-4.0 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/horst + SECTION:=net + CATEGORY:=Network + SUBMENU:=wireless + DEPENDS:=+libncurses + MAINTAINER:=Bruno Randolf <br1@einfach.org> + TITLE:=Highly Optimized 802.11 Radio Scanning Tool + URL:=http://br1.einfach.org/tech/horst/ +endef + +define Package/horst/description + [horst] is a scanning and analysis tool for 802.11 wireless networks + and especially IBSS (ad-hoc) mode and mesh networks (OLSR). +endef + +define Package/horst/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/horst $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/horst.sh $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,horst)) diff --git a/net/mwan3-luci/Makefile b/net/mwan3-luci/Makefile new file mode 100644 index 000000000..465363326 --- /dev/null +++ b/net/mwan3-luci/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-mwan3 +PKG_VERSION:=1.3 +PKG_RELEASE:=1 +PKG_MAINTAINER:=Aedan Renner <chipdankly@gmail.com> +PKG_LICENSE:=GPLv2 + +include $(INCLUDE_DIR)/package.mk + +define Package/luci-app-mwan3 + SECTION:=LuCI + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI support for the MWAN3 multiwan hotplug script + DEPENDS:=+mwan3 + PKGARCH:=all + MAINTAINER:=Aedan Renner <chipdankly@gmail.com> +endef + +define Package/luci-app-mwan3/description +Hotplug script which makes configuration of multiple WAN interfaces simple and manageable +With loadbalancing/failover support for up to 250 WAN interfaces, connection tracking and an easy to manage traffic ruleset +endef + +define Build/Compile +endef + +define Package/luci-app-mwan3/install + $(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,luci-app-mwan3)) diff --git a/net/mwan3-luci/files/etc/hotplug.d/iface/16-mwan3custombak b/net/mwan3-luci/files/etc/hotplug.d/iface/16-mwan3custombak new file mode 100644 index 000000000..9bd0beeff --- /dev/null +++ b/net/mwan3-luci/files/etc/hotplug.d/iface/16-mwan3custombak @@ -0,0 +1,38 @@ +#!/bin/sh + +# to enable this script uncomment the case loop at the bottom +# to report MWAN3 status on interface up/down events modify the lines in the send_reportdata function + +send_alert() +{ + # $1 stores the mwan3 status information + # insert your code here to send the contents of $1 + echo "$1" +} + +gather_event_info() +{ + # create event information message + local EVENT_INFO="Interface [ "$INTERFACE" ($DEVICE) ] on router [ "$(uci get -p /var/state system.@system[0].hostname)" ] has triggered an [ "$ACTION" ] hotplug event on "$(date)"" + + # get current interface, policy and rule status + local CURRENT_STATUS="$(mwan3 status)" + + # get last 50 mwan3 systemlog messages + local MWAN3_LOG="$(echo -e "Last 50 MWAN3 systemlog entries. Newest entries sorted at the top:\n$(logread | grep mwan3 | tail -n 50 | sed 'x;1!H;$!d;x')")" + + # pass event info to send_alert function + send_alert "$(echo -e "$EVENT_INFO\n\n$CURRENT_STATUS\n\n$MWAN3_LOG")" +} + +#case "$ACTION" in +# ifup) +# gather_event_info +# ;; +# +# ifdown) +# gather_event_info +# ;; +#esac + +exit 0 diff --git a/net/mwan3-luci/files/etc/uci-defaults/mwan3 b/net/mwan3-luci/files/etc/uci-defaults/mwan3 new file mode 100755 index 000000000..a19d4cb25 --- /dev/null +++ b/net/mwan3-luci/files/etc/uci-defaults/mwan3 @@ -0,0 +1,14 @@ +#!/bin/sh + +# delete existing mwan3 ucitrack entry and add new entry +uci -q batch <<-EOF >/dev/null + del ucitrack.@mwan3[-1] + add ucitrack mwan3 + set ucitrack.@mwan3[-1].exec="/etc/init.d/mwan3 restart" + commit ucitrack +EOF + +# make controller file addition take effect without system restart +rm -rf /tmp/luci-indexcache /tmp/luci-modulecache + +exit 0 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/controller/mwan3.lua b/net/mwan3-luci/files/usr/lib/lua/luci/controller/mwan3.lua new file mode 100644 index 000000000..13ff0902e --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/controller/mwan3.lua @@ -0,0 +1,355 @@ +module("luci.controller.mwan3", package.seeall) + +sys = require "luci.sys" +ut = require "luci.util" + +function index() + if not nixio.fs.access("/etc/config/mwan3") then + return + end + + entry({"admin", "network", "mwan3"}, + alias("admin", "network", "mwan3", "overview"), + _("Load Balancing"), 600) + + entry({"admin", "network", "mwan3", "overview"}, + alias("admin", "network", "mwan3", "overview", "over_iface"), + _("Overview"), 10) + entry({"admin", "network", "mwan3", "overview", "over_iface"}, + template("mwan3/mwan3_over_interface")) + entry({"admin", "network", "mwan3", "overview", "iface_status"}, + call("mwan3_iface_status")) + entry({"admin", "network", "mwan3", "overview", "over_detail"}, + template("mwan3/mwan3_over_detail")) + entry({"admin", "network", "mwan3", "overview", "detail_status"}, + call("mwan3_detail_status")) + + entry({"admin", "network", "mwan3", "configuration"}, + alias("admin", "network", "mwan3", "configuration", "interface"), + _("Configuration"), 20) + entry({"admin", "network", "mwan3", "configuration", "interface"}, + arcombine(cbi("mwan3/mwan3_interface"), cbi("mwan3/mwan3_interfaceconfig")), + _("Interfaces"), 10).leaf = true + entry({"admin", "network", "mwan3", "configuration", "member"}, + arcombine(cbi("mwan3/mwan3_member"), cbi("mwan3/mwan3_memberconfig")), + _("Members"), 20).leaf = true + entry({"admin", "network", "mwan3", "configuration", "policy"}, + arcombine(cbi("mwan3/mwan3_policy"), cbi("mwan3/mwan3_policyconfig")), + _("Policies"), 30).leaf = true + entry({"admin", "network", "mwan3", "configuration", "rule"}, + arcombine(cbi("mwan3/mwan3_rule"), cbi("mwan3/mwan3_ruleconfig")), + _("Rules"), 40).leaf = true + + entry({"admin", "network", "mwan3", "advanced"}, + alias("admin", "network", "mwan3", "advanced", "hotplug"), + _("Advanced"), 100) + entry({"admin", "network", "mwan3", "advanced", "hotplug"}, + form("mwan3/mwan3_adv_hotplug")) + entry({"admin", "network", "mwan3", "advanced", "mwan3"}, + form("mwan3/mwan3_adv_mwan3")) + entry({"admin", "network", "mwan3", "advanced", "network"}, + form("mwan3/mwan3_adv_network")) + entry({"admin", "network", "mwan3", "advanced", "diag"}, + template("mwan3/mwan3_adv_diagnostics")) + entry({"admin", "network", "mwan3", "advanced", "diag_display"}, + call("mwan3_diag_data"), nil).leaf = true + entry({"admin", "network", "mwan3", "advanced", "tshoot"}, + template("mwan3/mwan3_adv_troubleshoot")) + entry({"admin", "network", "mwan3", "advanced", "tshoot_display"}, + call("mwan3_tshoot_data")) +end + +function mwan3_get_iface_status(rulenum, ifname) + if ut.trim(sys.exec("uci get -p /var/state mwan3." .. ifname .. ".enabled")) == "1" then + if ut.trim(sys.exec("ip route list table " .. rulenum)) ~= "" then + if ut.trim(sys.exec("uci get -p /var/state mwan3." .. ifname .. ".track_ip")) ~= "" then + return "on" + else + return "nm" + end + else + return "off" + end + else + return "ne" + end +end + +function mwan3_get_iface() + local rulenum, str = 0, "" + uci.cursor():foreach("mwan3", "interface", + function (section) + rulenum = rulenum+1 + str = str .. section[".name"] .. "[" .. mwan3_get_iface_status(rulenum, section[".name"]) .. "]" + end + ) + return str +end + +function mwan3_iface_status() + local ntm = require "luci.model.network".init() + + local rv = { } + + -- overview status + local statstr = mwan3_get_iface() + if statstr ~= "" then + rv.wans = { } + wansid = {} + + for wanname, ifstat in string.gfind(statstr, "([^%[]+)%[([^%]]+)%]") do + local wanifname = ut.trim(sys.exec("uci get -p /var/state network." .. wanname .. ".ifname")) + if wanifname == "" then + wanifname = "X" + end + local wanlink = ntm:get_interface(wanifname) + wanlink = wanlink and wanlink:get_network() + wanlink = wanlink and wanlink:adminlink() or "#" + wansid[wanname] = #rv.wans + 1 + rv.wans[wansid[wanname]] = { name = wanname, link = wanlink, ifname = wanifname, status = ifstat } + end + end + + -- overview status log + local mwlg = ut.trim(sys.exec("logread | grep mwan3 | tail -n 50 | sed 'x;1!H;$!d;x'")) + if mwlg ~= "" then + rv.mwan3log = { } + mwlog = {} + mwlog[mwlg] = #rv.mwan3log + 1 + rv.mwan3log[mwlog[mwlg]] = { mwanlog = mwlg } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end + +function mwan3_detail_status() + local rv = { } + + -- detailed mwan3 status + local dst = ut.trim(sys.exec("mwan3 status")) + if dst ~= "" then + rv.mwan3dst = { } + dstat = {} + dstat[dst] = #rv.mwan3dst + 1 + rv.mwan3dst[dstat[dst]] = { detailstat = dst } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end + +function mwan3_diag_data(iface, tool, alt) + function get_ifnum() + local num = 0 + uci.cursor():foreach("mwan3", "interface", + function (section) + num = num+1 + if section[".name"] == iface then + ifnum = num + end + end + ) + end + + local rv = { } + + local res = "" + if tool == "service" then + os.execute("mwan3 " .. alt) + if alt == "restart" then + res = "MWAN3 restarted" + elseif alt == "stop" then + res = "MWAN3 stopped" + else + res = "MWAN3 started" + end + else + local ifdev = ut.trim(sys.exec("uci get -p /var/state network." .. iface .. ".ifname")) + if ifdev ~= "" then + if tool == "ping" then + local gateway = ut.trim(sys.exec("route -n | awk -F' ' '{ if ($8 == \"" .. ifdev .. "\" && $1 == \"0.0.0.0\") print $2 }'")) + if gateway ~= "" then + if alt == "gateway" then + local cmd = "ping -c 3 -W 2 -I " .. ifdev .. " " .. gateway + res = cmd .. "\n\n" .. sys.exec(cmd) + else + local str = ut.trim(sys.exec("uci get -p /var/state mwan3." .. iface .. ".track_ip")) + if str ~= "" then + for z in str:gmatch("[^ ]+") do + local cmd = "ping -c 3 -W 2 -I " .. ifdev .. " " .. z + res = res .. cmd .. "\n\n" .. sys.exec(cmd) .. "\n\n" + end + else + res = "No tracking IP addresses configured on " .. iface + end + end + else + res = "No default gateway for " .. iface .. " found. Default route does not exist or is configured incorrectly" + end + elseif tool == "rulechk" then + get_ifnum() + local rule1 = sys.exec("ip rule | grep $(echo $((" .. ifnum .. " + 1000)))") + local rule2 = sys.exec("ip rule | grep $(echo $((" .. ifnum .. " + 2000)))") + if rule1 ~= "" and rule2 ~= "" then + res = "All required interface IP rules found:\n\n" .. rule1 .. rule2 + elseif rule1 ~= "" or rule2 ~= "" then + res = "Missing 1 of the 2 required interface IP rules\n\n\nRules found:\n\n" .. rule1 .. rule2 + else + res = "Missing both of the required interface IP rules" + end + elseif tool == "routechk" then + get_ifnum() + local table = sys.exec("ip route list table " .. ifnum) + if table ~= "" then + res = "Interface routing table " .. ifnum .. " was found:\n\n" .. table + else + res = "Missing required interface routing table " .. ifnum + end + elseif tool == "hotplug" then + if alt == "ifup" then + os.execute("mwan3 ifup " .. iface) + res = "Hotplug ifup sent to interface " .. iface .. "..." + else + os.execute("mwan3 ifdown " .. iface) + res = "Hotplug ifdown sent to interface " .. iface .. "..." + end + end + else + res = "Unable to perform diagnostic tests on " .. iface .. ". There is no physical or virtual device associated with this interface" + end + end + if res ~= "" then + res = ut.trim(res) + rv.diagres = { } + dres = {} + dres[res] = #rv.diagres + 1 + rv.diagres[dres[res]] = { diagresult = res } + end + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end + +function mwan3_tshoot_data() + local rv = { } + + -- software versions + local wrtrelease = ut.trim(luci.version.distversion) + if wrtrelease ~= "" then + wrtrelease = "OpenWrt - " .. wrtrelease + else + wrtrelease = "OpenWrt - unknown" + end + local lucirelease = ut.trim(luci.version.luciversion) + if lucirelease ~= "" then + lucirelease = "\nLuCI - " .. lucirelease + else + lucirelease = "\nLuCI - unknown" + end + local mwan3version = ut.trim(sys.exec("opkg info mwan3 | grep Version | awk -F' ' '{ print $2 }'")) + if mwan3version ~= "" then + mwan3version = "\n\nmwan3 - " .. mwan3version + else + mwan3version = "\nmwan3 - unknown" + end + local mwan3lversion = ut.trim(sys.exec("opkg info luci-app-mwan3 | grep Version | awk -F' ' '{ print $2 }'")) + if mwan3lversion ~= "" then + mwan3lversion = "\nluci-app-mwan3 - " .. mwan3lversion + else + mwan3lversion = "\nluci-app-mwan3 - unknown" + end + local softrev = wrtrelease .. lucirelease .. mwan3version .. mwan3lversion + rv.mw3ver = { } + mwv = {} + mwv[softrev] = #rv.mw3ver + 1 + rv.mw3ver[mwv[softrev]] = { mwan3v = softrev } + + -- mwan3 config + local mwcg = ut.trim(sys.exec("cat /etc/config/mwan3")) + if mwcg == "" then + mwcg = "No data found" + end + rv.mwan3config = { } + mwan3cfg = {} + mwan3cfg[mwcg] = #rv.mwan3config + 1 + rv.mwan3config[mwan3cfg[mwcg]] = { mwn3cfg = mwcg } + + -- network config + local netcg = ut.trim(sys.exec("cat /etc/config/network | sed -e 's/.*username.*/ USERNAME HIDDEN/' -e 's/.*password.*/ PASSWORD HIDDEN/'")) + if netcg == "" then + netcg = "No data found" + end + rv.netconfig = { } + ncfg = {} + ncfg[netcg] = #rv.netconfig + 1 + rv.netconfig[ncfg[netcg]] = { netcfg = netcg } + + -- ifconfig + local ifcg = ut.trim(sys.exec("ifconfig")) + if ifcg == "" then + ifcg = "No data found" + end + rv.ifconfig = { } + icfg = {} + icfg[ifcg] = #rv.ifconfig + 1 + rv.ifconfig[icfg[ifcg]] = { ifcfg = ifcg } + + -- route -n + local routeshow = ut.trim(sys.exec("route -n")) + if routeshow == "" then + routeshow = "No data found" + end + rv.rtshow = { } + rshw = {} + rshw[routeshow] = #rv.rtshow + 1 + rv.rtshow[rshw[routeshow]] = { iprtshow = routeshow } + + -- ip rule show + local ipr = ut.trim(sys.exec("ip rule show")) + if ipr == "" then + ipr = "No data found" + end + rv.iprule = { } + ipruleid = {} + ipruleid[ipr] = #rv.iprule + 1 + rv.iprule[ipruleid[ipr]] = { rule = ipr } + + -- ip route list table 1-250 + local routelisting, rlstr = ut.trim(sys.exec("ip rule | sed 's/://g' | awk -F' ' '$1>=2001 && $1<=2250' | awk -F' ' '{ print $NF }'")), "" + if routelisting ~= "" then + for line in routelisting:gmatch("[^\r\n]+") do + rlstr = rlstr .. line .. "\n" .. sys.exec("ip route list table " .. line) + end + rlstr = ut.trim(rlstr) + else + rlstr = "No data found" + end + rv.routelist = { } + rtlist = {} + rtlist[rlstr] = #rv.routelist + 1 + rv.routelist[rtlist[rlstr]] = { iprtlist = rlstr } + + -- default firewall output policy + local defout = ut.trim(sys.exec("uci get -p /var/state firewall.@defaults[0].output")) + if defout == "" then + defout = "No data found" + end + rv.fidef = { } + fwdf = {} + fwdf[defout] = #rv.fidef + 1 + rv.fidef[fwdf[defout]] = { firedef = defout } + + -- iptables + local iptbl = ut.trim(sys.exec("iptables -L -t mangle -v -n")) + if iptbl == "" then + iptbl = "No data found" + end + rv.iptables = { } + tables = {} + tables[iptbl] = #rv.iptables + 1 + rv.iptables[tables[iptbl]] = { iptbls = iptbl } + + luci.http.prepare_content("application/json") + luci.http.write_json(rv) +end diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_hotplug.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_hotplug.lua new file mode 100644 index 000000000..93e125cf3 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_hotplug.lua @@ -0,0 +1,55 @@ +-- ------ hotplug script configuration ------ -- + +fs = require "nixio.fs" +sys = require "luci.sys" +ut = require "luci.util" + +script = "/etc/hotplug.d/iface/16-mwan3custom" +scriptbak = "/etc/hotplug.d/iface/16-mwan3custombak" + +if luci.http.formvalue("cbid.luci.1._restorebak") then -- restore button has been clicked + luci.http.redirect(luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug") .. "?restore=yes") +elseif luci.http.formvalue("restore") == "yes" then -- restore script from backup + os.execute("cp -f " .. scriptbak .. " " .. script) +end + + +m5 = SimpleForm("luci", nil) + m5:append(Template("mwan3/mwan3_adv_hotplug")) -- highlight current tab + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/hotplug.d/iface/16-mwan3custom<br />" .. + "This is useful for running system commands and/or scripts based on interface ifup or ifdown hotplug events<br /><br />" .. + "Notes:<br />" .. + "The first line of the script must be "#!/bin/sh" without quotes<br />" .. + "Lines beginning with # are comments and are not executed<br /><br />" .. + "Available variables:<br />" .. + "$ACTION is the hotplug event (ifup, ifdown)<br />" .. + "$INTERFACE is the interface name (wan1, wan2, etc.)<br />" .. + "$DEVICE is the device name attached to the interface (eth0.1, eth1, etc.)")) + + +restore = f:option(Button, "_restorebak", translate("Restore default hotplug script")) + restore.inputtitle = translate("Restore...") + restore.inputstyle = "apply" + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + local hps = fs.readfile(script) + if not hps or hps == "" then -- if script does not exist or is blank restore from backup + sys.call("cp -f " .. scriptbak .. " " .. script) + return fs.readfile(script) + else + return hps + end + end + + function t.write(self, section, data) -- format and write new data to script + return fs.writefile(script, ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_mwan3.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_mwan3.lua new file mode 100644 index 000000000..9eb0df52c --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_mwan3.lua @@ -0,0 +1,32 @@ +-- ------ mwan3 configuration ------ -- + +ut = require "luci.util" + +mwan3file = "/etc/config/mwan3" + + +m5 = SimpleForm("luci", nil) + m5:append(Template("mwan3/mwan3_adv_mwan3")) -- highlight current tab + + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/config/mwan3")) + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + return nixio.fs.readfile(mwan3file) or "" + end + + function t.write(self, section, data) -- format and write new data to script + return nixio.fs.writefile(mwan3file, "\n" .. ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function f.handle(self, state, data) + return true + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_network.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_network.lua new file mode 100644 index 000000000..fee6a07d2 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_adv_network.lua @@ -0,0 +1,32 @@ +-- ------ network configuration ------ -- + +ut = require "luci.util" + +netfile = "/etc/config/network" + + +m5 = SimpleForm("networkconf", nil) + m5:append(Template("mwan3/mwan3_adv_network")) -- highlight current tab + + +f = m5:section(SimpleSection, nil, + translate("This section allows you to modify the contents of /etc/config/network")) + +t = f:option(TextValue, "lines") + t.rmempty = true + t.rows = 20 + + function t.cfgvalue() + return nixio.fs.readfile(netfile) or "" + end + + function t.write(self, section, data) -- format and write new data to script + return nixio.fs.writefile(netfile, "\n" .. ut.trim(data:gsub("\r\n", "\n")) .. "\n") + end + + function f.handle(self, state, data) + return true + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interface.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interface.lua new file mode 100644 index 000000000..3d504a24f --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interface.lua @@ -0,0 +1,266 @@ +-- ------ extra functions ------ -- + +function iface_check() -- find issues with too many interfaces, reliability and metric + uci.cursor():foreach("mwan3", "interface", + function (section) + local ifname = section[".name"] + ifnum = ifnum+1 -- count number of mwan3 interfaces configured + -- create list of metrics for none and duplicate checking + local metlkp = ut.trim(sys.exec("uci get -p /var/state network." .. ifname .. ".metric")) + if metlkp == "" then + err_found = 1 + err_nomet_list = err_nomet_list .. ifname .. " " + else + metric_list = metric_list .. ifname .. " " .. metlkp .. "\n" + end + -- check if any interfaces have a higher reliability requirement than tracking IPs configured + local tipnum = tonumber(ut.trim(sys.exec("echo $(uci get -p /var/state mwan3." .. ifname .. ".track_ip) | wc -w"))) + if tipnum > 0 then + local relnum = tonumber(ut.trim(sys.exec("uci get -p /var/state mwan3." .. ifname .. ".reliability"))) + if relnum and relnum > tipnum then + err_found = 1 + err_rel_list = err_rel_list .. ifname .. " " + end + end + -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table + if ut.trim(sys.exec("uci get -p /var/state network." .. ifname)) == "interface" then + local ifdev = ut.trim(sys.exec("uci get -p /var/state network." .. ifname .. ".ifname")) + if ifdev == "uci: Entry not found" or ifdev == "" then + err_found = 1 + err_netcfg_list = err_netcfg_list .. ifname .. " " + err_route_list = err_route_list .. ifname .. " " + else + local rtcheck = ut.trim(sys.exec("route -n | awk -F' ' '{ if ($8 == \"" .. ifdev .. "\" && $1 == \"0.0.0.0\") print $1 }'")) + if rtcheck == "" then + err_found = 1 + err_route_list = err_route_list .. ifname .. " " + end + end + else + err_found = 1 + err_netcfg_list = err_netcfg_list .. ifname .. " " + err_route_list = err_route_list .. ifname .. " " + end + end + ) + -- check if any interfaces have duplicate metrics + local metric_dupnums = sys.exec("echo '" .. metric_list .. "' | awk -F' ' '{ print $2 }' | uniq -d") + if metric_dupnums ~= "" then + err_found = 1 + local metric_dupes = "" + for line in metric_dupnums:gmatch("[^\r\n]+") do + metric_dupes = sys.exec("echo '" .. metric_list .. "' | grep '" .. line .. "' | awk -F' ' '{ print $1 }'") + err_dupmet_list = err_dupmet_list .. metric_dupes + end + err_dupmet_list = sys.exec("echo '" .. err_dupmet_list .. "' | tr '\n' ' '") + end +end + +function iface_warn() -- display status and warning messages at the top of the page + local warns = "" + if ifnum <= 250 then + warns = "<strong>There are currently " .. ifnum .. " of 250 supported interfaces configured</strong>" + else + warns = "<font color=\"ff0000\"><strong>WARNING: " .. ifnum .. " interfaces are configured exceeding the maximum of 250!</strong></font>" + end + if err_rel_list ~= " " then + warns = warns .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have a higher reliability requirement than there are tracking IP addresses!</strong></font>" + end + if err_route_list ~= " " then + warns = warns .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have no default route in the main routing table!</strong></font>" + end + if err_netcfg_list ~= " " then + warns = warns .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces are configured incorrectly or not at all in /etc/config/network!</strong></font>" + end + if err_nomet_list ~= " " then + warns = warns .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have no metric configured in /etc/config/network!</strong></font>" + end + if err_dupmet_list ~= " " then + warns = warns .. "<br /><br /><font color=\"ff0000\"><strong>WARNING: some interfaces have duplicate metrics configured in /etc/config/network!</strong></font>" + end + return warns +end + +-- ------ interface configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" + +ifnum = 0 +metric_list = "" +err_found = 0 +err_dupmet_list = " " +err_netcfg_list = " " +err_nomet_list = " " +err_rel_list = " " +err_route_list = " " +iface_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Interface Configuration"), + translate(iface_warn())) + m5:append(Template("mwan3/mwan3_config_css")) + + +mwan_interface = m5:section(TypedSection, "interface", translate("Interfaces"), + translate("MWAN3 supports up to 250 physical and/or logical interfaces<br />" .. + "MWAN3 requires that all interfaces have a unique metric configured in /etc/config/network<br />" .. + "Names must match the interface name found in /etc/config/network (see advanced tab)<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Interfaces may not share the same name as configured members, policies or rules")) + mwan_interface.addremove = true + mwan_interface.dynamic = false + mwan_interface.sectionhead = "Interface" + mwan_interface.sortable = true + mwan_interface.template = "cbi/tblsection" + mwan_interface.extedit = dsp.build_url("admin", "network", "mwan3", "configuration", "interface", "%s") + function mwan_interface.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(dsp.build_url("admin", "network", "mwan3", "configuration", "interface", section)) + end + + +enabled = mwan_interface:option(DummyValue, "enabled", translate("Enabled")) + enabled.rawhtml = true + function enabled.cfgvalue(self, s) + if self.map:get(s, "enabled") == "1" then + return "Yes" + else + return "No" + end + end + +track_ip = mwan_interface:option(DummyValue, "track_ip", translate("Tracking IP")) + track_ip.rawhtml = true + function track_ip.cfgvalue(self, s) + local str = "" + tracked = self.map:get(s, "track_ip") + if tracked then + for k,v in pairs(tracked) do + str = str .. v .. "<br />" + end + return str + else + return "—" + end + end + +reliability = mwan_interface:option(DummyValue, "reliability", translate("Tracking reliability")) + reliability.rawhtml = true + function reliability.cfgvalue(self, s) + if tracked then + return self.map:get(s, "reliability") or "—" + else + return "—" + end + end + +count = mwan_interface:option(DummyValue, "count", translate("Ping count")) + count.rawhtml = true + function count.cfgvalue(self, s) + if tracked then + return self.map:get(s, "count") or "—" + else + return "—" + end + end + +timeout = mwan_interface:option(DummyValue, "timeout", translate("Ping timeout")) + timeout.rawhtml = true + function timeout.cfgvalue(self, s) + if tracked then + local tcheck = self.map:get(s, "timeout") + if tcheck then + return tcheck .. "s" + else + return "—" + end + else + return "—" + end + end + +interval = mwan_interface:option(DummyValue, "interval", translate("Ping interval")) + interval.rawhtml = true + function interval.cfgvalue(self, s) + if tracked then + local icheck = self.map:get(s, "interval") + if icheck then + return icheck .. "s" + else + return "—" + end + else + return "—" + end + end + +down = mwan_interface:option(DummyValue, "down", translate("Interface down")) + down.rawhtml = true + function down.cfgvalue(self, s) + if tracked then + return self.map:get(s, "down") or "—" + else + return "—" + end + end + +up = mwan_interface:option(DummyValue, "up", translate("Interface up")) + up.rawhtml = true + function up.cfgvalue(self, s) + if tracked then + return self.map:get(s, "up") or "—" + else + return "—" + end + end + +metric = mwan_interface:option(DummyValue, "metric", translate("Metric")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + local metcheck = sys.exec("uci get -p /var/state network." .. s .. ".metric") + if metcheck ~= "" then + return metcheck + else + return "—" + end + end + +errors = mwan_interface:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if err_found == 1 then + local mouseover, linebrk = "", "" + if string.find(err_rel_list, " " .. s .. " ") then + mouseover = "Higher reliability requirement than there are tracking IP addresses" + linebrk = " " + end + if string.find(err_route_list, " " .. s .. " ") then + mouseover = mouseover .. linebrk .. "No default route in the main routing table" + linebrk = " " + end + if string.find(err_netcfg_list, " " .. s .. " ") then + mouseover = mouseover .. linebrk .. "Configured incorrectly or not at all in /etc/config/network" + linebrk = " " + end + if string.find(err_nomet_list, " " .. s .. " ") then + mouseover = mouseover .. linebrk .. "No metric configured in /etc/config/network" + linebrk = " " + end + if string.find(err_dupmet_list, " " .. s .. " ") then + mouseover = mouseover .. linebrk .. "Duplicate metric configured in /etc/config/network" + end + if mouseover == "" then + return "" + else + return "<span title=\"" .. mouseover .. "\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + else + return "" + end + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interfaceconfig.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interfaceconfig.lua new file mode 100644 index 000000000..2119c048b --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_interfaceconfig.lua @@ -0,0 +1,191 @@ +-- ------ extra functions ------ -- + +function iface_check() + metcheck = ut.trim(sys.exec("uci get -p /var/state network." .. arg[1] .. ".metric")) + if metcheck == "" then -- no metric + err_nomet = 1 + else -- if metric exists create list of interface metrics to compare against for duplicates + uci.cursor():foreach("mwan3", "interface", + function (section) + local metlkp = ut.trim(sys.exec("uci get -p /var/state network." .. section[".name"] .. ".metric")) + metric_list = metric_list .. section[".name"] .. " " .. metlkp .. "\n" + end + ) + -- compare metric against list + local metric_dupnums, metric_dupes = sys.exec("echo '" .. metric_list .. "' | awk -F' ' '{ print $2 }' | uniq -d"), "" + for line in metric_dupnums:gmatch("[^\r\n]+") do + metric_dupes = sys.exec("echo '" .. metric_list .. "' | grep '" .. line .. "' | awk -F' ' '{ print $1 }'") + err_dupmet_list = err_dupmet_list .. metric_dupes + end + if sys.exec("echo '" .. err_dupmet_list .. "' | grep -w " .. arg[1]) ~= "" then + err_dupmet = 1 + end + end + -- check if this interface has a higher reliability requirement than track IPs configured + local tipnum = tonumber(ut.trim(sys.exec("echo $(uci get -p /var/state mwan3." .. arg[1] .. ".track_ip) | wc -w"))) + if tipnum > 0 then + local relnum = tonumber(ut.trim(sys.exec("uci get -p /var/state mwan3." .. arg[1] .. ".reliability"))) + if relnum and relnum > tipnum then + err_reliability = 1 + end + end + -- check if any interfaces are not properly configured in /etc/config/network or have no default route in main routing table + if ut.trim(sys.exec("uci get -p /var/state network." .. arg[1])) == "interface" then + local ifdev = ut.trim(sys.exec("uci get -p /var/state network." .. arg[1] .. ".ifname")) + if ifdev == "uci: Entry not found" or ifdev == "" then + err_netcfg = 1 + err_route = 1 + else + local rtcheck = ut.trim(sys.exec("route -n | awk -F' ' '{ if ($8 == \"" .. ifdev .. "\" && $1 == \"0.0.0.0\") print $1 }'")) + if rtcheck == "" then + err_route = 1 + end + end + else + err_netcfg = 1 + err_route = 1 + end +end + +function iface_warn() -- display warning messages at the top of the page + local warns, linebrk = "", "" + if err_reliability == 1 then + warns = "<font color=\"ff0000\"><strong>WARNING: this interface has a higher reliability requirement than there are tracking IP addresses!</strong></font>" + linebrk = "<br /><br />" + end + if err_route == 1 then + warns = warns .. linebrk .. "<font color=\"ff0000\"><strong>WARNING: this interface has no default route in the main routing table!</strong></font>" + linebrk = "<br /><br />" + end + if err_netcfg == 1 then + warns = warns .. linebrk .. "<font color=\"ff0000\"><strong>WARNING: this interface is configured incorrectly or not at all in /etc/config/network!</strong></font>" + linebrk = "<br /><br />" + end + if err_nomet == 1 then + warns = warns .. linebrk .. "<font color=\"ff0000\"><strong>WARNING: this interface has no metric configured in /etc/config/network!</strong></font>" + elseif err_dupmet == 1 then + warns = warns .. linebrk .. "<font color=\"ff0000\"><strong>WARNING: this and other interfaces have duplicate metrics configured in /etc/config/network!</strong></font>" + end + return warns +end + +-- ------ interface configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" +arg[1] = arg[1] or "" + +metcheck = "" +metric_list = "" +err_dupmet_list = "" +err_rel_list = "" +err_nomet = 0 +err_dupmet = 0 +err_route = 0 +err_netcfg = 0 +err_reliability = 0 +iface_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Interface Configuration - " .. arg[1]), + translate(iface_warn())) + m5.redirect = dsp.build_url("admin", "network", "mwan3", "configuration", "interface") + + +mwan_interface = m5:section(NamedSection, arg[1], "interface", "") + mwan_interface.addremove = false + mwan_interface.dynamic = false + + +enabled = mwan_interface:option(ListValue, "enabled", translate("Enabled")) + enabled.default = "1" + enabled:value("1", translate("Yes")) + enabled:value("0", translate("No")) + +track_ip = mwan_interface:option(DynamicList, "track_ip", translate("Tracking IP"), + translate("This IP address will be pinged to dermine if the link is up or down. Leave blank to assume interface is always online")) + track_ip.datatype = "ipaddr" + +reliability = mwan_interface:option(Value, "reliability", translate("Tracking reliability"), + translate("Acceptable values: 1-100. This many Tracking IP addresses must respond for the link to be deemed up")) + reliability.datatype = "range(1, 100)" + reliability.default = "1" + +count = mwan_interface:option(ListValue, "count", translate("Ping count")) + count.default = "1" + count:value("1") + count:value("2") + count:value("3") + count:value("4") + count:value("5") + +timeout = mwan_interface:option(ListValue, "timeout", translate("Ping timeout")) + timeout.default = "2" + timeout:value("1", translate("1 second")) + timeout:value("2", translate("2 seconds")) + timeout:value("3", translate("3 seconds")) + timeout:value("4", translate("4 seconds")) + timeout:value("5", translate("5 seconds")) + timeout:value("6", translate("6 seconds")) + timeout:value("7", translate("7 seconds")) + timeout:value("8", translate("8 seconds")) + timeout:value("9", translate("9 seconds")) + timeout:value("10", translate("10 seconds")) + +interval = mwan_interface:option(ListValue, "interval", translate("Ping interval")) + interval.default = "5" + interval:value("1", translate("1 second")) + interval:value("3", translate("3 seconds")) + interval:value("5", translate("5 seconds")) + interval:value("10", translate("10 seconds")) + interval:value("20", translate("20 seconds")) + interval:value("30", translate("30 seconds")) + interval:value("60", translate("1 minute")) + interval:value("300", translate("5 minutes")) + interval:value("600", translate("10 minutes")) + interval:value("900", translate("15 minutes")) + interval:value("1800", translate("30 minutes")) + interval:value("3600", translate("1 hour")) + +down = mwan_interface:option(ListValue, "down", translate("Interface down"), + translate("Interface will be deemed down after this many failed ping tests")) + down.default = "3" + down:value("1") + down:value("2") + down:value("3") + down:value("4") + down:value("5") + down:value("6") + down:value("7") + down:value("8") + down:value("9") + down:value("10") + +up = mwan_interface:option(ListValue, "up", translate("Interface up"), + translate("Downed interface will be deemed up after this many successful ping tests")) + up.default = "3" + up:value("1") + up:value("2") + up:value("3") + up:value("4") + up:value("5") + up:value("6") + up:value("7") + up:value("8") + up:value("9") + up:value("10") + +metric = mwan_interface:option(DummyValue, "metric", translate("Metric"), + translate("This displays the metric assigned to this interface in /etc/config/network")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + if err_nomet == 0 then + return metcheck + else + return "—" + end + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_member.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_member.lua new file mode 100644 index 000000000..68b9549e1 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_member.lua @@ -0,0 +1,46 @@ +-- ------ member configuration ------ -- + +ds = require "luci.dispatcher" + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Member Configuration")) + m5:append(Template("mwan3/mwan3_config_css")) + + +mwan_member = m5:section(TypedSection, "member", translate("Members"), + translate("Members are profiles attaching a metric and weight to an MWAN3 interface<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Members may not share the same name as configured interfaces, policies or rules")) + mwan_member.addremove = true + mwan_member.dynamic = false + mwan_member.sectionhead = "Member" + mwan_member.sortable = true + mwan_member.template = "cbi/tblsection" + mwan_member.extedit = ds.build_url("admin", "network", "mwan3", "configuration", "member", "%s") + function mwan_member.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(ds.build_url("admin", "network", "mwan3", "configuration", "member", section)) + end + + +interface = mwan_member:option(DummyValue, "interface", translate("Interface")) + interface.rawhtml = true + function interface.cfgvalue(self, s) + return self.map:get(s, "interface") or "—" + end + +metric = mwan_member:option(DummyValue, "metric", translate("Metric")) + metric.rawhtml = true + function metric.cfgvalue(self, s) + return self.map:get(s, "metric") or "1" + end + +weight = mwan_member:option(DummyValue, "weight", translate("Weight")) + weight.rawhtml = true + function weight.cfgvalue(self, s) + return self.map:get(s, "weight") or "1" + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_memberconfig.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_memberconfig.lua new file mode 100644 index 000000000..8ea7d9824 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_memberconfig.lua @@ -0,0 +1,47 @@ +-- ------ extra functions ------ -- + +function cbi_add_interface(field) + uci.cursor():foreach("mwan3", "interface", + function (section) + field:value(section[".name"]) + end + ) +end + +-- ------ member configuration ------ -- + +dsp = require "luci.dispatcher" +arg[1] = arg[1] or "" + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Member Configuration - ") .. arg[1]) + m5.redirect = dsp.build_url("admin", "network", "mwan3", "configuration", "member") + + +mwan_member = m5:section(NamedSection, arg[1], "member", "") + mwan_member.addremove = false + mwan_member.dynamic = false + + +interface = mwan_member:option(Value, "interface", translate("Interface")) + cbi_add_interface(interface) + +metric = mwan_member:option(Value, "metric", translate("Metric"), + translate("Acceptable values: 1-1000. Defaults to 1 if not set")) + metric.datatype = "range(1, 1000)" + +weight = mwan_member:option(Value, "weight", translate("Weight"), + translate("Acceptable values: 1-1000. Defaults to 1 if not set")) + weight.datatype = "range(1, 1000)" + + +-- ------ currently configured interfaces ------ -- + +mwan_interface = m5:section(TypedSection, "interface", translate("Currently Configured Interfaces")) + mwan_interface.addremove = false + mwan_interface.dynamic = false + mwan_interface.sortable = false + mwan_interface.template = "cbi/tblsection" + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policy.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policy.lua new file mode 100644 index 000000000..02471b992 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policy.lua @@ -0,0 +1,82 @@ +-- ------ extra functions ------ -- + +function policy_check() -- check to see if any policy names exceed the maximum of 15 characters + uci.cursor():foreach("mwan3", "policy", + function (section) + if string.len(section[".name"]) > 15 then + toolong = 1 + err_name_list = err_name_list .. section[".name"] .. " " + end + end + ) +end + +function policy_warn() -- display status and warning messages at the top of the page + if toolong == 1 then + return "<font color=\"ff0000\"><strong>WARNING: Some policies have names exceeding the maximum of 15 characters!</strong></font>" + else + return "" + end +end + +-- ------ policy configuration ------ -- + +ds = require "luci.dispatcher" +sys = require "luci.sys" + +toolong = 0 +err_name_list = " " +policy_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Policy Configuration"), + translate(policy_warn())) + m5:append(Template("mwan3/mwan3_config_css")) + + +mwan_policy = m5:section(TypedSection, "policy", translate("Policies"), + translate("Policies are profiles grouping one or more members controlling how MWAN3 distributes traffic<br />" .. + "Member interfaces with lower metrics are used first. Interfaces with the same metric load-balance<br />" .. + "Load-balanced member interfaces distribute more traffic out those with higher weights<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces. Names must be 15 characters or less<br />" .. + "Policies may not share the same name as configured interfaces, members or rules")) + mwan_policy.addremove = true + mwan_policy.dynamic = false + mwan_policy.sectionhead = "Policy" + mwan_policy.sortable = true + mwan_policy.template = "cbi/tblsection" + mwan_policy.extedit = ds.build_url("admin", "network", "mwan3", "configuration", "policy", "%s") + function mwan_policy.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(ds.build_url("admin", "network", "mwan3", "configuration", "policy", section)) + end + + +use_member = mwan_policy:option(DummyValue, "use_member", translate("Members assigned")) + use_member.rawhtml = true + function use_member.cfgvalue(self, s) + local tab, str = self.map:get(s, "use_member"), "" + if tab then + for k,v in pairs(tab) do + str = str .. v .. "<br />" + end + return str + else + return "—" + end + + end + +errors = mwan_policy:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if not string.find(err_name_list, " " .. s .. " ") then + return "" + else + return "<span title=\"Name exceeds 15 characters\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policyconfig.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policyconfig.lua new file mode 100644 index 000000000..a6523ad8e --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_policyconfig.lua @@ -0,0 +1,58 @@ +-- ------ extra functions ------ -- + +function policy_check() -- check to see if this policy's name exceed the maximum of 15 characters + polchar = string.len(arg[1]) + if polchar > 15 then + toolong = 1 + end +end + +function policy_warn() -- display status and warning messages at the top of the page + if toolong == 1 then + return "<font color=\"ff0000\"><strong>WARNING: this policy's name is " .. polchar .. " characters exceeding the maximum of 15!</strong></font>" + else + return "" + end +end + +function cbi_add_member(field) + uci.cursor():foreach("mwan3", "member", + function (section) + field:value(section[".name"]) + end + ) +end + +-- ------ policy configuration ------ -- + +dsp = require "luci.dispatcher" +arg[1] = arg[1] or "" + +toolong = 0 +policy_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Policy Configuration - " .. arg[1]), + translate(policy_warn())) + m5.redirect = dsp.build_url("admin", "network", "mwan3", "configuration", "policy") + + +mwan_policy = m5:section(NamedSection, arg[1], "policy", "") + mwan_policy.addremove = false + mwan_policy.dynamic = false + + +use_member = mwan_policy:option(DynamicList, "use_member", translate("Member used")) + cbi_add_member(use_member) + + +-- ------ currently configured members ------ -- + +mwan_member = m5:section(TypedSection, "member", translate("Currently Configured Members")) + mwan_member.addremove = false + mwan_member.dynamic = false + mwan_member.sortable = false + mwan_member.template = "cbi/tblsection" + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_rule.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_rule.lua new file mode 100644 index 000000000..efae81b2a --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_rule.lua @@ -0,0 +1,109 @@ +-- ------ extra functions ------ -- + +function rule_check() -- determine if rules needs a proper protocol configured + uci.cursor():foreach("mwan3", "rule", + function (section) + local sport = ut.trim(sys.exec("uci get -p /var/state mwan3." .. section[".name"] .. ".src_port")) + local dport = ut.trim(sys.exec("uci get -p /var/state mwan3." .. section[".name"] .. ".dest_port")) + if sport ~= "" or dport ~= "" then -- ports configured + local proto = ut.trim(sys.exec("uci get -p /var/state mwan3." .. section[".name"] .. ".proto")) + if proto == "" or proto == "all" then -- no or improper protocol + err_proto_list = err_proto_list .. section[".name"] .. " " + end + end + end + ) +end + +function rule_warn() -- display warning messages at the top of the page + if err_proto_list ~= " " then + return "<font color=\"ff0000\"><strong>WARNING: some rules have a port configured with no or improper protocol specified! Please configure a specific protocol!</strong></font>" + else + return "" + end +end + +-- ------ rule configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" + +err_proto = 0 +err_proto_list = " " +rule_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Traffic Rule Configuration"), + translate(rule_warn())) + m5:append(Template("mwan3/mwan3_config_css")) + + +mwan_rule = m5:section(TypedSection, "rule", translate("Traffic Rules"), + translate("Rules specify which traffic will use a particular MWAN3 policy based on IP address, port or protocol<br />" .. + "Rules are matched from top to bottom. Rules below a matching rule are ignored. Traffic not matching any rule is routed using the main routing table<br />" .. + "Traffic destined for known (other than default) networks is handled by the main routing table. Traffic matching a rule, but all WAN interfaces for that policy are down will be blackholed<br />" .. + "Names may contain characters A-Z, a-z, 0-9, _ and no spaces<br />" .. + "Rules may not share the same name as configured interfaces, members or policies")) + mwan_rule.addremove = true + mwan_rule.anonymous = false + mwan_rule.dynamic = false + mwan_rule.sectionhead = "Rule" + mwan_rule.sortable = true + mwan_rule.template = "cbi/tblsection" + mwan_rule.extedit = dsp.build_url("admin", "network", "mwan3", "configuration", "rule", "%s") + function mwan_rule.create(self, section) + TypedSection.create(self, section) + m5.uci:save("mwan3") + luci.http.redirect(dsp.build_url("admin", "network", "mwan3", "configuration", "rule", section)) + end + + +src_ip = mwan_rule:option(DummyValue, "src_ip", translate("Source address")) + src_ip.rawhtml = true + function src_ip.cfgvalue(self, s) + return self.map:get(s, "src_ip") or "—" + end + +src_port = mwan_rule:option(DummyValue, "src_port", translate("Source port")) + src_port.rawhtml = true + function src_port.cfgvalue(self, s) + return self.map:get(s, "src_port") or "—" + end + +dest_ip = mwan_rule:option(DummyValue, "dest_ip", translate("Destination address")) + dest_ip.rawhtml = true + function dest_ip.cfgvalue(self, s) + return self.map:get(s, "dest_ip") or "—" + end + +dest_port = mwan_rule:option(DummyValue, "dest_port", translate("Destination port")) + dest_port.rawhtml = true + function dest_port.cfgvalue(self, s) + return self.map:get(s, "dest_port") or "—" + end + +proto = mwan_rule:option(DummyValue, "proto", translate("Protocol")) + proto.rawhtml = true + function proto.cfgvalue(self, s) + return self.map:get(s, "proto") or "all" + end + +use_policy = mwan_rule:option(DummyValue, "use_policy", translate("Policy assigned")) + use_policy.rawhtml = true + function use_policy.cfgvalue(self, s) + return self.map:get(s, "use_policy") or "—" + end + +errors = mwan_rule:option(DummyValue, "errors", translate("Errors")) + errors.rawhtml = true + function errors.cfgvalue(self, s) + if not string.find(err_proto_list, " " .. s .. " ") then + return "" + else + return "<span title=\"No protocol specified\"><img src=\"/luci-static/resources/cbi/reset.gif\" alt=\"error\"></img></span>" + end + end + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_ruleconfig.lua b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_ruleconfig.lua new file mode 100644 index 000000000..e83fa629f --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/model/cbi/mwan3/mwan3_ruleconfig.lua @@ -0,0 +1,99 @@ +-- ------ extra functions ------ -- + +function rule_check() -- determine if rule needs a protocol specified + local sport = ut.trim(sys.exec("uci get -p /var/state mwan3." .. arg[1] .. ".src_port")) + local dport = ut.trim(sys.exec("uci get -p /var/state mwan3." .. arg[1] .. ".dest_port")) + if sport ~= "" or dport ~= "" then -- ports configured + local proto = ut.trim(sys.exec("uci get -p /var/state mwan3." .. arg[1] .. ".proto")) + if proto == "" or proto == "all" then -- no or improper protocol + err_proto = 1 + end + end +end + +function rule_warn() -- display warning message at the top of the page + if err_proto == 1 then + return "<font color=\"ff0000\"><strong>WARNING: this rule is incorrectly configured with no or improper protocol specified! Please configure a specific protocol!</strong></font>" + else + return "" + end +end + +function cbi_add_policy(field) + uci.cursor():foreach("mwan3", "policy", + function (section) + field:value(section[".name"]) + end + ) +end + +function cbi_add_protocol(field) + local protos = ut.trim(sys.exec("cat /etc/protocols | grep ' # ' | awk -F' ' '{print $1}' | grep -vw -e 'ip' -e 'tcp' -e 'udp' -e 'icmp' -e 'esp' | grep -v 'ipv6' | sort | tr '\n' ' '")) + for p in string.gmatch(protos, "%S+") do + field:value(p) + end +end + +-- ------ rule configuration ------ -- + +dsp = require "luci.dispatcher" +sys = require "luci.sys" +ut = require "luci.util" +arg[1] = arg[1] or "" + +err_proto = 0 +rule_check() + + +m5 = Map("mwan3", translate("MWAN3 Multi-WAN Rule Configuration - ") .. arg[1], + translate(rule_warn())) + m5.redirect = dsp.build_url("admin", "network", "mwan3", "configuration", "rule") + + +mwan_rule = m5:section(NamedSection, arg[1], "rule", "") + mwan_rule.addremove = false + mwan_rule.dynamic = false + + +src_ip = mwan_rule:option(Value, "src_ip", translate("Source address"), + translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes")) + src_ip.datatype = ipaddr + +src_port = mwan_rule:option(Value, "src_port", translate("Source port"), + translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes")) + +dest_ip = mwan_rule:option(Value, "dest_ip", translate("Destination address"), + translate("Supports CIDR notation (eg \"192.168.100.0/24\") without quotes")) + dest_ip.datatype = ipaddr + +dest_port = mwan_rule:option(Value, "dest_port", translate("Destination port"), + translate("May be entered as a single or multiple port(s) (eg \"22\" or \"80,443\") or as a portrange (eg \"1024:2048\") without quotes")) + +proto = mwan_rule:option(Value, "proto", translate("Protocol"), + translate("View the contents of /etc/protocols for protocol descriptions")) + proto.default = "all" + proto.rmempty = false + proto:value("all") + proto:value("ip") + proto:value("tcp") + proto:value("udp") + proto:value("icmp") + proto:value("esp") + cbi_add_protocol(proto) + +use_policy = mwan_rule:option(Value, "use_policy", translate("Policy assigned")) + cbi_add_policy(use_policy) + use_policy:value("unreachable") + use_policy:value("default") + + +-- ------ currently configured policies ------ -- + +mwan_policy = m5:section(TypedSection, "policy", translate("Currently Configured Policies")) + mwan_policy.addremove = false + mwan_policy.dynamic = false + mwan_policy.sortable = false + mwan_policy.template = "cbi/tblsection" + + +return m5 diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/admin_status/index/mwan3.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/admin_status/index/mwan3.htm new file mode 100644 index 000000000..f510f158c --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/admin_status/index/mwan3.htm @@ -0,0 +1 @@ +<%+mwan3/mwan3_status%> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_diagnostics.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_diagnostics.htm new file mode 100644 index 000000000..6d9abcbed --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_diagnostics.htm @@ -0,0 +1,134 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/mwan3")%>"><%:MWAN3 Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/network")%>"><%:Network Config%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/diag")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/tshoot")%>"><%:Troubleshooting%></a></li> +</ul> + +<% + local uci = require "luci.model.uci" + + str = "" + uci.cursor():foreach("mwan3", "interface", + function (section) + str = str .. section[".name"] .. " " + end + ) +%> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + var stxhr = new XHR(); + + function update_status(tool, alt) + { + var iface = document.getElementById('mwan3iface').value; + var output = document.getElementById('diag_output'); + + if (tool == "service") + { + output.innerHTML = + '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="padding: 20px; vertical-align: middle;" /> ' + + "Waiting for MWAN3 to " + alt + "..." + ; + } + else + { + output.innerHTML = + '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="padding: 20px; vertical-align: middle;" /> ' + + "Waiting for diagnostic results..." + ; + } + + output.parentNode.style.display = 'block'; + output.style.display = 'inline'; + + stxhr.get('<%=luci.dispatcher.build_url("admin", "network", "mwan3", "advanced")%>/diag_display' + '/' + iface + '/' + tool + '/' + alt, null, + function(x, st) + { + if (st.diagres) + { + output.innerHTML = String.format('<pre id="diag_output_css">%h</pre>', st.diagres[0].diagresult); + } + else + { + var temp = ''; + var ncint = 'No diagnostic results returned'; + temp = String.format( + '<pre id="diag_output_css"><strong>%s</strong></pre>', + ncint + ); + output.innerHTML = temp; + } + } + ); + } +//]]></script> + +<div id="mwan3_diagnostics" class="cbi-map"> + <fieldset id="diag_select" class="cbi-section"> + <legend><%:MWAN3 Interface Diagnostics%></legend> + <select id="mwan3iface"> + <% for z in str:gmatch("[^ ]+") do -%><option value="<%=z%>"><%=z%></option><%- end %> + </select> + <div id="buttoncss"> + <input type="button" value="<%:Ping default gateway%>" class="cbi-button cbi-button-apply" onclick="update_status('ping', 'gateway')" /> + <input type="button" value="<%:Ping tracking IP%>" class="cbi-button cbi-button-apply" onclick="update_status('ping', 'track_ip')" /> + <input type="button" value="<%:Check IP rules%>" class="cbi-button cbi-button-apply" onclick="update_status('rulechk', null)" /> + <input type="button" value="<%:Check routing table%>" class="cbi-button cbi-button-apply" onclick="update_status('routechk', null)" /> + <input type="button" value="<%:Hotplug ifup%>" class="cbi-button cbi-button-apply" onclick="update_status('hotplug', 'ifup')" /> + <input type="button" value="<%:Hotplug ifdown%>" class="cbi-button cbi-button-apply" onclick="update_status('hotplug', 'ifdown')" /> + </div> + </fieldset> + <fieldset id="diag_select" class="cbi-section"> + <legend><%:MWAN3 Service Control%></legend> + <div id="buttoncss"> + <input type="button" value="<%:Restart MWAN3%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'restart')" /> + <input type="button" value="<%:Stop MWAN3%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'stop')" /> + <input type="button" value="<%:Start MWAN3%>" class="cbi-button cbi-button-apply" onclick="update_status('service', 'start')" /> + </div> + </fieldset> + <fieldset class="cbi-section" style="display:none"> + <legend><%:Diagnostic Results%></legend> + <div id="diag_output"></div> + </fieldset> +</div> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan3_diagnostics { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #diag_select { + padding: 12px 20px 20px 20px; + } + #mwan3iface { + float: left; + margin: 8px 20px 0px 0px; + } + #buttoncss { + display: table; + float: left; + text-align: left; + } + .cbi-button { + margin: 8px 20px 0px 0px; + min-width: 153px; + } + #diag_output_css { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_hotplug.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_hotplug.htm new file mode 100644 index 000000000..e90942b91 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_hotplug.htm @@ -0,0 +1,23 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/mwan3")%>"><%:MWAN3 Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/network")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/diag")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/tshoot")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_mwan3.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_mwan3.htm new file mode 100644 index 000000000..d11bdd7d8 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_mwan3.htm @@ -0,0 +1,23 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/mwan3")%>"><%:MWAN3 Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/network")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/diag")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/tshoot")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_network.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_network.htm new file mode 100644 index 000000000..59dd4fa0e --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_network.htm @@ -0,0 +1,23 @@ +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/mwan3")%>"><%:MWAN3 Config%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/network")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/diag")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/tshoot")%>"><%:Troubleshooting%></a></li> +</ul> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin: 0px 0px 0px 30px; + padding-right: 30px; + width: auto; + } + .cbi-section-node { + margin-top: 20px; + } + .cbi-section { + border: 1px dotted #555555; + padding: 20px; + } +</style> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_troubleshoot.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_troubleshoot.htm new file mode 100644 index 000000000..1a92ebd02 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_adv_troubleshoot.htm @@ -0,0 +1,77 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/hotplug")%>"><%:Hotplug Script%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/mwan3")%>"><%:MWAN3 Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/network")%>"><%:Network Config%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/diag")%>"><%:Diagnostics%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/advanced/tshoot")%>"><%:Troubleshooting%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(15, '<%=luci.dispatcher.build_url("admin", "network", "mwan3", "advanced", "tshoot_display")%>', null, + function(x, st) + { + var tx = document.getElementById('mwan3_tshoot_text'); + if (st.mw3ver) + { + var temp = ''; + var mwanvers = 'Software versions : <br /><br />'; + var mwan3cnfg = '<br /><br />Output of "cat /etc/config/mwan3" : <br /><br />'; + var netcnfg = '<br /><br />Output of "cat /etc/config/network" : <br /><br />'; + var ifcnfg = '<br /><br />Output of "ifconfig" : <br /><br />'; + var iproute = '<br /><br />Output of "route -n" : <br /><br />'; + var iprulesh = '<br /><br />Output of "ip rule show" : <br /><br />'; + var routelisttbl = '<br /><br />Output of "ip route list table 1-250" : <br /><br />'; + var firewalldef = '<br /><br />Firewall default output policy (must be ACCEPT) : <br /><br />'; + var iptable = '<br /><br />Output of "iptables -L -t mangle -v -n" : <br /><br />'; + + temp = String.format( + '<pre><span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s<span class="tsht">%s</span>%s</pre>', + mwanvers, st.mw3ver[0].mwan3v, mwan3cnfg, st.mwan3config[0].mwn3cfg, netcnfg, st.netconfig[0].netcfg, ifcnfg, st.ifconfig[0].ifcfg, iproute, st.rtshow[0].iprtshow, iprulesh, st.iprule[0].rule, routelisttbl, st.routelist[0].iprtlist, firewalldef, st.fidef[0].firedef, iptable, st.iptables[0].iptbls + ); + tx.innerHTML = temp; + } + else + { + var temp = ''; + var terror = 'Error collecting troubleshooting information'; + temp = String.format( + '<strong>%s</strong>', + terror + ); + tx.innerHTML = temp; + } + } + ); +//]]></script> + +<div id="tshoot_div"> + <fieldset class="cbi-section"> + <legend><%:Troubleshooting Data%></legend> + <div id="mwan3_tshoot_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #tshoot_div { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #mwan3_tshoot_text { + padding: 20px; + text-align: left; + } + .tsht { + background-color: rgb(78, 186, 241); + } +</style> + +<%+footer%> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_config_css.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_config_css.htm new file mode 100644 index 000000000..303fa2094 --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_config_css.htm @@ -0,0 +1,34 @@ +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + table td { /*cells showing the configuration values*/ + padding: 0px; + text-align: center; + vertical-align: middle; + } + table th { /*column for configuration section name*/ + padding: 0px; + text-align: center; + vertical-align: middle; + } + table tbody th { /*column for configuration section name*/ + padding: 0px; + vertical-align: middle; + } + .cbi-section-node table div { /*rows*/ + padding-top: 5px; + } + table.cbi-section-table td.cbi-section-table-cell { /*sort buttons column*/ + text-align: center; + } + .cbi-section h3 { + color: rgb(85, 85, 85); + font-family: Trebuchet MS,Verdana,sans-serif; + font-style: italic; + font-weight: normal; + } +</style> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_detail.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_detail.htm new file mode 100644 index 000000000..920a20bda --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_detail.htm @@ -0,0 +1,62 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/overview")%>"><%:Interface Status%></a></li> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/overview/over_detail")%>"><%:Detailed Status%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan3", "overview", "detail_status")%>', null, + function(x, st) + { + var tx = document.getElementById('mwan3_detail_text'); + if (st.mwan3dst) + { + var temp = ''; + temp = String.format( + '<pre>%s</pre>', + st.mwan3dst[0].detailstat + ); + tx.innerHTML = temp; + } + else + { + var temp = ''; + var nslg = 'No detailed status information available'; + temp = String.format( + '<strong>%s</strong>', + nslg + ); + tx.innerHTML = temp; + } + } + ); +//]]></script> + +<div id="mwan3_detail_status"> + <fieldset class="cbi-section"> + <legend><%:MWAN3 Multi-WAN Detailed Status%></legend> + <div id="mwan3_detail_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan3_detail_status { + border: 1px dotted #555555; + background-color: #FFFFFF; + padding: 20px; + } + #mwan3_detail_text { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_interface.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_interface.htm new file mode 100644 index 000000000..2e846a71e --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_over_interface.htm @@ -0,0 +1,146 @@ +<%+header%> + +<ul class="cbi-tabmenu"> + <li class="cbi-tab"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/overview")%>"><%:Interface Status%></a></li> + <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/network/mwan3/overview/over_detail")%>"><%:Detailed Status%></a></li> +</ul> + +<script type="text/javascript" src="<%=resource%>/cbi.js"></script> +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan3", "overview", "iface_status")%>', null, + function(x, st) + { + var tx = document.getElementById('mwan3_status_text'); + if (st.wans) + { + var temp = ''; + + for( var i = 0; i < st.wans.length; i++ ) + { + var stat = ''; + var cssc = ''; + + switch (st.wans[i].status) + { + case 'on': + stat = 'Online (tracking active)'; + cssc = 'wanon'; + break; + + case 'nm': + stat = 'Online (tracking off)'; + cssc = 'wanon'; + break; + + case 'off': + stat = 'Offline'; + cssc = 'wanoff'; + break; + + case 'ne': + stat = 'Disabled'; + cssc = 'wanoff'; + break; + } + + temp += String.format( + '<span class="%s"><strong>%s (<a href="%q">%s</a>)</strong><br />%s</span>', + cssc, st.wans[i].name, st.wans[i].link, st.wans[i].ifname, stat + ); + } + tx.innerHTML = temp; + } + else + { + var temp = ''; + var ncint = 'No MWAN3 interfaces found'; + temp = String.format( + '<strong>%s</strong>', + ncint + ); + tx.innerHTML = temp; + } + + var tx = document.getElementById('mwan3_statuslog_text'); + if (st.mwan3log) + { + var temp = ''; + var mwan3lg = 'Last 50 MWAN3 systemlog entries. Newest entries sorted at the top :'; + + temp = String.format( + '<pre>%s<br /><br />%s</pre>', + mwan3lg, st.mwan3log[0].mwanlog + ); + tx.innerHTML = temp; + } + else + { + var temp = ''; + var nslg = 'No MWAN3 systemlog history found'; + temp = String.format( + '<strong>%s</strong>', + nslg + ); + tx.innerHTML = temp; + } + } + ); +//]]></script> + +<div id="mwan3_interface_status"> + <fieldset id="interface_field" class="cbi-section"> + <legend><%:MWAN3 Multi-WAN Interface Live Status%></legend> + <div id="mwan3_status_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> + <fieldset class="cbi-section"> + <legend><%:MWAN3 Multi-WAN Interface Systemlog%></legend> + <div id="mwan3_statuslog_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> + </fieldset> +</div> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: none; + margin-left: 30px; + padding-right: 30px; + width: auto; + } + #mwan3_interface_status { + background-color: #FFFFFF; + border: 1px dotted #555555; + padding: 20px; + } + #interface_field { + padding: 12px 20px 20px 20px; + } + #mwan3_status_text { + display: table; + font-size: 14px; + margin: auto; + max-width: 1044px; + min-width: 246px; + width: 100%; + } + .wanon { + background-color: rgb(144, 240, 144); + } + .wanoff { + background-color: rgb(240, 144, 144); + } + .wanon, .wanoff { + border-radius: 60px; + box-shadow: 0px 2px 5px -3px; + float: left; + margin: 8px 3px 0px 3px; + min-height: 30px; + min-width: 235px; + padding: 5px 10px 8px 10px; + text-align: center; + } + #mwan3_statuslog_text { + padding: 20px; + text-align: left; + } +</style> + +<%+footer%> diff --git a/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_status.htm b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_status.htm new file mode 100644 index 000000000..9315a850c --- /dev/null +++ b/net/mwan3-luci/files/usr/lib/lua/luci/view/mwan3/mwan3_status.htm @@ -0,0 +1,95 @@ +<script type="text/javascript">//<![CDATA[ + XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "network", "mwan3", "overview", "iface_status")%>', null, + function(x, st) + { + var tx = document.getElementById('mwan3_status_text'); + if (st.wans) + { + var temp = ''; + + for( var i = 0; i < st.wans.length; i++ ) + { + var stat = ''; + var cssc = ''; + + switch (st.wans[i].status) + { + case 'on': + stat = 'Online (tracking active)'; + cssc = 'wanon'; + break; + + case 'nm': + stat = 'Online (tracking off)'; + cssc = 'wanon'; + break; + + case 'off': + stat = 'Offline'; + cssc = 'wanoff'; + break; + + case 'ne': + stat = 'Disabled'; + cssc = 'wanoff'; + break; + } + + temp += String.format( + '<span class="%s"><strong>%s (<a href="%q">%s</a>)</strong><br />%s</span>', + cssc, st.wans[i].name, st.wans[i].link, st.wans[i].ifname, stat + ); + } + tx.innerHTML = temp; + } + else + { + var temp = ''; + var ncint = 'No MWAN3 interfaces found'; + temp += String.format( + '<strong>%s</strong>', + ncint + ); + tx.innerHTML = temp; + } + } + ); +//]]></script> + +<fieldset id="interface_field" class="cbi-section"> + <legend><%:MWAN3 Multi-WAN Interface Live Status%></legend> + <div id="mwan3_status_text"><img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> Collecting data...</div> +</fieldset> + +<style type="text/css"> + .container { /*container for entire page. fixes bootstrap theme's ridiculously small page width*/ + max-width: 1044px; + } + #interface_field { + padding: 12px 20px 20px 20px; + } + #mwan3_status_text { + display: table; + font-size: 14px; + margin: auto; + max-width: 1044px; + min-width: 246px; + width: 100%; + } + .wanon { + background-color: rgb(144, 240, 144); + } + .wanoff { + background-color: rgb(240, 144, 144); + } + .wanon, .wanoff { + border-radius: 60px; + box-shadow: 0px 2px 5px -3px; + float: left; + margin: 8px 3px 0px 3px; + min-height: 30px; + min-width: 235px; + padding: 5px 10px 8px 10px; + text-align: center; + } +</style> diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile new file mode 100644 index 000000000..49c8d592d --- /dev/null +++ b/net/mwan3/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mwan3 +PKG_VERSION:=1.4 +PKG_RELEASE:=22 +PKG_MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com> +PKG_LICENSE:=GPLv2 + +include $(INCLUDE_DIR)/package.mk + +define Package/mwan3 + SECTION:=net + CATEGORY:=Network + SUBMENU:=Routing and Redirection + DEPENDS:=+ip +iptables +iptables-mod-conntrack-extra +iptables-mod-ipopt + TITLE:=Multiwan hotplug script with connection tracking support + MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com> + PKGARCH:=all +endef + +define Package/mwan3/description + Hotplug script which makes configuration of multiple WAN interfaces simple and manageable. With loadbalancing/failover support for up to 250 wan interfaces, connection tracking and an easy to manage traffic ruleset. +endef + +define Package/mwan3/conffiles + /etc/config/mwan3 +endef + +define Build/Compile +endef + +define Package/mwan3/install + $(CP) ./files/* $(1) +endef + +define Package/mwan3/postinst + [ -n "$${IPKG_INSTROOT}" ] || /etc/init.d/mwan3 enable + exit 0 +endef + +$(eval $(call BuildPackage,mwan3)) diff --git a/net/mwan3/files/etc/config/mwan3 b/net/mwan3/files/etc/config/mwan3 new file mode 100644 index 000000000..53f2f9832 --- /dev/null +++ b/net/mwan3/files/etc/config/mwan3 @@ -0,0 +1,79 @@ + +config interface 'wan' + option enabled '1' + list track_ip '8.8.4.4' + list track_ip '8.8.8.8' + list track_ip '208.67.222.222' + list track_ip '208.67.220.220' + option reliability '2' + option count '1' + option timeout '2' + option interval '5' + option down '3' + option up '8' + +config interface 'wan2' + option enabled '0' + list track_ip '8.8.8.8' + list track_ip '208.67.220.220' + option reliability '1' + option count '1' + option timeout '2' + option interval '5' + option down '3' + option up '8' + +config member 'wan_m1_w3' + option interface 'wan' + option metric '1' + option weight '3' + +config member 'wan_m2_w3' + option interface 'wan' + option metric '2' + option weight '3' + +config member 'wan2_m1_w2' + option interface 'wan2' + option metric '1' + option weight '2' + +config member 'wan2_m2_w2' + option interface 'wan2' + option metric '2' + option weight '2' + +config policy 'wan_only' + list use_member 'wan_m1_w3' + +config policy 'wan2_only' + list use_member 'wan2_m1_w2' + +config policy 'balanced' + list use_member 'wan_m1_w3' + list use_member 'wan2_m1_w2' + +config policy 'wan_wan2' + list use_member 'wan_m1_w3' + list use_member 'wan2_m2_w2' + +config policy 'wan2_wan' + list use_member 'wan_m2_w3' + list use_member 'wan2_m1_w2' + +config rule 'sticky_even' + option src_ip '0.0.0.0/0.0.0.1' + option dest_port '443' + option proto 'tcp' + option use_policy 'wan_wan2' + +config rule 'sticky_odd' + option src_ip '0.0.0.1/0.0.0.1' + option dest_port '443' + option proto 'tcp' + option use_policy 'wan2_wan' + +config rule 'default_rule' + option dest_ip '0.0.0.0/0' + option use_policy 'balanced' + diff --git a/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 b/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 new file mode 100644 index 000000000..fe1375df8 --- /dev/null +++ b/net/mwan3/files/etc/hotplug.d/iface/15-mwan3 @@ -0,0 +1,328 @@ +#!/bin/sh + +mwan3_get_iface_id() +{ + let iface_count++ + [ "$1" == "$INTERFACE" ] && iface_id=$iface_count +} + +mwan3_get_route_args() +{ + route_args=$(ip -4 route list dev $DEVICE default | head -1 | sed '/.*via \([^ ]*\) .*$/!d;s//\1/;q' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}') + [ -n "$route_args" ] && route_args="via $route_args" + route_args="nexthop $route_args dev $DEVICE" +} + +mwan3_set_general_iptables() +{ + if ! iptables -S mwan3_ifaces -t mangle &> /dev/null; then + iptables -N mwan3_ifaces -t mangle + fi + + if ! iptables -S mwan3_rules -t mangle &> /dev/null; then + iptables -N mwan3_rules -t mangle + fi + + if ! iptables -S mwan3_connected -t mangle &> /dev/null; then + iptables -N mwan3_connected -t mangle + fi + + if ! iptables -S mwan3_hook -t mangle &> /dev/null; then + iptables -N mwan3_hook -t mangle + iptables -A mwan3_hook -t mangle -j CONNMARK --restore-mark --nfmask 0xff00 --ctmask 0xff00 + iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_ifaces + iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_connected + iptables -A mwan3_hook -t mangle -m mark --mark 0x0/0xff00 -j mwan3_rules + iptables -A mwan3_hook -t mangle -j CONNMARK --save-mark --nfmask 0xff00 --ctmask 0xff00 + fi + + if ! iptables -S mwan3_track_hook -t mangle &> /dev/null; then + iptables -N mwan3_track_hook -t mangle + fi + + if ! iptables -S PREROUTING -t mangle | grep mwan3_hook &> /dev/null; then + iptables -A PREROUTING -t mangle -j mwan3_hook + fi + + if ! iptables -S OUTPUT -t mangle | grep mwan3_hook &> /dev/null; then + iptables -A OUTPUT -t mangle -j mwan3_hook + fi + + if ! iptables -S OUTPUT -t mangle | grep mwan3_track_hook &> /dev/null; then + iptables -A OUTPUT -t mangle -j mwan3_track_hook + fi + + iptables -F mwan3_rules -t mangle +} + +mwan3_set_connected_iptables() +{ + local connected_networks + + if iptables -S mwan3_connected -t mangle &> /dev/null; then + iptables -F mwan3_connected -t mangle + + for connected_networks in $(ip -4 route | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}'); do + iptables -A mwan3_connected -t mangle -d $connected_networks -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00 + done + + iptables -I mwan3_connected -t mangle -d 224.0.0.0/3 -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00 + iptables -I mwan3_connected -t mangle -d 127.0.0.0/8 -m mark --mark 0x0/0xff00 -j MARK --set-xmark 0xff00/0xff00 + fi +} + +mwan3_set_iface_iptables() +{ + local local_net local_nets + + local_net=$(ip -4 route list dev $DEVICE scope link | awk '{print $1}' | egrep '[0-9]{1,3}(\.[0-9]{1,3}){3}') + + if ! iptables -S mwan3_iface_$INTERFACE -t mangle &> /dev/null; then + iptables -N mwan3_iface_$INTERFACE -t mangle + fi + + iptables -F mwan3_iface_$INTERFACE -t mangle + iptables -D mwan3_ifaces -t mangle -i $DEVICE -m mark --mark 0x0/0xff00 -j mwan3_iface_$INTERFACE &> /dev/null + + if [ $ACTION == "ifup" ]; then + if [ -n "$local_net" ]; then + for local_nets in $local_net ; do + if [ $ACTION == "ifup" ]; then + iptables -I mwan3_iface_$INTERFACE -t mangle -s $local_net -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE" -j MARK --set-xmark 0xff00/0xff00 + fi + done + fi + + iptables -A mwan3_iface_$INTERFACE -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE" -j MARK --set-xmark $(($iface_id*256))/0xff00 + iptables -A mwan3_ifaces -t mangle -i $DEVICE -m mark --mark 0x0/0xff00 -j mwan3_iface_$INTERFACE + fi + + if [ $ACTION == "ifdown" ]; then + iptables -X mwan3_iface_$INTERFACE -t mangle + fi +} + +mwan3_set_iface_route() +{ + ip -4 route flush table $iface_id + [ $ACTION == "ifup" ] && ip -4 route add table $iface_id default $route_args +} + +mwan3_set_iface_rules() +{ + while [ -n "$(ip -4 rule list | awk '$1 == "'$(($iface_id+1000)):'"')" ]; do + ip -4 rule del pref $(($iface_id+1000)) + done + + while [ -n "$(ip -4 rule list | awk '$1 == "'$(($iface_id+2000)):'"')" ]; do + ip -4 rule del pref $(($iface_id+2000)) + done + + while [ -n "$(ip -4 rule list | awk '$1 == "2254:"')" ]; do + ip -4 rule del pref 2254 + done + + [ $ACTION == "ifup" ] && ip -4 rule add pref $(($iface_id+1000)) iif $DEVICE lookup main + [ $ACTION == "ifup" ] && ip -4 rule add pref $(($iface_id+2000)) fwmark $(($iface_id*256))/0xff00 lookup $iface_id + ip rule add pref 2254 fwmark 0xfe00/0xff00 unreachable +} + +mwan3_track() +{ + local track_ip track_ips reliability count timeout interval down up + + mwan3_list_track_ips() + { + track_ips="$1 $track_ips" + } + config_list_foreach $INTERFACE track_ip mwan3_list_track_ips + + if [ -n "$track_ips" ]; then + config_get reliability $INTERFACE reliability 1 + config_get count $INTERFACE count 1 + config_get timeout $INTERFACE timeout 4 + config_get interval $INTERFACE interval 10 + config_get down $INTERFACE down 5 + config_get up $INTERFACE up 5 + + if ! iptables -S mwan3_track_$INTERFACE -t mangle &> /dev/null; then + iptables -N mwan3_track_$INTERFACE -t mangle + iptables -A mwan3_track_hook -t mangle -p icmp -m icmp --icmp-type 8 -m length --length 32 -j mwan3_track_$INTERFACE + fi + + iptables -F mwan3_track_$INTERFACE -t mangle + + for track_ip in $track_ips; do + iptables -A mwan3_track_$INTERFACE -t mangle -d $track_ip -j MARK --set-xmark 0xff00/0xff00 + done + + [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track $INTERFACE $DEVICE $reliability $count $timeout $interval $down $up $track_ips & + else + iptables -D mwan3_track_hook -t mangle -p icmp -m icmp --icmp-type 8 -m length --length 32 -j mwan3_track_$INTERFACE &> /dev/null + iptables -F mwan3_track_$INTERFACE -t mangle &> /dev/null + iptables -X mwan3_track_$INTERFACE -t mangle &> /dev/null + fi +} + +mwan3_set_policy() +{ + local iface_count iface_id metric probability weight + + config_get INTERFACE $1 interface + config_get metric $1 metric 1 + config_get weight $1 weight 1 + + [ -n "$INTERFACE" ] || return 0 + + config_foreach mwan3_get_iface_id interface + + [ -n "$iface_id" ] || return 0 + + if iptables -S mwan3_iface_$INTERFACE -t mangle &> /dev/null; then + if [ "$metric" -lt "$lowest_metric" ]; then + + total_weight=$weight + iptables -F mwan3_policy_$policy -t mangle + iptables -A mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "$INTERFACE $weight $weight" -j MARK --set-xmark $(($iface_id*256))/0xff00 + + lowest_metric=$metric + + elif [ "$metric" -eq "$lowest_metric" ]; then + + total_weight=$(($total_weight+$weight)) + probability=$(($weight*1000/$total_weight)) + + if [ "$probability" -lt 10 ]; then + probability="0.00$probability" + elif [ $probability -lt 100 ]; then + probability="0.0$probability" + elif [ $probability -lt 1000 ]; then + probability="0.$probability" + else + probability="1" + fi + + probability="-m statistic --mode random --probability $probability" + + iptables -I mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 $probability -m comment --comment "$INTERFACE $weight $total_weight" -j MARK --set-xmark $(($iface_id*256))/0xff00 + fi + fi +} + +mwan3_set_policies_iptables() +{ + local lowest_metric policy total_weight + + policy=$1 + + if [ "$policy" != $(echo "$policy" | cut -c1-15) ]; then + logger -t mwan3 -p warn "Policy $policy exceeds max of 15 chars. Not setting policy" && return 0 + fi + + if ! iptables -S mwan3_policy_$policy -t mangle &> /dev/null; then + iptables -N mwan3_policy_$policy -t mangle + fi + + iptables -F mwan3_policy_$policy -t mangle + iptables -A mwan3_policy_$policy -t mangle -m mark --mark 0x0/0xff00 -m comment --comment "unreachable" -j MARK --set-xmark 0xfe00/0xff00 + + lowest_metric=256 + total_weight=0 + + config_list_foreach $policy use_member mwan3_set_policy + + iptables -X $policy -t mangle &> /dev/null +} + +mwan3_set_user_rules_iptables() +{ + local proto src_ip src_port dest_ip dest_port use_policy + + config_get proto $1 proto all + config_get src_ip $1 src_ip 0.0.0.0/0 + config_get src_port $1 src_port 0:65535 + config_get dest_ip $1 dest_ip 0.0.0.0/0 + config_get dest_port $1 dest_port 0:65535 + config_get use_policy $1 use_policy + + if [ -n "$use_policy" ]; then + if [ "$use_policy" == "default" ]; then + use_policy="MARK --set-xmark 0xff00/0xff00" + elif [ "$use_policy" == "unreachable" ]; then + use_policy="MARK --set-xmark 0xfe00/0xff00" + else + use_policy="mwan3_policy_$use_policy" + fi + + case $proto in + tcp|udp) + iptables -A mwan3_rules -t mangle -p $proto -s $src_ip -d $dest_ip -m multiport --sports $src_port -m multiport --dports $dest_port -m mark --mark 0/0xff00 -m comment --comment "$1" -j $use_policy &> /dev/null + ;; + *) + iptables -A mwan3_rules -t mangle -p $proto -s $src_ip -d $dest_ip -m mark --mark 0/0xff00 -m comment --comment "$1" -j $use_policy &> /dev/null + ;; + esac + fi +} + +mwan3_ifupdown() +{ + local counter enabled iface_count iface_id route_args wan_metric + + [ -n "$DEVICE" ] || exit 0 + [ -n "$INTERFACE" ] || exit 0 + [ "$(uci get -P /var/state mwan3.$INTERFACE 2> /dev/null)" == "interface" ] || return 0 + + config_load mwan3 + config_get enabled $INTERFACE enabled 0 + + counter=0 + + if [ $ACTION == "ifup" ]; then + [ "$enabled" -eq 1 ] || exit 0 + + while [ -z "$(ip -4 route list dev $DEVICE default | head -1)" -a "$counter" -lt 10 ]; do + sleep 1 + let counter++ + if [ "$counter" -ge 10 ]; then + logger -t mwan3 -p warn "Could not find gateway for interface $INTERFACE ($DEVICE)" && exit 0 + fi + done + + mwan3_get_route_args + fi + + while [ "$(pgrep -f -o hotplug-call)" -ne $$ -a "$counter" -lt 60 ]; do + sleep 1 + let counter++ + if [ "$counter" -ge 60 ]; then + logger -t mwan3 -p warn "Timeout waiting for older hotplug processes to finish. $ACTION interface $INTERFACE ($DEVICE) aborted" && exit 0 + fi + done + + config_foreach mwan3_get_iface_id interface + + [ -n "$iface_id" ] || exit 0 + [ "$iface_count" -le 250 ] || exit 0 + unset iface_count + unset counter + + logger -t mwan3 -p notice "$ACTION interface $INTERFACE ($DEVICE)" + + mwan3_set_general_iptables + mwan3_set_iface_iptables + mwan3_set_iface_route + mwan3_set_iface_rules + + [ $ACTION == "ifup" ] && mwan3_track + + config_foreach mwan3_set_policies_iptables policy + config_foreach mwan3_set_user_rules_iptables rule +} + +case "$ACTION" in + ifup|ifdown) + mwan3_ifupdown + mwan3_set_connected_iptables + ;; +esac diff --git a/net/mwan3/files/etc/init.d/mwan3 b/net/mwan3/files/etc/init.d/mwan3 new file mode 100755 index 000000000..44af759ed --- /dev/null +++ b/net/mwan3/files/etc/init.d/mwan3 @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common +START=99 + +start() { + /usr/sbin/mwan3 start +} + +stop() { + /usr/sbin/mwan3 stop +} + +restart() { + stop + start +} + +boot() { + # Don't start on boot, mwan3 is started by hotplug event. + return 0 +} diff --git a/net/mwan3/files/usr/sbin/mwan3 b/net/mwan3/files/usr/sbin/mwan3 new file mode 100755 index 000000000..7d274d430 --- /dev/null +++ b/net/mwan3/files/usr/sbin/mwan3 @@ -0,0 +1,208 @@ +#!/bin/sh /etc/rc.common + +. /lib/network/config.sh + +extra_help() { + cat <<EOF + + ifup <iface> Start service on interface + ifdown <iface> Stop service on interface + interfaces Show interfaces status + policies Show policies status + rules Show rules status + status Show all status +EOF +} + +EXTRA_COMMANDS="ifdown ifup interfaces policies rules status" +EXTRA_HELP="$(extra_help)" + + +ifdown() +{ + if [ -z "$1" ]; then + echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>" && exit 0 + fi + + if [ -n "$2" ]; then + echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && exit 0 + fi + + local device + + device=$(uci get -p /var/state network.$1.ifname) &> /dev/null + + if [ -e /var/run/mwan3track-$1.pid ] ; then + kill $(cat /var/run/mwan3track-$1.pid) + rm /var/run/mwan3track-$1.pid + fi + + if [ -n "$device" ] ; then + ACTION=ifdown INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface + fi +} + +ifup() +{ + config_load mwan3 + + if [ -z "$1" ]; then + echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0 + fi + + if [ -n "$2" ]; then + echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0 + fi + + local device enabled + + config_get enabled "$1" enabled 0 + + device=$(uci get -p /var/state network.$1.ifname) &> /dev/null + + if [ -n "$device" ] ; then + [ "$enabled" -eq 1 ] && ACTION=ifup INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface + fi +} + +interfaces() +{ + config_load mwan3 + + local device enabled iface_id tracking + + echo "Interface status:" + + check_iface_status() + { + device=$(uci get -p /var/state network.$1.ifname) &> /dev/null + + if [ -z "$device" ]; then + echo "Interface $1 is unknown" + return 0 + fi + + config_get enabled "$1" enabled 0 + let iface_id++ + + if [ -n "$(ps -w | grep mwan3track | grep -v grep | sed '/.*\/usr\/sbin\/mwan3track \([^ ]*\) .*$/!d;s//\1/' | awk '$1 == ("'$1'")')" ]; then + tracking="active" + else + tracking="down" + fi + + if [ -n "$(ip rule | awk '$5 == ("'$device'")')" -a -n "$(iptables -S mwan3_iface_$1 -t mangle 2> /dev/null)" -a -n "$(ip -4 route list table $iface_id default dev $device 2> /dev/null)" ]; then + if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then + echo "Interface $1 is online (tracking $tracking)" + else + echo "Interface $1 is online" + fi + elif [ -n "$(ip rule | awk '$5 == ("'$device'")')" -o -n "$(iptables -S mwan3_iface_$1 -t mangle 2> /dev/null)" -o -n "$(ip -4 route list table $iface_id default dev $device 2> /dev/null)" ]; then + echo "Interface $1 error" + else + if [ "$enabled" -eq 1 ]; then + if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then + echo "Interface $1 is offline (tracking $tracking)" + else + echo "Interface $1 is offline" + fi + else + echo "Interface $1 is disabled" + fi + fi + } + config_foreach check_iface_status interface + echo -e +} + +policies() +{ + local percent policy share total_weight weight iface + + for policy in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3_policy_ | sort -u); do + echo "Policy $policy:" | sed 's/mwan3_policy_//g' + + for iface in $(iptables -S $policy -t mangle | cut -s -d'"' -f2 | awk '{print $1}'); do + [ -n "$total_weight" ] || total_weight=$(iptables -S $policy -t mangle | grep "$iface " | cut -s -d'"' -f2 | awk '{print $3}') + done + + if [ ! -z "${total_weight##*[!0-9]*}" ]; then + for iface in $(iptables -S $policy -t mangle | cut -s -d'"' -f2 | awk '{print $1}'); do + weight=$(iptables -S $policy -t mangle | grep "$iface " | cut -s -d'"' -f2 | awk '{print $2}') + percent=$(($weight*100/$total_weight)) + echo " $iface ($percent%)" + done + else + echo " $(iptables -S $policy -t mangle | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')" + fi + + echo -e + + unset iface + unset total_weight + done +} +rules() +{ + if [ -n "$(iptables -S mwan3_connected -t mangle 2> /dev/null)" ]; then + echo "Known networks:" + echo "destination policy hits" | awk '{ printf "%-19s%-19s%-9s%s\n",$1,$2,$3}' + echo "------------------------------------------------" + iptables -L mwan3_connected -t mangle -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//g' | awk '{printf "%-19s%-19s%-9s%s\n",$9,"default",$1}' + echo -e + fi + + if [ -n "$(iptables -S mwan3_rules -t mangle 2> /dev/null)" ]; then + echo "Active rules:" + echo "source destination proto src-port dest-port policy hits" | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$1,$2,$3,$4,$5,$6,$7}' + echo "---------------------------------------------------------------------------------------------------" + iptables -L mwan3_rules -t mangle -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//g' | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$8,$9,$4,$12,$15,$3,$1}' + echo -e + fi +} + +status() +{ + interfaces + policies + rules +} + +start() +{ + config_load mwan3 + config_foreach ifup interface +} + +stop() +{ + local route rule table + + killall mwan3track &> /dev/null + rm /var/run/mwan3track-* &> /dev/null + + for route in $(ip route list table all | sed 's/.*table \([^ ]*\) .*/\1/' | awk '{print $1}' | awk '{for(i=1;i<=NF;i++) if($i+0>0) if($i+0<255) {print;break}}'); do + ip -4 route flush table $route &> /dev/null + done + + for rule in $(ip -4 rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do + ip -4 rule del pref $rule &> /dev/null + done + + iptables -D PREROUTING -t mangle -j mwan3_hook &> /dev/null + iptables -D OUTPUT -t mangle -j mwan3_hook &> /dev/null + iptables -D OUTPUT -t mangle -j mwan3_track_hook &> /dev/null + + for table in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3 | sort -u); do + iptables -F $table -t mangle &> /dev/null + done + + for table in $(iptables -S -t mangle | awk '{print $2}' | grep mwan3 | sort -u); do + iptables -X $table -t mangle &> /dev/null + done +} + +restart() { + stop + start +} diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track new file mode 100755 index 000000000..c4d25e99d --- /dev/null +++ b/net/mwan3/files/usr/sbin/mwan3track @@ -0,0 +1,65 @@ +#!/bin/sh + +[ -z "$9" ] && echo "Error: should not be started manually" && exit 0 + +if [ -e /var/run/mwan3track-$1.pid ] ; then + kill $(cat /var/run/mwan3track-$1.pid) &> /dev/null + rm /var/run/mwan3track-$1.pid &> /dev/null +fi + +echo "$$" > /var/run/mwan3track-$1.pid + +score=$(($7+$8)) +track_ips=$(echo $* | cut -d ' ' -f 9-99) +host_up_count=0 +lost=0 + +while true; do + + for track_ip in $track_ips; do + ping -I $2 -c $4 -W $5 -s 4 -q $track_ip &> /dev/null + if [ $? -eq 0 ]; then + let host_up_count++ + else + let lost++ + fi + done + + if [ $host_up_count -lt $3 ]; then + let score-- + + if [ $score -lt $8 ]; then score=0 ; fi + if [ $score -eq $8 ]; then + + logger -t mwan3track -p notice "Interface $1 ($2) is offline" + env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + score=0 + + fi + + else + + if [ $score -lt $(($7+$8)) ] && [ $lost -gt 0 ]; then + + logger -t mwan3track -p info "Lost $(($lost*$4)) ping(s) on interface $1 ($2)" + + fi + + let score++ + lost=0 + + if [ $score -gt $8 ]; then score=$(($7+$8)); fi + if [ $score -eq $8 ]; then + + logger -t mwan3track -p notice "Interface $1 ($2) is online" + env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface + rm /var/run/mwan3track-$1.pid + exit 0 + fi + fi + + host_up_count=0 + sleep $6 +done + +exit 1 diff --git a/net/netatalk/Makefile b/net/netatalk/Makefile new file mode 100644 index 000000000..8729053c9 --- /dev/null +++ b/net/netatalk/Makefile @@ -0,0 +1,86 @@ +# +# Copyright (C) 2009-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=netatalk +PKG_VERSION:=2.2.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=@SF/netatalk +PKG_MD5SUM:=40753a32340c24e4ec395aeb55ef056e + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/netatalk + SECTION:=net + CATEGORY:=Network + SUBMENU:=Filesystem + DEPENDS:=+attr +libdb47 +libgcrypt +libopenssl $(LIBRPC_DEPENDS) + TITLE:=netatalk + URL:=http://netatalk.sourceforge.net + MAINTAINER:=W. Michael Petullo <mike@flyn.org> +endef + +define Package/netatalk/decription + Netatalk is a freely-available Open Source AFP fileserver. + It also provides a kernel level implementation of the AppleTalk + Protocol Suite. +endef + +define Package/netatalk/conffiles +/etc/netatalk/afpd.conf +endef + +TARGET_CFLAGS += -std=gnu99 +TARGET_LDFLAGS += $(LIBRPC) + +CONFIGURE_ARGS += \ + --disable-afs \ + --enable-hfs \ + --disable-debugging \ + --disable-shell-check \ + --disable-timelord \ + --disable-a2boot \ + --disable-cups \ + --disable-tcp-wrappers \ + --with-cnid-default-backend=dbd \ + --with-bdb="$(STAGING_DIR)/usr/" \ + --with-libgcrypt-dir="$(STAGING_DIR)/usr" \ + --with-ssl-dir="$(STAGING_DIR)/usr" \ + --with-uams-path="/usr/lib/uams" \ + --without-acls \ + --without-pam \ + --disable-admin-group \ + --disable-srvloc \ + --disable-zeroconf \ + $(if $(CONFIG_SHADOW_PASSWORDS),--with-shadow,--without-shadow) \ + --without-ldap + +define Package/netatalk/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/lib/uams + $(INSTALL_DIR) $(1)/etc/netatalk + $(INSTALL_DIR) $(1)/etc/init.d + $(CP) $(PKG_INSTALL_DIR)/usr/bin/afppasswd $(1)/usr/bin/ + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/afpd $(1)/usr/sbin/ + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/cnid_dbd $(1)/usr/sbin/ + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/cnid_metad $(1)/usr/sbin/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/uams/*.so $(1)/usr/lib/uams/ + $(CP) ./files/AppleVolumes.default $(1)/etc/netatalk/ + $(CP) $(PKG_INSTALL_DIR)/etc/netatalk/AppleVolumes.system $(1)/etc/netatalk/ + $(INSTALL_CONF) ./files/afpd.conf $(1)/etc/netatalk/ + $(INSTALL_BIN) ./files/afpd.init $(1)/etc/init.d/afpd +endef + +$(eval $(call BuildPackage,netatalk)) diff --git a/net/netatalk/files/AppleVolumes.default b/net/netatalk/files/AppleVolumes.default new file mode 100644 index 000000000..5835163a5 --- /dev/null +++ b/net/netatalk/files/AppleVolumes.default @@ -0,0 +1,2 @@ +- +/tmp Temp allow:root,nobody cnidscheme:dbd diff --git a/net/netatalk/files/afpd.conf b/net/netatalk/files/afpd.conf new file mode 100644 index 000000000..097e954e5 --- /dev/null +++ b/net/netatalk/files/afpd.conf @@ -0,0 +1 @@ +- -noddp -uampath /usr/lib/uams -uamlist uams_guest.so,uams_passwd.so,uams_dhx_passwd.so,uams_randnum.so,uams_dhx2.so -passwdfile /etc/netatalk/afppasswd -savepassword -passwdminlen 0 -nosetpassword -defaultvol /etc/netatalk/AppleVolumes.default -systemvol /etc/netatalk/AppleVolumes.system -nouservol -guestname "nobody" -sleep 1 -icon diff --git a/net/netatalk/files/afpd.init b/net/netatalk/files/afpd.init new file mode 100644 index 000000000..8b1333984 --- /dev/null +++ b/net/netatalk/files/afpd.init @@ -0,0 +1,23 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2010-2012 OpenWrt.org + +START=70 + +MAXCONS="7" + +start() +{ + service_start /usr/sbin/cnid_metad + service_start /usr/sbin/afpd -c ${MAXCONS} +} + +stop() +{ + service_stop /usr/sbin/afpd + service_stop /usr/sbin/cnid_metad +} + +reload() +{ + service_reload /usr/sbin/afpd +} diff --git a/net/netatalk/patches/001-automake-compat.patch b/net/netatalk/patches/001-automake-compat.patch new file mode 100644 index 000000000..e56b08650 --- /dev/null +++ b/net/netatalk/patches/001-automake-compat.patch @@ -0,0 +1,9 @@ +--- a/macros/iconv.m4 ++++ b/macros/iconv.m4 +@@ -114,6 +114,5 @@ int main() { + + CFLAGS="$savedcflags" + LDFLAGS="$savedldflags" +- CPPFLAGS="$saved_CPPFLAGS" + + ]) diff --git a/net/nginx/Makefile b/net/nginx/Makefile index 89a7ce99e..e93326e52 100644 --- a/net/nginx/Makefile +++ b/net/nginx/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nginx PKG_VERSION:=1.4.7 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://nginx.org/download/ diff --git a/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch index 52c1ce7ff..ba63834e8 100644 --- a/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch +++ b/net/nginx/patches/400-nginx-1.4.x_proxy_protocol_patch_v2.patch @@ -882,17 +882,6 @@ Index: nginx-1.4.7/src/http/ngx_http_request.c #if (NGX_HTTP_SSL) -@@ -1291,6 +1368,10 @@ ngx_http_read_request_header(ngx_http_re - c = r->connection; - rev = c->read; - -+fprintf(stderr, "DEBUG: pos: %p, last: %p, start: %p, end: %p\n", -+ r->header_in->pos, r->header_in->last, r->header_in->start, -+ r->header_in->end); -+ - n = r->header_in->last - r->header_in->pos; - - if (n > 0) { Index: nginx-1.4.7/src/http/ngx_http_upstream.c =================================================================== --- nginx-1.4.7.orig/src/http/ngx_http_upstream.c diff --git a/net/ocserv/files/ocserv.init b/net/ocserv/files/ocserv.init index d3e7f83a0..612262087 100644 --- a/net/ocserv/files/ocserv.init +++ b/net/ocserv/files/ocserv.init @@ -4,30 +4,6 @@ SERVICE_USE_PID=1 START=50 -setup_firewall() { - local port fw - config_get port $1 port - test -z "$port" && return - - config_get fwport $1 fwport - test "$fwport" = "$port" && return - - logger -t ocserv "opening port $port..." - #can we remove the old rule? - uci add firewall rule - uci set firewall.@rule[-1].src=wan - uci set firewall.@rule[-1].name="ocserv-ext-port" - uci set firewall.@rule[-1].target=ACCEPT - uci set firewall.@rule[-1].proto=tcpudp - uci set firewall.@rule[-1].dest_port=$port - uci commit firewall - - uci set ocserv.config.fwport="$port" - uci commit ocserv - - /etc/init.d/firewall restart -} - setup_config() { config_get port $1 port "4443" config_get max_clients $1 max_clients "8" @@ -170,8 +146,6 @@ start() { chmod 600 /var/etc/ocpasswd config_foreach setup_users ocservusers - setup_firewall config - service_start /usr/sbin/ocserv -c /var/etc/ocserv.conf } diff --git a/net/p910nd/Makefile b/net/p910nd/Makefile new file mode 100644 index 000000000..d07ee1ac3 --- /dev/null +++ b/net/p910nd/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2009-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=p910nd +PKG_VERSION:=0.97 +PKG_RELEASE:=4 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=@SF/p910nd +PKG_LICENSE:=GPLv2 +PKG_LICENSE_FILES:=COPYING +PKG_MD5SUM:=69461a6c54dca0b13ecad5b83864b43e +PKG_MAINTAINER:=Philipp Kerling <pkerling@casix.org> + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/p910nd + SECTION:=net + CATEGORY:=Network + SUBMENU:=Printing + TITLE:=A small non-spooling printer server + URL:=http://p910nd.sourceforge.net +endef + +define Package/p910nd/conffiles +/etc/config/p910nd +endef + +define Package/p910nd/description + p910nd is a small daemon that copies any data received on + the port it is listening on to the corresponding printer + port. It is primarily intended for diskless Linux hosts + running as printer drivers but there is no reason why it + could not be used on diskful hosts. Port 9100 is copied + to /dev/lp0, 9101 to /dev/lp1 and 9102 to /dev/lp2. The + default is port 9100 to /dev/lp0. +endef + +MAKE_FLAGS += \ + CFLAGS="$(TARGET_CFLAGS) -DLOCKFILE_DIR=\"\\\"/tmp\"\\\"" + +define Package/p910nd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/p910nd $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/p910nd.config $(1)/etc/config/p910nd + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/p910nd.init $(1)/etc/init.d/p910nd +endef + +$(eval $(call BuildPackage,p910nd)) diff --git a/net/p910nd/files/p910nd.config b/net/p910nd/files/p910nd.config new file mode 100644 index 000000000..d5090359b --- /dev/null +++ b/net/p910nd/files/p910nd.config @@ -0,0 +1,5 @@ +config p910nd + option device /dev/usb/lp0 + option port 0 + option bidirectional 1 + option enabled 0 diff --git a/net/p910nd/files/p910nd.init b/net/p910nd/files/p910nd.init new file mode 100644 index 000000000..8757551bf --- /dev/null +++ b/net/p910nd/files/p910nd.init @@ -0,0 +1,51 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2007 OpenWrt.org +START=50 + +append_bool() { + local section="$1" + local option="$2" + local value="$3" + local _val + config_get_bool _val "$section" "$option" '0' + [ "$_val" -gt 0 ] && append args "$3" +} + +append_string() { + local section="$1" + local option="$2" + local value="$3" + local _val + config_get _val "$section" "$option" + [ -n "$_val" ] && append args "$3$_val" +} + +start_service() { + local section="$1" + args="" + + append_bool "$section" bidirectional "-b" + append_string "$section" device "-f " + append_string "$section" bind "-i " + append_string "$section" port "" + config_get_bool "enabled" "$section" "enabled" '1' + [ "$enabled" -gt 0 ] && /usr/sbin/p910nd $args +} + +stop_service() { + local section="$1" + config_get port "$section" port + + PID_F=/var/run/p910${port}d.pid + [ -f $PID_F ] && kill $(cat $PID_F) +} + +start() { + config_load "p910nd" + config_foreach start_service p910nd +} + +stop() { + config_load "p910nd" + config_foreach stop_service p910nd +} diff --git a/net/radsecproxy/Makefile b/net/radsecproxy/Makefile new file mode 100644 index 000000000..b36503aa1 --- /dev/null +++ b/net/radsecproxy/Makefile @@ -0,0 +1,57 @@ +# +# Copyright (C) 2008-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=radsecproxy +PKG_VERSION:=1.6.5 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://software.uninett.no/radsecproxy/ +PKG_MD5SUM:=f74f82a7ae2cdf2b1d9d271a5c360617 + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/radsecproxy + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libopenssl +libpthread + TITLE:=radsecproxy + URL:=http://software.uninett.no/radsecproxy + MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk> +endef + +define Package/radsecproxy/description + A generic radius proxy for UDP/TLS (RadSec) +endef + +CONFIGURE_ARGS+= \ + --with-ssl="$(STAGING_DIR)/usr" + +#TARGET_CFLAGS += -ansi +#TARGET_CFLAGS += -std=c99 +TARGET_CFLAGS += -Wno-long-long + + +define Package/radsecproxy/install + $(INSTALL_DIR) $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/radsecproxy $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/ + $(CP) $(PKG_BUILD_DIR)/radsecproxy.conf-example $(1)/etc/radsecproxy.conf + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/radsecproxy.init $(1)/etc/init.d/radsecproxy +endef + +define Package/radsecproxy/conffiles +/etc/radsecproxy.conf +endef + +$(eval $(call BuildPackage,radsecproxy)) + diff --git a/net/radsecproxy/files/radsecproxy.init b/net/radsecproxy/files/radsecproxy.init new file mode 100644 index 000000000..39bdc6e4b --- /dev/null +++ b/net/radsecproxy/files/radsecproxy.init @@ -0,0 +1,16 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=70 + +USE_PROCD=1 +PROG=/usr/sbin/radsecproxy +CONFFILE=/etc/radsecproxy.conf + +start_service() { + procd_open_instance + procd_set_param command $PROG -f -c $CONFFILE + procd_set_param file $CONFFILE + procd_set_param respawn + procd_close_instance +} diff --git a/net/radsecproxy/patches/100-missing-return.patch b/net/radsecproxy/patches/100-missing-return.patch new file mode 100644 index 000000000..871fc6e10 --- /dev/null +++ b/net/radsecproxy/patches/100-missing-return.patch @@ -0,0 +1,58 @@ +--- a/dtls.c ++++ b/dtls.c +@@ -523,6 +523,7 @@ void *udpdtlsserverrd(void *arg) { + free(params); + cacheexpire(sessioncache, &lastexpiry); + } ++ return NULL; + } + + int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *text) { +@@ -642,6 +643,7 @@ void *udpdtlsclientrd(void *arg) { + if (udp2bio(s, conf->servers->rbios, cnt)) + debug(DBG_DBG, "radudpget: got DTLS in UDP from %s", addr2string((struct sockaddr *)&from)); + } ++ return NULL; + } + + void *dtlsclientrd(void *arg) { +--- a/radsecproxy.c ++++ b/radsecproxy.c +@@ -3203,6 +3203,8 @@ void *sighandler(void *arg) { + debug(DBG_WARN, "sighandler: ignoring signal %d", sig); + } + } ++ ++ return NULL; + } + + int createpidfile(const char *pidfile) { +@@ -3289,6 +3291,8 @@ int radsecproxy_main(int argc, char **ar + /* just hang around doing nothing, anything to do here? */ + for (;;) + sleep(1000); ++ ++ return 0; + } + + /* Local Variables: */ +--- a/udp.c ++++ b/udp.c +@@ -266,6 +266,8 @@ void *udpclientrd(void *arg) { + buf = radudpget(*s, NULL, &server, NULL); + replyh(server, buf); + } ++ ++ return NULL; + } + + void *udpserverrd(void *arg) { +@@ -310,6 +312,8 @@ void *udpserverwr(void *arg) { + debug(DBG_DBG, "udpserverwr: refcount %d", reply->refcount); + freerq(reply); + } ++ ++ return NULL; + } + + void addclientudp(struct client *client) { diff --git a/net/radsecproxy/patches/200-logdest-on-foreground.patch b/net/radsecproxy/patches/200-logdest-on-foreground.patch new file mode 100644 index 000000000..6678448ac --- /dev/null +++ b/net/radsecproxy/patches/200-logdest-on-foreground.patch @@ -0,0 +1,31 @@ +diff --git a/radsecproxy.c b/radsecproxy.c +index 563c4a8..9fa076d 100644 +--- a/radsecproxy.c ++++ b/radsecproxy.c +@@ -3382,18 +3382,16 @@ int radsecproxy_main(int argc, char **argv) { + options.loglevel = loglevel; + else if (options.loglevel) + debug_set_level(options.loglevel); +- if (!foreground) { +- debug_set_destination(options.logdestination +- ? options.logdestination +- : "x-syslog:///", LOG_TYPE_DEBUG); ++ debug_set_destination(options.logdestination ++ ? options.logdestination ++ : "x-syslog:///", LOG_TYPE_DEBUG); + #if defined(WANT_FTICKS) +- if (options.ftickssyslogfacility) { +- debug_set_destination(options.ftickssyslogfacility, +- LOG_TYPE_FTICKS); +- free(options.ftickssyslogfacility); +- } +-#endif ++ if (options.ftickssyslogfacility) { ++ debug_set_destination(options.ftickssyslogfacility, ++ LOG_TYPE_FTICKS); ++ free(options.ftickssyslogfacility); + } ++#endif + free(options.logdestination); + + if (!list_first(clconfs)) diff --git a/net/rsync/Makefile b/net/rsync/Makefile index e73aebca3..6d6d201b6 100644 --- a/net/rsync/Makefile +++ b/net/rsync/Makefile @@ -17,6 +17,7 @@ PKG_MD5SUM:=43bd6676f0b404326eee2d63be3cdcfe PKG_LICENSE:=GPL-3.0 PKG_LICENSE_FILES:=COPYING PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com> +PKG_LICENSE:=GPL-3.0 PKG_INSTALL:=1 PKG_BUILD_PARALLEL:=1 diff --git a/net/sslh/Makefile b/net/sslh/Makefile index a3a6cb4bd..043342fa7 100644 --- a/net/sslh/Makefile +++ b/net/sslh/Makefile @@ -13,7 +13,7 @@ PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://rutschle.net/tech/ -PKG_MD5SUM:=1e85b84eb82a96b81de9b1e637a3e795 +PKG_MD5SUM:=c6e7d1cb0adb15f6efe480e36d98c560 include $(INCLUDE_DIR)/package.mk diff --git a/net/tgt/Makefile b/net/tgt/Makefile index f94af51ac..8efa9e72a 100644 --- a/net/tgt/Makefile +++ b/net/tgt/Makefile @@ -18,6 +18,7 @@ PKG_SOURCE_VERSION:=$(PKG_REV) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REV).tar.gz PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com> +PKG_LICENSE:=GPL-2.0 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) diff --git a/net/tinc/Makefile b/net/tinc/Makefile new file mode 100644 index 000000000..dc1bbbb7b --- /dev/null +++ b/net/tinc/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2007-2013 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tinc +PKG_VERSION:=1.0.24 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://www.tinc-vpn.org/packages +PKG_MD5SUM:=14a91eb2e85bdc0451a815612521b708 + +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/tinc + SECTION:=net + CATEGORY:=Network + DEPENDS:=+liblzo +libopenssl +kmod-tun + TITLE:=VPN tunneling daemon + URL:=http://www.tinc-vpn.org/ + MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk> + SUBMENU:=VPN +endef + +define Package/tinc/description + tinc is a Virtual Private Network (VPN) daemon that uses tunnelling and + encryption to create a secure private network between hosts on the Internet. +endef + +TARGET_CFLAGS += -std=gnu99 + +CONFIGURE_ARGS += \ + --with-kernel="$(LINUX_DIR)" \ + --with-zlib="$(STAGING_DIR)/usr" \ + --with-lzo-include="$(STAGING_DIR)/usr/include/lzo" + +define Package/tinc/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tincd $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) files/$(PKG_NAME).init $(1)/etc/init.d/$(PKG_NAME) + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) files/$(PKG_NAME).config $(1)/etc/config/$(PKG_NAME) + $(INSTALL_DIR) $(1)/etc/tinc + $(INSTALL_DIR) $(1)/lib/upgrade/keep.d + $(INSTALL_DATA) files/tinc.upgrade $(1)/lib/upgrade/keep.d/tinc +endef + +define Package/tinc/conffiles +/etc/config/tinc +endef + +$(eval $(call BuildPackage,tinc)) diff --git a/net/tinc/files/tinc.config b/net/tinc/files/tinc.config new file mode 100644 index 000000000..18940781a --- /dev/null +++ b/net/tinc/files/tinc.config @@ -0,0 +1,56 @@ +config tinc-net NETNAME + option enabled 0 + + ## Daemon Configuration (cmd arguments) + #option generate_keys 0 + #option key_size 2048 + #option logfile /tmp/log/tinc.NETNAME.log + #option debug 3 + + ## Server Configuration (tinc.conf) + #option AddressFamily any + #option BindToAddress 127.0.0.1 + #option BindToInterface lo + + #list ConnectTo peer1 + + #option DirectOnly 0 + #option Forwarding internal + #option GraphDumpFile /tmp/log/tinc.NETNAME.dot + #option Hostnames 0 + #option IffOneQueue 0 + #option Interface NETNAME + #option KeyExpire 3600 + #option MACExpire 600 + #option MaxTimeout 900 + #option Mode router + + option Name NODENAME + + #option PingInterval 60 + #option PingTimeout 5 + #option PriorityInheritance 0 + #option PrivateKeyFile /etc/tinc/NETNAME/rsa_key.priv + #option ProcessPriority normal + #option ReplayWindow 16 + #option StrictSubnets 0 + #option TunnelServer 0 + #option UDPRcvBuf x + #option UDPSndBuf x + +config tinc-host NODENAME + option enabled 0 + + option net NETNAME + + #list Address example.com + #option Cipher blowfish + #option ClampMSS yes + #option Compression 0 + #option Digest sha1 + #option IndirectData 0 + #option MACLength 4 + #option PMTU 1514 + #option PMTUDiscovery yes + #option Port 655 + #option Subnet 192.168.1.0/24 diff --git a/net/tinc/files/tinc.init b/net/tinc/files/tinc.init new file mode 100644 index 000000000..b24bc682e --- /dev/null +++ b/net/tinc/files/tinc.init @@ -0,0 +1,241 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2011 OpenWrt.org +# Copyright (C) 2011 Linus Lüssing +# Based on Jo-Philipp Wich's OpenVPN init script +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +START=42 + +SERVICE_USE_PID=1 + +BIN=/usr/sbin/tincd +EXTRA_COMMANDS="up down" + +LIST_SEP=" +" +TMP_TINC="/tmp/tinc" + +append_param() { + local v="$1" + case "$v" in + *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;; + *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;; + *_*) v=${v%%_*}-${v#*_} ;; + esac + ARGS="$ARGS --$v" + return 0 +} + +append_conf_bools() { + local p; local v; local s="$1"; local f="$2"; shift; shift + for p in $*; do + config_get_bool v "$s" "$p" + [ "$v" == 1 ] && echo "$p = yes" >> "$f" + [ "$v" == 0 ] && echo "$p = no" >> "$f" + done +} + +append_params() { + local p; local v; local s="$1"; shift + for p in $*; do + config_get v "$s" "$p" + IFS="$LIST_SEP" + for v in $v; do + [ -n "$v" ] && append_param "$p" && ARGS="$ARGS=$v" + done + unset IFS + done +} + +append_conf_params() { + local p; local v; local s="$1"; local f="$2"; shift; shift + for p in $*; do + config_get v "$s" "$p" + IFS="$LIST_SEP" + for v in $v; do + # Look up OpenWRT interface names + [ "$p" = "BindToInterface" ] && { + local ifname=$(uci -P /var/state get network.$v.ifname 2>&-) + [ -n "$ifname" ] && v="$ifname" + } + + [ -n "$v" ] && echo "$p = $v" >> "$f" + done + unset IFS + done +} + +section_enabled() { + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +prepare_host() { + local s="$1" + local n + + # net disabled? + config_get n "$s" net + section_enabled "$n" || return 1 + + if [ "$#" = "2" ]; then + [ "$2" != "$n" ] && return 1 + fi + + # host disabled? + section_enabled "$s" || { + [ -f "$TMP_TINC/$n/hosts/$s" ] && rm "$TMP_TINC/$n/hosts/$s" + return 1 + } + + [ ! -f "/etc/tinc/$n/hosts/$s" ] && { + echo -n "tinc: Warning, public key for $s for network $n " + echo -n "missing in /etc/tinc/$n/hosts/$s, " + echo "skipping configuration of $s" + return 1 + } + + # append flags + append_conf_bools "$s" "$TMP_TINC/$n/hosts/$s" \ + ClampMSS IndirectData PMTUDiscovery TCPOnly + + # append params + append_conf_params "$s" "$TMP_TINC/$n/hosts/$s" \ + Address Cipher Compression Digest MACLength PMTU \ + Port PublicKey PublicKeyFile Subnet +} + +check_gen_own_key() { + local s="$1"; local n; local k + + config_get n "$s" Name + config_get_bool k "$s" generate_keys 0 + [ "$k" == 0 ] && return 0 + + ([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \ + return 0 + [ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts" + + config_get k "$s" key_size + if [ -z "$k" ]; then + $BIN -c "$TMP_TINC/$s" --generate-keys </dev/null + else + $BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null + fi + + [ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts" + cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/" + [ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/" +} + +prepare_net() { + local s="$1" + local n + + section_enabled "$s" || return 1 + + # rm old config + rm -rf "$TMP_TINC/$s/" + + [ ! -d "$TMP_TINC/$s" ] && mkdir -p "$TMP_TINC/$s" + [ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/" + + # append flags + append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \ + DecrementTTL DirectOnly Hostnames IffOneQueue \ + LocalDiscovery PriorityInheritance StrictSubnets TunnelServer \ + ClampMSS IndirectData PMTUDiscovery TCPOnly + + # append params + append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \ + AddressFamily BindToAddress ConnectTo BindToInterface \ + Broadcast Device DeviceType Forwarding \ + GraphDumpFile Interface KeyExpire MACExpire \ + MaxTimeout Mode Name PingInterval PingTimeout \ + PrivateKey PrivateKeyFile ProcessPriority ReplayWindow \ + UDPRcvBuf UDPSndBuf \ + Address Cipher Compression Digest MACLength PMTU \ + Port PublicKey PublicKeyFile Subnet + + check_gen_own_key "$s" && return 0 +} + +start_instance() { + local s="$1" + + section_enabled "$s" || return 1 + + ARGS="" + + # append params + append_params "$s" logfile debug + + SERVICE_PID_FILE="/var/run/tinc.$s.pid" + service_start $BIN -c "$TMP_TINC/$s" -n $s $ARGS --pidfile="$SERVICE_PID_FILE" +} + +stop_instance() { + local s="$1" + + section_enabled "$s" || return 1 + + SERVICE_PID_FILE="/var/run/tinc.$s.pid" + service_stop $BIN + # rm old config + rm -rf "$TMP_TINC/$s/" +} + +reload_instance() { + local s="$1" + + section_enabled "$s" || return 1 + + SERVICE_PID_FILE="/var/run/tinc.$s.pid" + service_reload $BIN +} + +start() { + config_load 'tinc' + + config_foreach prepare_net 'tinc-net' + config_foreach prepare_host 'tinc-host' + + config_foreach start_instance 'tinc-net' +} + +stop() { + config_load 'tinc' + config_foreach stop_instance 'tinc-net' +} + +reload() { + config_load 'tinc' + config_foreach reload_instance 'tinc-net' +} + +up() { + local exists + local instance + config_load 'tinc' + for instance in "$@"; do + config_get exists "$instance" 'TYPE' + if [ "$exists" == "tinc-net" ]; then + prepare_net "$instance" + config_foreach prepare_host 'tinc-host' "$instance" + start_instance "$instance" + fi + done +} + +down() { + local exists + local instance + config_load 'tinc' + for instance in "$@"; do + config_get exists "$instance" 'TYPE' + if [ "$exists" == "tinc-net" ]; then + stop_instance "$instance" + fi + done +} diff --git a/net/tinc/files/tinc.upgrade b/net/tinc/files/tinc.upgrade new file mode 100644 index 000000000..13f5d8049 --- /dev/null +++ b/net/tinc/files/tinc.upgrade @@ -0,0 +1 @@ +/etc/tinc/ diff --git a/net/vsftpd/Makefile b/net/vsftpd/Makefile index e1a4de017..a5c55ad06 100644 --- a/net/vsftpd/Makefile +++ b/net/vsftpd/Makefile @@ -14,6 +14,7 @@ PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://security.appspot.com/downloads/ PKG_MD5SUM:=8b00c749719089401315bd3c44dddbb2 +PKG_LICENSE:=GPLv2 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/net/wget/Makefile b/net/wget/Makefile index a791c06dd..c03dffcb3 100644 --- a/net/wget/Makefile +++ b/net/wget/Makefile @@ -15,6 +15,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) PKG_MD5SUM:=7a279d5ac5594919124d5526e7143e28 PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com> +PKG_LICENSE:=GPL-3.0+ PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) |