From owner-svn-src-stable-7@FreeBSD.ORG Tue Jul 13 20:13:38 2010 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A9419106566C; Tue, 13 Jul 2010 20:13:38 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 94FD28FC16; Tue, 13 Jul 2010 20:13:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6DKDcqS044204; Tue, 13 Jul 2010 20:13:38 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6DKDcvS044195; Tue, 13 Jul 2010 20:13:38 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201007132013.o6DKDcvS044195@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Tue, 13 Jul 2010 20:13:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210019 - in stable/7: share/man/man4 sys/conf sys/modules/netgraph sys/modules/netgraph/patch sys/netgraph X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Jul 2010 20:13:38 -0000 Author: ae Date: Tue Jul 13 20:13:38 2010 New Revision: 210019 URL: http://svn.freebsd.org/changeset/base/210019 Log: MFC r208946: New netgraph node ng_patch(4). It performs data modification of packets passing through. Modifications are restricted to a subset of C language operations on unsigned integers of 8, 16, 32 or 64 bit size. These are: set to new value (=), addition (+=), subtraction (-=), multiplication (*=), division (/=), negation (= -), bitwise AND (&=), bitwise OR (|=), bitwise eXclusive OR (^=), shift left (<<=), shift right (>>=). Several operations are all applied to a packet sequentially in order they were specified by user. Submitted by: Maxim Ignatenko Vadim Goncharov Discussed with: net@ MFC r208947: Fix typo. MFC r208989: Style(9) fixes: * Sort includes * Replace #define to #define * Split declarations and initializations * Split long lines Requested by: kib MFC r209194: * Include sys/systm.h for KASSERT() * Remove unneeded includes and comment * Replace home made OFFSETOF() macro with standard offsetof() Pointed out by: bde Tested by: Vadim Goncharov Approved by: mav (mentor) Added: stable/7/share/man/man4/ng_patch.4 - copied unchanged from r208946, head/share/man/man4/ng_patch.4 stable/7/sys/modules/netgraph/patch/ - copied from r208946, head/sys/modules/netgraph/patch/ stable/7/sys/netgraph/ng_patch.c - copied, changed from r208946, head/sys/netgraph/ng_patch.c stable/7/sys/netgraph/ng_patch.h - copied, changed from r208946, head/sys/netgraph/ng_patch.h Modified: stable/7/share/man/man4/Makefile stable/7/sys/conf/NOTES stable/7/sys/conf/files stable/7/sys/conf/options stable/7/sys/modules/netgraph/Makefile Directory Properties: stable/7/share/man/man4/ (props changed) stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/share/man/man4/Makefile ============================================================================== --- stable/7/share/man/man4/Makefile Tue Jul 13 20:09:14 2010 (r210018) +++ stable/7/share/man/man4/Makefile Tue Jul 13 20:13:38 2010 (r210019) @@ -239,6 +239,7 @@ MAN= aac.4 \ ng_nat.4 \ ng_netflow.4 \ ng_one2many.4 \ + ng_patch.4 \ ng_ppp.4 \ ng_pppoe.4 \ ng_pptpgre.4 \ Copied: stable/7/share/man/man4/ng_patch.4 (from r208946, head/share/man/man4/ng_patch.4) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/7/share/man/man4/ng_patch.4 Tue Jul 13 20:13:38 2010 (r210019, copy of r208946, head/share/man/man4/ng_patch.4) @@ -0,0 +1,235 @@ +.\" Copyright (c) 2010 Maxim Ignatenko +.\" Copyright (c) 2010 Vadim Goncharov +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 9, 2010 +.Dt NG_PATCH 4 +.Os +.Sh NAME +.Nm ng_patch +.Nd "trivial mbuf data modifying netgraph node type" +.Sh SYNOPSIS +.In netgraph/ng_patch.h +.Sh DESCRIPTION +The +.Nm patch +node performs data modification of packets passing through it. +Modifications are restricted to a subset of C language operations +on unsigned integers of 8, 16, 32 or 64 bit size. +These are: set to new value (=), addition (+=), subtraction (-=), +multiplication (*=), division (/=), negation (= -), +bitwise AND (&=), bitwise OR (|=), bitwise eXclusive OR (^=), +shift left (<<=), shift right (>>=). +A negation operation is the one exception: integer is treated as signed +and second operand (the +.Va value ) +is not used. +There may be several modification operations, they are all applied +to a packet sequentially in order they were specified by user. +Data payload of packet is viewed as array of bytes, with zero offset +corresponding to the very first byte of packet headers, and +.Va length +bytes beginning from +.Va offset +are taken as a single integer in network byte order. +.Sh HOOKS +This node type has two hooks: +.Bl -tag -width indent +.It Va in +Packets received on this hook are modified according to rules specified +in config and then forwarded to +.Ar out +hook, if it exists and connected. +Otherwise they are reflected back to the +.Ar in +hook. +.It Va out +Packets received on this hook are forwarded to +.Ar in +hook without any changes. +.El +.Sh CONTROL MESSAGES +This node type supports the generic control messages, plus the following: +.Bl -tag -width indent +.It Dv NGM_PATCH_SETCONFIG Pq Li setconfig +This command sets the sequence of modify operations +that will be applied to incoming data on a hook. +The following +.Vt "struct ng_patch_config" +must be supplied as an argument: +.Bd -literal -offset 4n +struct ng_patch_op { + uint64_t value; + uint32_t offset; + uint16_t length; /* 1,2,4 or 8 bytes */ + uint16_t mode; +}; +/* Patching modes */ +#define NG_PATCH_MODE_SET 1 +#define NG_PATCH_MODE_ADD 2 +#define NG_PATCH_MODE_SUB 3 +#define NG_PATCH_MODE_MUL 4 +#define NG_PATCH_MODE_DIV 5 +#define NG_PATCH_MODE_NEG 6 +#define NG_PATCH_MODE_AND 7 +#define NG_PATCH_MODE_OR 8 +#define NG_PATCH_MODE_XOR 9 +#define NG_PATCH_MODE_SHL 10 +#define NG_PATCH_MODE_SHR 11 + +struct ng_patch_config { + uint32_t count; + uint32_t csum_flags; + struct ng_patch_op ops[]; +}; +.Ed +.Pp +The +.Va csum_flags +can be set to any combination of CSUM_IP, CSUM_TCP, CSUM_SCTP and CSUM_UDP +(other values are ignored) for instructing the IP stack to recalculate the +corresponding checksum before transmitting packet on output interface. +The +.Nm +node does not do any checksum correction by itself. +.It Dv NGM_PATCH_GETCONFIG Pq Li getconfig +This control message obtains current set of modify operations, +returned as +.Vt "struct ng_patch_config" . +.It Dv NGM_PATCH_GET_STATS Pq Li getstats +Returns node statistics as a +.Vt "struct ng_patch_stats" . +.It Dv NGM_PATCH_CLR_STATS Pq Li clrstats +Clear node statistics. +.It Dv NGM_PATCH_GETCLR_STATS Pq Li getclrstats +This command is identical to +.Dv NGM_PATCH_GET_STATS , +except that the statistics are also atomically cleared. +.El +.Sh SHUTDOWN +This node shuts down upon receipt of a +.Dv NGM_SHUTDOWN +control message, or when all hooks have been disconnected. +.Sh EXAMPLES +The +.Nm +node allows to modify TTL and TOS/DSCP fields in IP packets. +Suppose you have two adjacent simplex links to remote network +(e.g.\& satellite), so that the packets expiring in between +will generate unwanted ICMP-replies which have to go forth, not back. +Thus you need to raise TTL of every packet entering link link by 2 +to ensure the TTL will not reach zero there. +So you setup +.Xr ipfw 8 +rule with +.Cm netgraph +action to inject packets going to other end of simplex link by the +following +.Xr ngctl 8 +script: +.Bd -literal -offset 4n +/usr/sbin/ngctl -f- <<-SEQ + mkpeer ipfw: patch 200 in + name ipfw:200 ttl_add + msg ttl_add: setconfig { count=1 csum_flags=1 ops=[ \e + { mode=2 value=3 length=1 offset=8 } ] } +SEQ +/sbin/ipfw add 150 netgraph 200 ip from any to simplex.remote.net +.Ed +.Pp +Here +.Dq Li ttl_add +node of type +.Nm +configured to add (mode +.Dv NG_PATCH_MODE_ADD ) +a +.Va value +of 3 to a one-byte TTL field, which is 9th byte of IP packet header. +.Pp +Another example would be two consecutive modifications of packet TOS +field: say, you need to clear the +.Dv IPTOS_THROUGHPUT +bit and set the +.Dv IPTOS_MINCOST +bit. +So you do: +.Bd -literal -offset 4n +/usr/sbin/ngctl -f- <<-SEQ + mkpeer ipfw: patch 300 in + name ipfw:300 tos_chg + msg tos_chg: setconfig { count=2 csum_flags=1 ops=[ \e + { mode=7 value=0xf7 length=1 offset=1 } \e + { mode=8 value=0x02 length=1 offset=1 } ] } +SEQ +/sbin/ipfw add 160 netgraph 600 ip from any to any not dst-port 80 +.Ed +.Pp +This first does +.Dv NG_PATCH_MODE_AND +clearing the fourth bit and then +.Dv NG_PATCH_MODE_OR +setting the third bit. +.Pp +In both examples the +.Va csum_flags +field indicates that IP checksum (but not TCP or UDP checksum) should be +recalculated before transmit. +.Pp +Note: one should ensure that packets are returned to ipfw after processing +inside +.Xr netgraph 4 , +by setting appropriate +.Xr sysctl 8 +variable: +.Bd -literal -offset 4n +sysctl net.inet.ip.fw.one_pass=0 +.Ed +.Sh SEE ALSO +.Xr netgraph 4 , +.Xr ng_ipfw 4 , +.Xr ngctl 8 +.Sh HISTORY +The +.Nm +node type was implemented in +.Fx 8.1 . +.Sh AUTHORS +.An "Maxim Ignatenko" Aq gelraen.ua@gmail.com . +This manual page was written by +.An "Vadim Goncharov" Aq vadimnuclight@tpu.ru . +.Sh BUGS +Node blindly tries to apply every patching operation to each packet +(except those which offset if greater than length of the packet), +so be sure that you supply only the right packets to it (e.g. changing +bytes in the ARP packets meant to be in IP header could corrupt +them and make your machine unreachable from the network). +.Pp +.Em !!! WARNING !!! +.Pp +Output path of the IP stack assumes correct fields and lengths in the +packets - changing them by mistake to incorrect values can cause +unpredictable results including kernel panics. Modified: stable/7/sys/conf/NOTES ============================================================================== --- stable/7/sys/conf/NOTES Tue Jul 13 20:09:14 2010 (r210018) +++ stable/7/sys/conf/NOTES Tue Jul 13 20:13:38 2010 (r210019) @@ -678,6 +678,7 @@ options NETGRAPH_MPPC_ENCRYPTION options NETGRAPH_NETFLOW options NETGRAPH_NAT options NETGRAPH_ONE2MANY +options NETGRAPH_PATCH options NETGRAPH_PPP options NETGRAPH_PPPOE options NETGRAPH_PPTPGRE Modified: stable/7/sys/conf/files ============================================================================== --- stable/7/sys/conf/files Tue Jul 13 20:09:14 2010 (r210018) +++ stable/7/sys/conf/files Tue Jul 13 20:13:38 2010 (r210019) @@ -1934,6 +1934,7 @@ netgraph/ng_mppc.c optional netgraph_mp netgraph/ng_nat.c optional netgraph_nat netgraph/ng_one2many.c optional netgraph_one2many netgraph/ng_parse.c optional netgraph +netgraph/ng_patch.c optional netgraph_patch netgraph/ng_ppp.c optional netgraph_ppp netgraph/ng_pppoe.c optional netgraph_pppoe netgraph/ng_pptpgre.c optional netgraph_pptpgre Modified: stable/7/sys/conf/options ============================================================================== --- stable/7/sys/conf/options Tue Jul 13 20:09:14 2010 (r210018) +++ stable/7/sys/conf/options Tue Jul 13 20:13:38 2010 (r210019) @@ -464,6 +464,7 @@ NETGRAPH_MPPC_ENCRYPTION opt_netgraph.h NETGRAPH_NAT opt_netgraph.h NETGRAPH_NETFLOW opt_netgraph.h NETGRAPH_ONE2MANY opt_netgraph.h +NETGRAPH_PATCH opt_netgraph.h NETGRAPH_PPP opt_netgraph.h NETGRAPH_PPPOE opt_netgraph.h NETGRAPH_PPTPGRE opt_netgraph.h Modified: stable/7/sys/modules/netgraph/Makefile ============================================================================== --- stable/7/sys/modules/netgraph/Makefile Tue Jul 13 20:09:14 2010 (r210018) +++ stable/7/sys/modules/netgraph/Makefile Tue Jul 13 20:13:38 2010 (r210019) @@ -34,6 +34,7 @@ SUBDIR= async \ netflow \ netgraph \ one2many \ + patch \ ppp \ pppoe \ pptpgre \ Copied and modified: stable/7/sys/netgraph/ng_patch.c (from r208946, head/sys/netgraph/ng_patch.c) ============================================================================== --- head/sys/netgraph/ng_patch.c Wed Jun 9 12:25:57 2010 (r208946, copy source) +++ stable/7/sys/netgraph/ng_patch.c Tue Jul 13 20:13:38 2010 (r210019) @@ -29,12 +29,11 @@ __FBSDID("$FreeBSD$"); #include +#include #include -#include +#include #include -#include -#include -#include /* be64toh(), htobe64() */ +#include #include #include #include @@ -47,16 +46,14 @@ static ng_newhook_t ng_patch_newhook; static ng_rcvdata_t ng_patch_rcvdata; static ng_disconnect_t ng_patch_disconnect; -#define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0)) - static int -ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, - const u_char *buf) +ng_patch_config_getlen(const struct ng_parse_type *type, + const u_char *start, const u_char *buf) { const struct ng_patch_config *p; p = (const struct ng_patch_config *)(buf - - OFFSETOF(struct ng_patch_config, ops)); + offsetof(struct ng_patch_config, ops)); return (p->count); } @@ -158,7 +155,7 @@ struct ng_patch_priv { }; typedef struct ng_patch_priv *priv_p; -#define NG_PATCH_CONF_SIZE(count) (sizeof(struct ng_patch_config) + \ +#define NG_PATCH_CONF_SIZE(count) (sizeof(struct ng_patch_config) + \ (count) * sizeof(struct ng_patch_op)) static void do_patch(priv_p conf, struct mbuf *m); @@ -195,12 +192,14 @@ static int ng_patch_rcvmsg(node_p node, item_p item, hook_p lasthook) { const priv_p privp = NG_NODE_PRIVATE(node); - struct ng_patch_config *conf; + struct ng_patch_config *conf, *newconf; + union patch_val *newval; struct ng_mesg *msg; - struct ng_mesg *resp = NULL; - int i, clear = 0; - int error = 0; + struct ng_mesg *resp; + int i, clear, error; + clear = error = 0; + resp = NULL; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { case NGM_PATCH_COOKIE: @@ -215,16 +214,15 @@ ng_patch_rcvmsg(node_p node, item_p item break; case NGM_PATCH_SETCONFIG: { - struct ng_patch_config *newconf; - union patch_val *newval; - - if (msg->header.arglen < sizeof(struct ng_patch_config)) { + if (msg->header.arglen < + sizeof(struct ng_patch_config)) { error = EINVAL; break; } conf = (struct ng_patch_config *)msg->data; - if (msg->header.arglen < NG_PATCH_CONF_SIZE(conf->count)) { + if (msg->header.arglen < + NG_PATCH_CONF_SIZE(conf->count)) { error = EINVAL; break; } @@ -248,27 +246,34 @@ ng_patch_rcvmsg(node_p node, item_p item CSUM_SCTP; if (error == 0) { - newconf = malloc(NG_PATCH_CONF_SIZE(conf->count), - M_NETGRAPH, M_WAIT); - newval = malloc(conf->count * sizeof(union patch_val), + newconf = malloc( + NG_PATCH_CONF_SIZE(conf->count), M_NETGRAPH, M_WAIT); + newval = malloc(conf->count * + sizeof(union patch_val), M_NETGRAPH, + M_WAIT); for(i = 0; i < conf->count; i++) { switch (conf->ops[i].length) { case 1: - newval[i].v1 = conf->ops[i].value; + newval[i].v1 = + conf->ops[i].value; break; case 2: - newval[i].v2 = conf->ops[i].value; + newval[i].v2 = + conf->ops[i].value; break; case 4: - newval[i].v4 = conf->ops[i].value; + newval[i].v4 = + conf->ops[i].value; break; case 8: - newval[i].v8 = conf->ops[i].value; + newval[i].v8 = + conf->ops[i].value; break; } } - bcopy(conf, newconf, NG_PATCH_CONF_SIZE(conf->count)); + bcopy(conf, newconf, + NG_PATCH_CONF_SIZE(conf->count)); if (privp->val != NULL) free(privp->val, M_NETGRAPH); privp->val = newval; @@ -310,12 +315,15 @@ ng_patch_rcvmsg(node_p node, item_p item static void do_patch(priv_p privp, struct mbuf *m) { - struct ng_patch_config *conf = privp->config; + struct ng_patch_config *conf; uint64_t buf; - int i, patched = 0; + int i, patched; + conf = privp->config; + patched = 0; for(i = 0; i < conf->count; i++) { - if (conf->ops[i].offset + conf->ops[i].length > m->m_pkthdr.len) + if (conf->ops[i].offset + conf->ops[i].length > + m->m_pkthdr.len) continue; /* for "=" operation we don't need to copy data from mbuf */ @@ -323,7 +331,7 @@ do_patch(priv_p privp, struct mbuf *m) m_copydata(m, conf->ops[i].offset, conf->ops[i].length, (caddr_t)&buf); } - + switch (conf->ops[i].length) { case 1: switch (conf->ops[i].mode) { @@ -550,16 +558,17 @@ ng_patch_shutdown(node_p node) static int ng_patch_disconnect(hook_p hook) { - priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); + priv_p priv; + priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); if (hook == priv->in) { priv->in = NULL; } if (hook == priv->out) { priv->out = NULL; } - if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) - && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) /* already shutting down? */ + if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 && + NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */ ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); } Copied and modified: stable/7/sys/netgraph/ng_patch.h (from r208946, head/sys/netgraph/ng_patch.h) ============================================================================== --- head/sys/netgraph/ng_patch.h Wed Jun 9 12:25:57 2010 (r208946, copy source) +++ stable/7/sys/netgraph/ng_patch.h Tue Jul 13 20:13:38 2010 (r210019) @@ -30,14 +30,14 @@ #define _NETGRAPH_NG_PATCH_H_ /* Node type name. */ -#define NG_PATCH_NODE_TYPE "patch" +#define NG_PATCH_NODE_TYPE "patch" /* Node type cookie. */ -#define NGM_PATCH_COOKIE 1262445509 +#define NGM_PATCH_COOKIE 1262445509 /* Hook names */ -#define NG_PATCH_HOOK_IN "in" -#define NG_PATCH_HOOK_OUT "out" +#define NG_PATCH_HOOK_IN "in" +#define NG_PATCH_HOOK_OUT "out" /* Netgraph commands understood by this node type */ enum { @@ -70,7 +70,7 @@ struct ng_patch_op { uint16_t mode; }; -#define NG_PATCH_OP_TYPE_INFO { \ +#define NG_PATCH_OP_TYPE_INFO { \ { "value", &ng_parse_uint64_type }, \ { "offset", &ng_parse_uint32_type }, \ { "length", &ng_parse_uint16_type }, \ @@ -84,7 +84,7 @@ struct ng_patch_config { struct ng_patch_op ops[]; }; -#define NG_PATCH_CONFIG_TYPE_INFO { \ +#define NG_PATCH_CONFIG_TYPE_INFO { \ { "count", &ng_parse_uint32_type }, \ { "csum_flags", &ng_parse_uint32_type }, \ { "ops", &ng_patch_confarr_type }, \ @@ -97,7 +97,7 @@ struct ng_patch_stats { uint64_t dropped; }; -#define NG_PATCH_STATS_TYPE_INFO { \ +#define NG_PATCH_STATS_TYPE_INFO { \ { "received", &ng_parse_uint64_type }, \ { "patched", &ng_parse_uint64_type }, \ { "dropped", &ng_parse_uint64_type }, \