home  wiki

Spelling: MWRPFrottleDevDiscussion

FROTTLE CONFIG FILE

DanFlett [1]: Here's how I'd like to be able configure a
multi-interface version of Frottle...

PROPOSED FROTTLE.CONF

daemon 1 verbose 1 logfile /var/log/frottle.log clientstatsfile
/var/www/html/frottle/client.html masterinfofile
/var/www/html/frottle/master.html #MODE-CLIENT INTERFACE MASTER IP
PRIORITY PORTS PORT QUEUESIZE client wlan0 10.10.144.49 22,53 999 100
client eth0 10.10.255.1 22,53,5001 - 100 client eth2 10.10.129.1 -
1001
# CLIENTMODE #MODE-MASTER INTERFACE (SELF/CLIENT/NONE) TIMEOUT
POLLPARAMS master eth1 self 100 60000,10,6000,7,5000,5,4000 master
wlan1 - 200
You get the idea - leaving a paramater blank (if there are no
parameters to be specified after it) or specifying '-' (if there are
parameters to be specified after it) for a parameter sets it to
default - where appropriate. This is similar to the way Shorewall [2]
sets out its config files [3].

-------------------------
Frottle uses the iptables QUEUE target to delay outgoing traffic. The
QUEUE target was designed to allow userspace applications, like
Frottle, to inspect and control network traffic.

The QUEUE target is explained here:
http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-7.html#ss7.4
[4]

Here is the relevant exerpt:

QUEUE is a special target, which queues the packet for userspace
processing. For this to be useful, two further components are
required:

* a "queue handler", which deals with the actual mechanics of passing
packets between the kernel and userspace; and
* a userspace application to receive, possibly manipulate, and issue
verdicts on packets.

The standard queue handler for IPv4 iptables is the ip_queue module,
which is distributed with the kernel and marked as experimental.

The following is a quick example of how to use iptables to queue
packets for userspace processing:

# modprobe iptable_filter # modprobe ip_queue # iptables -A OUTPUT
-p icmp -j QUEUE
With this rule, locally generated outgoing ICMP packets (as created
with, say, ping) are passed to the ip_queue module, which then
attempts to deliver the packets to a userspace application. If no
userspace application is waiting, the packets are dropped.

To write a userspace application, use the libipq API. This is
distributed with iptables. Example code may be found in the testsuite
tools (e.g. redirect.c) in CVS.

The status of ip_queue may be checked via:

/proc/net/ip_queue
The maximum length of the queue (i.e. the number packets delivered to
userspace with no verdict issued back) may be controlled via:

/proc/sys/net/ipv4/ip_queue_maxlen
The default value for the maximum queue length is 1024. Once this
limit is reached, new packets will be dropped until the length of the
queue falls below the limit again. Nice protocols such as TCP
interpret dropped packets as congestion, and will hopefully back off
when the queue fills up. However, it may take some experimenting to
determine an ideal maximum queue length for a given situation if the
default value is too small.

Presently, Frottle is only capable of acting on one network interface
at a time on the host on which it is running. To be part of a truly
scalable network, it would be desireable for Frottle to act on any and
all of a hosts' wireless interfaces. For instance, a host may have one
interface which is acting as a Access Point, and two more interfaces
making client connections to two remote APs. It would be desireable
for Frottle to be able to simultaneously act as a Master on the AP
interface and as a Client on each of the client interfaces.

As mentioned in the exeprt above, the QUEUE target requires:
_a userspace application to receive, possibly manipulate, and issue
verdicts on packets._
Frottle does this, but currently it is able to manipulate the
transmit order of packets in the QUEUE based on port number only. This
is the controlled by the "HIPORT" paramater in the Frottle config
file.

For Frottle to be able to act on different interfaces, it needs to be
able to manipulate packets in the QUEUE based on their destination IP
or Ethernet MAC address also. Packets being sent to one interface will
be within a certain IP address range, packets being sent to another
interface will be from a different IP address range.

-------------------------

LIBIPQ is the API that allows userspace applications to inspect an
manipulate the packets in the QUEUE. Doing a search on Google turns up
some info:
Google Search - libipq [5]
Google Search - "libipq" address [6]
A good place to start is here:
Quick Intro to libipq [7]

From reading the various pages out there on LIBIPQ, it appears it can
read a field called "hw_addr" from the "ipq_packet_msg" record. This
is the _source_ MAC address of the packet. This is useful to us, as it
tells us out which interface the packet is destined to leave the host.
It is unclear at this point wether or not packets sent to the QUEUE
from the FORWARD and OUTPUT chains will have "hw_addr" set (it looks
like they don't). Perhaps QUEUEing packets from the POSTROUTING chain
would work better (if this is allowed).

-------------------------

OK, we don't need "hw_addr", iptables MARK, routing table lookups or
anything like that. The name of the outgoing is contained in the
packet. LIBIPQ can read it from packets in the QUEUE.
From SuperHac.com [8]:

ipq_packet_msg structure
Just a dump of the ipq_packet_msg structure.

ipq_packet_msg structure defined in
/usr/include/linux/netfilter_ipv4/ip_queue.h:

typedef struct ipq_packet_msg {

unsigned long packet_id; /* ID of queued packet */ unsigned long
mark; /* Netfilter mark value */ long timestamp_sec; /* Packet arrival
time (seconds) */ long timestamp_usec; /* Packet arrvial time
(+useconds) */ unsigned int hook; /* Netfilter hook we rode in on */
char indev_nameIFNAMSIZ [9]; /* Name of incoming interface */
char outdev_nameIFNAMSIZ [10]; /* Name of outgoing interface */

unsigned short hw_protocol; /* Hardware protocol (network order) */
unsigned short hw_type; /* Hardware type */ unsigned char hw_addrlen;
/* Hardware address length */ unsigned char hw_addr8 [11]; /* Hardware
address */ size_t data_len; /* Length of packet data */ unsigned char
payload0 [12]; /* Optional packet data */
} ipq_packet_msg_t;

"outdev_name" is what we're after. We can use this to put packets
into subqueues (inside Frottle, in userspace) based on outgoing
interface name.

Links:
------
[1] http://melbournewireless.org.au/?DanFlett
[2] http://shorewall.sourceforge.net/
[3] http://shorewall.sourceforge.net/Documentation.htm#Rules
[4]
http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO-7.html#ss7.4
[5]
http://www.google.com/search?num=100&hl=en&safe=off&q=%22libipq%22&btnG=Search&meta=lr%3Dlang_en
[6]
http://www.google.com/search?num=100&hl=en&safe=off&q=%22libipq%22+address&btnG=Search&meta=lr%3Dlang_en
[7] http://www.crhc.uiuc.edu/~grier/projects/libipq.html
[8] http://www.superhac.com/archives/01-01-2005_01-31-2005.html
[9] http://melbournewireless.org.au/?IFNAMSIZ
[10] http://melbournewireless.org.au/?IFNAMSIZ
[11] http://melbournewireless.org.au/?8
[12] http://melbournewireless.org.au/?0

[EditText] [Spelling] [Current] [Raw] [Code] [Diff] [Subscribe] [VersionHistory] [Revert] [Delete] [RecentChanges]

> home> about> events> files> members> maps> wiki board   > home   > categories   > search   > changes   > formatting   > extras> site map

Username
Password

 Remember me.
>

> forgotten password?
> register?
currently 0 users online
Node Statistics
building132
gathering191
interested520
operational232
testing212