summaryrefslogtreecommitdiffstats
path: root/libipq/IPQ.notes.txt
blob: a2547fa41a3745c5361372b473aef58b6debb536 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
------------------------------------------------------------------------------------
IPv4 Queuing Documentation
------------------------------------------------------------------------------------

Note: this file is temporary until the documentation is complete.

Upgrade information:
	* If upgrading from the queue device (v0.90.4 or below), you will need to
	  delete the old shared library, usually found in
	  /usr/local/lib/iptables/libipt_QUEUE.so
	
TODO List:
	* Non-blocking i/o for userspace api
	* Buffered verdicts
	* Reschedule processing if userspace busy
	* Better session reliability
	* Testsuite scripts, fix/improve tools
	* Documentation
	* Multiple queues per protocol?
	* Performance analysis
	* Userspace language bindings


Overview:
The following diagram is a conceptual view of how the queue operates:

 +---------+
 |  QUEUE  |
 +---------+
 |         |
 |  +---+  | --> dequeue() --> nf_reinject() [stack]
 |  | V |  |
 |  +---+  |
 |         |
 |  +---+  |
 |  | W |  |
 |  +---+  |
 |         |
 |  +---+  | 
 |  | V |  |
 |  +---+  |
 |         |
 |  +---+  |
 |  | V |  | <-- set_verdict() [user]
 |  +---+  |
 |         |
 |  +---+  | 
 |  | W |  | 
 |  +---+  |
 |         |
 |  +---+  |
 |  | N |  | --> notify_user() [user]
 |  +---+  |
 |         |
 +---------+ <-- set_mode()  [user]
      ^
      |
   enqueue() 
      ^
      | 
   nf_queue() [stack]
  

The queue is processed via a kernel thread, which is woken up upon enqueue()
set_mode() and set_verdict().

As the queue is modal, and netlink is connectionless, a reasonable amount of
state needs to be maintained.
 
Packet states:
N = new packet (default initial state)
W = user notfied, waiting for verdict
V = verdict set (usually by user)

Queue states (settable by user):
* HOLD (default initial state)
enqueue packets
do not notify user
do not accept verdicts
do not dequeue packets

* NORMAL
enqueue packets
notify user of new packets (may copy entire packet)
accept verdicts from user (may include modified packet)
dequeue packets

* FLUSH (returns to HOLD when queue is empty, unless terminating)
do not enqueue packets
do not not notify user
set verdicts on all packets to NF_DROP
dequeue all packets for dropping

Note that for HOLD & NORMAL queue states, new packets are dropped if the 
queue is full.

Known bugs:
- Userspace app gets unknown message from kernel if it sends an invalid
  message type (should get an NLMSG_ERROR).
  
Documentation notes:
libipq:
- Queue is held after flush completes, user must either start copying 
  or shutdown or the queue will fill up.
  
- If you get a IPQ_ERR_RTRUNC message, your local receive
  buffer is probably too small.  Netlink has no way of detecting
  this, and thinks the message was delivered (technically, it was,
  to your *socket* receive buffer though).  Thus you need to respond
  with an NF_DROP for the packet and use a bigger buffer.
  
- If you modify a packet, you must recalculate checksums as 
  appropriate before sending it back.

- The code wont stop you from doing this, but try not to set NF_QUEUE
  verdict on packets.