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 indent 116.It Dv NGM_TAG_SET_HOOKIN 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 153This command takes an 154.Tn ASCII 155string argument, the hook name, and returns the 156corresponding 157.Vt "struct ng_tag_hookin" 158as shown above. 159.It Dv NGM_TAG_SET_HOOKOUT 160This command sets tags values which will be applied to outgoing 161packets. 162The following structure must be supplied as an argument: 163.Bd -literal -offset 4n 164struct ng_tag_hookout { 165 char thisHook[NG_HOOKSIZ]; /* name of hook */ 166 uint32_t tag_cookie; /* ABI/Module ID */ 167 uint16_t tag_id; /* tag ID */ 168 uint16_t tag_len; /* length of data */ 169 uint8_t tag_data[0]; /* tag data */ 170}; 171.Ed 172.Pp 173The hook to be updated is specified in 174.Va thisHook . 175Other variables mean basically the same as in 176.Vt "struct ng_tag_hookin" 177shown above, except used for setting values in a new tag. 178.It Dv NGM_TAG_GET_HOOKOUT 179This command takes an 180.Tn ASCII 181string argument, the hook name, and returns the 182corresponding 183.Vt "struct ng_tag_hookout" 184as shown above. 185.It Dv NGM_TAG_GET_STATS 186This command takes an 187.Tn ASCII 188string argument, the hook name, and returns the 189statistics associated with the hook as a 190.Vt "struct ng_tag_hookstat" . 191.It Dv NGM_TAG_CLR_STATS 192This command takes an 193.Tn ASCII 194string argument, the hook name, and clears the 195statistics associated with the hook. 196.It Dv NGM_TAG_GETCLR_STATS 197This command is identical to 198.Dv NGM_TAG_GET_STATS , 199except that the statistics are also atomically cleared. 200.El 201.Pp 202.Em Note: 203statistics counters as well as three statistics messages above work 204only if code was compiled with the 205.Dv NG_TAG_DEBUG 206option. 207The reason for this is that statistics is rarely used in practice, 208but still consumes CPU cycles for every packet. 209Moreover, it is even not accurate on SMP systems due to lack of 210synchronization between threads, as this is very expensive. 211.Sh SHUTDOWN 212This node shuts down upon receipt of a 213.Dv NGM_SHUTDOWN 214control message, or when all hooks have been disconnected. 215.Sh EXAMPLES 216It is possible to do a simple L7 filtering by using 217.Xr ipfw 8 218tags in conjunction with 219.Xr ng_bpf 4 220traffic analyzer. 221Example below explains how to filter DirectConnect P2P network data traffic, 222which cannot be done by usual means as it uses random ports. 223It is known that such data connection always contains a TCP packet with 2246-byte payload string "$Send|". 225So ipfw's 226.Cm netgraph 227action will be used to divert all TCP packets to an 228.Xr ng_bpf 4 229node which will check for the specified string and return non-matching 230packets to 231.Xr ipfw 8 . 232Matching packets are passed to 233.Xr ng_tag 4 234node, which will set a tag and pass them back to 235.Xr ng_bpf 4 236node on a hook programmed to accept all packets and pass them back to 237.Xr ipfw 8 . 238A script provided in 239.Xr ng_bpf 4 240manual page will be used for programming node. 241Note that packets diverted from 242.Xr ipfw 8 243to Netgraph have no link-level header, so offsets in 244.Xr tcpdump 1 245expressions must be altered accordingly. 246Thus, there will be expression 247.Dq Li "ether[40:2]=0x244c && ether[42:4]=0x6f636b20" 248on incoming hook and empty expression to match all packets from 249.Xr ng_tag 4 . 250.Pp 251So, this is 252.Xr ngctl 8 253script for nodes creating and naming for easier access: 254.Bd -literal -offset 4n 255/usr/sbin/ngctl -f- <<-SEQ 256 mkpeer ipfw: bpf 41 ipfw 257 name ipfw:41 dcbpf 258 mkpeer dcbpf: tag matched th1 259 name dcbpf:matched ngdc 260SEQ 261.Ed 262.Pp 263Now 264.Dq Li ngdc 265node (which is of type 266.Nm ) 267must be programmed to echo all packets received on the 268.Dq Li th1 269hook back, with the 270.Xr ipfw 8 271tag 412 attached. 272.Dv MTAG_IPFW 273value for 274.Va tag_cookie 275was taken from file 276.In netinet/ip_fw.h 277and value for 278.Va tag_id 279is tag number (412), with zero tag length: 280.Bd -literal -offset 4n 281ngctl msg ngdc: sethookin { thisHook=\e"th1\e" ifNotMatch=\e"th1\e" } 282ngctl msg ngdc: sethookout { thisHook=\e"th1\e" \e 283 tag_cookie=1148380143 \e 284 tag_id=412 } 285.Ed 286.Pp 287Don't forget to program 288.Xr ng_bpf 4 289.Dq Li ipfw 290hook with the above expression (see 291.Xr ng_bpf 4 292for script doing this) and 293.Dq Li matched 294hook with an empty expression: 295.Bd -literal -offset 4n 296ngctl msg dcbpf: setprogram { thisHook=\e"matched\e" ifMatch=\e"ipfw\e" \e 297 bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] } 298.Ed 299.Pp 300After finishing with 301.Xr netgraph 4 302nodes, 303.Xr ipfw 8 304rules must be added to enable packet flow: 305.Bd -literal -offset 4n 306ipfw add 100 netgraph 41 tcp from any to any iplen 46 307ipfw add 110 reset tcp from any to any tagged 412 308.Ed 309.Pp 310Note: one should ensure that packets are returned to ipfw after processing 311inside 312.Xr netgraph 4 , 313by setting appropriate 314.Xr sysctl 8 315variable: 316.Bd -literal -offset 4n 317sysctl net.inet.ip.fw.one_pass=0 318.Ed 319.Sh SEE ALSO 320.Xr netgraph 4 , 321.Xr ng_bpf 4 , 322.Xr ng_ipfw 4 , 323.Xr ipfw 8 , 324.Xr ngctl 8 , 325.Xr mbuf_tags 9 326.Sh HISTORY 327The 328.Nm 329node type was implemented in 330.Fx 6.2 . 331.Sh AUTHORS 332.An Vadim Goncharov Aq vadimnuclight@tpu.ru 333.Sh BUGS 334For manipulating any tags with data payload (that is, all tags with non-zero 335.Va tag_len ) 336one should care about non-portable machine-dependent representation of 337tags on the low level as byte stream. 338Perhaps this should be done by another program rather than manually. 339