ovs 删除openflow流表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ovs 删除openflow流表相关的知识,希望对你有一定的参考价值。
参考技术A 有如下三种方法可以删除openflow流表:
a. controller/ovs-ofctl主动发命令(OFPFC_DELETE or OFPFC_DELETE_STRICT)删除流表。OFPFC_DELETE_STRICT和OFPFC_DELETE 的区别是前者需要匹配所有的字段才能删除(包括优先级),并且一次只能删除一条流表,后者要求指定的字段必须是流表的一个子集(不能指定优先级),可以一次删除多个流表。
b. 流表的超时机制: 添加流表时如果指定idle_timeout或者hard_timeout参数,则流表超时后将被删除。如果不指定这俩参数,则默认不会被超时机制删除。hard_timeout指定的超时时间是从创建流表,或者修改流表开始计时,超时时间到后,不管此流表有没有被使用,都会被删除。idle_timeout指定流表空闲超时时间,从最近流表被使用开始计时,如果指定时间内此流表没有被使用,则被删除。
c. 强制回收机制: 添加流表时,如果当前流表个数大于等于最大流表个数,则判断是否可以强制回收之前添加的流表。可以通过Flow_Table里的overflow_policy参数指定当前流表个数大于等于最大流表个数时的行为,如果为refuse则拒绝添加新流表,如果为evict则强制删除即将超时的流表。强制回收只考虑指定了超时时间的流表。
添加流表时,如果指定了超时时间,并且流表指定的field包含group指定的field,则会将流表添加到一个分组中。具体为根据group指定的这些field计算hash值,再根据hash值到table->eviction_groups_by_id查找struct eviction_group。然后根据超时时间计算优先级,根据优先级将此流表插入struct eviction_group
针对强制删除流表,可以做如下实验
下面分析下这三种情况下的源码
controller/ovs-ofctl主动删除流表
将流表从分类器中删除
超时机制
添加流表时,如果指定了超时时间,则会将流表挂到链表ofproto->expirable上,在ovs-vswitchd的主循环中,会周期性的调用ofproto-dpif.c中的run函数,此函数会遍历链表ofproto->expirable判断流表是否超时,如果超时则将流表删除。
evict强制删除
添加流表时会将流表插入eviction_group中
当再次添加流表时,如果当前流表个数超过最大流表个数,则
Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population
问题导读:
1.怎样使用arp_responder ?
3. ARP Responder
3.1 升级 OVS
1
2
3
|
uname -r . /configure --with-linux= /lib/modules/3 .13.0-51-generic /build make && make install |
1
2
3
4
|
ovs-vsctl (Open vSwitch) 2.3.2 Compiled Jul 12 2015 09:09:42 DB Schema 7.6.2 |
1
2
|
rm /etc/openvswitch/conf .db (老的db要删除掉,否则会报错) ovsdb-tool create /etc/openvswitch/conf .db vswitchd /vswitch .ovsschema |
1
2
3
|
cp /usr/local/bin/ovs- * /usr/bin ovsdb-server /etc/openvswitch/conf .db -vconsole:emer -vsyslog:err -vfile:info --remote=punix: /usr/local/var/run/openvswitch/db .sock --private-key=db:Open_vSwitch,SSL,private_key --certificate=db:Open_vSwitch,SSL,certificate --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert --no-chdir --log- file = /var/log/openvswitch/ovsdb-server .log --pidfile= /var/run/openvswitch/ovsdb-server .pid --detach --monitor ovs-vswitchd unix: /usr/local/var/run/openvswitch/db .sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log- file = /var/log/openvswitch/ovs-vswitchd .log --pidfile= /var/run/openvswitch/ovs-vswitchd .pid --detach --monitor |
3.2 ARP Responder
# ARP broadcast-ed request go to the local ARP_RESPONDER table to be locally resolved
table=2, n_packets=0, n_bytes=0, idle_age=3, priority=1,arp,dl_dst=ff:ff:ff:ff:ff:ff actions=resubmit(,21)
# If none of the ARP entries correspond to the requested IP, the broadcast-ed packet is resubmitted to the flooding table
table=21, n_packets=0, n_bytes=0, idle_age=4, priority=0 actions=resubmit(,22)
如果下面第 (3)步增加的 flow rule 都处理不了这条 request,那么转到table 22 去 flood 到所有端口。
br.add_flow(table=21, priority=1, proto=‘arp‘, dl_vlan=local_vid, nw_dst= ip, actions=actions)
1
2
3
4
5
6
7
8
|
ARP_RESPONDER_ACTIONS = ( ‘move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],‘ ‘mod_dl_src:%(mac)s,‘ ‘load:0x2->NXM_OF_ARP_OP[],‘ ‘move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],‘ ‘move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],‘ ‘load:%(mac)#x->NXM_NX_ARP_SHA[],‘ ‘load:%(ip)#x->NXM_OF_ARP_SPA[],‘ ‘in_port‘ ) |
(4)table 21 的处理过程
4. L2 population
4.1 原理
‘status‘: ‘DOWN/BUILD/ACTIVE‘, ‘binding:host_id‘: u‘compute1‘, ‘allowed_address_pairs‘: [], ‘extra_dhcp_opts‘: [], ‘device_owner‘: u‘compute:nova‘, ‘binding:profile‘: , ‘fixed_ips‘: [‘subnet_id‘: u‘4ec65731-35a5-4637-a59b-a9f2932099f1‘, ‘ip_address‘: u‘81.1.180.15‘], ‘id‘: u‘1167e9ac-e10f-4cf5-bd09-6649eab38b32‘, ‘security_groups‘: [u‘f5377a66-803d-481b-b4c3-a6631e8ab456‘], ‘device_id‘: u‘30580ea7-c456-416b-a01e-0fe645edf5dc‘, ‘name‘: u‘‘, ‘admin_state_up‘: True, ‘network_id‘: u‘86c0d29b-4880-4739-bd68-eb3c392f5099‘, ‘tenant_id‘: u‘74c8ada23a3449f888d9e19b76d13aab‘, ‘binding:vif_details‘: u‘port_filter‘: True, u‘ovs_hybrid_plug‘: True, ‘binding:vnic_type‘: u‘normal‘, ‘binding:vif_type‘: u‘ovs‘, ‘mac_address‘: u‘fa:16:3e:4f:59:9d‘
- update_port_postcommit (down to active) -> _update_port_up -> add_fdb_entries -> fdb_add -> fdb_add_tun -> setup_tunnel_port (如果 tunnel port 不存在,则创建 tunnel port), add_fdb_flow -> add FLOOD_TO_TUN flow (如果是 Flood port,则将端口添加到 Flood output ports); setup_entry_for_arp_reply(‘add‘。如果不是 Flood port,那么 添加 ARP Responder entry (MAC -> IP)) 以及 add UCAST_TO_TUN flow Unicast Flow entry (MAC -> Tunnel port number)。
- update_port_postcommit (active to down) -> _update_port_down -> remove_fdb_entries
- delete_port_postcommit (active to down) -> _update_port_down -> remove_fdb_entries -> fdb_remove -> fdb_remove_tun -> cleanup_tunnel_port, del_fdb_flow -> mod/del FLOOD_TO_TUN flow; setup_entry_for_arp_reply (‘remove‘), delete UCAST_TO_TUN flow
- update_port_postcommit (fixed ip changed) -> _fixed_ips_changed -> update_fdb_entries
- Tunnel port
- FLOOD_TO_TUN (table 22)flow
- ARP responder flow
- UCAST_TO_TUN (table 20) flow
4.2 过程实验
- 通知 compute1: ‘segment_id‘: 6L, ‘ports‘: u‘10.0.1.21‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:87:40:f3‘, u‘81.1.180.1‘]], ‘network_type‘: u‘gre‘
- 通知所有 agent: ‘segment_id‘: 6L, ‘ports‘: u‘10.0.1.31‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:b3:e7:7a‘, u‘81.1.180.8‘]], ‘network_type‘: u‘gre‘
- 添加和网络节点的tunnel options: df_default="true", in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.21"
- 添加到网段网关的 Unicast flow:table=20, n_packets=0, n_bytes=0, idle_age=130, priority=2,dl_vlan=2,dl_dst=fa:16:3e:87:40:f3 actions=strip_vlan,set_tunnel:0x6,output:4
- 增加网段 81.1.180.1 网关的 ARP flows:table=21, n_packets=0, n_bytes=0, idle_age=130, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:87:40:f3,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e8740f3->NXM_NX_ARP_SHA[],load:0x5101b401->NXM_OF_ARP_SPA[],IN_PORT
- 修改 Flood flow
- 通知 compute 2 : ‘segment_id‘: 6L, ‘ports‘: u‘10.0.1.31‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:b3:e7:7a‘, u‘81.1.180.8‘]], u‘10.0.1.21‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:87:40:f3‘, u‘81.1.180.1‘]], ‘network_type‘: u‘gre‘
- 通知所有 agent: ‘segment_id‘: 6L, ‘ports‘: u‘10.0.1.39‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:73:49:41‘, u‘81.1.180.9‘]], ‘network_type‘: u‘gre‘
- 建立 tunnel(ID 5): df_default="true", in_key=flow, local_ip="10.0.1.31", out_key=flow, remote_ip="10.0.1.39"
- 增加 arp responder flow(compute2 上新的虚机 IP -> MAC):table=21, n_packets=0, n_bytes=0, idle_age=79, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.9 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:73:49:41,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e734941->NXM_NX_ARP_SHA[],load:0x5101b409->NXM_OF_ARP_SPA[],IN_PORT
- 增加 unicast flow (新虚机的 MAC -> Tunnel port):table=20, n_packets=0, n_bytes=0, idle_age=79, priority=2,dl_vlan=2,dl_dst=fa:16:3e:73:49:41 actions=strip_vlan,set_tunnel:0x6,output:5
- 添加新的 Tunnel port 到 Flood flow:table=22, n_packets=13, n_bytes=1717, idle_age=255, hard_age=78, dl_vlan=2 actions=strip_vlan,set_tunnel:0x6,output:5,output:4
- 建立和计算节点以及compute1的tunnel:options: df_default="true", in_key=flow, local_ip="10.0.1.39", out_key=flow, remote_ip="10.0.1.21",options: df_default="true", in_key=flow, local_ip="10.0.1.39", out_key=flow, remote_ip="10.0.1.31"
- 增加 ARP flow(compute 1 上的虚机的 MAC -> IP):table=21, n_packets=0, n_bytes=0, idle_age=268, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.8 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:b3:e7:7a,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163eb3e77a->NXM_NX_ARP_SHA[],load:0x5101b408->NXM_OF_ARP_SPA[],IN_PORT
- 增加 Unicast flow (compute 1 上的虚机 MAC -> Tunnel port):table=20, n_packets=0, n_bytes=0, idle_age=268, priority=2,dl_vlan=2,dl_dst=fa:16:3e:b3:e7:7a actions=strip_vlan,set_tunnel:0x6,output:4
-
增加 ARP flow(新虚机的网关的 MAC -> IP) table=21, n_packets=0, n_bytes=0, idle_age=268, priority=1,arp,dl_vlan=2,arp_tpa=81.1.180.1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],mod_dl_src:fa:16:3e:87:40:f3,load:0x2->NXM_OF_ARP_OP[],move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],load:0xfa163e8740f3->NXM_NX_ARP_SHA[],load:0x5101b401->NXM_OF_ARP_SPA[],IN_PORT
- 修改 Flood flow(添加到 Compute 1 的 port):table=22, n_packets=13, n_bytes=1717, idle_age=128, dl_vlan=2 actions=strip_vlan,set_tunnel:0x6,output:5,output:4
- 通知所有 agent: ‘segment_id‘: 6L, ‘ports‘: u‘10.0.1.31‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:b3:e7:7a‘, u‘81.1.180.8‘]], ‘network_type‘: u‘gre‘
- 因为没有别的虚机了,删除所有 tunnel ports
- 修改或者删除 ARP, Unicast 和 Flood flows
- 删除了 compute1 的 tunnel
- 删除该虚机对应的 ARP flow
- 通知 compute 1: u‘e2022937-ec2a-467a-8cf1-f642a3f777b6‘: ‘segment_id‘: 4L, ‘ports‘: u‘10.0.1.21‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:90:e5:50‘, u‘91.1.180.1‘], [u‘fa:16:3e:17:c9:26‘, u‘90.1.180.1‘], [u‘fa:16:3e:69:92:30‘, u‘90.1.180.3‘], [u‘fa:16:3e:69:92:30‘, u‘91.1.180.2‘]], ‘network_type‘: u‘gre‘
- 通知所有 agent:u‘e2022937-ec2a-467a-8cf1-f642a3f777b6‘: ‘segment_id‘: 4L, ‘ports‘: u‘10.0.1.31‘: [[‘00:00:00:00:00:00‘, ‘0.0.0.0‘], [u‘fa:16:3e:e9:ee:0c‘, u‘91.1.180.9‘]], ‘network_type‘: u‘gre‘
- 虚机在收到 fannout FDB entries 后,检查其中每个 port 的 network_id(即 “segment_id”)。如果本机上有该 network 内的 port,那么就处理 entries 中的 “ports”部分;否则,不处理该 entries。
- 因此,当计算节点上没有运行任何虚机时,不会建立任何 tunnel。如果两个虚机上有相同网络内的虚机,那么建立会建立 tunnel。
- 这种机制能实时建立 tunnel port,Flood entry (创建 Tunnel port 同时添加到 Flood output ports 列表), Unicast flow (虚机和网关 MAC -> Tunnel port) 和 ARP Responder entry (虚机和网关 MAC -> IP)。下图中的蓝色部分的流表都会被及时更新。
- Neutron server 在端口创建/删除/修改时,如果是该节点上的第一个虚机,首先发送直接消息;然后发通知消息给所有的计算和网络节点。
4.3 性能
4.3.1 MQ 性能问题
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
def __init__( self , topic = topics.AGENT): super (L2populationAgentNotifyAPI, self ).__init__( topic = topic, default_version = self .BASE_RPC_API_VERSION) self .topic_l2pop_update = topics.get_topic_name(topic, topics.L2POPULATION, topics.UPDATE) def _notification_fanout( self , context, method, fdb_entries): self .fanout_cast(context, self .make_msg(method, fdb_entries = fdb_entries), topic = self .topic_l2pop_update) def _notification_host( self , context, method, fdb_entries, host): self .cast(context, self .make_msg(method, fdb_entries = fdb_entries), topic = ‘%s.%s‘ % ( self .topic_l2pop_update, host)) def add_fdb_entries( self , context, fdb_entries, host = None ): if fdb_entries: if host: self ._notification_host(context, ‘add_fdb_entries‘ ,fdb_entries, host) #cast 给指定 host else : self ._notification_fanout(context, ‘add_fdb_entries‘ , fdb_entries) #fanout 给所有计算和网络节点 |
4.3.2 大规模网络环境中节点上的 OpenFlow flows 过多
以上是关于ovs 删除openflow流表的主要内容,如果未能解决你的问题,请参考以下文章
Neutron 理解 : Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population
Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population