Giter Site home page Giter Site logo

wifi_broadcast's Introduction

wifi_broadcast BCH compliance

P2P WiFi data transmission project

To compile natively use:

  • make all

To crosscompile explicitly to Raspberry Pi download:

  • git clone https://github.com/raspberrypi/tools
  • You can then copy the /tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian directory to a common location, and add /tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/ to the TOOLS_PATH varible in the Makefile. For 64-bit host systems, use /tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/
  • make armhf

Do not forget to clean already compiled files between changes from host compilation to cross compilation and vise versa by:

  • make clean

Data integrity test example. To test data integrity the following shell pipeline can be used:

  • ./traffic_gen -r 2000000|tee dump_orig|./tx -p 0 -a 78 -i 48 wlan0|tee dump_tx|./rx -p 0 wlan0|pv>dump
  • Wait several minutes, then Ctrl^c
  • cat dump_orig | sed -r -e "s/;/\n/g" >dump_orig_n; cat dump | sed -r -e "s/;/\n/g" >dump_n;vimdiff dump_orig_n dump_n Discprepancies are normal to be seen at the end, since Ctrl^c kills different processes in different times.

wifi_broadcast's People

Contributors

dmitry-kutergin avatar shipus avatar

Stargazers

 avatar

Watchers

James Cloos avatar

wifi_broadcast's Issues

Implement DEBUG mode in RX for TX->RX integration

  • Implement debug mode in RX part that will read from STDIN instead of real NIC, similar to what TX does in DEBUG mode.
  • Determine on what layer packets should be transmitted from TX and received on RX (ideally include all header from TX packet encapsulation, but maybe move upwards a layer or two).
  • Check that data is being conveyed correctly from traffic_gen to TX and then to RX. Test from 100 Bytes/S to 20 MBytes/S.

Merge TX and RX into one process

Merge RX module into TX. Add init section from RX main to TX main. Reuse TX epoll for RX packets. This will result in 4 threads footprint which will match RPi3 CPU map. Also this will make communication between TX and RX easier and TAP interface statistics update unification.

Implement interface info (Speed/Duplex) and stats (counters) update from TX/RX on TAP interfaces

We need to set correct speed and stats on TAP interfaces to try to utilize bonded driver mode Bonded:

balance-tlb or 5

  Adaptive transmit load balancing: channel bonding that
  does not require any special switch support.

  In tlb_dynamic_lb=1 mode; the outgoing traffic is
  distributed according to the current load (computed
  relative to the speed) on each slave.

  In tlb_dynamic_lb=0 mode; the load balancing based on
  current load is disabled and the load is distributed
  only using the hash distribution.

  Incoming traffic is received by the current slave.
  If the receiving slave fails, another slave takes over
  the MAC address of the failed receiving slave.

  Prerequisite:

  Ethtool support in the base drivers for retrieving the
  speed of each slave.

The tun kernel driver should be patched for info set Patch speed:

NB Speed is set in Mbits/Sec.

drivers/net/tun.c           |   56 +++++++++++++++++++++++++++++++++-----------
include/uapi/linux/if_tun.h |   15 +++++++++++
2 files changed, 58 insertions(+), 13 deletions(-)

--- a/drivers/net/tun.c	2013-07-23 09:18:01.936046624 -0700
+++ b/drivers/net/tun.c	2013-07-23 09:52:37.054143993 -0700
@@ -187,6 +187,8 @@ struct tun_struct {
	struct list_head disabled;
	void *security;
	u32 flow_count;
+
+	struct tun_info info;
};

static inline u32 tun_hashfn(u32 rxhash)
@@ -870,9 +872,12 @@ static void tun_net_init(struct net_devi
{
	struct tun_struct *tun = netdev_priv(dev);

+	strlcpy(tun->info.driver, DRV_NAME, sizeof(tun->info.driver));
+
	switch (tun->flags & TUN_TYPE_MASK) {
	case TUN_TUN_DEV:
		dev->netdev_ops = &tun_netdev_ops;
+		strlcpy(tun->info.bus, "tun", sizeof(tun->info.bus));

		/* Point-to-Point TUN Device */
		dev->hard_header_len = 0;
@@ -887,6 +892,8 @@ static void tun_net_init(struct net_devi

	case TUN_TAP_DEV:
		dev->netdev_ops = &tap_netdev_ops;
+		strlcpy(tun->info.bus, "tap", sizeof(tun->info.bus));
+
		/* Ethernet TAP Device */
		ether_setup(dev);
		dev->priv_flags &= ~IFF_TX_SKB_SHARING;
@@ -1426,6 +1433,9 @@ static void tun_setup(struct net_device

	tun->owner = INVALID_UID;
	tun->group = INVALID_GID;
+	tun->info.speed = SPEED_10;
+	tun->info.duplex = DUPLEX_FULL;
+	tun->info.port = PORT_TP;

	dev->ethtool_ops = &tun_ethtool_ops;
	dev->destructor = tun_free_netdev;
@@ -2088,6 +2098,15 @@ static long __tun_chr_ioctl(struct file
		tun_detach_filter(tun, tun->numqueues);
		break;

+	case TUNSETINFO: {
+		struct tun_info info;
+		if (copy_from_user(argp, &info, sizeof(info)))
+			ret = -EFAULT;
+
+		tun->info = info;
+		break;
+	}
+
	default:
		ret = -EINVAL;
		break;
@@ -2229,11 +2248,13 @@ static struct miscdevice tun_miscdev = {

static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
+	struct tun_struct *tun = netdev_priv(dev);
+
	cmd->supported		= 0;
	cmd->advertising	= 0;
-	ethtool_cmd_speed_set(cmd, SPEED_10);
-	cmd->duplex		= DUPLEX_FULL;
-	cmd->port		= PORT_TP;
+	ethtool_cmd_speed_set(cmd, tun->info.speed);
+	cmd->duplex		= tun->info.duplex;
+	cmd->port		= tun->info.port;
	cmd->phy_address	= 0;
	cmd->transceiver	= XCVR_INTERNAL;
	cmd->autoneg		= AUTONEG_DISABLE;
@@ -2242,21 +2263,24 @@ static int tun_get_settings(struct net_d
	return 0;
}

+static int tun_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	tun->info.speed  = ethtool_cmd_speed(ecmd);
+	tun->info.duplex = ecmd->duplex;
+	tun->info.port   = ecmd->port;
+
+	return 0;
+}
+
static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
	struct tun_struct *tun = netdev_priv(dev);

-	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strlcpy(info->driver, tun->info.driver, sizeof(info->driver));
	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-
-	switch (tun->flags & TUN_TYPE_MASK) {
-	case TUN_TUN_DEV:
-		strlcpy(info->bus_info, "tun", sizeof(info->bus_info));
-		break;
-	case TUN_TAP_DEV:
-		strlcpy(info->bus_info, "tap", sizeof(info->bus_info));
-		break;
-	}
+	strlcpy(info->bus_info, tun->info.bus, sizeof(info->bus_info));
}

static u32 tun_get_msglevel(struct net_device *dev)
@@ -2279,6 +2303,7 @@ static void tun_set_msglevel(struct net_

static const struct ethtool_ops tun_ethtool_ops = {
	.get_settings	= tun_get_settings,
+	.set_settings	= tun_set_settings,
	.get_drvinfo	= tun_get_drvinfo,
	.get_msglevel	= tun_get_msglevel,
	.set_msglevel	= tun_set_msglevel,
--- a/include/uapi/linux/if_tun.h	2013-07-23 09:18:01.936046624 -0700
+++ b/include/uapi/linux/if_tun.h	2013-07-23 09:52:26.870271418 -0700
@@ -56,6 +56,7 @@
#define TUNGETVNETHDRSZ _IOR('T', 215, int)
#define TUNSETVNETHDRSZ _IOW('T', 216, int)
#define TUNSETQUEUE  _IOW('T', 217, int)
+#define TUNSETINFO     _IOW('T', 219, struct tun_info)

/* TUNSETIFF ifr flags */
#define IFF_TUN		0x0001
@@ -103,4 +104,17 @@ struct tun_filter {
	__u8   addr[0][ETH_ALEN];
};

+/*
+ * Ethtool info
+ * This is used to allow spoofing the speed/duplex and driver information
+ */
+struct tun_info {
+	__u32 speed;
+	__u8  duplex;
+	__u8  port;
+
+	char driver[32];
+	char bus[32];
+};
+
#endif /* _UAPI__IF_TUN_H */

The tun kernel driver should be patched for stats set Patch stats:

--- a/drivers/net/tun.c	2013-07-23 10:17:04.335800821 -0700
+++ b/drivers/net/tun.c	2013-07-23 10:22:10.903948347 -0700
@@ -189,6 +189,10 @@ struct tun_struct {
 	u32 flow_count;
 
 	struct tun_info info;
+	struct tun_stats __rcu {
+		struct rtnl_link_stats64 link_stats;
+		struct rcu_head rcu;
+	} *stats;
 };
 
 static inline u32 tun_hashfn(u32 rxhash)
@@ -802,6 +806,32 @@ static netdev_features_t tun_net_fix_fea
 
 	return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
 }
+
+static struct rtnl_link_stats64 *
+tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	struct tun_stats __rcu *stats;
+
+	rcu_read_lock();
+	stats = rcu_dereference(tun->stats);
+	if (stats) {
+		/* Stats received from device */
+		*storage = stats->link_stats;
+		rcu_read_unlock();
+
+		/* Add tunnel detected errors to mix */
+		storage->tx_dropped += dev->stats.tx_dropped;
+		storage->rx_dropped += dev->stats.rx_dropped;
+		storage->rx_frame_errors += dev->stats.rx_frame_errors;
+		return storage;
+	}
+	rcu_read_unlock();
+
+	netdev_stats_to_stats64(storage, &dev->stats);
+	return storage;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tun_poll_controller(struct net_device *dev)
 {
@@ -824,6 +854,7 @@ static const struct net_device_ops tun_n
 	.ndo_open		= tun_net_open,
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
+	.ndo_get_stats64	= tun_net_get_stats64,
 	.ndo_change_mtu		= tun_net_change_mtu,
 	.ndo_fix_features	= tun_net_fix_features,
 	.ndo_select_queue	= tun_select_queue,
@@ -837,6 +868,7 @@ static const struct net_device_ops tap_n
 	.ndo_open		= tun_net_open,
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
+	.ndo_get_stats64	= tun_net_get_stats64,
 	.ndo_change_mtu		= tun_net_change_mtu,
 	.ndo_fix_features	= tun_net_fix_features,
 	.ndo_set_rx_mode	= tun_net_mclist,
@@ -1420,9 +1452,13 @@ out:
 static void tun_free_netdev(struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
+	struct tun_stats *stats;
 
 	BUG_ON(!(list_empty(&tun->disabled)));
 	tun_flow_uninit(tun);
+	stats = xchg(&tun->stats, NULL);
+	if (stats)
+		kfree_rcu(stats, rcu);
 	security_tun_dev_free_security(tun->security);
 	free_netdev(dev);
 }
@@ -1885,6 +1921,28 @@ unlock:
 	return ret;
 }
 
+static int tun_set_stats(struct tun_struct *tun, struct ifreq *ifr)
+{
+	struct tun_stats *stats, *old;
+
+	stats = kmalloc(sizeof(struct tun_stats), GFP_KERNEL);
+	if (!stats)
+		return -ENOMEM;
+
+	if (copy_from_user(&stats->link_stats,
+			   ifr->ifr_ifru.ifru_data,
+			   sizeof(struct rtnl_link_stats64))) {
+		kfree(stats);
+		return -EFAULT;
+	}
+
+	old = xchg(&tun->stats, stats);
+	if (old)
+		kfree_rcu(old, rcu);
+
+	return 0;
+}
+
 static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 			    unsigned long arg, int ifreq_len)
 {
@@ -2107,6 +2165,10 @@ static long __tun_chr_ioctl(struct file
 		break;
 	}
 
+	case TUNSETSTATS:
+		ret = tun_set_stats(tun, &ifr);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
--- a/include/uapi/linux/if_tun.h	2013-07-23 10:17:04.335800821 -0700
+++ b/include/uapi/linux/if_tun.h	2013-07-23 10:19:09.358230639 -0700
@@ -57,6 +57,7 @@
 #define TUNSETVNETHDRSZ _IOW('T', 216, int)
 #define TUNSETQUEUE  _IOW('T', 217, int)
 #define TUNSETINFO     _IOW('T', 219, struct tun_info)
+#define TUNSETSTATS    _IOW('T', 220, struct rtnl_link_stats64)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001

Also need to change BOND_TLB_REBALANCE_INTERVAL to minimum value of 1 sec.

Simplify functions in all modules for easier code maintenace

Analyze sources and locate source blocks that are too big and/or too complicated. Split them in smaller source blocks (create new smaller functions), keeping interfaces as simple as possible.
As the guide use analyzer results Code analysis resultes, for example:

  • Write Short Units of Code:
DefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 788 in tx.​cDefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 76 in traffic_gen.​cDefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 654 in rx.​cDefaultNamespace.​DefaultClass::tx_block(block_buffer_t*,​ uint8_t,​ int*)
     starts at line 217 in rx.​cDefaultNamespace.​DefaultClass::pb_transmit_block(fifo_t*,​ int)
     starts at line 586 in tx.​cDefaultNamespace.​DefaultClass::process_payload(uint8_t*,​ size_t,​ block_buffer_t*)
     starts at line 356 in rx.​cDefaultNamespace.​DefaultClass::process_packet(monitor_interface_t*,​ int,​ block_buffer_t*,​ pkt_buff_t*)
     starts at line 477 in rx.​cDefaultNamespace.​DefaultClass::fifo_init(fifo_t*,​ uint8_t,​ uint8_t,​ uint8_t,​ uint8_t,​ uint16_t)
     starts at line 192 in tx.​cDefaultNamespace.​DefaultClass::open_and_configure_interface(char*,​ int,​ monitor_interface_t*)
     starts at line 131 in rx.​cDefaultNamespace.​DefaultClass::pb_process_block(fifo_t*,​ int,​ uint16_t)
     starts at line 517 in tx.​c
  • Write Simple Units of Code:
DefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 788 in tx.​cDefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 76 in traffic_gen.​cDefaultNamespace.​DefaultClass::main(int,​ char*)
     starts at line 654 in rx.​cDefaultNamespace.​DefaultClass::tx_block(block_buffer_t*,​ uint8_t,​ int*)
     starts at line 217 in rx.​cDefaultNamespace.​DefaultClass::pb_transmit_block(fifo_t*,​ int)
     starts at line 586 in tx.​cDefaultNamespace.​DefaultClass::process_payload(uint8_t*,​ size_t,​ block_buffer_t*)
     starts at line 356 in rx.​cDefaultNamespace.​DefaultClass::process_packet(monitor_interface_t*,​ int,​ block_buffer_t*,​ pkt_buff_t*)
     starts at line 477 in rx.​c
  • Keep Unit Interfaces Small:
    DefaultNamespace.​DefaultClass::fifo_init(fifo_t*,​ uint8_t,​ uint8_t,​ uint8_t,​ uint8_t,​ uint16_t)
        starts at line 192 in tx.​cDefaultNamespace.​DefaultClass::pb_transmit_packet(fifo_t*,​ int,​ uint8_t*,​ uint16_t,​ uint8_t)
        starts at line 447 in tx.​cDefaultNamespace.​DefaultClass::tx_block(block_buffer_t*,​ uint8_t,​ int*)
        starts at line 217 in rx.​cDefaultNamespace.​DefaultClass::process_payload(uint8_t*,​ size_t,​ block_buffer_t*)
        starts at line 356 in rx.​cDefaultNamespace.​DefaultClass::process_packet(monitor_interface_t*,​ int,​ block_buffer_t*,​ pkt_buff_t*)
        starts at line 477 in rx.​c

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.