我是靠谱客的博主 冷酷奇异果,这篇文章主要介绍【OVS2.5.0源码分析】mirror实现原理(1),现在分享给大家,希望可以做个参考。

端口镜像是交换机的标准功能之一,针对某个端口的报文拷贝到除真实目的之外的另外一个目的地(output),这一篇我们先分析配置mirror之后,如何生成流表,在什么阶段生成流表。

1、xlate_actions函数

复制代码
1
2
3
4
5
mirror_ingress_packet(&ctx); //生成满足入端口的流表生成,即进入该端口的报文会被镜像到其他目的地。 do_xlate_actions(ofpacts, ofpacts_len, &ctx); //解析成精确流表。 针对源端口的mirror,先执行mirror动作,再执行其他操作。 if (ctx.error) { goto exit; }

mirror_ingress_packet函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
static void mirror_ingress_packet(struct xlate_ctx *ctx) { if (mbridge_has_mirrors(ctx->xbridge->mbridge)) { bool warn = ctx->xin->packet != NULL; struct xbundle *xbundle = lookup_input_bundle( ctx->xbridge, ctx->xin->flow.in_port.ofp_port, warn, NULL); if (xbundle) { mirror_packet(ctx, xbundle, //生成mirror的精确流表 xbundle_mirror_src(ctx->xbridge, xbundle)); } } }
mirror_packet函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
static void mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle, mirror_mask_t mirrors) { /* Figure out what VLAN the packet is in (because mirrors can select * packets on basis of VLAN). */ bool warn = ctx->xin->packet != NULL; uint16_t vid = vlan_tci_to_vid(ctx->xin->flow.vlan_tci); if (!input_vid_is_valid(vid, xbundle, warn)) { return; } uint16_t vlan = input_vid_to_vlan(xbundle, vid); const struct xbridge *xbridge = ctx->xbridge; /* Don't mirror to destinations that we've already mirrored to. */ mirrors &= ~ctx->mirrors; //避免出现循环地生成mirror actions if (!mirrors) { return; } if (ctx->xin->resubmit_stats) { mirror_update_stats(xbridge->mbridge, mirrors, ctx->xin->resubmit_stats->n_packets, ctx->xin->resubmit_stats->n_bytes); } if (ctx->xin->xcache) { struct xc_entry *entry; entry = xlate_cache_add_entry(ctx->xin->xcache, XC_MIRROR); entry->u.mirror.mbridge = mbridge_ref(xbridge->mbridge); entry->u.mirror.mirrors = mirrors; } /* 'mirrors' is a bit-mask of candidates for mirroring. Iterate as long as * some candidates remain. */ while (mirrors) { const unsigned long *vlans; mirror_mask_t dup_mirrors; struct ofbundle *out; int out_vlan; /* Get the details of the mirror represented by the rightmost 1-bit. */ bool has_mirror = mirror_get(xbridge->mbridge, raw_ctz(mirrors), //针对该mirror的out端口或者out vlan,两者选其一。 &vlans, &dup_mirrors, &out, &out_vlan); ovs_assert(has_mirror); /* If this mirror selects on the basis of VLAN, and it does not select * 'vlan', then discard this mirror and go on to the next one. */ if (vlans) { ctx->wc->masks.vlan_tci |= htons(VLAN_CFI | VLAN_VID_MASK); } if (vlans && !bitmap_is_set(vlans, vlan)) { mirrors = zero_rightmost_1bit(mirrors); continue; } /* Record the mirror, and the mirrors that output to the same * destination, so that we don't mirror to them again. This must be * done now to ensure that output_normal(), below, doesn't recursively * output to the same mirrors. */ ctx->mirrors |= dup_mirrors; /* Send the packet to the mirror. */ if (out) { struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); struct xbundle *out_xbundle = xbundle_lookup(xcfg, out); if (out_xbundle) { output_normal(ctx, out_xbundle, vlan); //如果是端口,则生成一个output action。 } } else if (vlan != out_vlan && !eth_addr_is_reserved(ctx->xin->flow.dl_dst)) { struct xbundle *xbundle; LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) { if (xbundle_includes_vlan(xbundle, out_vlan) //端口必须包含out vlan && !xbundle_mirror_out(xbridge, xbundle)) { //端口不允许同时作为mirror的output端口 output_normal(ctx, xbundle, out_vlan); //生成一个output action } } } /* output_normal() could have recursively output (to different * mirrors), so make sure that we don't send duplicates. */ mirrors &= ~ctx->mirrors; } }

2、do_xlate_actions函数

复制代码
1
2
3
4
5
6
switch (a->type) { case OFPACT_OUTPUT: xlate_output_action(ctx, ofpact_get_OUTPUT(a)->port, //生成output actions ofpact_get_OUTPUT(a)->max_len, true); break;

3、xlate_ouput_action函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
static void xlate_output_action(struct xlate_ctx *ctx, ofp_port_t port, uint16_t max_len, bool may_packet_in) { ofp_port_t prev_nf_output_iface = ctx->nf_output_iface; ctx->nf_output_iface = NF_OUT_DROP; switch (port) { case OFPP_IN_PORT: compose_output_action(ctx, ctx->xin->flow.in_port.ofp_port, NULL); break; case OFPP_TABLE: xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port, 0, may_packet_in, true); break; case OFPP_NORMAL: xlate_normal(ctx); break; case OFPP_FLOOD: flood_packets(ctx, false); break; case OFPP_ALL: flood_packets(ctx, true); break; case OFPP_CONTROLLER: execute_controller_action(ctx, max_len, (ctx->in_group ? OFPR_GROUP : ctx->in_action_set ? OFPR_ACTION_SET : OFPR_ACTION), 0); break; case OFPP_NONE: break; case OFPP_LOCAL: default: if (port != ctx->xin->flow.in_port.ofp_port) { compose_output_action(ctx, port, NULL); } else { xlate_report(ctx, "skipping output to input port"); } break; } if (prev_nf_output_iface == NF_OUT_FLOOD) { ctx->nf_output_iface = NF_OUT_FLOOD; } else if (ctx->nf_output_iface == NF_OUT_DROP) { ctx->nf_output_iface = prev_nf_output_iface; } else if (prev_nf_output_iface != NF_OUT_DROP && ctx->nf_output_iface != NF_OUT_FLOOD) { ctx->nf_output_iface = NF_OUT_MULTI; } }

4、compose_outpu_action函数

复制代码
1
2
3
4
5
6
7
static void compose_output_action(struct xlate_ctx *ctx, ofp_port_t ofp_port, const struct xlate_bond_recirc *xr) { compose_output_action__(ctx, ofp_port, xr, true); }


compose_output_action__函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
if (mbridge_has_mirrors(ctx->xbridge->mbridge) && xport->xbundle) { //判断output端口是否有mirror,对于patch port,会针对peer重现遍历流表和mirror mirror_packet(ctx, xport->xbundle, //针对output的mirror,类似深度优先原则,嵌套越深的mirror越先执行 xbundle_mirror_dst(xport->xbundle->xbridge, //在output阶段,基于input的mirror规则不被生效 xport->xbundle)); } out: /* Restore flow */ flow->vlan_tci = flow_vlan_tci; flow->pkt_mark = flow_pkt_mark; flow->nw_tos = flow_nw_tos; }







最后

以上就是冷酷奇异果最近收集整理的关于【OVS2.5.0源码分析】mirror实现原理(1)的全部内容,更多相关【OVS2内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部