diff --git a/alfred/Makefile b/alfred/Makefile index 8b2d9e3..0af4221 100644 --- a/alfred/Makefile +++ b/alfred/Makefile @@ -7,14 +7,11 @@ include $(TOPDIR)/rules.mk -# -# The latest alfred git hash in PKG_REV can be obtained from https://git.open-mesh.org/alfred.git -# PKG_NAME:=alfred -PKG_VERSION:=2017.0 +PKG_VERSION:=2017.2 PKG_RELEASE:=0 -PKG_MD5SUM:=2e9ae897b1d477f14d06389eb7c1f97b -PKG_HASH:=f8d6d83d2ce30b2238354ce12073285387c0f4ca1a28060390ff50b411b50fa8 +PKG_MD5SUM:=9e2090e043b940a8765ba17394606896 +PKG_HASH:=3d5256abe298f7ee266f9d2a0c41b0878e81bc5c8413c4f66cf8813e7f7f4a03 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/alfred/files/bat-hosts.lua b/alfred/files/bat-hosts.lua index 8648caf..f9fe586 100644 --- a/alfred/files/bat-hosts.lua +++ b/alfred/files/bat-hosts.lua @@ -87,19 +87,24 @@ end local function receive_bat_hosts() -- read raw chunks from alfred, convert them to a nested table and call write_bat_hosts - local fd = io.popen("alfred -r " .. type_id) - --[[ this command returns something like - { "54:e6:fc:b9:cb:37", "00:11:22:33:44:55 ham_wlan0\x0a00:22:33:22:33:22 ham_eth0\x0a" }, - { "90:f6:52:bb:ec:57", "00:22:33:22:33:23 spam\x0a" }, - ]]-- +-- "alfred -r" can fail in slave nodes (returns empty stdout), so: +-- check output is not null before writing /tmp/bat-hosts, and retry 3 times before giving up. + for n = 1, 3 do + local fd = io.popen("alfred -r " .. type_id) + --[[ this command returns something like + { "54:e6:fc:b9:cb:37", "00:11:22:33:44:55 ham_wlan0\x0a00:22:33:22:33:22 ham_eth0\x0a" }, + { "90:f6:52:bb:ec:57", "00:22:33:22:33:23 spam\x0a" }, + ]]-- - if fd then - local output = fd:read("*a") - if output then - assert(loadstring("rows = {" .. output .. "}"))() - write_bat_hosts(rows) + if fd then + local output = fd:read("*a") + fd:close() + if output and output ~= "" then + assert(loadstring("rows = {" .. output .. "}"))() + write_bat_hosts(rows) + break + end end - fd:close() end end diff --git a/batctl/Makefile b/batctl/Makefile index 819d42b..433f0df 100644 --- a/batctl/Makefile +++ b/batctl/Makefile @@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batctl -PKG_VERSION:=2017.0 +PKG_VERSION:=2017.2 PKG_RELEASE:=0 -PKG_MD5SUM:=17c0ac0746f1994ddacc88ebf48e5aec -PKG_HASH:=c0bb1127d6070b46abeb8d6a63d1150d71fa85f87f9a846873b649a21934c686 +PKG_MD5SUM:=be82ff074beb2fdb160b54d4e579fbed +PKG_HASH:=c460d0910d03916e2cb43b60ca427d0101474680cfc096cc2d28a259a94f536c PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batman-adv/Makefile b/batman-adv/Makefile index 0ba7310..d51bc65 100644 --- a/batman-adv/Makefile +++ b/batman-adv/Makefile @@ -4,16 +4,15 @@ # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # -# $Id: Makefile 5624 2006-11-23 00:29:07Z nbd $ include $(TOPDIR)/rules.mk PKG_NAME:=batman-adv -PKG_VERSION:=2017.0 -PKG_RELEASE:=0 -PKG_MD5SUM:=1b3121f0baa8771ff6d8ad172c95904f -PKG_HASH:=65df01222bc51ec788fb1b6dc63feaf69d393f2d0a96e347d55de83b1602c509 +PKG_VERSION:=2017.2 +PKG_RELEASE:=1 +PKG_MD5SUM:=937b5f1d0188e3522d67ad45ee0a4f5a +PKG_HASH:=d487974e21cb53d39f139e93a2cf297807df5b7bf63ba6d810bad6d91537394f PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batman-adv/files/compat-hacks.h b/batman-adv/files/compat-hacks.h index 8c8a889..4ae2bcc 100644 --- a/batman-adv/files/compat-hacks.h +++ b/batman-adv/files/compat-hacks.h @@ -11,6 +11,13 @@ #endif /* < KERNEL_VERSION(4, 1, 0) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) + +/* Linux 3.15 misses the uapi include.... */ +#include + +#endif /* < KERNEL_VERSION(3, 16, 0) */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #include @@ -36,6 +43,11 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) +/* for batadv_v_elp_get_throughput which would have used + * STATION_INFO_EXPECTED_THROUGHPUT in Linux 4.0.0 + */ +#define NL80211_STA_INFO_EXPECTED_THROUGHPUT 28 + /* wild hack for batadv_getlink_net only */ #define get_link_net get_xstats_size || 1 ? fallback_net : (struct net*)netdev->rtnl_link_ops->get_xstats_size @@ -214,6 +226,56 @@ static inline int batadv_nla_put_u64_64bit(struct sk_buff *skb, int attrtype, #endif /* < KERNEL_VERSION(4, 10, 0) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 9) + +#include + +/* work around missing attribute needs_free_netdev and priv_destructor in + * net_device + */ +#define ether_setup(dev) \ + void batadv_softif_free2(struct net_device *dev) \ + { \ + batadv_softif_free(dev); \ + free_netdev(dev); \ + } \ + void (*t1)(struct net_device *dev) __attribute__((unused)); \ + bool t2 __attribute__((unused)); \ + ether_setup(dev) +#define needs_free_netdev destructor = batadv_softif_free2; t2 +#define priv_destructor destructor = batadv_softif_free2; t1 + +#endif /* < KERNEL_VERSION(4, 11, 9) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) + +static inline void *batadv_skb_put(struct sk_buff *skb, unsigned int len) +{ + return (void *)skb_put(skb, len); +} +#define skb_put batadv_skb_put + +static inline void *skb_put_zero(struct sk_buff *skb, unsigned int len) +{ + void *tmp = skb_put(skb, len); + + memset(tmp, 0, len); + + return tmp; +} + +static inline void *skb_put_data(struct sk_buff *skb, const void *data, + unsigned int len) +{ + void *tmp = skb_put(skb, len); + + memcpy(tmp, data, len); + + return tmp; +} + +#endif /* < KERNEL_VERSION(4, 13, 0) */ + /* */ #include diff --git a/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch b/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch deleted file mode 100644 index c2f9467..0000000 --- a/batman-adv/patches/0001-batman-adv-average-change-to-declare-precision-not-f.patch +++ /dev/null @@ -1,132 +0,0 @@ -From: Johannes Berg -Date: Wed, 15 Feb 2017 09:49:26 +0100 -Subject: [PATCH] batman-adv: average: change to declare precision, not factor - -Declaring the factor is counter-intuitive, and people are prone -to using small(-ish) values even when that makes no sense. - -Change the DECLARE_EWMA() macro to take the fractional precision, -in bits, rather than a factor, and update all users. - -While at it, add some more documentation. - -Acked-by: David S. Miller -Signed-off-by: Johannes Berg -[sven@narfation.org: Added compatibility code] -Signed-off-by: Sven Eckelmann ---- - compat-include/linux/average.h | 67 +++++++++++++++++++++++++++--------------- - net/batman-adv/types.h | 2 +- - 2 files changed, 45 insertions(+), 24 deletions(-) - -diff --git a/compat-include/linux/average.h b/compat-include/linux/average.h -index ec022cb6..a1e3c254 100644 ---- a/compat-include/linux/average.h -+++ b/compat-include/linux/average.h -@@ -26,49 +26,70 @@ - - #include - --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) -+#undef DECLARE_EWMA -+#endif /* < KERNEL_VERSION(4, 3, 0) */ - --/* Exponentially weighted moving average (EWMA) */ -+/* -+ * Exponentially weighted moving average (EWMA) -+ * -+ * This implements a fixed-precision EWMA algorithm, with both the -+ * precision and fall-off coefficient determined at compile-time -+ * and built into the generated helper funtions. -+ * -+ * The first argument to the macro is the name that will be used -+ * for the struct and helper functions. -+ * -+ * The second argument, the precision, expresses how many bits are -+ * used for the fractional part of the fixed-precision values. -+ * -+ * The third argument, the weight reciprocal, determines how the -+ * new values will be weighed vs. the old state, new values will -+ * get weight 1/weight_rcp and old values 1-1/weight_rcp. Note -+ * that this parameter must be a power of two for efficiency. -+ */ - --#define DECLARE_EWMA(name, _factor, _weight) \ -+#define DECLARE_EWMA(name, _precision, _weight_rcp) \ - struct ewma_##name { \ - unsigned long internal; \ - }; \ - static inline void ewma_##name##_init(struct ewma_##name *e) \ - { \ -- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ -- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ -+ /* \ -+ * Even if you want to feed it just 0/1 you should have \ -+ * some bits for the non-fractional part... \ -+ */ \ -+ BUILD_BUG_ON((_precision) > 30); \ -+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ - e->internal = 0; \ - } \ - static inline unsigned long \ - ewma_##name##_read(struct ewma_##name *e) \ - { \ -- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ -- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ -- return e->internal >> ilog2(_factor); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ -+ BUILD_BUG_ON((_precision) > 30); \ -+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ -+ return e->internal >> (_precision); \ - } \ - static inline void ewma_##name##_add(struct ewma_##name *e, \ - unsigned long val) \ - { \ - unsigned long internal = ACCESS_ONCE(e->internal); \ -- unsigned long weight = ilog2(_weight); \ -- unsigned long factor = ilog2(_factor); \ -+ unsigned long weight_rcp = ilog2(_weight_rcp); \ -+ unsigned long precision = _precision; \ - \ -- BUILD_BUG_ON(!__builtin_constant_p(_factor)); \ -- BUILD_BUG_ON(!__builtin_constant_p(_weight)); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_factor); \ -- BUILD_BUG_ON_NOT_POWER_OF_2(_weight); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ -+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ -+ BUILD_BUG_ON((_precision) > 30); \ -+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ - \ - ACCESS_ONCE(e->internal) = internal ? \ -- (((internal << weight) - internal) + \ -- (val << factor)) >> weight : \ -- (val << factor); \ -+ (((internal << weight_rcp) - internal) + \ -+ (val << precision)) >> weight_rcp : \ -+ (val << precision); \ - } - --#endif /* < KERNEL_VERSION(4, 3, 0) */ -- - #endif /* _NET_BATMAN_ADV_COMPAT_LINUX_AVERAGE_H */ -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index 8f64a5c0..66b25e41 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -402,7 +402,7 @@ struct batadv_gw_node { - struct rcu_head rcu; - }; - --DECLARE_EWMA(throughput, 1024, 8) -+DECLARE_EWMA(throughput, 10, 8) - - /** - * struct batadv_hardif_neigh_node_bat_v - B.A.T.M.A.N. V private neighbor diff --git a/batman-adv/patches/0001-batman-adv-fix-TT-sync-flag-inconsistencies.patch b/batman-adv/patches/0001-batman-adv-fix-TT-sync-flag-inconsistencies.patch new file mode 100644 index 0000000..c96f9fd --- /dev/null +++ b/batman-adv/patches/0001-batman-adv-fix-TT-sync-flag-inconsistencies.patch @@ -0,0 +1,208 @@ +From: Linus Lüssing +Date: Thu, 6 Jul 2017 07:02:25 +0200 +Subject: [PATCH] batman-adv: fix TT sync flag inconsistencies + +This patch fixes an issue in the translation table code potentially +leading to a TT Request + Response storm. The issue may occur for nodes +involving BLA and an inconsistent configuration of the batman-adv AP +isolation feature. However, since the new multicast optimizations, a +single, malformed packet may lead to a mesh-wide, persistent +Denial-of-Service, too. + +The issue occurs because nodes are currently OR-ing the TT sync flags of +all originators announcing a specific MAC address via the +translation table. When an intermediate node now receives a TT Request +and wants to answer this on behave of the destination node then this +intermediate node now responds with an altered flag field and broken +CRC. The next OGM of the real destination will lead to a CRC mismatch +and triggering a TT Request and Response again. + +Furthermore, the OR-ing is currently never undone as long as at least +one originator announcing the according MAC address remains, leading to +the potential persistency of this issue. + +This patch fixes this issue by storing the flags used in the CRC +calculation on a a per TT orig entry basis to be able to respond with +the correct, original flags in an intermediate TT Response for one +thing. And to be able to correctly unset sync flags once all nodes +announcing a sync flag vanish for another. + +Fixes: fa614fd04692 ("batman-adv: fix tt_global_entries flags update") +Signed-off-by: Linus Lüssing +Acked-by: Antonio Quartulli +Signed-off-by: Sven Eckelmann + +Origin: other, https://patchwork.open-mesh.org/patch/17072/ +--- + net/batman-adv/translation-table.c | 60 ++++++++++++++++++++++++++++++++------ + net/batman-adv/types.h | 2 ++ + 2 files changed, 53 insertions(+), 9 deletions(-) + +diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c +index e1133bc634b5e8ed9a4639677e577a0d52e7c1d5..8a3ce79b1307b7f260ce2f64e96bdacfb9a322f0 100644 +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -1549,9 +1549,41 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, + return found; + } + ++/** ++ * batadv_tt_global_sync_flags - update TT sync flags ++ * @tt_global: the TT global entry to update sync flags in ++ * ++ * Updates the sync flag bits in the tt_global flag attribute with a logical ++ * OR of all sync flags from any of its TT orig entries. ++ */ ++static void ++batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global) ++{ ++ struct batadv_tt_orig_list_entry *orig_entry; ++ const struct hlist_head *head; ++ u16 flags = BATADV_NO_FLAGS; ++ ++ rcu_read_lock(); ++ head = &tt_global->orig_list; ++ hlist_for_each_entry_rcu(orig_entry, head, list) ++ flags |= orig_entry->flags; ++ rcu_read_unlock(); ++ ++ flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK); ++ tt_global->common.flags = flags; ++} ++ ++/** ++ * batadv_tt_global_orig_entry_add - add or update a TT orig entry ++ * @tt_global: the TT global entry to add an orig entry in ++ * @orig_node: the originator to add an orig entry for ++ * @ttvn: translation table version number of this changeset ++ * @flags: TT sync flags ++ */ + static void + batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, +- struct batadv_orig_node *orig_node, int ttvn) ++ struct batadv_orig_node *orig_node, int ttvn, ++ u8 flags) + { + struct batadv_tt_orig_list_entry *orig_entry; + +@@ -1561,7 +1593,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, + * was added during a "temporary client detection" + */ + orig_entry->ttvn = ttvn; +- goto out; ++ orig_entry->flags = flags; ++ goto sync_flags; + } + + orig_entry = kmem_cache_zalloc(batadv_tt_orig_cache, GFP_ATOMIC); +@@ -1573,6 +1606,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, + batadv_tt_global_size_inc(orig_node, tt_global->common.vid); + orig_entry->orig_node = orig_node; + orig_entry->ttvn = ttvn; ++ orig_entry->flags = flags; + kref_init(&orig_entry->refcount); + + spin_lock_bh(&tt_global->list_lock); +@@ -1582,6 +1616,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, + spin_unlock_bh(&tt_global->list_lock); + atomic_inc(&tt_global->orig_list_count); + ++sync_flags: ++ batadv_tt_global_sync_flags(tt_global); + out: + if (orig_entry) + batadv_tt_orig_list_entry_put(orig_entry); +@@ -1703,10 +1739,10 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, + } + + /* the change can carry possible "attribute" flags like the +- * TT_CLIENT_WIFI, therefore they have to be copied in the ++ * TT_CLIENT_TEMP, therefore they have to be copied in the + * client entry + */ +- common->flags |= flags; ++ common->flags |= flags & (~BATADV_TT_SYNC_MASK); + + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only + * one originator left in the list and we previously received a +@@ -1723,7 +1759,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, + } + add_orig_entry: + /* add the new orig_entry (if needed) or update it */ +- batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn); ++ batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn, ++ flags & BATADV_TT_SYNC_MASK); + + batadv_dbg(BATADV_DBG_TT, bat_priv, + "Creating new global tt entry: %pM (vid: %d, via %pM)\n", +@@ -1946,6 +1983,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, + struct batadv_tt_orig_list_entry *orig, + bool best) + { ++ u16 flags = (common->flags & (~BATADV_TT_SYNC_MASK)) | orig->flags; + void *hdr; + struct batadv_orig_node_vlan *vlan; + u8 last_ttvn; +@@ -1975,7 +2013,7 @@ batadv_tt_global_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq, + nla_put_u8(msg, BATADV_ATTR_TT_LAST_TTVN, last_ttvn) || + nla_put_u32(msg, BATADV_ATTR_TT_CRC32, crc) || + nla_put_u16(msg, BATADV_ATTR_TT_VID, common->vid) || +- nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, common->flags)) ++ nla_put_u32(msg, BATADV_ATTR_TT_FLAGS, flags)) + goto nla_put_failure; + + if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) +@@ -2589,6 +2627,7 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, + unsigned short vid) + { + struct batadv_hashtable *hash = bat_priv->tt.global_hash; ++ struct batadv_tt_orig_list_entry *tt_orig; + struct batadv_tt_common_entry *tt_common; + struct batadv_tt_global_entry *tt_global; + struct hlist_head *head; +@@ -2627,8 +2666,9 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, + /* find out if this global entry is announced by this + * originator + */ +- if (!batadv_tt_global_entry_has_orig(tt_global, +- orig_node)) ++ tt_orig = batadv_tt_global_orig_entry_find(tt_global, ++ orig_node); ++ if (!tt_orig) + continue; + + /* use network order to read the VID: this ensures that +@@ -2640,10 +2680,12 @@ static u32 batadv_tt_global_crc(struct batadv_priv *bat_priv, + /* compute the CRC on flags that have to be kept in sync + * among nodes + */ +- flags = tt_common->flags & BATADV_TT_SYNC_MASK; ++ flags = tt_orig->flags; + crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags)); + + crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN); ++ ++ batadv_tt_orig_list_entry_put(tt_orig); + } + rcu_read_unlock(); + } +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h +index ea43a64492479809fe6bdf95b436792078f50e9f..a62795868794103d7e712ba91def5997dc3a5779 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -1260,6 +1260,7 @@ struct batadv_tt_global_entry { + * struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client + * @orig_node: pointer to orig node announcing this non-mesh client + * @ttvn: translation table version number which added the non-mesh client ++ * @flags: per orig entry TT sync flags + * @list: list node for batadv_tt_global_entry::orig_list + * @refcount: number of contexts the object is used + * @rcu: struct used for freeing in an RCU-safe manner +@@ -1267,6 +1268,7 @@ struct batadv_tt_global_entry { + struct batadv_tt_orig_list_entry { + struct batadv_orig_node *orig_node; + u8 ttvn; ++ u8 flags; + struct hlist_node list; + struct kref refcount; + struct rcu_head rcu; diff --git a/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch b/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch deleted file mode 100644 index 3286cf3..0000000 --- a/batman-adv/patches/0002-batman-adv-Keep-fragments-equally-sized.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Sven Eckelmann -Date: Wed, 22 Feb 2017 17:25:42 +0100 -Subject: [PATCH] batman-adv: Keep fragments equally sized - -The batman-adv fragmentation packets have the design problem that they -cannot be refragmented and cannot handle padding by the underlying link. -The latter often leads to problems when networks are incorrectly configured -and don't use a common MTU. - -The sender could for example fragment a 1271 byte frame (plus external -ethernet header (14) and batadv unicast header (10)) to fit in a 1280 bytes -large MTU of the underlying link (max. 1294 byte frames). This would create -a 1294 bytes large frame (fragment 2) and a 55 bytes large frame -(fragment 1). The extra 54 bytes are the fragment header (20) added to each -fragment and the external ethernet header (14) for the second fragment. - -Let us assume that the next hop is then not able to transport 1294 bytes to -its next hop. The 1294 byte large frame will be dropped but the 55 bytes -large fragment will still be forwarded to its destination. - -Or let us assume that the underlying hardware requires that each frame has -a minimum size (e.g. 60 bytes). Then it will pad the 55 bytes frame to 60 -bytes. The receiver of the 60 bytes frame will no longer be able to -correctly assemble the two frames together because it is not aware that 5 -bytes of the 60 bytes frame are padding and don't belong to the reassembled -frame. - -This can partly be avoided by splitting frames more equally. In this -example, the 675 and 674 bytes large fragment frames could both potentially -reach its destination without being too large or too small. - -Reported-by: Martin Weinelt -Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") -Signed-off-by: Sven Eckelmann -Acked-by: Linus Lüssing ---- - net/batman-adv/fragmentation.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c -index 11a23fd6..8f964bea 100644 ---- a/net/batman-adv/fragmentation.c -+++ b/net/batman-adv/fragmentation.c -@@ -404,7 +404,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, - * batadv_frag_create - create a fragment from skb - * @skb: skb to create fragment from - * @frag_head: header to use in new fragment -- * @mtu: size of new fragment -+ * @fragment_size: size of new fragment - * - * Split the passed skb into two fragments: A new one with size matching the - * passed mtu and the old one with the rest. The new skb contains data from the -@@ -414,11 +414,11 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, - */ - static struct sk_buff *batadv_frag_create(struct sk_buff *skb, - struct batadv_frag_packet *frag_head, -- unsigned int mtu) -+ unsigned int fragment_size) - { - struct sk_buff *skb_fragment; - unsigned int header_size = sizeof(*frag_head); -- unsigned int fragment_size = mtu - header_size; -+ unsigned int mtu = fragment_size + header_size; - - skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); - if (!skb_fragment) -@@ -456,7 +456,7 @@ int batadv_frag_send_packet(struct sk_buff *skb, - struct sk_buff *skb_fragment; - unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; - unsigned int header_size = sizeof(frag_header); -- unsigned int max_fragment_size, max_packet_size; -+ unsigned int max_fragment_size, num_fragments; - int ret; - - /* To avoid merge and refragmentation at next-hops we never send -@@ -464,10 +464,15 @@ int batadv_frag_send_packet(struct sk_buff *skb, - */ - mtu = min_t(unsigned int, mtu, BATADV_FRAG_MAX_FRAG_SIZE); - max_fragment_size = mtu - header_size; -- max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS; -+ -+ if (skb->len == 0 || max_fragment_size == 0) -+ return -EINVAL; -+ -+ num_fragments = (skb->len - 1) / max_fragment_size + 1; -+ max_fragment_size = (skb->len - 1) / num_fragments + 1; - - /* Don't even try to fragment, if we need more than 16 fragments */ -- if (skb->len > max_packet_size) { -+ if (num_fragments > BATADV_FRAG_MAX_FRAGMENTS) { - ret = -EAGAIN; - goto free_skb; - } -@@ -507,7 +512,8 @@ int batadv_frag_send_packet(struct sk_buff *skb, - goto put_primary_if; - } - -- skb_fragment = batadv_frag_create(skb, &frag_header, mtu); -+ skb_fragment = batadv_frag_create(skb, &frag_header, -+ max_fragment_size); - if (!skb_fragment) { - ret = -ENOMEM; - goto put_primary_if; diff --git a/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch b/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch deleted file mode 100644 index f65ac45..0000000 --- a/batman-adv/patches/0003-batman-adv-Initialize-gw-sel_class-via-batadv_algo.patch +++ /dev/null @@ -1,141 +0,0 @@ -From: Sven Eckelmann -Date: Sat, 4 Mar 2017 15:48:50 +0100 -Subject: [PATCH] batman-adv: Initialize gw sel_class via batadv_algo - -The gateway selection class variable is shared between different algorithm -versions. But the interpretation of the content is algorithm specific. The -initialization is therefore also algorithm specific. - -But this was implemented incorrectly and the initialization for BATMAN_V -always overwrote the value previously written for BATMAN_IV. This could -only be avoided when BATMAN_V was disabled during compile time. - -Using a special batadv_algo hook for this initialization avoids this -problem. - -Fixes: 80b2d47be2c7 ("batman-adv: B.A.T.M.A.N. V - implement GW selection logic") -Signed-off-by: Sven Eckelmann ---- - net/batman-adv/bat_iv_ogm.c | 11 +++++++++++ - net/batman-adv/bat_v.c | 14 +++++++++++--- - net/batman-adv/gateway_common.c | 5 +++++ - net/batman-adv/soft-interface.c | 1 - - net/batman-adv/types.h | 2 ++ - 5 files changed, 29 insertions(+), 4 deletions(-) - -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index 7c3d994e..71343d0f 100644 ---- a/net/batman-adv/bat_iv_ogm.c -+++ b/net/batman-adv/bat_iv_ogm.c -@@ -2477,6 +2477,16 @@ static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface) - batadv_iv_ogm_schedule(hard_iface); - } - -+/** -+ * batadv_iv_init_sel_class - initialize GW selection class -+ * @bat_priv: the bat priv with all the soft interface information -+ */ -+static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv) -+{ -+ /* set default TQ difference threshold to 20 */ -+ atomic_set(&bat_priv->gw.sel_class, 20); -+} -+ - static struct batadv_gw_node * - batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv) - { -@@ -2823,6 +2833,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { - .del_if = batadv_iv_ogm_orig_del_if, - }, - .gw = { -+ .init_sel_class = batadv_iv_init_sel_class, - .get_best_gw_node = batadv_iv_gw_get_best_gw_node, - .is_eligible = batadv_iv_gw_is_eligible, - #ifdef CONFIG_BATMAN_ADV_DEBUGFS -diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c -index 0acd081d..a36c8e72 100644 ---- a/net/batman-adv/bat_v.c -+++ b/net/batman-adv/bat_v.c -@@ -668,6 +668,16 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, - return ret; - } - -+/** -+ * batadv_v_init_sel_class - initialize GW selection class -+ * @bat_priv: the bat priv with all the soft interface information -+ */ -+static void batadv_v_init_sel_class(struct batadv_priv *bat_priv) -+{ -+ /* set default throughput difference threshold to 5Mbps */ -+ atomic_set(&bat_priv->gw.sel_class, 50); -+} -+ - static ssize_t batadv_v_store_sel_class(struct batadv_priv *bat_priv, - char *buff, size_t count) - { -@@ -1052,6 +1062,7 @@ static struct batadv_algo_ops batadv_batman_v __read_mostly = { - .dump = batadv_v_orig_dump, - }, - .gw = { -+ .init_sel_class = batadv_v_init_sel_class, - .store_sel_class = batadv_v_store_sel_class, - .show_sel_class = batadv_v_show_sel_class, - .get_best_gw_node = batadv_v_gw_get_best_gw_node, -@@ -1092,9 +1103,6 @@ int batadv_v_mesh_init(struct batadv_priv *bat_priv) - if (ret < 0) - return ret; - -- /* set default throughput difference threshold to 5Mbps */ -- atomic_set(&bat_priv->gw.sel_class, 50); -- - return 0; - } - -diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c -index 5db2e43e..33940c5c 100644 ---- a/net/batman-adv/gateway_common.c -+++ b/net/batman-adv/gateway_common.c -@@ -253,6 +253,11 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, - */ - void batadv_gw_init(struct batadv_priv *bat_priv) - { -+ if (bat_priv->algo_ops->gw.init_sel_class) -+ bat_priv->algo_ops->gw.init_sel_class(bat_priv); -+ else -+ atomic_set(&bat_priv->gw.sel_class, 1); -+ - batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1, - NULL, BATADV_TVLV_GW, 1, - BATADV_TVLV_HANDLER_OGM_CIFNOTFND); -diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c -index 5d099b2e..d042c99a 100644 ---- a/net/batman-adv/soft-interface.c -+++ b/net/batman-adv/soft-interface.c -@@ -819,7 +819,6 @@ static int batadv_softif_init_late(struct net_device *dev) - atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); - #endif - atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); -- atomic_set(&bat_priv->gw.sel_class, 20); - atomic_set(&bat_priv->gw.bandwidth_down, 100); - atomic_set(&bat_priv->gw.bandwidth_up, 20); - atomic_set(&bat_priv->orig_interval, 1000); -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index 66b25e41..246f21b4 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -1489,6 +1489,7 @@ struct batadv_algo_orig_ops { - - /** - * struct batadv_algo_gw_ops - mesh algorithm callbacks (GW specific) -+ * @init_sel_class: initialize GW selection class (optional) - * @store_sel_class: parse and stores a new GW selection class (optional) - * @show_sel_class: prints the current GW selection class (optional) - * @get_best_gw_node: select the best GW from the list of available nodes -@@ -1499,6 +1500,7 @@ struct batadv_algo_orig_ops { - * @dump: dump gateways to a netlink socket (optional) - */ - struct batadv_algo_gw_ops { -+ void (*init_sel_class)(struct batadv_priv *bat_priv); - ssize_t (*store_sel_class)(struct batadv_priv *bat_priv, char *buff, - size_t count); - ssize_t (*show_sel_class)(struct batadv_priv *bat_priv, char *buff); diff --git a/bmx6/Makefile b/bmx6/Makefile index 411d9cb..1741d94 100644 --- a/bmx6/Makefile +++ b/bmx6/Makefile @@ -31,9 +31,9 @@ PKG_SOURCE_PROTO:=git #PKG_SOURCE_URL:=git://bmx6.net/bmx6.git PKG_SOURCE_URL:=git://github.com/axn/bmx6.git -PKG_REV:=d9b985d8838ad6fe6d5c79f858a588b96abcf306 -PKG_VERSION:=r2017021601 -PKG_RELEASE:=4 +PKG_REV:=4016a1980d900309771e432d1f7c741d6c48d477 +PKG_VERSION:=r2017032301 +PKG_RELEASE:=5 PKG_LICENSE:=GPL-2.0 PKG_SOURCE_VERSION:=$(PKG_REV) diff --git a/bmx6/files/etc/init.d/bmx6 b/bmx6/files/etc/init.d/bmx6 index cb2d5b3..9d48eb4 100755 --- a/bmx6/files/etc/init.d/bmx6 +++ b/bmx6/files/etc/init.d/bmx6 @@ -1,41 +1,37 @@ #!/bin/sh /etc/rc.common +# Copyright (C) 2017 Gui Iribarren # Copyright (C) 2011 Fundacio Privada per a la Xarxa Oberta, Lliure i Neutral guifi.net # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# The full GNU General Public License is included in this distribution in -# the file called "COPYING". +# This is free software, licensed under the GNU General Public License v3. START=91 +STOP=91 +USE_PROCD=1 +NAME=bmx6 BIN=/usr/sbin/bmx6 CONF=/etc/config/bmx6 PID=/var/run/bmx6/pid +DEBUG=0 +start_service() { + procd_open_instance "$NAME" + procd_set_param command "$BIN" -f "$CONF" -d "$DEBUG" -start() { - cd /root/ - while pgrep -f mac80211.sh ; do sleep 1; done - ulimit -c 20000 - $BIN -f $CONF -d0 > /dev/null & + ### Respawn automatically when process dies, after waiting respawn_timeout seconds + ### If respawn_retry consecutives respawns die before respawn_threshold seconds (i.e. they crash) + ### it will stop trying and leave it dead. + procd_set_param respawn ${respawn_threshold:-60} ${respawn_timeout:-3} ${respawn_retry:-5} + + procd_set_param limits core="20000" # Equivalent to 'ulimit -c 20000' + procd_close_instance } -stop() { - start-stop-daemon -p $PID -K +reload_service() { + "$BIN" -c configReload } -restart() { - stop; sleep 3; start +service_triggers() +{ + procd_add_reload_trigger "bmx6" # Call reload_service() when /etc/config/bmx6 changed and reload_config is run } diff --git a/bmx7/Makefile b/bmx7/Makefile index 215ec72..f1e4485 100644 --- a/bmx7/Makefile +++ b/bmx7/Makefile @@ -31,8 +31,8 @@ PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=git://github.com/axn/bmx6.git #PKG_SOURCE_URL:=file:///usr/src/bmx6/bmx6.git -PKG_REV:=589ee21b49d370056a24d8931d663626608f3c12 -PKG_VERSION:=r2017011101 +PKG_REV:=1b8cf4c119d3bf886a9b9c5a1bca8043506f3684 +PKG_VERSION:=r2017071001 PKG_RELEASE:=4 PKG_LICENSE:=GPL-2.0 diff --git a/luci-app-bmx6/Makefile b/luci-app-bmx6/Makefile index ec69d2d..bb37c20 100644 --- a/luci-app-bmx6/Makefile +++ b/luci-app-bmx6/Makefile @@ -20,7 +20,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-bmx6 -PKG_RELEASE:=3 +PKG_RELEASE:=5 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_LICENSE:=GPL-2.0+ @@ -32,14 +32,40 @@ define Package/luci-app-bmx6 CATEGORY:=LuCI SUBMENU:=3. Applications TITLE:= bmx6 configuration, status and visualization module - DEPENDS:=+luci-lib-json +luci-mod-admin-full +luci-lib-httpclient +bmx6 + DEPENDS:=+luci-lib-json +luci-base +luci-lib-httpclient +bmx6 +luci-lib-jquery-1-4 +luci-lib-dracula MAINTAINER:= Pau Escrich endef +define Package/luci-lib-jquery-1-4 + SECTION:=luci + CATEGORY:=LuCI + TITLE:=LuCI - Lua Configuration Interface + MAINTAINER:=Gui Iribarren + SUBMENU:=6. Libraries + TITLE:=jQuery 1.4 javascript library +endef + +define Package/luci-lib-dracula + SECTION:=luci + CATEGORY:=LuCI + TITLE:=LuCI - Lua Configuration Interface + MAINTAINER:=Pau Escrich + SUBMENU:=6. Libraries + TITLE:=dracula graph javascript library +endef + define Package/luci-app-bmx6/description bmx6 web application (status and configuration) for LuCi web interface endef +define Package/luci-lib-jquery-1-4/description + minified javascript jQuery 1.4 library +endef + +define Package/luci-lib-dracula-graph/description + minified dracula javascript graph library +endef + define Package/luci-app-bmx6/conffiles /etc/config/luci-bmx6 endef @@ -54,9 +80,20 @@ define Build/Compile endef define Package/luci-app-bmx6/install - $(CP) ./files/* $(1)/ + $(CP) ./bmx6/* $(1)/ chmod 755 $(1)/www/cgi-bin/bmx6-info endef -$(eval $(call BuildPackage,luci-app-bmx6)) +define Package/luci-lib-jquery-1-4/install + $(INSTALL_DIR) $(1)/www/luci-static/resources/jquery/ + $(CP) ./jquery/* $(1)/www/luci-static/resources/jquery/ +endef +define Package/luci-lib-dracula/install + $(INSTALL_DIR) $(1)/www/luci-static/resources/dracula + $(CP) ./dracula/* $(1)/www/luci-static/resources/dracula/ +endef + +$(eval $(call BuildPackage,luci-app-bmx6)) +$(eval $(call BuildPackage,luci-lib-jquery-1-4)) +$(eval $(call BuildPackage,luci-lib-dracula)) diff --git a/luci-app-bmx6/files/etc/config/luci-bmx6 b/luci-app-bmx6/bmx6/etc/config/luci-bmx6 similarity index 100% rename from luci-app-bmx6/files/etc/config/luci-bmx6 rename to luci-app-bmx6/bmx6/etc/config/luci-bmx6 diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/controller/bmx6.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/controller/bmx6.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/controller/bmx6.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/controller/bmx6.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/bmx6json.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/bmx6json.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/bmx6json.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/advanced.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/advanced.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/advanced.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/advanced.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/hna.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/hna.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/hna.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/hna.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/interfaces.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/interfaces.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/interfaces.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/interfaces.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/main.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/main.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/main.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/main.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/plugins.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/plugins.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/plugins.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/plugins.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/tunnels.lua b/luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/tunnels.lua similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/model/cbi/bmx6/tunnels.lua rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/model/cbi/bmx6/tunnels.lua diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/admin_status/index/neighbours_simple.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/admin_status/index/neighbours_simple.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/admin_status/index/neighbours_simple.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/admin_status/index/neighbours_simple.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/chat.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/chat.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/chat.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/chat.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/error.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/error.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/error.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/error.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/gateways_j.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/gateways_j.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/gateways_j.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/gateways_j.htm diff --git a/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/graph.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/graph.htm new file mode 100644 index 0000000..0655302 --- /dev/null +++ b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/graph.htm @@ -0,0 +1,49 @@ +<%# +Copyright (C) 2011 Pau Escrich +Contributors Jo-Philip + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +The full GNU General Public License is included in this distribution in +the file called "COPYING". +-%> + +<% + luci.http.prepare_content("text/html") + + local location = { unpack(luci.dispatcher.context.path) } + location[#location] = "topology" +%> + +<%+header%> + + + +
+

+ +<%:Collecting data...%> + +
+ +
+ + + + + + + +<%+footer%> diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/links.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/links.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/links.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/links.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/nodes_j.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/nodes_j.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/nodes_j.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/nodes_j.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/status_j.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/status_j.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/status_j.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/status_j.htm diff --git a/luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/tunnels_j.htm b/luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/tunnels_j.htm similarity index 100% rename from luci-app-bmx6/files/usr/lib/lua/luci/view/bmx6/tunnels_j.htm rename to luci-app-bmx6/bmx6/usr/lib/lua/luci/view/bmx6/tunnels_j.htm diff --git a/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info b/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info new file mode 100755 index 0000000..9c615e4 --- /dev/null +++ b/luci-app-bmx6/bmx6/www/cgi-bin/bmx6-info @@ -0,0 +1,121 @@ +#!/bin/sh +# This script gives information about bmx6 +# Can be executed from a linux shell: ./bmx6-info -s links +# Or from web interfae (with cgi enabled): http://host/cgi-bin/bmx6-info?links +# Special methods are tagged with '$', like $myself or $neighbours: http://host/cgi-bin/bmx6-info?$myself +# When '$' is not used, raw bmx6 information from the filesystem is returned (/var/runb/bmx6/json/) + +BMX6_DIR="$(uci get bmx6.general.runtimeDir 2>/dev/null)" || BMX6_DIR="/var/run/bmx6/json" + +#Checking if shell mode or cgi-bin mode +if [ "$1" == "-s" ]; then + QUERY="$2" +else + QUERY="${QUERY_STRING%%=*}" + QUERY="${QUERY%%\?*}" + QUERY="${QUERY%%\&*}" + echo "Content-type: application/json" + echo "" +fi + +# workaround to support old format starting with '$' +QUERY="$(echo "$QUERY" | sed s/'\$'//)" + +check_path() { + [ -d "$1" ] && path=$(cd $1; pwd) + [ -f "$1" ] && path=$(cd $1/..; pwd) + [ $(echo "$path" | grep -c "^$BMX6_DIR") -ne 1 ] && exit 1 +} + +print_query() { + # If the query is a directory + [ -d "$BMX6_DIR/$1" ] && + { + # If /all has not been specified + [ -z "$QALL" ] && + { + total=$(ls $BMX6_DIR/$1 | wc -w) + i=1 + echo -n "{ \"$1\": [ " + for f in $(ls $BMX6_DIR/$1); do + echo -n "{ \"name\": \"$f\" }" + [ $i -lt $total ] && echo -n ',' + i=$(( $i + 1 )) + done + echo -n " ] }" + + # If /all has been specified, printing all the files together + } || { + comma="" + echo -n "[ " + for entry in "$BMX6_DIR/$1/"*; do + [ -f "$entry" ] && + { + ${comma:+echo -n "$comma"} + tr -d '\n' < "$entry" + comma="," + } + done + echo -n " ]" + } + } + # If the query is a file, just printing the file + [ -f "$BMX6_DIR/$1" ] && cat "$BMX6_DIR/$1"; +} + +if [ "${QUERY##*/}" == "all" ]; then + QUERY="${QUERY%/all}" + QALL=1 +fi + +if [ "$QUERY" == 'myself' ]; then + hostname="$(cat /proc/sys/kernel/hostname)" + ip6="$(bmx6 -c show=status | grep ^BMX | awk '{print $5}')" + ip4="$(bmx6 -c show=status | grep ^BMX | awk '{print $6}')" + cidr6=$(lua -l luci.ip -e "ip=luci.ip.new(\"$ip6\"); print(ip:network():string()..'/'..ip:prefix())") + cidr4=$(lua -l luci.ip -e "ip=luci.ip.new(\"$ip4\"); print(ip:network():string()..'/'..ip:prefix())") + echo -n "{\"myself\":{\"hostname\":\"$hostname\",\"ip6\":\"$ip6\",\"ip4\":\"$ip4\",\"net6\":\"$cidr6\",\"net4\":\"$cidr4\"}}" + exit 0 +fi + +if [ "$QUERY" == 'info' ]; then + echo -n '{ "info": [ ' + print_query status + echo -n "," + print_query interfaces + echo -n "] }" + exit 0 +fi + +if [ "$QUERY" == 'neighbours' ]; then + QALL=1 + echo -n '{ "neighbours": [ ' + echo -n '{ "originators": ' + print_query originators + echo -n '}, ' + echo -n '{ "descriptions": ' + print_query descriptions + echo -n "} ] }" + exit 0 +fi + +if [ "$QUERY" == 'tunnels' ]; then + bmx6 -c --jshow tunnels /r=0 + exit 0 +fi + +if [ "$QUERY" == "" ]; then + echo -n '{ "queries": [' + echo -n '{ "name": "myself", "info": "basic network information of self node" },' + echo -n '{ "name": "info", "info": "full network and device information of self node" },' + echo -n '{ "name": "tunnels", "info": "accnouncements (tunnels) published by the mesh network" },' + echo -n '{ "name": "neighbours", "info": "list of all my neighbours and their information" },' + echo -n '{ "name": "/", "info": "raw bmx6 json API" }]}' + exit 0 +fi + +check_path "$BMX6_DIR/$QUERY" +print_query $QUERY + +#ls -1F "$BMX6_DIR" +exit 0 diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/bmx6logo.png b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/bmx6logo.png similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/bmx6logo.png rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/bmx6logo.png diff --git a/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js new file mode 100644 index 0000000..80233ff --- /dev/null +++ b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/bmx6-graph.js @@ -0,0 +1,234 @@ +var graph, canvas, layouter, renderer, divwait, nodes, announcements, nodesIndex, palette, localInfo; +document.addEventListener( "DOMContentLoaded", init, false); + +/** + * Returns an index of nodes by name + */ +function createNodeIndex(nodes) { + var inode, index = {}; + + for (inode in nodes) + index[nodes[inode].name] = nodes[inode]; + + return index; +} + +/** + * Updates to have announcements in nodes list + */ +function processNodeAnnouncements(nodes, announcements) { + var iannouncement, remoteNode, announcement; + nodesIndex = createNodeIndex(nodes); + + for(iannouncement in announcements) { + announcement = announcements[iannouncement]; + if (announcement.remoteName == '---' ) continue; + if (!( announcement.remoteName in nodesIndex )) { + newNode = { + name: announcement.remoteName, + links: [] + }; + nodes.push(newNode); + nodesIndex[newNode.name] = newNode; + }; + + remoteNode = nodesIndex[announcement.remoteName]; + if (!( 'announcements' in remoteNode )) remoteNode.announcements = []; + remoteNode.announcements.push(announcement); + }; +} + +function init() { + palette = generatePalette(200); + + graph = new Graph(); + canvas = document.getElementById('canvas'); + layouter = new Graph.Layout.Spring(graph); + renderer = new Graph.Renderer.Raphael(canvas.id, graph, canvas.offsetWidth, canvas.offsetHeight); + + divwait = document.getElementById("wait"); + + XHR.get('/cgi-bin/luci/status/bmx6/topology', null, function(nodesRequest, nodesData) { + nodes = nodesData; + + XHR.get('/cgi-bin/bmx6-info?$myself&', null, function(myselfRequest, myselfData) { + if (myselfData) + localAnnouncements = [ + {remoteName: myselfData.myself.hostname, advNet: myselfData.myself.net4}, + {remoteName: myselfData.myself.hostname, advNet: myselfData.myself.net6} + ]; + + XHR.get('/cgi-bin/bmx6-info?$tunnels=&', null, function(tunnelsRequest, tunnelsData) { + var iAnnouncement; + + announcements = tunnelsData.tunnels; + for(iAnnouncement in localAnnouncements) { + announcements.push(localAnnouncements[iAnnouncement]) + }; + + processNodeAnnouncements(nodes, announcements); + + divwait.parentNode.removeChild(divwait); + draw(nodes); + }); + }); + }); +} + +function hashCode(str) { + var hash = 0; + if (str.length == 0) return hash; + for (i = 0; i < str.length; i++) { + char = str.charCodeAt(i); + hash = ((hash<<5)-hash)+char; + hash = hash & hash; // Convert to 32bit integer + } + return hash; +} + +function generatePalette(size) { + var i, arr = []; + Raphael.getColor(); // just to remove the grey one + for(i = 0; i < size; i++) { + arr.push(Raphael.getColor()) + } + + return arr; +} + +function getFillFromHash(hash) { + return palette[Math.abs(hash % palette.length)]; +} + +function hashAnnouncementsNames(announcementsNames) { + return hashCode(announcementsNames.sort().join('-')); +} + +function getNodeAnnouncements(networkNode) { + return networkNode.announcements; +} + +function nodeRenderer(raphael, node) { + var nodeFill, renderedNode, options; + options = { + 'fill': 'announcements' in node.networkNode ? getFillFromHash( + hashAnnouncementsNames( + getNodeAnnouncements(node.networkNode).map(function(ann) {return ann.advNet;}) + ) + ) : '#bfbfbf', + 'stroke-width': 1, + + }; + + renderedNode = raphael.set(); + + renderedNode.push(raphael.ellipse(node.point[0], node.point[1], 30, 20).attr({"fill": options['fill'], "stroke-width": options['stroke-width']})); + renderedNode.push(raphael.text(node.point[0], node.point[1] + 30, node.networkNode.name).attr({})); + + renderedNode.items.forEach(function(el) { + var announcements, tooltip = raphael.set(); + tooltip.push(raphael.rect(-60, -60, 120, 60).attr({"fill": "#fec", "stroke-width": 1, r : "9px"})); + + announcements = getNodeAnnouncements(node.networkNode); + if (announcements) { + + announcements = announcements.map(function(ann) {return ann.advNet}); + tooltip.push(raphael.text(0, -40, 'announcements\n' + announcements.join('\n')).attr({})); + }; + + el.tooltip(tooltip); + }); + + return renderedNode; +} + +function genericNodeRenderer(raphael, node) { + var renderedNode; + + renderedNode = raphael.set(); + + renderedNode.push(raphael.ellipse(node.point[0], node.point[1], 30, 20).attr({"fill": '#bfbfbf', "stroke-width": 1})); + renderedNode.push(raphael.text(node.point[0], node.point[1] + 30, node.networkNode.name).attr({})); + + return renderedNode; +} + +function redraw() { + layouter.layout(); + renderer.draw(); +} + +function interpolateColor(minColor,maxColor,maxDepth,depth){ + + function d2h(d) {return d.toString(16);} + function h2d(h) {return parseInt(h,16);} + + if(depth == 0){ + return minColor; + } + if(depth == maxDepth){ + return maxColor; + } + + var color = "#"; + + for(var i=1; i <= 6; i+=2){ + var minVal = new Number(h2d(minColor.substr(i,2))); + var maxVal = new Number(h2d(maxColor.substr(i,2))); + var nVal = minVal + (maxVal-minVal) * (depth/maxDepth); + var val = d2h(Math.floor(nVal)); + while(val.length < 2){ + val = "0"+val; + } + color += val; + } + return color; +} +function draw(nodes) { + var node, neighbourNode, seenKey, rxRate, txRate, seen, i, j, currentName, linkQuality; + + seen = { }; + + for (i = 0; i < (nodes.length); i++) { + node = nodes[i]; + graph.addNode(node.name, { + networkNode: node, + render: nodeRenderer + }); + }; + + for (i = 0; i < (nodes.length); i++) { + node = nodes[i]; + + if (! node.name) continue; + + currentName = node.name; + + for (j = 0; j < (node.links.length); j++) { + neighbourNode = node.links[j]; + + graph.addNode(neighbourNode.name, {render: genericNodeRenderer, networkNode: neighbourNode}); + + seenKey = (node.name < neighbourNode.name) ? node.name + '|' + neighbourNode.name : neighbourNode.name + '|' + node.name; + + rxRate = neighbourNode.rxRate; + txRate = neighbourNode.txRate; + + if (!seen[seenKey] && rxRate > 0 && txRate > 0) { + linkQuality = ( rxRate + txRate ) / 2; + + graph.addEdge(node.name, neighbourNode.name, { + 'label': rxRate + '/' + txRate, + 'directed': false, + 'stroke': interpolateColor('FF0000','00FF00', 5, 5 * ( linkQuality - 1 )/100), + 'fill': interpolateColor('FF0000','00FF00', 5, 5 * ( linkQuality - 1 )/100), + 'label-style': { 'font-size': 8 } + }); + + seen[seenKey] = true; + } + } + } + + redraw(); +} diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/polling.js b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/polling.js similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/js/polling.js rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/js/polling.js diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/link.png b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/link.png similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/link.png rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/link.png diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/style.css b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/style.css similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/style.css rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/style.css diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/wifi.png b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/wifi.png similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/wifi.png rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/wifi.png diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/world.png b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/world.png similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/world.png rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/world.png diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/world_small.png b/luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/world_small.png similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/world_small.png rename to luci-app-bmx6/bmx6/www/luci-static/resources/bmx6/world_small.png diff --git a/luci-app-bmx6/dracula/dracula_graffle.js b/luci-app-bmx6/dracula/dracula_graffle.js new file mode 100644 index 0000000..9832727 --- /dev/null +++ b/luci-app-bmx6/dracula/dracula_graffle.js @@ -0,0 +1 @@ +Raphael.fn.connection=function(a,b,c){var d=this,e={draw:function(){for(var f=a.getBBox(),g=b.getBBox(),h=0,i=0,j=[{x:f.x+f.width/2,y:f.y-h},{x:f.x+f.width/2,y:f.y+f.height+h},{x:f.x-h,y:f.y+f.height/2},{x:f.x+f.width+h,y:f.y+f.height/2},{x:g.x+g.width/2,y:g.y-i},{x:g.x+g.width/2,y:g.y+g.height+i},{x:g.x-i,y:g.y+g.height/2},{x:g.x+g.width+i,y:g.y+g.height/2}],k={},l=[],m=0;m<4;m++)for(var n=4;n<8;n++){var o=Math.abs(j[m].x-j[n].x),p=Math.abs(j[m].y-j[n].y);(m==n-4||(3!=m&&6!=n||j[m].xj[n].x)&&(0!=m&&5!=n||j[m].y>j[n].y)&&(1!=m&&4!=n||j[m].ye.width-20?c-e.width+20:0),g=a.clientY-(d<20?d-20:d>e.height-20?d-e.height+20:0);e.isDrag.set.translate(f-Math.round(e.isDrag.dx),g-Math.round(e.isDrag.dy));for(var h in e.graph.edges)e.graph.edges[h].connection&&e.graph.edges[h].connection.draw();e.isDrag.dx=f,e.isDrag.dy=g}},f.onmouseup=function(){e.isDrag&&e.isDrag.set.animate({"fill-opacity":.6},500),e.isDrag=!1},this.draw()},Graph.Renderer.Raphael.prototype={translate:function(a){return[(a[0]-this.graph.layoutMinX)*this.factorX+this.radius,(a[1]-this.graph.layoutMinY)*this.factorY+this.radius]},rotate:function(a,b,c){var d=b*Math.cos(c),e=b*Math.sin(c);return[a[0]+d,a[1]+e]},draw:function(){this.factorX=(this.width-2*this.radius)/(this.graph.layoutMaxX-this.graph.layoutMinX),this.factorY=(this.height-2*this.radius)/(this.graph.layoutMaxY-this.graph.layoutMinY);for(a in this.graph.nodes)this.drawNode(this.graph.nodes[a]);for(var a=0;ab&&(b=e),ed&&(d=f),fk&&(i=k),i<-k&&(i=-k),j>k&&(j=k),j<-k&&(j=-k),h.layoutPosX+=i,h.layoutPosY+=j,h.layoutForceX=0,h.layoutForceY=0}},layoutRepulsive:function(a,b){if("undefined"!=typeof a&&"undefined"!=typeof b){var c=b.layoutPosX-a.layoutPosX,d=b.layoutPosY-a.layoutPosY,e=c*c+d*d;if(e<.01){c=.1*Math.random()+.1,d=.1*Math.random()+.1;var e=c*c+d*d}var f=Math.sqrt(e);if(fthis.maxRepulsiveForceDistance&&(g=this.maxRepulsiveForceDistance,f=g*g);var h=(f-this.k*this.k)/this.k;void 0==a.attraction&&(a.attraction=1),h*=.5*Math.log(a.attraction)+1,c.layoutForceX-=h*d/g,c.layoutForceY-=h*e/g,b.layoutForceX+=h*d/g,b.layoutForceY+=h*e/g}},Graph.Layout.Ordered=function(a,b){this.graph=a,this.order=b,this.layout()},Graph.Layout.Ordered.prototype={layout:function(){this.layoutPrepare(),this.layoutCalcBounds()},layoutPrepare:function(a){for(i in this.graph.nodes){var b=this.graph.nodes[i];b.layoutPosX=0,b.layoutPosY=0}var c=0;for(i in this.order){var b=this.order[i];b.layoutPosX=c,b.layoutPosY=Math.random(),c++}},layoutCalcBounds:function(){var a=1/0,b=-(1/0),c=1/0,d=-(1/0);for(i in this.graph.nodes){var e=this.graph.nodes[i].layoutPosX,f=this.graph.nodes[i].layoutPosY;e>b&&(b=e),ed&&(d=f),f -Contributors Jo-Philip - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -The full GNU General Public License is included in this distribution in -the file called "COPYING". --%> - -<% - luci.http.prepare_content("text/html") - - local location = { unpack(luci.dispatcher.context.path) } - location[#location] = "topology" -%> - -<%+header%> - - - - - - - - -
-

- -<%:Collecting data...%> - -
- -
- - - - -<%+footer%> diff --git a/luci-app-bmx6/files/www/cgi-bin/bmx6-info b/luci-app-bmx6/files/www/cgi-bin/bmx6-info deleted file mode 100644 index 5263081..0000000 --- a/luci-app-bmx6/files/www/cgi-bin/bmx6-info +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh -# Copyright (C) 2011 Pau Escrich -# Contributors Jo-Philipp Wich -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# The full GNU General Public License is included in this distribution in -# the file called "COPYING". -# -# This script gives information about bmx6 -# Can be executed from a linux shell: ./bmx6-info -s links -# Or from web interfae (with cgi enabled): http://host/cgi-bin/bmx6-info?links -# If you ask for a directory you wil get the directory contents in JSON forman - -BMX6_DIR="$(uci get bmx6.general.runtimeDir 2>/dev/null)" || BMX6_DIR="/var/run/bmx6/json" - -#Checking if shell mode or cgi-bin mode -if [ "$1" == "-s" ]; then - QUERY="$2" -else - QUERY="${QUERY_STRING%%=*}" - echo "Content-type: application/json" - echo "" - -fi - -check_path() { - [ -d "$1" ] && path=$(cd $1; pwd) - [ -f "$1" ] && path=$(cd $1/..; pwd) - [ $(echo "$path" | grep -c "^$BMX6_DIR") -ne 1 ] && exit 1 -} - -print_query() { - # If the query is a directory - [ -d "$BMX6_DIR/$1" ] && - { - # If /all has not been specified - [ -z "$QALL" ] && - { - total=$(ls $BMX6_DIR/$1 | wc -w) - i=1 - echo -n "{ \"$1\": [ " - for f in $(ls $BMX6_DIR/$1); do - echo -n "{ \"name\": \"$f\" }" - [ $i -lt $total ] && echo -n ',' - i=$(( $i + 1 )) - done - echo -n " ] }" - - # If /all has been specified, printing all the files together - } || { - comma="" - echo -n "[ " - for entry in "$BMX6_DIR/$1/"*; do - [ -f "$entry" ] && - { - ${comma:+echo "$comma"} - tr -d '\n' < "$entry" - comma="," - } - done - echo -n " ]" - } - } - - # If the query is a file, just printing the file - [ -f "$BMX6_DIR/$1" ] && cat "$BMX6_DIR/$1"; -} - -if [ "${QUERY##*/}" == "all" ]; then - QUERY="${QUERY%/all}" - QALL=1 -fi - -if [ "$QUERY" == '$info' ]; then - echo '{ "info": [ ' - print_query status - echo -n "," - print_query interfaces - echo "] }" -fi - -if [ "$QUERY" == '$neighbours' ]; then - QALL=1 - echo '{ "neighbours": [ ' - echo '{ "originators": ' - print_query originators - echo '}, ' - echo '{ "descriptions": ' - print_query descriptions - echo "} ] }" - exit 0 - -else if [ "$QUERY" == '$tunnels' ]; then - bmx6 -c --jshow tunnels /r=0 - exit 0 - -else - check_path "$BMX6_DIR/$QUERY" - print_query $QUERY - exit 0 -fi -fi - -ls -1F "$BMX6_DIR" -exit 0 - diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/Curry-1.0.1.js b/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/Curry-1.0.1.js deleted file mode 100644 index f5aa0f9..0000000 --- a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/Curry-1.0.1.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Curry - Function currying - * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com - * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php) - * Date: 10/4/2008 - * - * @author Ariel Flesler - * @version 1.0.1 - */ - -function curry( fn ){ - return function(){ - var args = curry.args(arguments), - master = arguments.callee, - self = this; - - return args.length >= fn.length ? fn.apply(self,args) : function(){ - return master.apply( self, args.concat(curry.args(arguments)) ); - }; - }; -}; - -curry.args = function( args ){ - return Array.prototype.slice.call(args); -}; - -Function.prototype.curry = function(){ - return curry(this); -}; \ No newline at end of file diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graffle.js b/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graffle.js deleted file mode 100644 index ddf171d..0000000 --- a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graffle.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Originally grabbed from the official RaphaelJS Documentation - * http://raphaeljs.com/graffle.html - * Adopted (arrows) and commented by Philipp Strathausen http://blog.ameisenbar.de - * Licenced under the MIT licence. - */ - -/** - * Usage: - * connect two shapes - * parameters: - * source shape [or connection for redrawing], - * target shape, - * style with { fg : linecolor, bg : background color, directed: boolean } - * returns: - * connection { draw = function() } - */ -Raphael.fn.connection = function (obj1, obj2, style) { - var selfRef = this; - /* create and return new connection */ - var edge = {/* - from : obj1, - to : obj2, - style : style,*/ - draw : function() { - /* get bounding boxes of target and source */ - var bb1 = obj1.getBBox(); - var bb2 = obj2.getBBox(); - var off1 = 0; - var off2 = 0; - /* coordinates for potential connection coordinates from/to the objects */ - var p = [ - {x: bb1.x + bb1.width / 2, y: bb1.y - off1}, /* NORTH 1 */ - {x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + off1}, /* SOUTH 1 */ - {x: bb1.x - off1, y: bb1.y + bb1.height / 2}, /* WEST 1 */ - {x: bb1.x + bb1.width + off1, y: bb1.y + bb1.height / 2}, /* EAST 1 */ - {x: bb2.x + bb2.width / 2, y: bb2.y - off2}, /* NORTH 2 */ - {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + off2}, /* SOUTH 2 */ - {x: bb2.x - off2, y: bb2.y + bb2.height / 2}, /* WEST 2 */ - {x: bb2.x + bb2.width + off2, y: bb2.y + bb2.height / 2} /* EAST 2 */ - ]; - - /* distances between objects and according coordinates connection */ - var d = {}, dis = []; - - /* - * find out the best connection coordinates by trying all possible ways - */ - /* loop the first object's connection coordinates */ - for (var i = 0; i < 4; i++) { - /* loop the seond object's connection coordinates */ - for (var j = 4; j < 8; j++) { - var dx = Math.abs(p[i].x - p[j].x), - dy = Math.abs(p[i].y - p[j].y); - if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) { - dis.push(dx + dy); - d[dis[dis.length - 1].toFixed(3)] = [i, j]; - } - } - } - var res = dis.length == 0 ? [0, 4] : d[Math.min.apply(Math, dis).toFixed(3)]; - /* bezier path */ - var x1 = p[res[0]].x, - y1 = p[res[0]].y, - x4 = p[res[1]].x, - y4 = p[res[1]].y, - dx = Math.max(Math.abs(x1 - x4) / 2, 10), - dy = Math.max(Math.abs(y1 - y4) / 2, 10), - x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3), - y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3), - x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3), - y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3); - /* assemble path and arrow */ - var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(","); - /* arrow */ - if(style && style.directed) { - /* magnitude, length of the last path vector */ - var mag = Math.sqrt((y4 - y3) * (y4 - y3) + (x4 - x3) * (x4 - x3)); - /* vector normalisation to specified length */ - var norm = function(x,l){return (-x*(l||5)/mag);}; - /* calculate array coordinates (two lines orthogonal to the path vector) */ - var arr = [ - {x:(norm(x4-x3)+norm(y4-y3)+x4).toFixed(3), y:(norm(y4-y3)+norm(x4-x3)+y4).toFixed(3)}, - {x:(norm(x4-x3)-norm(y4-y3)+x4).toFixed(3), y:(norm(y4-y3)-norm(x4-x3)+y4).toFixed(3)} - ]; - path = path + ",M"+arr[0].x+","+arr[0].y+",L"+x4+","+y4+",L"+arr[1].x+","+arr[1].y; - } - /* function to be used for moving existent path(s), e.g. animate() or attr() */ - var move = "attr"; - /* applying path(s) */ - edge.fg && edge.fg[move]({path:path}) - || (edge.fg = selfRef.path(path).attr({stroke: style && style.stroke || "#000", fill: "none"}).toBack()); - edge.bg && edge.bg[move]({path:path}) - || style && style.fill && (edge.bg = style.fill.split && selfRef.path(path).attr({stroke: style.fill.split("|")[0], fill: "none", "stroke-width": style.fill.split("|")[1] || 3}).toBack()); - /* setting label */ - style && style.label - && (edge.label && edge.label.attr({x:(x1+x4)/2, y:(y1+y4)/2}) - || (edge.label = selfRef.text((x1+x4)/2, (y1+y4)/2, style.label).attr({fill: "#000", "font-size": style["font-size"] || "12px"}))); - style && style.label && style["label-style"] && edge.label && edge.label.attr(style["label-style"]); - style && style.callback && style.callback(edge); - } - } - edge.draw(); - return edge; -}; -//Raphael.prototype.set.prototype.dodo=function(){console.log("works");}; diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graph.js b/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graph.js deleted file mode 100644 index f3e43e1..0000000 --- a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/dracula_graph.js +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Dracula Graph Layout and Drawing Framework 0.0.3alpha - * (c) 2010 Philipp Strathausen , http://strathausen.eu - * Contributions by Jake Stothard . - * - * based on the Graph JavaScript framework, version 0.0.1 - * (c) 2006 Aslak Hellesoy - * (c) 2006 Dave Hoover - * - * Ported from Graph::Layouter::Spring in - * http://search.cpan.org/~pasky/Graph-Layderer-0.02/ - * The algorithm is based on a spring-style layouter of a Java-based social - * network tracker PieSpy written by Paul Mutton . - * - * This code is freely distributable under the MIT license. Commercial use is - * hereby granted without any cost or restriction. - * - * Links: - * - * Graph Dracula JavaScript Framework: - * http://graphdracula.net - * - /*--------------------------------------------------------------------------*/ - -/* - * Edge Factory - */ -var AbstractEdge = function() { -} -AbstractEdge.prototype = { - hide: function() { - this.connection.fg.hide(); - this.connection.bg && this.bg.connection.hide(); - } -}; -var EdgeFactory = function() { - this.template = new AbstractEdge(); - this.template.style = new Object(); - this.template.style.directed = false; - this.template.weight = 1; -}; -EdgeFactory.prototype = { - build: function(source, target) { - var e = jQuery.extend(true, {}, this.template); - e.source = source; - e.target = target; - return e; - } -}; - -/* - * Graph - */ -var Graph = function() { - this.nodes = {}; - this.edges = []; - this.snapshots = []; // previous graph states TODO to be implemented - this.edgeFactory = new EdgeFactory(); -}; -Graph.prototype = { - /* - * add a node - * @id the node's ID (string or number) - * @content (optional, dictionary) can contain any information that is - * being interpreted by the layout algorithm or the graph - * representation - */ - addNode: function(id, content) { - /* testing if node is already existing in the graph */ - if(this.nodes[id] == undefined) { - this.nodes[id] = new Graph.Node(id, content); - } - return this.nodes[id]; - }, - - addEdge: function(source, target, style) { - var s = this.addNode(source); - var t = this.addNode(target); - var edge = this.edgeFactory.build(s, t); - jQuery.extend(edge.style,style); - s.edges.push(edge); - this.edges.push(edge); - // NOTE: Even directed edges are added to both nodes. - t.edges.push(edge); - }, - - /* TODO to be implemented - * Preserve a copy of the graph state (nodes, positions, ...) - * @comment a comment describing the state - */ - snapShot: function(comment) { - /* FIXME - var graph = new Graph(); - graph.nodes = jQuery.extend(true, {}, this.nodes); - graph.edges = jQuery.extend(true, {}, this.edges); - this.snapshots.push({comment: comment, graph: graph}); - */ - }, - removeNode: function(id) { - delete this.nodes[id]; - for(var i = 0; i < this.edges.length; i++) { - if (this.edges[i].source.id == id || this.edges[i].target.id == id) { - this.edges.splice(i, 1); - i--; - } - } - } -}; - -/* - * Node - */ -Graph.Node = function(id, node){ - node = node || {}; - node.id = id; - node.edges = []; - node.hide = function() { - this.hidden = true; - this.shape && this.shape.hide(); /* FIXME this is representation specific code and should be elsewhere */ - for(i in this.edges) - (this.edges[i].source.id == id || this.edges[i].target == id) && this.edges[i].hide && this.edges[i].hide(); - }; - node.show = function() { - this.hidden = false; - this.shape && this.shape.show(); - for(i in this.edges) - (this.edges[i].source.id == id || this.edges[i].target == id) && this.edges[i].show && this.edges[i].show(); - }; - return node; -}; -Graph.Node.prototype = { -}; - -/* - * Renderer base class - */ -Graph.Renderer = {}; - -/* - * Renderer implementation using RaphaelJS - */ -Graph.Renderer.Raphael = function(element, graph, width, height) { - this.width = width || 400; - this.height = height || 400; - var selfRef = this; - this.r = Raphael(element, this.width, this.height); - this.radius = 40; /* max dimension of a node */ - this.graph = graph; - this.mouse_in = false; - - /* TODO default node rendering function */ - if(!this.graph.render) { - this.graph.render = function() { - return; - } - } - - /* - * Dragging - */ - this.isDrag = false; - this.dragger = function (e) { - this.dx = e.clientX; - this.dy = e.clientY; - selfRef.isDrag = this; - this.set && this.set.animate({"fill-opacity": .1}, 200) && this.set.toFront(); - e.preventDefault && e.preventDefault(); - }; - - var d = document.getElementById(element); - d.onmousemove = function (e) { - e = e || window.event; - if (selfRef.isDrag) { - var bBox = selfRef.isDrag.set.getBBox(); - // TODO round the coordinates here (eg. for proper image representation) - var newX = e.clientX - selfRef.isDrag.dx + (bBox.x + bBox.width / 2); - var newY = e.clientY - selfRef.isDrag.dy + (bBox.y + bBox.height / 2); - /* prevent shapes from being dragged out of the canvas */ - var clientX = e.clientX - (newX < 20 ? newX - 20 : newX > selfRef.width - 20 ? newX - selfRef.width + 20 : 0); - var clientY = e.clientY - (newY < 20 ? newY - 20 : newY > selfRef.height - 20 ? newY - selfRef.height + 20 : 0); - selfRef.isDrag.set.translate(clientX - Math.round(selfRef.isDrag.dx), clientY - Math.round(selfRef.isDrag.dy)); - // console.log(clientX - Math.round(selfRef.isDrag.dx), clientY - Math.round(selfRef.isDrag.dy)); - for (var i in selfRef.graph.edges) { - selfRef.graph.edges[i].connection && selfRef.graph.edges[i].connection.draw(); - } - //selfRef.r.safari(); - selfRef.isDrag.dx = clientX; - selfRef.isDrag.dy = clientY; - } - }; - d.onmouseup = function () { - selfRef.isDrag && selfRef.isDrag.set.animate({"fill-opacity": .6}, 500); - selfRef.isDrag = false; - }; - this.draw(); -}; -Graph.Renderer.Raphael.prototype = { - translate: function(point) { - return [ - (point[0] - this.graph.layoutMinX) * this.factorX + this.radius, - (point[1] - this.graph.layoutMinY) * this.factorY + this.radius - ]; - }, - - rotate: function(point, length, angle) { - var dx = length * Math.cos(angle); - var dy = length * Math.sin(angle); - return [point[0]+dx, point[1]+dy]; - }, - - draw: function() { - this.factorX = (this.width - 2 * this.radius) / (this.graph.layoutMaxX - this.graph.layoutMinX); - this.factorY = (this.height - 2 * this.radius) / (this.graph.layoutMaxY - this.graph.layoutMinY); - for (i in this.graph.nodes) { - this.drawNode(this.graph.nodes[i]); - } - for (var i = 0; i < this.graph.edges.length; i++) { - this.drawEdge(this.graph.edges[i]); - } - }, - - drawNode: function(node) { - var point = this.translate([node.layoutPosX, node.layoutPosY]); - node.point = point; - - /* if node has already been drawn, move the nodes */ - if(node.shape) { - var oBBox = node.shape.getBBox(); - var opoint = { x: oBBox.x + oBBox.width / 2, y: oBBox.y + oBBox.height / 2}; - node.shape.translate(Math.round(point[0] - opoint.x), Math.round(point[1] - opoint.y)); - this.r.safari(); - return node; - }/* else, draw new nodes */ - - var shape; - - /* if a node renderer function is provided by the user, then use it - or the default render function instead */ - if(!node.render) { - node.render = function(r, node) { - /* the default node drawing */ - var color = Raphael.getColor(); - var ellipse = r.ellipse(0, 0, 30, 20).attr({fill: color, stroke: color, "stroke-width": 2}); - /* set DOM node ID */ - ellipse.node.id = node.label || node.id; - shape = r.set(). - push(ellipse). - push(r.text(0, 30, node.label || node.id)); - return shape; - } - } - /* or check for an ajax representation of the nodes */ - if(node.shapes) { - // TODO ajax representation evaluation - } - - shape = node.render(this.r, node).hide(); - - shape.attr({"fill-opacity": .6}); - /* re-reference to the node an element belongs to, needed for dragging all elements of a node */ - shape.items.forEach(function(item){ item.set = shape; item.node.style.cursor = "move"; }); - shape.mousedown(this.dragger); - - var box = shape.getBBox(); - shape.translate(Math.round(point[0]-(box.x+box.width/2)),Math.round(point[1]-(box.y+box.height/2))) - //console.log(box,point); - node.hidden || shape.show(); - node.shape = shape; - }, - drawEdge: function(edge) { - /* if this edge already exists the other way around and is undirected */ - if(edge.backedge) - return; - if(edge.source.hidden || edge.target.hidden) { - edge.connection && edge.connection.fg.hide() | edge.connection.bg && edge.connection.bg.hide(); - return; - } - /* if edge already has been drawn, only refresh the edge */ - if(!edge.connection) { - edge.style && edge.style.callback && edge.style.callback(edge); // TODO move this somewhere else - edge.connection = this.r.connection(edge.source.shape, edge.target.shape, edge.style); - return; - } - //FIXME showing doesn't work well - edge.connection.fg.show(); - edge.connection.bg && edge.connection.bg.show(); - edge.connection.draw(); - } -}; -Graph.Layout = {}; -Graph.Layout.Spring = function(graph) { - this.graph = graph; - this.iterations = 500; - this.maxRepulsiveForceDistance = 6; - this.k = 2; - this.c = 0.01; - this.maxVertexMovement = 0.5; - this.layout(); -}; -Graph.Layout.Spring.prototype = { - layout: function() { - this.layoutPrepare(); - for (var i = 0; i < this.iterations; i++) { - this.layoutIteration(); - } - this.layoutCalcBounds(); - }, - - layoutPrepare: function() { - for (i in this.graph.nodes) { - var node = this.graph.nodes[i]; - node.layoutPosX = 0; - node.layoutPosY = 0; - node.layoutForceX = 0; - node.layoutForceY = 0; - } - - }, - - layoutCalcBounds: function() { - var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity; - - for (i in this.graph.nodes) { - var x = this.graph.nodes[i].layoutPosX; - var y = this.graph.nodes[i].layoutPosY; - - if(x > maxx) maxx = x; - if(x < minx) minx = x; - if(y > maxy) maxy = y; - if(y < miny) miny = y; - } - - this.graph.layoutMinX = minx; - this.graph.layoutMaxX = maxx; - this.graph.layoutMinY = miny; - this.graph.layoutMaxY = maxy; - }, - - layoutIteration: function() { - // Forces on nodes due to node-node repulsions - - var prev = new Array(); - for(var c in this.graph.nodes) { - var node1 = this.graph.nodes[c]; - for (var d in prev) { - var node2 = this.graph.nodes[prev[d]]; - this.layoutRepulsive(node1, node2); - - } - prev.push(c); - } - - // Forces on nodes due to edge attractions - for (var i = 0; i < this.graph.edges.length; i++) { - var edge = this.graph.edges[i]; - this.layoutAttractive(edge); - } - - // Move by the given force - for (i in this.graph.nodes) { - var node = this.graph.nodes[i]; - var xmove = this.c * node.layoutForceX; - var ymove = this.c * node.layoutForceY; - - var max = this.maxVertexMovement; - if(xmove > max) xmove = max; - if(xmove < -max) xmove = -max; - if(ymove > max) ymove = max; - if(ymove < -max) ymove = -max; - - node.layoutPosX += xmove; - node.layoutPosY += ymove; - node.layoutForceX = 0; - node.layoutForceY = 0; - } - }, - - layoutRepulsive: function(node1, node2) { - if (typeof node1 == 'undefined' || typeof node2 == 'undefined') - return; - var dx = node2.layoutPosX - node1.layoutPosX; - var dy = node2.layoutPosY - node1.layoutPosY; - var d2 = dx * dx + dy * dy; - if(d2 < 0.01) { - dx = 0.1 * Math.random() + 0.1; - dy = 0.1 * Math.random() + 0.1; - var d2 = dx * dx + dy * dy; - } - var d = Math.sqrt(d2); - if(d < this.maxRepulsiveForceDistance) { - var repulsiveForce = this.k * this.k / d; - node2.layoutForceX += repulsiveForce * dx / d; - node2.layoutForceY += repulsiveForce * dy / d; - node1.layoutForceX -= repulsiveForce * dx / d; - node1.layoutForceY -= repulsiveForce * dy / d; - } - }, - - layoutAttractive: function(edge) { - var node1 = edge.source; - var node2 = edge.target; - - var dx = node2.layoutPosX - node1.layoutPosX; - var dy = node2.layoutPosY - node1.layoutPosY; - var d2 = dx * dx + dy * dy; - if(d2 < 0.01) { - dx = 0.1 * Math.random() + 0.1; - dy = 0.1 * Math.random() + 0.1; - var d2 = dx * dx + dy * dy; - } - var d = Math.sqrt(d2); - if(d > this.maxRepulsiveForceDistance) { - d = this.maxRepulsiveForceDistance; - d2 = d * d; - } - var attractiveForce = (d2 - this.k * this.k) / this.k; - if(edge.attraction == undefined) edge.attraction = 1; - attractiveForce *= Math.log(edge.attraction) * 0.5 + 1; - - node2.layoutForceX -= attractiveForce * dx / d; - node2.layoutForceY -= attractiveForce * dy / d; - node1.layoutForceX += attractiveForce * dx / d; - node1.layoutForceY += attractiveForce * dy / d; - } -}; - -Graph.Layout.Ordered = function(graph, order) { - this.graph = graph; - this.order = order; - this.layout(); -}; -Graph.Layout.Ordered.prototype = { - layout: function() { - this.layoutPrepare(); - this.layoutCalcBounds(); - }, - - layoutPrepare: function(order) { - for (i in this.graph.nodes) { - var node = this.graph.nodes[i]; - node.layoutPosX = 0; - node.layoutPosY = 0; - } - var counter = 0; - for (i in this.order) { - var node = this.order[i]; - node.layoutPosX = counter; - node.layoutPosY = Math.random(); - counter++; - } - }, - - layoutCalcBounds: function() { - var minx = Infinity, maxx = -Infinity, miny = Infinity, maxy = -Infinity; - - for (i in this.graph.nodes) { - var x = this.graph.nodes[i].layoutPosX; - var y = this.graph.nodes[i].layoutPosY; - - if(x > maxx) maxx = x; - if(x < minx) minx = x; - if(y > maxy) maxy = y; - if(y < miny) miny = y; - } - - this.graph.layoutMinX = minx; - this.graph.layoutMaxX = maxx; - - this.graph.layoutMinY = miny; - this.graph.layoutMaxY = maxy; - } -}; - -/* - * usefull JavaScript extensions, - */ - -function log(a) {console.log&&console.log(a);} - -/* - * Raphael Tooltip Plugin - * - attaches an element as a tooltip to another element - * - * Usage example, adding a rectangle as a tooltip to a circle: - * - * paper.circle(100,100,10).tooltip(paper.rect(0,0,20,30)); - * - * If you want to use more shapes, you'll have to put them into a set. - * - */ -Raphael.el.tooltip = function (tp) { - this.tp = tp; - this.tp.o = {x: 0, y: 0}; - this.tp.hide(); - this.hover( - function(event){ - this.mousemove(function(event){ - this.tp.translate(event.clientX - - this.tp.o.x,event.clientY - this.tp.o.y); - this.tp.o = {x: event.clientX, y: event.clientY}; - }); - this.tp.show().toFront(); - }, - function(event){ - this.tp.hide(); - this.unmousemove(); - }); - return this; -}; - -/* For IE */ -if (!Array.prototype.forEach) -{ - Array.prototype.forEach = function(fun /*, thisp*/) - { - var len = this.length; - if (typeof fun != "function") - throw new TypeError(); - - var thisp = arguments[1]; - for (var i = 0; i < len; i++) - { - if (i in this) - fun.call(thisp, this[i], i, this); - } - }; -} diff --git a/luci-app-bmx6/files/www/luci-static/resources/bmx6/js/jquery-1.4.2.min.js b/luci-app-bmx6/jquery/jquery-1.4.js similarity index 100% rename from luci-app-bmx6/files/www/luci-static/resources/bmx6/js/jquery-1.4.2.min.js rename to luci-app-bmx6/jquery/jquery-1.4.js diff --git a/miniupnpd/Makefile b/miniupnpd/Makefile index 5537e2c..1841200 100644 --- a/miniupnpd/Makefile +++ b/miniupnpd/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=miniupnpd -PKG_VERSION:=2.0.20161216 -PKG_RELEASE:=1 +PKG_VERSION:=2.0.20170421 +PKG_RELEASE:=2 PKG_SOURCE_URL:=http://miniupnp.free.fr/files PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MD5SUM:=9e73d50ac830b5e08b6eb1df4e4c917833a5ab54351809f615d15d0f30cdeef3 +PKG_HASH:=9677aeccadf73b4bf8bb9d832c32b5da8266b4d58eed888f3fd43d7656405643 PKG_MAINTAINER:=Markus Stenberg PKG_LICENSE:=BSD-3-Clause @@ -32,7 +32,7 @@ endef define Package/miniupnpd/config config MINIUPNPD_IGDv2 bool - default y + default n prompt "Enable IGDv2" endef diff --git a/nat46/Makefile b/nat46/Makefile index 47b5a5b..1140bcf 100644 --- a/nat46/Makefile +++ b/nat46/Makefile @@ -9,14 +9,15 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=nat46 -PKG_VERSION:=8 +PKG_VERSION:=10 PKG_RELEASE:=$(PKG_SOURCE_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_MIRROR_HASH:=43b7004bfa2c830d6025386bc2128015db0012277fd015f4ee44b9ee3b772a12 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_URL:=https://github.com/ayourtch/nat46.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=1cd9fc7025906e1825767b05615d2cf02e1528da +PKG_SOURCE_VERSION:=683fbd2b765506332a1af141545652bf58f03166 PKG_MAINTAINER:=Steven Barth PKG_LICENSE:=GPL-2.0 @@ -32,7 +33,7 @@ endef define Package/464xlat SECTION:=net CATEGORY:=Network - DEPENDS:=+kmod-nat46 + DEPENDS:=+kmod-nat46 +ip TITLE:=464xlat CLAT support endef diff --git a/nat46/files/464xlat.sh b/nat46/files/464xlat.sh index 2ec1094..4b3cd1c 100755 --- a/nat46/files/464xlat.sh +++ b/nat46/files/464xlat.sh @@ -43,6 +43,11 @@ proto_464xlat_setup() { return fi + ip -6 rule del from all lookup local + ip -6 rule add from all lookup local pref 1 + ip -6 rule add to $ip6addr lookup prelocal pref 0 + echo "$ip6addr" > /tmp/464-$cfg-anycast + proto_init_update "$link" 1 proto_add_ipv4_route "0.0.0.0" 0 "" "" 2048 proto_add_ipv6_route $ip6addr 128 "" "" "" "" 128 @@ -74,7 +79,20 @@ proto_464xlat_setup() { } proto_464xlat_teardown() { - 464xlatcfg "464-$1" + local cfg="$1" + local link="464-$cfg" + local ip6addr=$(cat /tmp/464-$cfg-anycast) + local anycast_active + + 464xlatcfg "$link" + + rm -rf /tmp/464-$cfg-anycast + ip -6 rule del to $ip6addr lookup prelocal + + if [ -z "$(ls /tmp/464-*-anycast 2>&-)" ]; then + ip -6 rule del from all lookup local + ip -6 rule add from all lookup local pref 0 + fi } proto_464xlat_init_config() { diff --git a/nat46/src/464xlatcfg.c b/nat46/src/464xlatcfg.c index f184616..288733e 100644 --- a/nat46/src/464xlatcfg.c +++ b/nat46/src/464xlatcfg.c @@ -1,6 +1,7 @@ /* 464xlatcfg.c * * Copyright (c) 2015 Steven Barth + * Copyright (c) 2017 Hans Dedecker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -31,28 +32,31 @@ int main(int argc, const char *argv[]) { char buf[INET6_ADDRSTRLEN], prefix[INET6_ADDRSTRLEN + 4]; int pid; - + if (argc <= 1) { fprintf(stderr, "Usage: %s [ifname] [ipv6prefix] [ipv4addr] [ipv6addr]\n", argv[0]); return 1; } - + snprintf(buf, sizeof(buf), "/var/run/%s.pid", argv[1]); FILE *fp = fopen(buf, "r"); if (fp) { - fscanf(fp, "%d", &pid); - kill(pid, SIGTERM); + if (fscanf(fp, "%d", &pid) == 1) + kill(pid, SIGTERM); + unlink(buf); fclose(fp); } - + if (!argv[2]) return 0; - + if (!argv[3] || !argv[4] || !(fp = fopen(buf, "wx"))) return 1; - signal(SIGTERM, sighandler); + signal(SIGTERM, SIG_DFL); + setvbuf(fp, NULL, _IOLBF, 0); + fprintf(fp, "%d\n", getpid()); prefix[sizeof(prefix) - 1] = 0; strncpy(prefix, argv[3], sizeof(prefix) - 1); @@ -70,7 +74,7 @@ int main(int argc, const char *argv[]) strcat(prefix, "/96"); freeaddrinfo(res); } - + int i = 0; int sock; struct sockaddr_in6 saddr; @@ -98,7 +102,7 @@ int main(int argc, const char *argv[]) sleep(3); i++; } while (i < 3); - + struct ipv6_mreq mreq = {saddr.sin6_addr, if_nametoindex(argv[2])}; if (!argv[5]) { if (IN6_IS_ADDR_LINKLOCAL(&mreq.ipv6mr_multiaddr)) @@ -111,21 +115,21 @@ int main(int argc, const char *argv[]) } else if (inet_pton(AF_INET6, argv[5], &mreq.ipv6mr_multiaddr) != 1) { return 1; } - + if (setsockopt(sock, SOL_IPV6, IPV6_JOIN_ANYCAST, &mreq, sizeof(mreq))) return 3; - + inet_ntop(AF_INET6, &mreq.ipv6mr_multiaddr, buf, sizeof(buf)); fputs(buf, stdout); fputc('\n', stdout); fflush(stdout); - + FILE *nat46 = fopen("/proc/net/nat46/control", "w"); if (!nat46 || fprintf(nat46, "add %s\nconfig %s local.style NONE local.v4 %s/32 local.v6 %s/128 " "remote.style RFC6052 remote.v6 %s\n", argv[1], argv[1], argv[4], buf, prefix) < 0 || fclose(nat46)) return 4; - + if (!(pid = fork())) { fclose(fp); fclose(stdin); @@ -133,6 +137,7 @@ int main(int argc, const char *argv[]) fclose(stderr); chdir("/"); setsid(); + signal(SIGTERM, sighandler); pause(); nat46 = fopen("/proc/net/nat46/control", "w"); @@ -141,8 +146,9 @@ int main(int argc, const char *argv[]) fclose(nat46); } } else { + rewind(fp); fprintf(fp, "%d\n", pid); } - + return 0; } diff --git a/nodogsplash/Makefile b/nodogsplash/Makefile index 971fbac..b0f9da8 100644 --- a/nodogsplash/Makefile +++ b/nodogsplash/Makefile @@ -1,6 +1,4 @@ # -# Copyright (C) 2013-2016 OpenWrt.org -# # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # @@ -9,13 +7,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nodogsplash PKG_FIXUP:=autoreconf -PKG_VERSION:=1.0.1 -PKG_RELEASE:=2 +PKG_VERSION:=1.0.2 +PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=git://github.com/nodogsplash/nodogsplash.git -PKG_SOURCE_VERSION:=485d6dba05cce7a4ed87c28beaaf1199c0f832cf +PKG_SOURCE_VERSION:=9ef7d5fc16351585baf65877776d19cf85bf3031 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_BUILD_PARALLEL:=1 PKG_LICENSE:=GPL-2.0+ diff --git a/nodogsplash/files/nodogsplash.config b/nodogsplash/files/nodogsplash.config index 986a3d9..9626b80 100644 --- a/nodogsplash/files/nodogsplash.config +++ b/nodogsplash/files/nodogsplash.config @@ -13,7 +13,7 @@ config nodogsplash option network 'lan' option gatewayname 'OpenWrt Nodogsplash' option maxclients '250' - option idletimeout '1200' + option clientidletimeout '1200' # Your router may have several interfaces, and you # probably want to keep them private from the network/gatewayinterface. diff --git a/nodogsplash/patches/100-musl-compat.patch b/nodogsplash/patches/100-musl-compat.patch deleted file mode 100644 index bb186bc..0000000 --- a/nodogsplash/patches/100-musl-compat.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/src/client_list.c -+++ b/src/client_list.c -@@ -36,7 +36,7 @@ - #include - #include - #include --#include -+#include - - #include - ---- a/src/firewall.c -+++ b/src/firewall.c -@@ -37,7 +37,7 @@ - #include - #include - #include --#include -+#include - - #include - ---- a/src/util.c -+++ b/src/util.c -@@ -38,7 +38,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include ---- a/libhttpd/protocol.c -+++ b/libhttpd/protocol.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #if defined(_WIN32) - #else diff --git a/nodogsplash2/Makefile b/nodogsplash2/Makefile new file mode 100644 index 0000000..ccebc78 --- /dev/null +++ b/nodogsplash2/Makefile @@ -0,0 +1,61 @@ +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nodogsplash2 +PKG_FIXUP:=autoreconf +PKG_VERSION:=2.0.0 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/ +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=git://github.com/nodogsplash/nodogsplash.git +PKG_SOURCE_VERSION:=9d985d93f15db4052677dc34c37232bc958944bc +PKG_MIRROR_HASH:=12f9ea4e19c76f438f54a2214b098af233645713db7f8893c968fe1cab98ab1b +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_MAINTAINER:=Moritz Warning +PKG_BUILD_PARALLEL:=1 +PKG_LICENSE:=GPL-2.0+ + +include $(INCLUDE_DIR)/package.mk + + +define Package/nodogsplash2 + SUBMENU:=Captive Portals + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libpthread +iptables-mod-ipopt +libmicrohttpd-no-ssl + TITLE:=Open public network gateway daemon + URL:=https://github.com/nodogsplash/nodogsplash + CONFLICTS:=nodogsplash +endef + +define Package/nodogsplash2/description + Nodogsplash offers a simple way to open a free hotspot providing + restricted access to an internet connection. +endef + +define Package/nodogsplash2/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/nodogsplash $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ndsctl $(1)/usr/bin/ + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) files/nodogsplash.init $(1)/etc/init.d/nodogsplash + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) files/nodogsplash.config $(1)/etc/config/nodogsplash + + $(INSTALL_DIR) $(1)/etc/nodogsplash/htdocs/images + $(CP) $(PKG_BUILD_DIR)/resources/splash.html $(1)/etc/nodogsplash/htdocs/ + $(CP) $(PKG_BUILD_DIR)/resources/infoskel.html $(1)/etc/nodogsplash/htdocs/ + $(CP) $(PKG_BUILD_DIR)/resources/splash.jpg $(1)/etc/nodogsplash/htdocs/images/ +endef + +define Package/nodogsplash2/conffiles +/etc/nodogsplash/nodogsplash.conf +endef + +$(eval $(call BuildPackage,nodogsplash2)) diff --git a/nodogsplash2/files/nodogsplash.config b/nodogsplash2/files/nodogsplash.config new file mode 100644 index 0000000..c02b66f --- /dev/null +++ b/nodogsplash2/files/nodogsplash.config @@ -0,0 +1,53 @@ + +# The options available here are an adaptation of the settings used in nodogsplash.conf. +# See https://github.com/nodogsplash/nodogsplash/blob/master/resources/nodogsplash.conf + +config nodogsplash + # Set to 1 to enable nodogsplash + option enabled 0 + + # Use plain configuration file + #option config '/etc/nodogsplash/nodogsplash.conf' + + # The network the users are connected to + option network 'lan' + option gatewayname 'LEDE Nodogsplash' + option maxclients '250' + option clientidletimeout '1200' + + # Your router may have several interfaces, and you + # probably want to keep them private from the network/gatewayinterface. + # If so, you should block the entire subnets on those interfaces, e.g.: + list authenticated_users 'block to 192.168.0.0/16' + list authenticated_users 'block to 10.0.0.0/8' + + # Typical ports you will probably want to open up. + list authenticated_users 'allow tcp port 22' + list authenticated_users 'allow tcp port 53' + list authenticated_users 'allow udp port 53' + list authenticated_users 'allow tcp port 80' + list authenticated_users 'allow tcp port 443' + + # For preauthenticated users to resolve IP addresses in their + # initial request not using the router itself as a DNS server, + list preauthenticated_users 'allow tcp port 53' + list preauthenticated_users 'allow udp port 53' + + # Allow ports for SSH/Telnet/DNS/DHCP/HTTP/HTTPS + list users_to_router 'allow tcp port 22' + list users_to_router 'allow tcp port 23' + list users_to_router 'allow tcp port 53' + list users_to_router 'allow udp port 53' + list users_to_router 'allow udp port 67' + list users_to_router 'allow tcp port 80' + list users_to_router 'allow tcp port 443' + + # MAC addresses that are / are not allowed to access the splash page + # Value is either 'allow' or 'block'. The allowedmac or blockedmac list is used. + #option macmechanism 'allow' + #list allowedmac '00:00:C0:01:D0:0D' + #list allowedmac '00:00:C0:01:D0:1D' + #list blockedmac '00:00:C0:01:D0:2D' + + #MAC addresses that do not need to authenticate + #list trustedmac '00:00:C0:01:D0:1D' diff --git a/nodogsplash2/files/nodogsplash.init b/nodogsplash2/files/nodogsplash.init new file mode 100755 index 0000000..32dc1eb --- /dev/null +++ b/nodogsplash2/files/nodogsplash.init @@ -0,0 +1,355 @@ +#!/bin/sh /etc/rc.common +# +# description: Startup/shutdown script for nodogsplash captive portal +# +# Alexander Couzens 2014 +# P. Kube 2007 +# +# (Based on wifidog startup script +# Date : 2004-08-25 +# Version : 1.0 +# Comment by that author: Could be better, but it's working as expected) +# + +START=95 +STOP=95 + +USE_PROCD=1 + +IPT=/usr/sbin/iptables +WD_DIR=/usr/bin +# -s -d 5 runs in background, with level 5 (not so verbose) messages to syslog +# -f -d 7 runs in foreground, with level 7 (verbose) debug messages to terminal +OPTIONS="-s -f -d 5" +CONFIGFILE="/tmp/invalid_nodogsplash.conf" + +# nolog(loglevel message ...) +nolog() { + local level=$1 + shift + logger -s -t nodogsplash -p daemon.$level $@ +} + +# append_config_option_map [] +# append "$config_counterpart $value" to cfgfile if option_name exists +# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address BindAddress 0.0.0.0 +# will append "BindAddress 192.168.1.1" if uci bind_address is '192.168.1.1' +append_config_option_map() { + local val="" + local config_file="$1" + local cfg="$2" + local option_name="$3" + local config_counterpart="$4" + local default="$5" + config_get val "$cfg" "$option_name" "$default" + [ -n "$val" ] && echo "$config_counterpart $val" >> $config_file +} + +# append_config_option [] +# append "$option_name $value" to cfgfile if option_name exists +# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address 0.0.0.0 +# will append "bind_address 192.168.1.1" if uci bind_address is '192.168.1.1' +# if uci bind_address is unset append "bind_address 0.0.0.0" +append_config_option() { + local val="" + local config_file="$1" + local cfg="$2" + local option_name="$3" + local default="$4" + config_get val "$cfg" "$option_name" "$default" + [ -n "$val" ] && echo "$option_name $val" >> $config_file +} + +setup_mac_lists() { + local cfg="$1" + local MAC="" + local val + + append_mac() { + append MAC "$1" "," + } + + config_get val "$cfg" macmechanism + if [ -z "$val" ] ; then + # check if we have AllowedMACList or BlockedMACList defined they will be ignored + config_get val "$cfg" allowedmac + if [ -n "$val" ] ; then + echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2 + fi + + config_get val "$cfg" blockedmac + if [ -n "$val" ] ; then + echo "Ignoring blockedmac - macmechanism not \"block\"" >&2 + fi + elif [ "$val" == "allow" ] ; then + MAC="" + config_list_foreach "$cfg" allowedmac append_mac + echo "AllowedMACList $MAC" >> $CONFIGFILE + elif [ "$val" == "block" ] ; then + MAC="" + config_list_foreach "$cfg" blockedmac append_mac + echo "BlockedMACList $MAC" >> $CONFIGFILE + else + nolog error "$cfg Invalid macmechanism '$val' - allow or block are valid." + return 1 + fi + MAC="" + config_list_foreach "$cfg" trustedmac append_mac + [ -n "$MAC" ] && echo "TrustedMACList $MAC" >> $CONFIGFILE +} + +setup_firewall() { + local cfg="$1" + local uciname + local val + + append_firewall() { + echo " FirewallRule $1" >> $CONFIGFILE + } + + for rule in $(echo authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router) + do + uci_name=${rule//-/_} + # uci does not allow - dashes + echo "FirewallRuleSet $rule {" >> $CONFIGFILE + config_list_foreach "$cfg" ${uci_name} append_firewall + echo "}" >> $CONFIGFILE + config_get val "$cfg" policy_${uci_name} + [ -n "$val" ] && echo "EmptyRuleSetPolicy $rule $val" >> $CONFIGFILE + done +} + +wait_for_interface() +{ + local ifname="$1" + local timeout=10 + for i in $(seq $timeout); do + if [ $(ip -4 addr show dev $ifname 2> /dev/null | grep -c inet) -ne 0 ]; then + break + fi + sleep 1 + if [ $i == $timeout ] ; then + nolog error "$ifname not detected, NoDogSplash not starting." + exit 1 + fi + done +} + +generate_uci_config() { + local cfg="$1" + local val + local ifname + local download + local upload + + CONFIGFILE="/tmp/etc/nodogsplash_$cfg.conf" + + echo "# auto-generated config file from /etc/config/nodogsplash" > $CONFIGFILE + + config_get val "$cfg" config + if [ -n "$val" ] ; then + if [ ! -f "$val" ] ; then + nolog error "Configuration file '$file' doesn't exist" + return 0 + fi + cat "$val" >> $CONFIGFILE + fi + + config_get val "$cfg" network + if [ -n "$val" ] ; then + if ! network_get_device ifname "$val" ; then + nolog error "$cfg can not find ifname for network '$val'" + return 1 + fi + fi + + config_get val "$cfg" gatewayinterface + if [ -n "$val" ] ; then + if [ -n "$ifname" ] ; then + nolog error "$cfg cannot use both option network and gatewayinterface" + return 1 + fi + ifname="$val" + fi + + if [ -z "$ifname" ] ; then + nolog error "$cfg option network or gatewayinterface missing" + return 1 + fi + + wait_for_interface "$ifname" + + echo "GatewayInterface $ifname" >> $CONFIGFILE + + append_config_option "$CONFIGFILE" "$cfg" gatewayname + append_config_option "$CONFIGFILE" "$cfg" gatewayaddress + append_config_option "$CONFIGFILE" "$cfg" gatewayport + append_config_option "$CONFIGFILE" "$cfg" maxclients + append_config_option "$CONFIGFILE" "$cfg" webroot + append_config_option "$CONFIGFILE" "$cfg" debuglevel + append_config_option "$CONFIGFILE" "$cfg" splashpage + append_config_option "$CONFIGFILE" "$cfg" pagesdir + append_config_option "$CONFIGFILE" "$cfg" checkinterval + append_config_option "$CONFIGFILE" "$cfg" syslogfacility + append_config_option "$CONFIGFILE" "$cfg" gatewayiprange + append_config_option "$CONFIGFILE" "$cfg" imagedir + append_config_option "$CONFIGFILE" "$cfg" redirecturl + append_config_option "$CONFIGFILE" "$cfg" clientidletimeout + append_config_option "$CONFIGFILE" "$cfg" clientforcetimeout + append_config_option "$CONFIGFILE" "$cfg" gatewayiprange + append_config_option "$CONFIGFILE" "$cfg" passwordattempts + append_config_option "$CONFIGFILE" "$cfg" macmechanism + append_config_option "$CONFIGFILE" "$cfg" uploadlimit + append_config_option "$CONFIGFILE" "$cfg" downloadlimit + append_config_option "$CONFIGFILE" "$cfg" remoteauthenticatoraction + append_config_option "$CONFIGFILE" "$cfg" enablepreauth + append_config_option "$CONFIGFILE" "$cfg" binvoucher + append_config_option "$CONFIGFILE" "$cfg" forcevoucher + append_config_option "$CONFIGFILE" "$cfg" passwordauthentication + append_config_option "$CONFIGFILE" "$cfg" usernameauthentication + append_config_option "$CONFIGFILE" "$cfg" passwordattempts + append_config_option "$CONFIGFILE" "$cfg" username + append_config_option "$CONFIGFILE" "$cfg" password + append_config_option "$CONFIGFILE" "$cfg" authenticateimmediately + append_config_option "$CONFIGFILE" "$cfg" decongesthttpdthreads + append_config_option "$CONFIGFILE" "$cfg" httpdthreadthreshold + append_config_option "$CONFIGFILE" "$cfg" httpdthreaddelayms + append_config_option "$CONFIGFILE" "$cfg" fw_mark_authenticated + append_config_option "$CONFIGFILE" "$cfg" fw_mark_trusted + append_config_option "$CONFIGFILE" "$cfg" fw_mark_blocked + + config_get download "$cfg" downloadlimit + config_get upload "$cfg" uploadlimit + [ -n "$upload" -o -n "$download" ] && echo "TrafficControl yes" >> $CONFIGFILE + + setup_mac_lists "$cfg" + setup_firewall "$cfg" +} + +# setup configuration and start instance +create_instance() { + local cfg="$1" + local manual_config + local val + + config_get_bool val "$cfg" enabled 0 + [ $val -gt 0 ] || return 0 + + generate_uci_config "$cfg" + + if ! test_module ; then + logger -s -t nodogsplash -p daemon.error "nodogsplash is missing some kernel modules" + fi + + procd_open_instance $cfg + procd_set_param command /usr/bin/nodogsplash -c $CONFIGFILE $OPTIONS + procd_set_param respawn + procd_set_param file $CONFIGFILE + procd_close_instance +} + +start_service() { + include /lib/functions + + mkdir -p /tmp/etc/ + config_load nodogsplash + + config_foreach create_instance nodogsplash +} + +stop_service() { + # nodogsplash doesn't exit fast enought, when procd terminates it. + # otherwise procd will restart nodogsplash twice. first time starting nodogsplash fails, second time it succeeds + sleep 1 +} + +status() { + $WD_DIR/ndsctl status +} + +# Test if we got all modules loaded +test_module() { + ### Test ipt_mark with iptables + test_ipt_mark () { + ($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null + IPTABLES_OK=$? + if [ "$IPTABLES_OK" -eq 0 ]; then + ($IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null + return 0 + else + return 1 + fi + } + + ### Test ipt_mac with iptables + test_ipt_mac () { + ($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null + IPTABLES_OK=$? + if [ "$IPTABLES_OK" -eq 0 ]; then + ($IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null + return 0 + else + return 1 + fi + } + + ### Test ipt_IMQ with iptables + test_ipt_IMQ () { + ($IPT -t mangle -A PREROUTING -j IMQ --todev 0 2>&1) > /dev/null + IPTABLES_OK=$? + if [ "$IPTABLES_OK" -eq 0 ]; then + ($IPT -t mangle -D PREROUTING -j IMQ --todev 0 2>&1) > /dev/null + return 0 + else + return 1 + fi + } + + ### Test imq with ip + test_imq () { + (ip link set imq0 up 2>&1) > /dev/null + IMQ0_OK=$? + (ip link set imq1 up 2>&1) > /dev/null + IMQ1_OK=$? + if [ "$IMQ0_OK" -eq 0 -a "$IMQ1_OK" -eq 0 ]; then + (ip link set imq0 down 2>&1) > /dev/null + (ip link set imq1 down 2>&1) > /dev/null + return 0 + else + return 1 + fi + } + + ### Test sch_htb with tc; requires imq0 + test_sch_htb () { + (tc qdisc del dev imq0 root 2>&1) > /dev/null + (tc qdisc add dev imq0 root htb 2>&1) > /dev/null + TC_OK=$? + if [ "$TC_OK" -eq 0 ]; then + (tc qdisc del dev imq0 root 2>&1) > /dev/null + return 0 + else + return 1 + fi + } + + ### Find a module on disk + module_exists () { + EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2> /dev/null) + if [ -n "$EXIST" ]; then + return 0 + else + return 1 + fi + } + + ### Test if a module is in memory + module_in_memory () { + MODULE=$(lsmod | grep $1 | awk '{print $1}') + if [ "$MODULE" = "$1" ]; then + return 0 + else + return 1 + fi + } +} diff --git a/ohybridproxy/patches/0001-find-libubox.patch b/ohybridproxy/patches/0001-find-libubox.patch new file mode 100644 index 0000000..e29db5c --- /dev/null +++ b/ohybridproxy/patches/0001-find-libubox.patch @@ -0,0 +1,26 @@ +From c015e7e62ed4c7645595f7f83cf156810433d0cd Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Mon, 5 Jun 2017 17:56:33 -0700 +Subject: [PATCH] Cmake: Search and find libubox/utils.h + +--- + CMakeLists.txt | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2556669d2a52..1c970d92ff56 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -16,6 +16,9 @@ else(${APPLE}) + set(dns_sd "dns_sd") + endif(${APPLE}) + ++FIND_PATH(ubox_include_dir libubox/utils.h) ++INCLUDE_DIRECTORIES(${ubox_include_dir}) ++ + set(CORE src/cache.c src/io.c src/socket.c) + + add_executable(ohybridproxy src/ohybridproxy.c src/dns2mdns.c ${CORE}) +-- +2.9.3 + diff --git a/poprouting/Makefile b/poprouting/Makefile index 0f51a8b..6bede93 100644 --- a/poprouting/Makefile +++ b/poprouting/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=prince PKG_VERSION:=v0.3.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_USE_MIPS16:=0 @@ -14,14 +14,13 @@ PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION) include $(INCLUDE_DIR)/package.mk define Package/prince - SECTION :=net - CATEGORY :=Network - SUBMENU :=Routing and Redirection - Mantainer :=Gabriele Gemmi - TITLE :=PopRouting daemon - URL :=https://github.com/gabri94/poprouting - MENU :=0 - DEPENDS := +libjson-c +libpthread + SECTION:=net + CATEGORY:=Network + SUBMENU:=Routing and Redirection + MAINTAINER:=Gabriele Gemmi + TITLE:=PopRouting daemon + URL:=https://github.com/gabri94/poprouting + DEPENDS:= +libjson-c +libpthread endef define Package/prince/description @@ -34,6 +33,9 @@ the timer's value are optimized. Finally the timers are pushed back to the routi Currently it only supports OLSRd2 (aka OONF). endef +CFLAGS += $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) +LDFLAGS += $(TARGET_LDFLAGS) + define Package/prince/install $(INSTALL_DIR) $(1)/usr/lib $(INSTALL_DIR) $(1)/usr/sbin diff --git a/poprouting/patches/001-cflags.patch b/poprouting/patches/001-cflags.patch new file mode 100644 index 0000000..c1f13a1 --- /dev/null +++ b/poprouting/patches/001-cflags.patch @@ -0,0 +1,27 @@ +From dda5c5a0cd2204816f2f83f18e7820ded6c962df Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Mon, 5 Jun 2017 17:30:24 -0700 +Subject: [PATCH] Honor CFLAGS and LDFLAGS when passed + +--- + Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: prince-v0.3.1/Makefile +=================================================================== +--- prince-v0.3.1.orig/Makefile ++++ prince-v0.3.1/Makefile +@@ -1,11 +1,11 @@ + CFLAGS+=-lm -ldl -ljson-c -pthread + poprouting:out libs + cp prince/src/common_c.h prince/src/common.h +- $(CC) $(LDFLAGS) prince/src/prince.c prince/src/lib/ini.c prince/src/parser.c prince/src/socket.c graph-parser_c/src/brandes.c graph-parser_c/src/biconnected.c graph-parser_c/src/graph_parser.c graph-parser_c/src/graph/graph.c graph-parser_c/src/graph/list.c graph-parser_c/src/network_change.c -o output/prince $(CFLAGS) ++ $(CC) $(LDFLAGS) $(CFLAGS) prince/src/prince.c prince/src/lib/ini.c prince/src/parser.c prince/src/socket.c graph-parser_c/src/brandes.c graph-parser_c/src/biconnected.c graph-parser_c/src/graph_parser.c graph-parser_c/src/graph/graph.c graph-parser_c/src/graph/list.c graph-parser_c/src/network_change.c -o output/prince + rm prince/src/common.h + libs: + cp prince/src/common_c.h prince/src/common.h +- $(CC) -shared -fPIC -o output/libprince_oonf_c.so prince/src/oonf.c prince/src/socket.c prince/src/parser.c graph-parser_c/src/brandes.c graph-parser_c/src/biconnected.c graph-parser_c/src/graph_parser.c graph-parser_c/src/graph/graph.c graph-parser_c/src/graph/list.c graph-parser_c/src/network_change.c ++ $(CC) $(LDFLAGS) $(CFLAGS) -shared -fPIC -o output/libprince_oonf_c.so prince/src/oonf.c prince/src/socket.c prince/src/parser.c graph-parser_c/src/brandes.c graph-parser_c/src/biconnected.c graph-parser_c/src/graph_parser.c graph-parser_c/src/graph/graph.c graph-parser_c/src/graph/list.c graph-parser_c/src/network_change.c + clean: + rm output/* +