ng_patch.c (208946) | ng_patch.c (208989) |
---|---|
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> | 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 $"); | 29__FBSDID("$FreeBSD: head/sys/netgraph/ng_patch.c 208989 2010-06-10 16:45:30Z ae $"); |
30 31#include <sys/param.h> 32#include <sys/kernel.h> | 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> | 33#include <sys/ctype.h> |
36#include <sys/errno.h> | |
37#include <sys/endian.h> /* be64toh(), htobe64() */ | 34#include <sys/endian.h> /* be64toh(), htobe64() */ |
35#include <sys/errno.h> 36#include <sys/malloc.h> 37#include <sys/mbuf.h> |
|
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 | 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)) | 50#define OFFSETOF(s, e) ((char *)&((s *)0)->e - (char *)((s *)0)) |
51 52static int | 51 52static int |
53ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, 54 const u_char *buf) | 53ng_patch_config_getlen(const struct ng_parse_type *type, 54 const u_char *start, 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 | 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) + \ | 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); | 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; | 198 struct ng_patch_config *conf, *newconf; 199 union patch_val *newval; |
199 struct ng_mesg *msg; | 200 struct ng_mesg *msg; |
200 struct ng_mesg *resp = NULL; 201 int i, clear = 0; 202 int error = 0; | 201 struct ng_mesg *resp; 202 int i, clear, error; |
203 | 203 |
204 clear = error = 0; 205 resp = NULL; |
|
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 { | 206 NGI_GET_MSG(item, msg); 207 switch (msg->header.typecookie) { 208 case NGM_PATCH_COOKIE: 209 switch (msg->header.cmd) { 210 case NGM_PATCH_GETCONFIG: 211 if (privp->config == NULL) 212 break; 213 NG_MKRESPONSE(resp, msg, 214 NG_PATCH_CONF_SIZE(privp->config->count), M_WAIT); 215 bcopy(privp->config, resp->data, 216 NG_PATCH_CONF_SIZE(privp->config->count)); 217 break; 218 case NGM_PATCH_SETCONFIG: 219 { |
218 struct ng_patch_config *newconf; 219 union patch_val *newval; 220 221 if (msg->header.arglen < sizeof(struct ng_patch_config)) { | 220 if (msg->header.arglen < 221 sizeof(struct ng_patch_config)) { |
222 error = EINVAL; 223 break; 224 } 225 226 conf = (struct ng_patch_config *)msg->data; | 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)) { | 227 if (msg->header.arglen < 228 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) { | 229 error = EINVAL; 230 break; 231 } 232 233 for(i = 0; i < conf->count; i++) { 234 switch(conf->ops[i].length) { 235 case 1: 236 case 2: --- 7 unchanged lines hidden (view full) --- 244 if (error != 0) 245 break; 246 } 247 248 conf->csum_flags &= CSUM_IP | CSUM_TCP | CSUM_UDP | 249 CSUM_SCTP; 250 251 if (error == 0) { |
251 newconf = malloc(NG_PATCH_CONF_SIZE(conf->count), | 252 newconf = malloc( 253 NG_PATCH_CONF_SIZE(conf->count), |
252 M_NETGRAPH, M_WAIT); | 254 M_NETGRAPH, M_WAIT); |
253 newval = malloc(conf->count * sizeof(union patch_val), 254 M_NETGRAPH, M_WAIT); | 255 newval = malloc(conf->count * 256 sizeof(union patch_val), M_NETGRAPH, 257 M_WAIT); |
255 for(i = 0; i < conf->count; i++) { 256 switch (conf->ops[i].length) { 257 case 1: | 258 for(i = 0; i < conf->count; i++) { 259 switch (conf->ops[i].length) { 260 case 1: |
258 newval[i].v1 = conf->ops[i].value; | 261 newval[i].v1 = 262 conf->ops[i].value; |
259 break; 260 case 2: | 263 break; 264 case 2: |
261 newval[i].v2 = conf->ops[i].value; | 265 newval[i].v2 = 266 conf->ops[i].value; |
262 break; 263 case 4: | 267 break; 268 case 4: |
264 newval[i].v4 = conf->ops[i].value; | 269 newval[i].v4 = 270 conf->ops[i].value; |
265 break; 266 case 8: | 271 break; 272 case 8: |
267 newval[i].v8 = conf->ops[i].value; | 273 newval[i].v8 = 274 conf->ops[i].value; |
268 break; 269 } 270 } | 275 break; 276 } 277 } |
271 bcopy(conf, newconf, NG_PATCH_CONF_SIZE(conf->count)); | 278 bcopy(conf, newconf, 279 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{ | 280 if (privp->val != NULL) 281 free(privp->val, M_NETGRAPH); 282 privp->val = newval; 283 if (privp->config != NULL) 284 free(privp->config, M_NETGRAPH); 285 privp->config = newconf; 286 } 287 break; --- 25 unchanged lines hidden (view full) --- 313 NG_RESPOND_MSG(error, node, item, resp); 314 NG_FREE_MSG(msg); 315 return(error); 316} 317 318static void 319do_patch(priv_p privp, struct mbuf *m) 320{ |
313 struct ng_patch_config *conf = privp->config; | 321 struct ng_patch_config *conf; |
314 uint64_t buf; | 322 uint64_t buf; |
315 int i, patched = 0; | 323 int i, patched; |
316 | 324 |
325 conf = privp->config; 326 patched = 0; |
|
317 for(i = 0; i < conf->count; i++) { | 327 for(i = 0; i < conf->count; i++) { |
318 if (conf->ops[i].offset + conf->ops[i].length > m->m_pkthdr.len) | 328 if (conf->ops[i].offset + conf->ops[i].length > 329 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 } | 330 continue; 331 332 /* for "=" operation we don't need to copy data from mbuf */ 333 if (conf->ops[i].mode != NG_PATCH_MODE_SET) { 334 m_copydata(m, conf->ops[i].offset, 335 conf->ops[i].length, (caddr_t)&buf); 336 } |
326 | 337 |
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{ | 338 switch (conf->ops[i].length) { 339 case 1: 340 switch (conf->ops[i].mode) { 341 case NG_PATCH_MODE_SET: 342 *((uint8_t *)&buf) = privp->val[i].v1; 343 break; 344 case NG_PATCH_MODE_ADD: 345 *((uint8_t *)&buf) += privp->val[i].v1; --- 210 unchanged lines hidden (view full) --- 556 NG_NODE_UNREF(node); 557 free(privdata, M_NETGRAPH); 558 return (0); 559} 560 561static int 562ng_patch_disconnect(hook_p hook) 563{ |
553 priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); | 564 priv_p priv; |
554 | 565 |
566 priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); |
|
555 if (hook == priv->in) { 556 priv->in = NULL; 557 } 558 if (hook == priv->out) { 559 priv->out = NULL; 560 } | 567 if (hook == priv->in) { 568 priv->in = NULL; 569 } 570 if (hook == priv->out) { 571 priv->out = NULL; 572 } |
561 if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 562 && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) /* already shutting down? */ | 573 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 && 574 NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */ |
563 ng_rmnode_self(NG_HOOK_NODE(hook)); 564 return (0); 565} 566 | 575 ng_rmnode_self(NG_HOOK_NODE(hook)); 576 return (0); 577} 578 |