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 208989 2010-06-10 16:45:30Z ae $");
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/ctype.h>
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
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,
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
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, *newconf;
199 union patch_val *newval;
200 struct ng_mesg *msg;
201 struct ng_mesg *resp;
202 int i, clear, error;
203
204 clear = error = 0;
205 resp = NULL;
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 {
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;
227 if (msg->header.arglen <
228 NG_PATCH_CONF_SIZE(conf->count)) {
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) {
252 newconf = malloc(
253 NG_PATCH_CONF_SIZE(conf->count),
254 M_NETGRAPH, M_WAIT);
255 newval = malloc(conf->count *
256 sizeof(union patch_val), M_NETGRAPH,
257 M_WAIT);
258 for(i = 0; i < conf->count; i++) {
259 switch (conf->ops[i].length) {
260 case 1:
261 newval[i].v1 =
262 conf->ops[i].value;
263 break;
264 case 2:
265 newval[i].v2 =
266 conf->ops[i].value;
267 break;
268 case 4:
269 newval[i].v4 =
270 conf->ops[i].value;
271 break;
272 case 8:
273 newval[i].v8 =
274 conf->ops[i].value;
275 break;
276 }
277 }
278 bcopy(conf, newconf,
279 NG_PATCH_CONF_SIZE(conf->count));
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{
321 struct ng_patch_config *conf;
322 uint64_t buf;
323 int i, patched;
324
325 conf = privp->config;
326 patched = 0;
327 for(i = 0; i < conf->count; i++) {
328 if (conf->ops[i].offset + conf->ops[i].length >
329 m->m_pkthdr.len)
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 }
337
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{
564 priv_p priv;
565
566 priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
567 if (hook == priv->in) {
568 priv->in = NULL;
569 }
570 if (hook == priv->out) {
571 priv->out = NULL;
572 }
573 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
574 NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */
575 ng_rmnode_self(NG_HOOK_NODE(hook));
576 return (0);
577}
578