| 488 | } |
| 489 | |
| 490 | static int |
| 491 | bpf_eth_elf_load(struct bpf_eth_cbh *cbh, uint16_t port, uint16_t queue, |
| 492 | const struct rte_bpf_prm *prm, const char *fname, const char *sname, |
| 493 | uint32_t flags) |
| 494 | { |
| 495 | int32_t rc; |
| 496 | struct bpf_eth_cbi *bc; |
| 497 | struct rte_bpf *bpf; |
| 498 | rte_rx_callback_fn frx; |
| 499 | rte_tx_callback_fn ftx; |
| 500 | struct rte_bpf_jit jit; |
| 501 | |
| 502 | frx = NULL; |
| 503 | ftx = NULL; |
| 504 | |
| 505 | if (prm == NULL || rte_eth_dev_is_valid_port(port) == 0 || |
| 506 | queue >= RTE_MAX_QUEUES_PER_PORT) |
| 507 | return -EINVAL; |
| 508 | |
| 509 | if (cbh->type == BPF_ETH_RX) |
| 510 | frx = select_rx_callback(prm->prog_arg.type, flags); |
| 511 | else |
| 512 | ftx = select_tx_callback(prm->prog_arg.type, flags); |
| 513 | |
| 514 | if (frx == NULL && ftx == NULL) { |
| 515 | RTE_BPF_LOG(ERR, "%s(%u, %u): no callback selected;\n", |
| 516 | __func__, port, queue); |
| 517 | return -EINVAL; |
| 518 | } |
| 519 | |
| 520 | bpf = rte_bpf_elf_load(prm, fname, sname); |
| 521 | if (bpf == NULL) |
| 522 | return -rte_errno; |
| 523 | |
| 524 | rte_bpf_get_jit(bpf, &jit); |
| 525 | |
| 526 | if ((flags & RTE_BPF_ETH_F_JIT) != 0 && jit.func == NULL) { |
| 527 | RTE_BPF_LOG(ERR, "%s(%u, %u): no JIT generated;\n", |
| 528 | __func__, port, queue); |
| 529 | rte_bpf_destroy(bpf); |
| 530 | return -ENOTSUP; |
| 531 | } |
| 532 | |
| 533 | /* setup/update global callback info */ |
| 534 | bc = bpf_eth_cbh_add(cbh, port, queue); |
| 535 | if (bc == NULL) |
| 536 | return -ENOMEM; |
| 537 | |
| 538 | /* remove old one, if any */ |
| 539 | if (bc->cb != NULL) |
| 540 | bpf_eth_unload(cbh, port, queue); |
| 541 | |
| 542 | bc->bpf = bpf; |
| 543 | bc->jit = jit; |
| 544 | |
| 545 | if (cbh->type == BPF_ETH_RX) |
| 546 | bc->cb = rte_eth_add_rx_callback(port, queue, frx, bc); |
| 547 | else |
no test coverage detected