如何在VPP中添加graph node

参照VPP自带的example,写一个自己的graph node。

1. 定义打印trace时使用的参数。

typedef struct {
u32 sw_if_index;
u8 is_fragment;
u8 is_inner;
u8 protocol;
u32 dst_vm;
i32 port;
} abc_icmp_classify_trace_t;

2. 声明registration函数。

vlib_node_registration_t abc_icmp_classify_node;

3. 打印trace函数实现。

static u8 * format_abc_icmp_classify_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  abc_icmp_classify_trace_t * t = va_arg (*args, abc_icmp_classify_trace_t *);

  s = format (s, "abc_icmp_classify: sw_if_index %d is_fragment %d has_inner %d protocol %x dst_vm %x port %d",
              t->sw_if_index, t->is_fragment, t->is_inner, t->protocol, t->dst_vm, t->port);

  return s;
}
4. 定义下一个node。

typedef enum
{
    ABC_ICMP_CLASSIFY_ERROR_DROP,
        ABC_ICMP_CLASSIFY_NEXT_L4_REASS,
        ABC_ICMP_CLASSIFY_NEXT_PING_REPLY,
        ABC_ICMP_CLASSIFY_NEXT_L2_LEARN,
        ABC_ICMP_CLASSIFY_N_NEXT
} abc_icmp_classify_next_t;
5. 真正实现该node功能的函数。

abc_icmp_classify_fn (vlib_main_t * vm,
                      vlib_node_runtime_t * node,
                      vlib_frame_t * frame)
{
    u32 n_left_from, * from, * to_next;
    abc_icmp_classify_next_t next_index;
    vlib_node_runtime_t *error_node = vlib_node_get_runtime (vm, abc_icmp_classify_node.index);
    from = vlib_frame_vector_args (frame);
    n_left_from = frame->n_vectors;
    next_index = node->cached_next_index;
    u8  dst_vm = NOT_FOUND;
    u8 flag_frag = 0, flag_inner = 0;
    i32  port0 = 0;
    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)
       {
          u32 bi0;
          vlib_buffer_t * b0;
          ethernet_header_t *en0;
          ip4_header_t *ip0;
          u8 error0 = ABC_L4_ERROR_NONE;
          /* speculatively enqueue b0 to the current next frame */
              bi0 = from[0];
              to_next[0] = bi0;
              from += 1;
              to_next += 1;
              n_left_from -= 1;
              n_left_to_next -= 1;
              u32 next0 = ABC_ICMP_CLASSIFY_NEXT_L2_LEARN;
              b0 = vlib_get_buffer (vm, bi0);
              ...
         if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE) && (b0->flags & VLIB_BUFFER_IS_TRACED))) {
              abc_icmp_classify_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
                               t->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_RX];
                               t->is_fragment = flag_frag;
                               t->is_inner = flag_inner;
                               t->protocol = ip0->protocol;
                               t->dst_vm = dst_vm;
                               t->port = port0;


          }
          next0 = (error0 == ABC_L4_ERROR_NONE) ? next0 : ABC_ICMP_CLASSIFY_ERROR_DROP;
          /* verify speculative enqueue, maybe switch current next frame */
           b0->error = error_node->errors[error0];
           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;
}
6. register新node。

VLIB_REGISTER_NODE (abc_icmp_classify_node) = {
  .function = abc_icmp_classify_fn,
  .name = "abc-icmp-classify",
  .vector_size = sizeof (u32),
  .format_trace = format_abc_icmp_classify_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,
  .n_errors = ABC_L4_N_ERROR,
  .error_strings = abc_l4_error_strings,
  .n_next_nodes = ABC_ICMP_CLASSIFY_N_NEXT,
  .next_nodes = {

                [ABC_ICMP_CLASSIFY_NEXT_L4_REASS] = "abc-l4-reass",
                [ABC_ICMP_CLASSIFY_NEXT_PING_REPLY] = "abc-ping-reply",
                [ABC_ICMP_CLASSIFY_NEXT_L2_LEARN] = "l2-learn",
                [ABC_ICMP_CLASSIFY_ERROR_DROP] = "error-drop",

  }
};
7. 放到某个feature中

VNET_FEATURE_INIT (abc_icmp_classify, static) = {
  .arc_name = "device-input",
  .node_name = "abc-icmp-classify",
};






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值