1.\" Copyright (c) 2006 Vadim Goncharov <vadimnuclight@tpu.ru> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd June 10, 2006 28.Dt NG_TAG 4 29.Os 30.Sh NAME 31.Nm ng_tag 32.Nd "mbuf tags manipulating netgraph node type" 33.Sh SYNOPSIS 34.In netgraph/ng_tag.h 35.Sh DESCRIPTION 36The 37.Nm tag 38node type allows mbuf packet tags (see 39.Xr mbuf_tags 9 ) 40to be examined, stripped or applied to data travelling through a 41Netgraph network. 42Mbuf tags are used in many parts of the 43.Fx 44kernel network subsystem, 45including the storage of VLAN tags as described in 46.Xr vlan 4 , 47Mandatory Access Control (MAC) labels as described in 48.Xr mac 9 , 49IPsec policy information as described in 50.Xr ipsec 4 , 51and packet filter tags used by 52.Xr pf 4 . 53One should also consider useful setting or checking 54.Xr ipfw 8 55tags, which are implemented as mbuf tags, too. 56.Pp 57Each node allows an arbitrary number of connections to arbitrarily 58named hooks. 59With each hook is associated a tag which will be searched in the list 60of all tags attached to a packet incoming to this hook, a destination hook 61for matching packets, a destination hook for non-matching packets, 62a tag which will be appended to data leaving node through this hook, 63and various statistics counters. 64.Pp 65The list of incoming packet's tags is traversed to find a tag with 66specified 67.Va type 68and 69.Va cookie 70values. 71Upon match, if specified 72.Va tag_len 73is non-zero, 74.Va tag_data 75of tag is checked to be identical to that specified in the hook structure. 76Packets with matched tags are forwarded to 77.Dq match 78destination hook, or forwarded to 79.Dq non-match 80hook otherwise. 81Either or both destination hooks can be an empty string, or may 82not exist, in which case the packet is dropped. 83.Pp 84Tag list of packets leaving the node is extended with a new tag 85specified in outgoing hook structure (it is possible to avoid appending 86a new tag to pass packet completely unchanged by specifying zero 87.Va type 88and 89.Va cookie 90values in the structure of the corresponding outgoing hook). 91Additionally, 92a tag can be stripped from incoming packet after match if 93.Va strip 94flag is set. 95This can be used for simple tag removal or tag replacement, if combined 96with tag addition on outgoing matching hook. 97Note that new tag is appended unconditionally, without checking if 98such a tag is already present in the list (it is up to user to check 99if this is a concern). 100.Pp 101New hooks are initially configured to drop all incoming packets 102(as all hook names are empty strings; zero values can be specified 103to forward all packets to non-matching hook), 104and to forward all outgoing packets without any tag appending. 105.Pp 106Data payload of packets passing through the node is completely 107unchanged, all operations can affect tag list only. 108.Sh HOOKS 109This node type supports any number of hooks having arbitrary names. 110In order to allow internal optimizations, user should never try to 111configure a hook with a structure pointing to hooks which do not exist yet. 112The safe way is to create all hooks first, then begin to configure them. 113.Sh CONTROL MESSAGES 114This node type supports the generic control messages, plus the following: 115.Bl -tag -width foo 116.It Dv NGM_TAG_SET_HOOKIN Pq Ic sethookin 117This command sets tag values which will be searched in the tag list of 118incoming packets on a hook. 119The following structure must be supplied as an argument: 120.Bd -literal -offset 4n 121struct ng_tag_hookin { 122 char thisHook[NG_HOOKSIZ]; /* name of hook */ 123 char ifMatch[NG_HOOKSIZ]; /* match dest hook */ 124 char ifNotMatch[NG_HOOKSIZ]; /* !match dest hook */ 125 uint8_t strip; /* strip tag if found */ 126 uint32_t tag_cookie; /* ABI/Module ID */ 127 uint16_t tag_id; /* tag ID */ 128 uint16_t tag_len; /* length of data */ 129 uint8_t tag_data[0]; /* tag data */ 130}; 131.Ed 132.Pp 133The hook to be updated is specified in 134.Va thisHook . 135Data bytes of tag corresponding to specified 136.Va tag_id 137(type) and 138.Va tag_cookie 139are placed in the 140.Va tag_data 141array; there must be 142.Va tag_len 143of them. 144Matching and non-matching incoming packets are delivered out the hooks named 145.Va ifMatch 146and 147.Va ifNotMatch , 148respectively. 149If 150.Va strip 151flag is non-zero, then found tag is deleted from list of packet tags. 152.It Dv NGM_TAG_GET_HOOKIN Pq Ic gethookin 153This command takes an ASCII string argument, the hook name, and returns the 154corresponding 155.Vt "struct ng_tag_hookin" 156as shown above. 157.It Dv NGM_TAG_SET_HOOKOUT Pq Ic sethookout 158This command sets tags values which will be applied to outgoing 159packets. 160The following structure must be supplied as an argument: 161.Bd -literal -offset 4n 162struct ng_tag_hookout { 163 char thisHook[NG_HOOKSIZ]; /* name of hook */ 164 uint32_t tag_cookie; /* ABI/Module ID */ 165 uint16_t tag_id; /* tag ID */ 166 uint16_t tag_len; /* length of data */ 167 uint8_t tag_data[0]; /* tag data */ 168}; 169.Ed 170.Pp 171The hook to be updated is specified in 172.Va thisHook . 173Other variables mean basically the same as in 174.Vt "struct ng_tag_hookin" 175shown above, except used for setting values in a new tag. 176.It Dv NGM_TAG_GET_HOOKOUT Pq Ic gethookout 177This command takes an ASCII string argument, the hook name, and returns the 178corresponding 179.Vt "struct ng_tag_hookout" 180as shown above. 181.It Dv NGM_TAG_GET_STATS Pq Ic getstats 182This command takes an ASCII string argument, the hook name, and returns the 183statistics associated with the hook as a 184.Vt "struct ng_tag_hookstat" . 185.It Dv NGM_TAG_CLR_STATS Pq Ic clrstats 186This command takes an ASCII string argument, the hook name, and clears the 187statistics associated with the hook. 188.It Dv NGM_TAG_GETCLR_STATS Pq Ic getclrstats 189This command is identical to 190.Dv NGM_TAG_GET_STATS , 191except that the statistics are also atomically cleared. 192.El 193.Pp 194.Em Note : 195statistics counters as well as three statistics messages above work 196only if code was compiled with the 197.Dv NG_TAG_DEBUG 198option. 199The reason for this is that statistics is rarely used in practice, 200but still consumes CPU cycles for every packet. 201Moreover, it is even not accurate on SMP systems due to lack of 202synchronization between threads, as this is very expensive. 203.Sh SHUTDOWN 204This node shuts down upon receipt of a 205.Dv NGM_SHUTDOWN 206control message, or when all hooks have been disconnected. 207.Sh EXAMPLES 208It is possible to do a simple L7 filtering by using 209.Xr ipfw 8 210tags in conjunction with 211.Xr ng_bpf 4 212traffic analyzer. 213Example below explains how to filter DirectConnect P2P network data traffic, 214which cannot be done by usual means as it uses random ports. 215It is known that such data connection always contains a TCP packet with 2166-byte payload string "$Send|". 217So ipfw's 218.Cm netgraph 219action will be used to divert all TCP packets to an 220.Xr ng_bpf 4 221node which will check for the specified string and return non-matching 222packets to 223.Xr ipfw 8 . 224Matching packets are passed to 225.Nm 226node, which will set a tag and pass them back to 227.Xr ng_bpf 4 228node on a hook programmed to accept all packets and pass them back to 229.Xr ipfw 8 . 230A script provided in 231.Xr ng_bpf 4 232manual page will be used for programming node. 233Note that packets diverted from 234.Xr ipfw 8 235to Netgraph have no link-level header, so offsets in 236.Xr tcpdump 1 237expressions must be altered accordingly. 238Thus, there will be expression 239.Dq Li "ether[40:2]=0x244c && ether[42:4]=0x6f636b20" 240on incoming hook and empty expression to match all packets from 241.Nm . 242.Pp 243So, this is 244.Xr ngctl 8 245script for nodes creating and naming for easier access: 246.Bd -literal -offset 4n 247/usr/sbin/ngctl -f- <<-SEQ 248 mkpeer ipfw: bpf 41 ipfw 249 name ipfw:41 dcbpf 250 mkpeer dcbpf: tag matched th1 251 name dcbpf:matched ngdc 252SEQ 253.Ed 254.Pp 255Now 256.Dq Li ngdc 257node (which is of type 258.Nm ) 259must be programmed to echo all packets received on the 260.Dq Li th1 261hook back, with the 262.Xr ipfw 8 263tag 412 attached. 264.Dv MTAG_IPFW 265value for 266.Va tag_cookie 267was taken from file 268.In netinet/ip_fw.h 269and value for 270.Va tag_id 271is tag number (412), with zero tag length: 272.Bd -literal -offset 4n 273ngctl msg ngdc: sethookin { thisHook=\e"th1\e" ifNotMatch=\e"th1\e" } 274ngctl msg ngdc: sethookout { thisHook=\e"th1\e" \e 275 tag_cookie=1148380143 \e 276 tag_id=412 } 277.Ed 278.Pp 279Do not forget to program 280.Xr ng_bpf 4 281.Dq Li ipfw 282hook with the above expression (see 283.Xr ng_bpf 4 284for script doing this) and 285.Dq Li matched 286hook with an empty expression: 287.Bd -literal -offset 4n 288ngctl msg dcbpf: setprogram { thisHook=\e"matched\e" ifMatch=\e"ipfw\e" \e 289 bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] } 290.Ed 291.Pp 292After finishing with 293.Xr netgraph 4 294nodes, 295.Xr ipfw 8 296rules must be added to enable packet flow: 297.Bd -literal -offset 4n 298ipfw add 100 netgraph 41 tcp from any to any iplen 46 299ipfw add 110 reset tcp from any to any tagged 412 300.Ed 301.Pp 302Note: one should ensure that packets are returned to ipfw after processing 303inside 304.Xr netgraph 4 , 305by setting appropriate 306.Xr sysctl 8 307variable: 308.Bd -literal -offset 4n 309sysctl net.inet.ip.fw.one_pass=0 310.Ed 311.Sh SEE ALSO 312.Xr netgraph 4 , 313.Xr ng_bpf 4 , 314.Xr ng_ipfw 4 , 315.Xr ipfw 8 , 316.Xr ngctl 8 , 317.Xr mbuf_tags 9 318.Sh HISTORY 319The 320.Nm 321node type was implemented in 322.Fx 6.2 . 323.Sh AUTHORS 324.An Vadim Goncharov Aq Mt vadimnuclight@tpu.ru 325.Sh BUGS 326For manipulating any tags with data payload (that is, all tags with non-zero 327.Va tag_len ) 328one should care about non-portable machine-dependent representation of 329tags on the low level as byte stream. 330Perhaps this should be done by another program rather than manually. 331