summaryrefslogtreecommitdiff
path: root/static/freebsd/man4/ng_pipe.4 3.html
blob: 4033ae931238167308adbee05f755d4c76b9b643 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<table class="head">
  <tr>
    <td class="head-ltitle">NG_PIPE(4)</td>
    <td class="head-vol">Device Drivers Manual</td>
    <td class="head-rtitle">NG_PIPE(4)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">ng_pipe</code> &#x2014; <span class="Nd">Traffic
    manipulating netgraph node type</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">netgraph/ng_pipe.h</a>&gt;</code></p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">pipe</code> node type manipulates traffic by
    emulating bandwidth and delay, as well as random packet losses.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="HOOKS"><a class="permalink" href="#HOOKS">HOOKS</a></h1>
<p class="Pp">This node type supports the following hooks:</p>
<dl class="Bl-tag">
  <dt id="upper"><var class="Va">upper</var></dt>
  <dd>Hook leading to upper layer protocols.</dd>
  <dt id="lower"><var class="Va">lower</var></dt>
  <dd>Hook leading to lower layer protocols.</dd>
</dl>
<p class="Pp" id="downstream">Traffic flowing from <var class="Va">upper</var>
    to <var class="Va">lower</var> is considered
    <a class="permalink" href="#downstream"><b class="Sy">downstream</b></a>
    traffic. Traffic flowing from <var class="Va">lower</var> to
    <var class="Va">upper</var> is considered
    <a class="permalink" href="#upstream"><b class="Sy" id="upstream">upstream</b></a>
    traffic.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="MODE_OF_OPERATION"><a class="permalink" href="#MODE_OF_OPERATION">MODE
  OF OPERATION</a></h1>
<p class="Pp">Data received on a hook - both in upstream and downstream
    direction - is put into an inbound queue. If inbound queue is full, discard
    one frame depending on dropping policy (from the head or from the tail of
    the queue).</p>
<p class="Pp">There are three mutually exclusive modes for the input queue:</p>
<dl class="Bl-tag">
  <dt id="First"><a class="permalink" href="#First"><code class="Dv">First In
    First Out (FIFO)</code></a></dt>
  <dd>A single queue holds packets in chronological order.</dd>
  <dt id="Weighted"><a class="permalink" href="#Weighted"><code class="Dv">Weighted
    fair queuing (WFQ)</code></a></dt>
  <dd>There are multiple queues for different traffic flows (based on IPv4 IPs).
      The longest queue is truncated if necessary. This approach assumes that
      the stalling flow is the flow with the most packets currently on
    hold.</dd>
  <dt id="Deficit"><a class="permalink" href="#Deficit"><code class="Dv">Deficit
    Round Robin (DRR)</code></a></dt>
  <dd>This mode is similar to WFQ, but packets are not taken out in strict
      chronological order. In principle oldest packets come first, but not too
      many packets from the same flow.</dd>
</dl>
<p class="Pp">It is possible to configure a duplication probability. As the dice
    decides, the currently active packet stays in the queue while a copy of the
    packet is sent out. Nothing prevents a packet from being duplicated multiple
    times.</p>
<p class="Pp">Packets are dropped with an increasing probability depending on
    the size of the packet, if a <var class="Va">ber</var> (bit error rate) is
    configured.</p>
<p class="Pp">Surviving packets are delayed by the time the packet would need to
    travel through a link of the configured bandwidth. If this outbound queue is
    full, the packet is dropped.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="CONTROL_MESSAGES"><a class="permalink" href="#CONTROL_MESSAGES">CONTROL
  MESSAGES</a></h1>
<p class="Pp">This node type supports the generic control messages and the
    following specific messages.</p>
<dl class="Bl-tag">
  <dt id="NGM_PIPE_SET_CFG"><a class="permalink" href="#NGM_PIPE_SET_CFG"><code class="Dv">NGM_PIPE_SET_CFG</code></a>
    (<code class="Ic">setcfg</code>)</dt>
  <dd>Set node configuration to the one specified in <var class="Vt">struct
      ng_pipe_cfg</var>
    <p class="Pp">Note: To set a value to zero, specify -1 instead. This allows
        omitting configuration values, which should not be modified.</p>
  </dd>
  <dt id="NGM_PIPE_GET_CFG"><a class="permalink" href="#NGM_PIPE_GET_CFG"><code class="Dv">NGM_PIPE_GET_CFG</code></a>
    (<code class="Ic">getcfg</code>)</dt>
  <dd>Return current node configuration as <var class="Vt">struct
      ng_pipe_cfg</var>
    <div class="Bd Pp Li">
    <pre>struct ng_pipe_cfg {
  u_int64_t  bandwidth;     /* bits per second */
  u_int64_t  delay;         /* additional delay, usec */
  u_int32_t  header_offset; /* offset of IP header in bytes */
  u_int32_t  overhead;      /* assumed L2 overhead in bytes */
  struct ng_pipe_hookcfg  downstream;
  struct ng_pipe_hookcfg  upstream;
};

/* Config structure for one hook */
struct ng_pipe_hookcfg {
  u_int64_t  bandwidth;       /* bits per second */
  u_int64_t  ber;             /* avg. interval between bit errors (1 / BER) */
  u_int32_t  qin_size_limit;  /* number of queue items */
  u_int32_t  qout_size_limit; /* number of queue items */
  u_int32_t  duplicate;       /* probability in % */
  u_int32_t  fifo;            /* 0 = off, 1 = on */
  u_int32_t  drr;             /* 0 = off, 1 = 2048 bytes, or x bytes */
  u_int32_t  wfq;             /* 0 = off, 1 = on */
  u_int32_t  droptail;        /* 0 = off, 1 = on */
  u_int32_t  drophead;        /* 0 = off, 1 = on */
};</pre>
    </div>
  </dd>
  <dt id="NGM_PIPE_GET_STATS"><a class="permalink" href="#NGM_PIPE_GET_STATS"><code class="Dv">NGM_PIPE_GET_STATS</code></a>
    (<code class="Ic">getstats</code>)</dt>
  <dd>Return node statistics as <var class="Vt">struct ng_pipe_stats</var>
    <div class="Bd Pp Li">
    <pre>/* Statistics structure for one hook */
struct ng_pipe_hookstat {
  u_int64_t  fwd_octets;
  u_int64_t  fwd_frames;
  u_int64_t  in_disc_octets;
  u_int64_t  in_disc_frames;
  u_int64_t  out_disc_octets;
  u_int64_t  out_disc_frames;
};

/* Statistics structure returned by NGM_PIPE_GET_STATS */
struct ng_pipe_stats {
  struct ng_pipe_hookstat  downstream;
  struct ng_pipe_hookstat  upstream;
};</pre>
    </div>
  </dd>
  <dt id="NGM_PIPE_CLR_STATS"><a class="permalink" href="#NGM_PIPE_CLR_STATS"><code class="Dv">NGM_PIPE_CLR_STATS</code></a>
    (<code class="Ic">clrstats</code>)</dt>
  <dd>Clear node statistics.</dd>
  <dt id="NGM_PIPE_GETCLR_STATS"><a class="permalink" href="#NGM_PIPE_GETCLR_STATS"><code class="Dv">NGM_PIPE_GETCLR_STATS</code></a>
    (<code class="Ic">getclrstats</code>)</dt>
  <dd>Atomically return and clear node statistics.</dd>
  <dt id="NGM_PIPE_GET_RUN"><a class="permalink" href="#NGM_PIPE_GET_RUN"><code class="Dv">NGM_PIPE_GET_RUN</code></a>
    (<code class="Ic">getrun</code>)</dt>
  <dd>Return node statistics as <var class="Vt">struct ng_pipe_run</var>
    <div class="Bd Pp Li">
    <pre>/* Runtime structure for one hook */
struct ng_pipe_hookrun {
  u_int32_t  fifo_queues;
  u_int32_t  qin_octets;
  u_int32_t  qin_frames;
  u_int32_t  qout_octets;
  u_int32_t  qout_frames;
};

/* Runtime structure returned by NGM_PIPE_GET_RUN */
struct ng_pipe_run {
  struct ng_pipe_hookrun  downstream;
  struct ng_pipe_hookrun  upstream;
};</pre>
    </div>
  </dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="SHUTDOWN"><a class="permalink" href="#SHUTDOWN">SHUTDOWN</a></h1>
<p class="Pp">This node shuts down upon receipt of a
    <code class="Dv">NGM_SHUTDOWN</code> control message, or when all hooks have
    been disconnected.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
<p class="Pp">Limit outgoing data rate over fxp0 Ethernet interface to 20Mbps in
    fifo mode and incoming to 50kbps in drr mode and 2% duplicate
  probability.</p>
<div class="Bd Pp Bd-indent Li">
<pre>/usr/sbin/ngctl -f- &lt;&lt;-SEQ
  mkpeer fxp0: pipe lower lower
  name fxp0:lower fxp0_pipe
  connect fxp0: fxp0_pipe: upper upper
  msg fxp0_pipe: setcfg { downstream={ bandwidth=20000000 fifo=1 } }
  msg fxp0_pipe: setcfg { upstream={ bandwidth=500000 drr=1 duplicate=2 } }
SEQ</pre>
</div>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">netgraph(4)</a>, <a class="Xr">ngctl(8)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
<p class="Pp"><span class="An">Lutz Donnerhacke</span>
    &lt;<a class="Mt" href="mailto:lutz@donnerhacke.de">lutz@donnerhacke.de</a>&gt;
    (man page)</p>
</section>
<section class="Sh">
<h1 class="Sh" id="BUGS"><a class="permalink" href="#BUGS">BUGS</a></h1>
<p class="Pp">Error handling for memory issues is missing. If kernel memory
    cannot be allocated immediately, a kernel panic will be triggered. Same
    happens if an mbuf is fragmented within the transport headers.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">October 17, 2019</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>