OpenNetVM supports 2 modes, by default NFs use the packet_handler callback function that processes packets 1 by 1. The second is the advanced rings mode which gives the NF full control of its rings and allows the developer to do anything they want.
The Bridge NF is a simple example illustrating this process.
- First step is initializing the onvm context
struct onvm_nf_local_ctx *nf_local_ctx;
nf_local_ctx = onvm_nflib_init_nf_local_ctx();
This configures basic meta data the NF.
- Start the signal handler
onvm_nflib_start_signal_handler(nf_local_ctx, NULL);
This ensures signals will be caught to correctly shut down the NF (i.e., to notify the manager).
- Define the function table for the NF
struct onvm_nf_function_table *nf_function_table;
nf_function_table = onvm_nflib_init_nf_function_table();
nf_function_table->pkt_handler = &packet_handler;
nf_function_table->setup = &nf_setup;
The pkt_handler
call back will be executed on each packet arrival. The setup
function is called only once after the NF is initialized.
- Initialize ONVM and adjust the argc, argv based on the return value.
if ((arg_offset = onvm_nflib_init(argc, argv, NF_TAG, nf_local_ctx, nf_function_table)) < 0) {
onvm_nflib_stop(nf_local_ctx);
if (arg_offset == ONVM_SIGNAL_TERMINATION) {
printf("Exiting due to user termination\n");
return 0;
} else {
rte_exit(EXIT_FAILURE, "Failed ONVM init\n");
}
}
argc -= arg_offset;
argv += arg_offset;
This initializes DPDK and notifies the Manager that a new NF is starting.
- Parse NF specific args
nf_info = nf_context->nf_info;
if (parse_app_args(argc, argv, progname) < 0) {
onvm_nflib_stop(nf_context);
rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n");
}
- Run the NF
onvm_nflib_run(nf_local_ctx);
This will cause the NF to enter the run loop, trigger a callback on each new packet.
- Stop the NF
onvm_nflib_stop(nf_local_ctx);
The scaling NF provides a clear separation of the two modes and can be found here.
- First step is initializing the onvm context
struct onvm_nf_local_ctx *nf_local_ctx;
nf_local_ctx = onvm_nflib_init_nf_local_ctx();
- Start the signal handler
onvm_nflib_start_signal_handler(nf_local_ctx, NULL);
- Contrary to default rings Next we don't need to define the function table
- Initialize ONVM and adjust the argc, argv based on the return value.
if ((arg_offset = onvm_nflib_init(argc, argv, NF_TAG, nf_local_ctx, NULL)) < 0) {
onvm_nflib_stop(nf_local_ctx);
if (arg_offset == ONVM_SIGNAL_TERMINATION) {
printf("Exiting due to user termination\n");
return 0;
} else {
rte_exit(EXIT_FAILURE, "Failed ONVM init\n");
}
}
argc -= arg_offset;
argv += arg_offset;
- Parse NF specific args
nf_info = nf_context->nf_info;
if (parse_app_args(argc, argv, progname) < 0) {
onvm_nflib_stop(nf_context);
rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n");
}
- To start packet processing run this function to let onvm mgr know that NF is running (instead of onvm_nflib_run in default mode
onvm_nflib_nf_ready(nf_context->nf);
- Stop the NF
onvm_nflib_stop(nf_local_ctx);
If the NF needs additional NF state data it can be put into the data field, this is NF specific and won't be altered by onvm_nflib functions. This can be defined after the onvm_nflib_init
has finished
nf_local_ctx->nf->data = (void *)rte_malloc("nf_state_data", sizeof(struct custom_state_data), 0);