OVS实现mirror功能时,限制了out端口的通信能力。
1、限制mirror out端口通信总结
xlate_normal_flood函数
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16static void xlate_normal_flood(struct xlate_ctx *ctx, struct xbundle *in_xbundle, uint16_t vlan) { struct xbundle *xbundle; LIST_FOR_EACH (xbundle, list_node, &ctx->xbridge->xbundles) { if (xbundle != in_xbundle && xbundle_includes_vlan(xbundle, vlan) && xbundle->floodable && !xbundle_mirror_out(ctx->xbridge, xbundle)) { //作为mirror out端口不允许以normal flood方式发包报文到该端口 output_normal(ctx, xbundle, vlan); } } ctx->nf_output_iface = NF_OUT_FLOOD; }
xlate_normal函数
复制代码
1
2
3
4
5
6
7
8
9
10
11/* Drop frames on bundles reserved for mirroring. */ if (xbundle_mirror_out(ctx->xbridge, in_xbundle)) { //如果报文入端口,也同时是mirror的out端口,则丢弃该报文 if (ctx->xin->packet != NULL) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_WARN_RL(&rl, "bridge %s: dropping packet received on port " "%s, which is reserved exclusively for mirroring", ctx->xbridge->name, in_xbundle->name); } xlate_report(ctx, "input port is mirror output port, dropping"); return; }
复制代码
总结一下,1)作为mirror out端口,不能通过normal规则进行通信;2)recircle下,报文的input端口也不能是mirror out端口;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21if (!xin->recirc && process_special(&ctx, in_port)) { /* process_special() did all the processing for this packet. * * We do not perform special processing on recirculated packets, as * recirculated packets are not really received by the bridge.*/ } else if (in_port && in_port->xbundle && xbundle_mirror_out(xbridge, in_port->xbundle)) { //如果报文入端口,也同时是mirror的out端口,则丢弃该报文 if (ctx.xin->packet != NULL) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_WARN_RL(&rl, "bridge %s: dropping packet received on port " "%s, which is reserved exclusively for mirroring", ctx.xbridge->name, in_port->xbundle->name); } } else { /* Sampling is done only for packets really received by the bridge. */ unsigned int user_cookie_offset = 0; if (!xin->recirc) { user_cookie_offset = compose_sflow_action(&ctx); compose_ipfix_action(&ctx, ODPP_NONE); } size_t sample_actions_len = ctx.odp_actions->size;
2、mirror out加速实现
复制代码
1
2
3
4
5
6
7static mirror_mask_t xbundle_mirror_out(const struct xbridge *xbridge, struct xbundle *xbundle) { return xbundle != &ofpp_none_bundle ? mirror_bundle_out(xbridge->mbridge, xbundle->ofbundle) : 0; }
复制代码
1
2
3
4
5
6mirror_mask_t mirror_bundle_out(struct mbridge *mbridge, struct ofbundle *ofbundle) { struct mbundle *mbundle = mbundle_lookup(mbridge, ofbundle); return mbundle ? mbundle->mirror_out : 0; }
复制代码
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
88
89
90
91
92
93
94
95
96int mirror_set(struct mbridge *mbridge, void *aux, const char *name, struct ofbundle **srcs, size_t n_srcs, struct ofbundle **dsts, size_t n_dsts, unsigned long *src_vlans, struct ofbundle *out_bundle, uint16_t out_vlan) { struct mbundle *mbundle, *out; mirror_mask_t mirror_bit; struct mirror *mirror; struct hmapx srcs_map; /* Contains "struct ofbundle *"s. */ struct hmapx dsts_map; /* Contains "struct ofbundle *"s. */ mirror = mirror_lookup(mbridge, aux); if (!mirror) { int idx; idx = mirror_scan(mbridge); if (idx < 0) { VLOG_WARN("maximum of %d port mirrors reached, cannot create %s", MAX_MIRRORS, name); return EFBIG; } mirror = mbridge->mirrors[idx] = xzalloc(sizeof *mirror); mirror->mbridge = mbridge; mirror->idx = idx; mirror->aux = aux; mirror->out_vlan = -1; } /* Get the new configuration. */ if (out_bundle) { out = mbundle_lookup(mbridge, out_bundle); if (!out) { mirror_destroy(mbridge, mirror->aux); return EINVAL; } out_vlan = -1; } else { out = NULL; } mbundle_lookup_multiple(mbridge, srcs, n_srcs, &srcs_map); mbundle_lookup_multiple(mbridge, dsts, n_dsts, &dsts_map); /* If the configuration has not changed, do nothing. */ if (hmapx_equals(&srcs_map, &mirror->srcs) && hmapx_equals(&dsts_map, &mirror->dsts) && vlan_bitmap_equal(mirror->vlans, src_vlans) && mirror->out == out && mirror->out_vlan == out_vlan) { hmapx_destroy(&srcs_map); hmapx_destroy(&dsts_map); return 0; } hmapx_swap(&srcs_map, &mirror->srcs); hmapx_destroy(&srcs_map); hmapx_swap(&dsts_map, &mirror->dsts); hmapx_destroy(&dsts_map); free(mirror->vlans); mirror->vlans = vlan_bitmap_clone(src_vlans); mirror->out = out; mirror->out_vlan = out_vlan; /* Update mbundles. */ mirror_bit = MIRROR_MASK_C(1) << mirror->idx; HMAP_FOR_EACH (mbundle, hmap_node, &mirror->mbridge->mbundles) { if (hmapx_contains(&mirror->srcs, mbundle)) { mbundle->src_mirrors |= mirror_bit; //当端口作为mirror的入端口时,src_mirrors中的某一位会置1,该位置是mirrors数组的索引,即mirror数量不超过32个 } else { mbundle->src_mirrors &= ~mirror_bit; } if (hmapx_contains(&mirror->dsts, mbundle)) { mbundle->dst_mirrors |= mirror_bit; } else { mbundle->dst_mirrors &= ~mirror_bit; } if (mirror->out == mbundle) { mbundle->mirror_out |= mirror_bit; //当端口为mirror out时,mirror_out中的某一位会置1,该位置是mirrors数组的索引,即mirror数量不超过32个 } else { mbundle->mirror_out &= ~mirror_bit; } } mbridge->has_mirrors = true; mirror_update_dups(mbridge); return 0; }
最后
以上就是开心月亮最近收集整理的关于【OVS2.5.0源码分析】mirror实现原理(2)的全部内容,更多相关【OVS2内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复