Slide 14
Slide 14 text
int override_ethernet_input(vlib_main_t *vm){
vlib_node_t *node = vlib_get_node_by_name(vlib_get_main(), “ethernet-input”);
vlib_node_runtime_t *runtime = vlib_node_get_runtime(vm, node->index);
tap_mirror_main_t *xm = tap_mirror_get_main();
xm->target_fn = runtime->function; //override元を退避
runtime->function = tap_mirror_input_fn;
return 0;
}
overrideの設定をする部分
uint64_t tap_mirror_input_fn(vlib_main_t *vm,
vlib_node_runtime_t *node,vlib_frame_t *f){
uint32_t *pkts = vlib_frame_vector_args (f);
for (uint32_t i = 0; i < f->n_vectors; ++i) {
uint32_t clones[2];
vlib_buffer_clone (vm, pkts[i], clones, 2, VLIB_BUFFER_CLONE_HEAD_SIZE);
vlib_buffer_t *b = vlib_get_buffer (vm, clones[2]);
vlib_buffer_advance (b, -b->current_data);
write(xm->tap_fd,vlib_buffer_get_current(b),vlib_buffer_length_in_chain(vm, b));
vlib_buffer_free (vm, &xm->clones[thread_index][1], 1);
}
tap_mirror_main_t *xm = tap_mirror_get_main();
return xm->target_fn(vm, node, f);
}
14
パケット処理機能の拡張(2): feature arcs
VPP internal for Dummies
各ノードの実行される関数はvlib_node_runtimeオブジェクトか
ら取得可能, 上書き可能で, これは各ノード名から受け取ることが
できる.
以下は任意のノードの関数実行前に独自の関数を挿入する関数.
パケットをcloneしてからtap_fdに書き込んで, cloneで追加した
分だけfreeをする. 基本的な考えはDPDKと同様でよいが, clone
の仕様が少しだけ違うので注意が必要.
この例はinlineで処理しているがこれにより性能ダウンする.
実際のtap-mirrorではvlib_bufferを別threadに渡してからtap
書き込みをおこおなう.
この方法なら既存のnodeのコンテキストで動くのでスレッドとか追
加しなくて良い.
実際にoverrideされた場所で呼び出される処理