VPP应用

本篇从vpp 18.01应用开始着手,开始了解vpp框架的使用

要了解vpp框架,需要抓住几点了解vpp:

1. vpp命令行注册,命令行回调开关可打开对应node功能;

2. plugin,feature,function初始化,main函数初始化调用;

3. node注册,报文接收到后回调。

本篇实现一个node抓包功能,并打印出来,plugin编译加载,命令行配置后生效,disable后失效。

1. 注册命令行,plugin及function

#ifndef __included_ck_sample_h__
#define __included_ck_sample_h__

#include <vnet/vnet.h>
#include <vnet/ip/ip.h>

#include <vppinfra/hash.h>
#include <vppinfra/error.h>
#include <vppinfra/elog.h>

typedef struct {
    /* API message ID base */
    u16 msg_id_base;

    /* convenience */
    vnet_main_t * vnet_main;
} ck_sample_main_t;

extern ck_sample_main_t ck_sample_main;

extern vlib_node_registration_t ck_sample_node;

#define CK_SAMPLE_PLUGIN_BUILD_VER "1.0"

#endif /* __included_ck_sample_h__ */
#include <vnet/plugin/plugin.h>
#include <pktdump/pktdump.h>

/* vnet_main_t注册*/
ck_sample_main_t ck_sample_main;

/* 命令行开关*/
int ck_sample_enable_disable(u32 sw_if_index, int enable)
{
        if (pool_is_free_index (ck_sample_main.vnet_main->interface_main.sw_interfaces, 
                                sw_if_index))
                return VNET_API_ERROR_INVALID_SW_IF_INDEX;

        vnet_feature_enable_disable("ip4-unicast",
                "ck_sample",
                sw_if_index, enable, 0, 0);
        return 0;
}


static clib_error_t*
ck_sample_enable_disable_command_fn(vlib_main_t* vm,
                                    unformat_input_t *input,
                                    vlib_cli_command_t *cmd)
{
        u32 sw_if_index = ~0;
        int enable_disable = 1;

        while(unformat_check_input(input) != UNFORMAT_END_OF_INPUT) {
				/* 命令行关闭*/
                if (unformat(input, "disable"))
                        enable_disable = 0;
				/* 接口索引获取*/
                else if (unformat(input, "%U",
                        unformat_vnet_sw_interface,
                        ck_sample_main.vnet_main, &sw_if_index));
                else
                        break;
        }

        if (sw_if_index == ~0)
                return clib_error_return(0, "Please specify an interface...");
		
        ck_sample_enable_disable(sw_if_index, enable_disable);

        return 0;
}

/*命令行注册及函数回调*/
VLIB_CLI_COMMAND (ck_sample_command, static) = {
    .path = "pkt dump",
    .short_help = 
    "pkt dump <interface-name> [disable]",
    .function = ck_sample_enable_disable_command_fn,
};

/*插件注册*/
VLIB_PLUGIN_REGISTER () = {
    .version = CK_SAMPLE_PLUGIN_BUILD_VER,
    .description = "Sample of VPP Plugin",
};

static clib_error_t *ck_sample_init(vlib_main_t* vm)
{
	ck_sample_main.vnet_main = vnet_get_main();
	return 0;
}
/* FUNCTION注册*/
VLIB_INIT_FUNCTION(ck_sample_init);
/*featrure注册*/
VNET_FEATURE_INIT(ck_sample, static) = 
{
	.arc_name = "ip4-unicast",
	.node_name = "ck_sample",
	.runs_before = VNET_FEATURES("ip4-lookup"),
};

2. 注册node节点

#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/pg/pg.h>
#include <vnet/ethernet/ethernet.h>
#include <vppinfra/error.h>
#include <pktdump/pktdump.h>

typedef enum
{
  CK_SAMPLE_NEXT_IP4,
  CK_SAMPLE_DROP,
  CK_SAMPLE_NEXT_N,
} ck_sample_next_t;

typedef struct
{
  u32 next_index;
  u32 sw_if_index;
  u8 new_src_mac[6];
  u8 new_dst_mac[6];
} ck_sample_trace_t;

#define foreach_ck_sample_error \
_(SHOWED, "show packets processed")

typedef enum
{
#define _(sym,str) SAMPLE_ERROR_##sym,
  foreach_ck_sample_error
#undef _
    SAMPLE_N_ERROR,
} ck_ssample_error_t;


static char *ck_sample_error_strings[] = {
#define _(sym, str) str,
        foreach_ck_sample_error
#undef _
};

extern vlib_node_registration_t ck_sample_node;

static u8 *
format_ck_sample_trace (u8 * s, va_list * args)
{
        s = format(s, "To Do!\n");
        return s;
}

/* node的function处理*/
static uword ck_sample_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node,
        vlib_frame_t * frame)
{
        u32 n_left_from, *from, *to_next;
        ck_sample_next_t     next_index;

        from        = vlib_frame_vector_args(frame);
        n_left_from = frame->n_vectors;
        next_index  = node->cached_next_index;

        while(n_left_from > 0){
                u32 n_left_to_next;
                vlib_get_next_frame(vm, node, next_index, to_next, n_left_to_next);

                while(n_left_from > 0 && n_left_to_next > 0){
                        vlib_buffer_t  *b0;
                        u32             bi0, next0 = 0;

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

                        b0 = vlib_get_buffer(vm, bi0);
                        
						void *en0 = vlib_buffer_get_current(b0);
                        int i = 0;
                        for (i = 0; i < 20 i++)
                        {
                        	printf("%02x ", *(u8*)(en0+i));
                        }
                        printf("\n");
                        vlib_validate_buffer_enqueue_x1(vm, node, next_index,
                                to_next, n_left_to_next, bi0, next0);
                }

                vlib_put_next_frame(vm, node, next_index, n_left_to_next);
        }

        return frame->n_vectors;
}

/* VLIB NODE注册*/
VLIB_REGISTER_NODE (ck_sample_node) = {
        .name		= "ck_sample",
        .function       = ck_sample_node_fn,
        .vector_size    = sizeof(u32),
        .format_trace   = format_ck_sample_trace,
        .type           = VLIB_NODE_TYPE_INTERNAL,
        .n_errors       = ARRAY_LEN(ck_sample_error_strings),
        .error_strings  = ck_sample_error_strings,
        .n_next_nodes   = CK_SAMPLE_NEXT_N,
        .next_nodes     = {
                [CK_SAMPLE_NEXT_IP4]    = "ip4-lookup",
                [CK_SAMPLE_DROP]        = "error-drop",
        },
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值