ZBLOG

实现一个vpp plugin例子

下面是一个简单的vpp插件示例,该插件使用VLIB库来处理IPv4数据包并输出打印消息:

  1. 定义插件的输入和输出结构体。在这个例子中,我们定义了input_structure_t和output_structure_t结构体,用于输入和输出数据:
typedef struct {
    u32 data;
} input_structure_t;

typedef struct {
    u8 message[256];
} output_structure_t;
  1. 编写插件代码。在这个例子中,我们编写了ipv4_hello_world.c文件,其中包含了整个插件的实现。具体代码如下:
#include <vnet/plugin/plugin.h>
#include <vnet/ip/ip.h>

typedef struct {
    u32 data;
} input_structure_t;

typedef struct {
    u8 message[256];
} output_structure_t;

typedef struct {
    u32 next_index;
} ipv4_hello_world_trace_t;

/* packet trace format function */
static u8 * format_ipv4_hello_world_trace (u8 * s, va_list * args) {
    return s;
}

/* trace config structure */
typedef struct {
    /* per-packet trace data */
    ipv4_hello_world_trace_t *traces;
    /* packet buffer flags */
    u8 *buffer_flags;
} ipv4_hello_world_trace_config_t;

/* stats */
#define foreach_ipv4_hello_world_error \
_(NONE, "No error") \
_(DROP, "Drop packets")

typedef enum {
#define _(sym,str) IPV4_HELLO_WORLD_ERROR_##sym,
    foreach_ipv4_hello_world_error
#undef _
    IPV4_HELLO_WORLD_N_ERROR,
} ipv4_hello_world_error_t;

static char * ipv4_hello_world_error_strings[] = {
#define _(sym,string) string,
    foreach_ipv4_hello_world_error
#undef _
};

typedef struct {
    /* counter for dropped packets */
    vlib_simple_counter_main_t drop_counters;
} ipv4_hello_world_main_t;

/* packet processing function */
static uword ipv4_hello_world_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) {
    u32 n_left_from, *from, *to_next;
    ipv4_hello_world_main_t *hwm = &ipv4_hello_world_main;
    vlib_node_t *n = vlib_get_node_by_name (vm, (u8 *) "ipv4-hello-world");

    /* get input/output buffer index */
    u32 input_buffer_index = vlib_frame_vector_args (frame);
    u32 output_buffer_index = vlib_frame_alloc_output_buffer (vm, &to_next, frame, 1);

    from = vlib_frame_vector_args (frame);
    n_left_from = frame->n_vectors;

    while (n_left_from > 0) {

        u32 n_left_to_next = VLIB_FRAME_SIZE - to_next;

        while (n_left_from > 0 && n_left_to_next > 0) {

            u32 bi0;
            vlib_buffer_t *b0;
            input_structure_t *input_data;
            output_structure_t *output_data;
            int next_index = 0;

            bi0 = from[0];
            from += 1;
            n_left_from -= 1;

            b0 = vlib_get_buffer (vm, bi0);

            /* get input buffer data */
            input_data = vlib_buffer_get_current (b0);

            /* get output buffer data */
            output_data = vlib_buffer_get_current (vm->buffers[output_buffer_index]);

            /* copy message to output */
            snprintf ((char *)output_data->message, sizeof(output_data->message), "Hello world! Data: %d", input_data->data);

            /* set next node index */
            next_index = n->next_nodes[0];

            /* send packet to next node */
            to_next[0] = bi0;
            to_next += 1;
            n_left_to_next -= 1;

            vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
                                             n_left_to_next, bi0, output_buffer_index, 0);
        }
    }

    /* send packets to the next node */
    vlib_put_next_frame (vm, node, n->index, frame->n_vectors);

    return frame->n_vectors;
}

/* register nodes and create arcs */
static clib_error_t * ipv4_hello_world_init (vlib_main_t * vm) {

    /* declare node functions */
    vlib_node_t *node = &ipv4_hello_world_node;
    vlib_node_register (vm, node);

    /* set node flags */
    node->flags |= VLIB_NODE_FLAG_TRACE_SUPPORTED;
    node->function = ipv4_hello_world_node_fn;

    /* register input/output structs */
    vlib_register_input_node (vm, node->index, VLIB_NODE_STATE_DISABLED, 1, sizeof(input_structure_t), NULL);
    vlib_register_output_node (vm, node->index, VLIB_NODE_STATE_DISABLED, 1, sizeof(output_structure_t), NULL);

    return 0;
}

VLIB_INIT_FUNCTION (ipv4_hello_world_init);
  1. 将插件添加到vpp中。我们可以将上面的代码保存在$VPP_ROOT/plugins/ipv4_hello_world目录下,并使用以下命令来构建插件:
$ cd $VPP_ROOT
$ make build
  1. 在vpp中测试插件。可以使用以下命令来启用插件并测试它:
$ vppctl
# set interface ip address GigabitEthernet0/8/0 10.0.0.1/24
# create host-interface name test-hif
# set int state test-hif up
# set int l2 bridge test-hif 1 bvi
# set int ip address test-bvi 10.0.1.1/24
# trace add node ipv4-hello-world
# ping 10.0.1.2 verbose

在上面的代码中,我们添加了一个名为ipv4-hello-world的新节点,并使用trace add命令跟踪该节点。然后,我们ping测试10.0.1.2,并查看输出结果。

  1. 调试和优化插件。确保插件可以正常运行,并使用调试工具和技术来优化其性能和可靠性。

  2. 发布插件。如果插件被认为是有价值的,则可以将其发布到VPP社区中,并与其他开发者共享。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=376

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?