Merge branch 'master' of git://github.com/openwrt-routing/packages

This commit is contained in:
Eloi Carbo 2017-08-19 10:27:37 +01:00
commit 51a71a572e
62 changed files with 1353 additions and 1406 deletions

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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 <uapi/linux/nl80211.h>
#endif /* < KERNEL_VERSION(3, 16, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
#include <linux/netdevice.h>
@ -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 <linux/netdevice.h>
/* 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) */
/* <DECLARE_EWMA> */
#include <linux/version.h>

View file

@ -1,132 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
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 <davem@davemloft.net>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[sven@narfation.org: Added compatibility code]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
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 <linux/bug.h>
-#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

View file

@ -0,0 +1,208 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
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 <linus.luessing@c0d3.blue>
Acked-by: Antonio Quartulli <a@unstable.cc>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
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;

View file

@ -1,103 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
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 <martin@darmstadt.freifunk.net>
Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
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;

View file

@ -1,141 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
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 <sven@narfation.org>
---
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);

View file

@ -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)

View file

@ -1,41 +1,37 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2017 Gui Iribarren <gui@altermundi.net>
# 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
}

View file

@ -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

View file

@ -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 <p4u@dabax.net>
endef
define Package/luci-lib-jquery-1-4
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI - Lua Configuration Interface
MAINTAINER:=Gui Iribarren <gui@altermundi.net>
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 <p4u@dabax.net>
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))

View file

@ -0,0 +1,49 @@
<%#
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
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%>
<button id="redraw" onclick="redraw();">&nbsp redraw &nbsp</button>
<div id="wait" style="text-align: center">
<br /><br />
<img src="<%=resource%>/icons/loading.gif" />
<%:Collecting data...%>
</div>
<div id="canvas" style="min-width:1024px; min-height:1024px"></div>
<script type="text/javascript" src="<%=resource%>/jquery/jquery-1.4.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/raphael-min.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graffle.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graph.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/bmx6-graph.js"></script>
<%+footer%>

View file

@ -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

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -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();
}

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

Before

Width:  |  Height:  |  Size: 923 B

After

Width:  |  Height:  |  Size: 923 B

View file

@ -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].x<j[n].x)&&(2!=m&&7!=n||j[m].x>j[n].x)&&(0!=m&&5!=n||j[m].y>j[n].y)&&(1!=m&&4!=n||j[m].y<j[n].y))&&(l.push(o+p),k[l[l.length-1].toFixed(3)]=[m,n])}var q=0==l.length?[0,4]:k[Math.min.apply(Math,l).toFixed(3)],r=j[q[0]].x,s=j[q[0]].y,t=j[q[1]].x,u=j[q[1]].y,o=Math.max(Math.abs(r-t)/2,10),p=Math.max(Math.abs(s-u)/2,10),v=[r,r,r-o,r+o][q[0]].toFixed(3),w=[s-p,s+p,s,s][q[0]].toFixed(3),x=[0,0,0,0,t,t,t-o,t+o][q[1]].toFixed(3),y=[0,0,0,0,s+p,s-p,u,u][q[1]].toFixed(3),z=["M",r.toFixed(3),s.toFixed(3),"C",v,w,x,y,t.toFixed(3),u.toFixed(3)].join(",");if(c&&c.directed){var A=Math.sqrt((u-y)*(u-y)+(t-x)*(t-x)),B=function(a,b){return-a*(b||5)/A},C=[{x:(B(t-x)+B(u-y)+t).toFixed(3),y:(B(u-y)+B(t-x)+u).toFixed(3)},{x:(B(t-x)-B(u-y)+t).toFixed(3),y:(B(u-y)-B(t-x)+u).toFixed(3)}];z=z+",M"+C[0].x+","+C[0].y+",L"+t+","+u+",L"+C[1].x+","+C[1].y}var D="attr";e.fg&&e.fg[D]({path:z})||(e.fg=d.path(z).attr({stroke:c&&c.stroke||"#000",fill:"none"}).toBack()),e.bg&&e.bg[D]({path:z})||c&&c.fill&&(e.bg=c.fill.split&&d.path(z).attr({stroke:c.fill.split("|")[0],fill:"none","stroke-width":c.fill.split("|")[1]||3}).toBack()),c&&c.label&&(e.label&&e.label.attr({x:(r+t)/2,y:(s+u)/2})||(e.label=d.text((r+t)/2,(s+u)/2,c.label).attr({fill:"#000","font-size":c["font-size"]||"12px"}))),c&&c.label&&c["label-style"]&&e.label&&e.label.attr(c["label-style"]),c&&c.callback&&c.callback(e)}};return e.draw(),e};

File diff suppressed because one or more lines are too long

View file

@ -1,110 +0,0 @@
<%#
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
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%>
<script type="text/javascript" src="<%=resource%>/bmx6/js/raphael-min.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/dracula_graffle.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/dracula_graph.js"></script>
<button id="redraw" onclick="redraw();">&nbsp redraw &nbsp</button>
<div id="wait" style="text-align: center">
<br /><br />
<img src="<%=resource%>/icons/loading.gif" />
<%:Collecting data...%>
</div>
<div id="canvas" style="min-width:800px; min-height:800px"></div>
<script type="text/javascript">//<![CDATA[
var redraw;
XHR.get('<%=luci.dispatcher.build_url(unpack(location))%>', null,
function(x, data)
{
var g = new Graph();
var seen = { };
for (var i = 0; i < (data.length); i++)
{
// node->node
if (data[i].name)
{
for (var j = 0; j < (data[i].links.length); j++)
{
var key = (data[i].name < data[i].links[j].name)
? data[i].name + '|' + data[i].links[j].name
: data[i].links[j].name + '|' + data[i].name;
var rxRate = data[i].links[j].rxRate;
var txRate = data[i].links[j].txRate;
if (!seen[key] && rxRate>0 && txRate>0)
{
g.addEdge(data[i].name, data[i].links[j].name,
{ label: rxRate + '/' + txRate,
directed: false, stroke: '#aaaaaa', fill: '#ffffff',
'label-style': { 'font-size': 8 }});
seen[key] = true;
}
}
}
//g.addEdge(data[i].router, data[i].neighbor,
// { label: data[i].label, directed: true, stroke: '#aaaaaa' });
// node->leaf
//else if (data[i].router && data[i].gateway)
// g.addEdge(data[i].router, data[i].gateway,
// { label: 'leaf', stroke: '#cccccc' });
}
var canvas = document.getElementById('canvas');
var layouter = new Graph.Layout.Spring(g);
layouter.layout();
var divwait = document.getElementById("wait");
divwait.parentNode.removeChild(divwait);
var renderer = new Graph.Renderer.Raphael(canvas.id, g, canvas.offsetWidth, canvas.offsetHeight);
renderer.draw();
redraw = function() {
layouter.layout();
renderer.draw();
}
}
);
//]]></script>
<%+footer%>

View file

@ -1,119 +0,0 @@
#!/bin/sh
# Copyright (C) 2011 Pau Escrich
# Contributors Jo-Philipp Wich <xm@subsignal.org>
#
# 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

View file

@ -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);
};

View file

@ -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");};

View file

@ -1,527 +0,0 @@
/*
* Dracula Graph Layout and Drawing Framework 0.0.3alpha
* (c) 2010 Philipp Strathausen <strathausen@gmail.com>, http://strathausen.eu
* Contributions by Jake Stothard <stothardj@gmail.com>.
*
* based on the Graph JavaScript framework, version 0.0.1
* (c) 2006 Aslak Hellesoy <aslak.hellesoy@gmail.com>
* (c) 2006 Dave Hoover <dave.hoover@gmail.com>
*
* 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 <paul@jibble.org>.
*
* 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);
}
};
}

View file

@ -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 <fingon@iki.fi>
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

View file

@ -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 <cyrus@openwrt.org>
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

View file

@ -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() {

View file

@ -1,6 +1,7 @@
/* 464xlatcfg.c
*
* Copyright (c) 2015 Steven Barth <cyrus@openwrt.org>
* Copyright (c) 2017 Hans Dedecker <dedeckeh@gmail.com>
*
* 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 <name> [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;
}

View file

@ -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+

View file

@ -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.

View file

@ -1,43 +0,0 @@
--- a/src/client_list.c
+++ b/src/client_list.c
@@ -36,7 +36,7 @@
#include <pthread.h>
#include <sys/wait.h>
#include <sys/types.h>
-#include <sys/unistd.h>
+#include <unistd.h>
#include <string.h>
--- a/src/firewall.c
+++ b/src/firewall.c
@@ -37,7 +37,7 @@
#include <pthread.h>
#include <sys/wait.h>
#include <sys/types.h>
-#include <sys/unistd.h>
+#include <unistd.h>
#include <string.h>
--- a/src/util.c
+++ b/src/util.c
@@ -38,7 +38,7 @@
#include <pthread.h>
#include <sys/wait.h>
#include <sys/types.h>
-#include <sys/unistd.h>
+#include <unistd.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
--- a/libhttpd/protocol.c
+++ b/libhttpd/protocol.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
+#include <fcntl.h>
#if defined(_WIN32)
#else

61
nodogsplash2/Makefile Normal file
View file

@ -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 <moritzwarning@web.de>
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))

View file

@ -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'

View file

@ -0,0 +1,355 @@
#!/bin/sh /etc/rc.common
#
# description: Startup/shutdown script for nodogsplash captive portal
#
# Alexander Couzens <lynxis@fe80.eu> 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 <cfgfile> <uci_cfg_obj> <option_name> <config_counterpart> [<optional default>]
# 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 <cfgfile> <uci_cfg_obj> <option_name> [<optional default>]
# 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
}
}

View file

@ -0,0 +1,26 @@
From c015e7e62ed4c7645595f7f83cf156810433d0cd Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
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

View file

@ -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 <gabriel@autistici.org>
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 <gabriel@autistici.org>
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

View file

@ -0,0 +1,27 @@
From dda5c5a0cd2204816f2f83f18e7820ded6c962df Mon Sep 17 00:00:00 2001
From: Florian Fainelli <f.fainelli@gmail.com>
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/*