* Set the BPF program associated with a hook */
| 552 | * Set the BPF program associated with a hook |
| 553 | */ |
| 554 | static int |
| 555 | ng_bpf_setprog(hook_p hook, const struct ng_bpf_hookprog *hp0) |
| 556 | { |
| 557 | const hinfo_p hip = NG_HOOK_PRIVATE(hook); |
| 558 | struct ng_bpf_hookprog *hp; |
| 559 | #ifdef BPF_JITTER |
| 560 | bpf_jit_filter *jit_prog; |
| 561 | #endif |
| 562 | int size; |
| 563 | |
| 564 | /* Check program for validity */ |
| 565 | if (hp0->bpf_prog_len > bpf_maxinsns || |
| 566 | !bpf_validate(hp0->bpf_prog, hp0->bpf_prog_len)) |
| 567 | return (EINVAL); |
| 568 | |
| 569 | /* Make a copy of the program */ |
| 570 | size = NG_BPF_HOOKPROG_SIZE(hp0->bpf_prog_len); |
| 571 | hp = malloc(size, M_NETGRAPH_BPF, M_NOWAIT); |
| 572 | if (hp == NULL) |
| 573 | return (ENOMEM); |
| 574 | bcopy(hp0, hp, size); |
| 575 | #ifdef BPF_JITTER |
| 576 | jit_prog = bpf_jitter(hp->bpf_prog, hp->bpf_prog_len); |
| 577 | #endif |
| 578 | |
| 579 | /* Free previous program, if any, and assign new one */ |
| 580 | if (hip->prog != NULL) |
| 581 | free(hip->prog, M_NETGRAPH_BPF); |
| 582 | hip->prog = hp; |
| 583 | #ifdef BPF_JITTER |
| 584 | if (hip->jit_prog != NULL) |
| 585 | bpf_destroy_jit_filter(hip->jit_prog); |
| 586 | hip->jit_prog = jit_prog; |
| 587 | #endif |
| 588 | |
| 589 | /* Prepare direct references on target hooks. */ |
| 590 | hip->match = ng_findhook(NG_HOOK_NODE(hook), hip->prog->ifMatch); |
| 591 | hip->nomatch = ng_findhook(NG_HOOK_NODE(hook), hip->prog->ifNotMatch); |
| 592 | return (0); |
| 593 | } |
no test coverage detected