Deleted Added
sdiff udiff text old ( 208946 ) new ( 208989 )
full compact
1/*-
2 * Copyright (C) 2010 by Maxim Ignatenko <gelraen.ua@gmail.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 12 unchanged lines hidden (view full) ---

21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/netgraph/ng_patch.c 208946 2010-06-09 12:25:57Z ae $");
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/mbuf.h>
34#include <sys/malloc.h>
35#include <sys/ctype.h>
36#include <sys/errno.h>
37#include <sys/endian.h> /* be64toh(), htobe64() */
38#include <netgraph/ng_message.h>
39#include <netgraph/ng_parse.h>
40#include <netgraph/ng_patch.h>
41#include <netgraph/netgraph.h>
42
43static ng_constructor_t ng_patch_constructor;
44static ng_rcvmsg_t ng_patch_rcvmsg;
45static ng_shutdown_t ng_patch_shutdown;
46static ng_newhook_t ng_patch_newhook;
47static ng_rcvdata_t ng_patch_rcvdata;
48static ng_disconnect_t ng_patch_disconnect;
49
50#define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0))
51
52static int
53ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start,
54 const u_char *buf)
55{
56 const struct ng_patch_config *p;
57
58 p = (const struct ng_patch_config *)(buf -
59 OFFSETOF(struct ng_patch_config, ops));
60 return (p->count);
61}
62

--- 90 unchanged lines hidden (view full) ---

153 hook_p in;
154 hook_p out;
155 struct ng_patch_config *config;
156 union patch_val *val;
157 struct ng_patch_stats stats;
158};
159typedef struct ng_patch_priv *priv_p;
160
161#define NG_PATCH_CONF_SIZE(count) (sizeof(struct ng_patch_config) + \
162 (count) * sizeof(struct ng_patch_op))
163
164static void do_patch(priv_p conf, struct mbuf *m);
165
166static int
167ng_patch_constructor(node_p node)
168{
169 priv_p privdata;

--- 20 unchanged lines hidden (view full) ---

190 return (EINVAL);
191 return(0);
192}
193
194static int
195ng_patch_rcvmsg(node_p node, item_p item, hook_p lasthook)
196{
197 const priv_p privp = NG_NODE_PRIVATE(node);
198 struct ng_patch_config *conf;
199 struct ng_mesg *msg;
200 struct ng_mesg *resp = NULL;
201 int i, clear = 0;
202 int error = 0;
203
204 NGI_GET_MSG(item, msg);
205 switch (msg->header.typecookie) {
206 case NGM_PATCH_COOKIE:
207 switch (msg->header.cmd) {
208 case NGM_PATCH_GETCONFIG:
209 if (privp->config == NULL)
210 break;
211 NG_MKRESPONSE(resp, msg,
212 NG_PATCH_CONF_SIZE(privp->config->count), M_WAIT);
213 bcopy(privp->config, resp->data,
214 NG_PATCH_CONF_SIZE(privp->config->count));
215 break;
216 case NGM_PATCH_SETCONFIG:
217 {
218 struct ng_patch_config *newconf;
219 union patch_val *newval;
220
221 if (msg->header.arglen < sizeof(struct ng_patch_config)) {
222 error = EINVAL;
223 break;
224 }
225
226 conf = (struct ng_patch_config *)msg->data;
227 if (msg->header.arglen < NG_PATCH_CONF_SIZE(conf->count)) {
228 error = EINVAL;
229 break;
230 }
231
232 for(i = 0; i < conf->count; i++) {
233 switch(conf->ops[i].length) {
234 case 1:
235 case 2:

--- 7 unchanged lines hidden (view full) ---

243 if (error != 0)
244 break;
245 }
246
247 conf->csum_flags &= CSUM_IP | CSUM_TCP | CSUM_UDP |
248 CSUM_SCTP;
249
250 if (error == 0) {
251 newconf = malloc(NG_PATCH_CONF_SIZE(conf->count),
252 M_NETGRAPH, M_WAIT);
253 newval = malloc(conf->count * sizeof(union patch_val),
254 M_NETGRAPH, M_WAIT);
255 for(i = 0; i < conf->count; i++) {
256 switch (conf->ops[i].length) {
257 case 1:
258 newval[i].v1 = conf->ops[i].value;
259 break;
260 case 2:
261 newval[i].v2 = conf->ops[i].value;
262 break;
263 case 4:
264 newval[i].v4 = conf->ops[i].value;
265 break;
266 case 8:
267 newval[i].v8 = conf->ops[i].value;
268 break;
269 }
270 }
271 bcopy(conf, newconf, NG_PATCH_CONF_SIZE(conf->count));
272 if (privp->val != NULL)
273 free(privp->val, M_NETGRAPH);
274 privp->val = newval;
275 if (privp->config != NULL)
276 free(privp->config, M_NETGRAPH);
277 privp->config = newconf;
278 }
279 break;

--- 25 unchanged lines hidden (view full) ---

305 NG_RESPOND_MSG(error, node, item, resp);
306 NG_FREE_MSG(msg);
307 return(error);
308}
309
310static void
311do_patch(priv_p privp, struct mbuf *m)
312{
313 struct ng_patch_config *conf = privp->config;
314 uint64_t buf;
315 int i, patched = 0;
316
317 for(i = 0; i < conf->count; i++) {
318 if (conf->ops[i].offset + conf->ops[i].length > m->m_pkthdr.len)
319 continue;
320
321 /* for "=" operation we don't need to copy data from mbuf */
322 if (conf->ops[i].mode != NG_PATCH_MODE_SET) {
323 m_copydata(m, conf->ops[i].offset,
324 conf->ops[i].length, (caddr_t)&buf);
325 }
326
327 switch (conf->ops[i].length) {
328 case 1:
329 switch (conf->ops[i].mode) {
330 case NG_PATCH_MODE_SET:
331 *((uint8_t *)&buf) = privp->val[i].v1;
332 break;
333 case NG_PATCH_MODE_ADD:
334 *((uint8_t *)&buf) += privp->val[i].v1;

--- 210 unchanged lines hidden (view full) ---

545 NG_NODE_UNREF(node);
546 free(privdata, M_NETGRAPH);
547 return (0);
548}
549
550static int
551ng_patch_disconnect(hook_p hook)
552{
553 priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
554
555 if (hook == priv->in) {
556 priv->in = NULL;
557 }
558 if (hook == priv->out) {
559 priv->out = NULL;
560 }
561 if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
562 && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) /* already shutting down? */
563 ng_rmnode_self(NG_HOOK_NODE(hook));
564 return (0);
565}
566