openflow里面有个buffer_id
的概念,用于标记缓存在交换机中的报文的id,该报文会被发送packet-in到控制器,控制器决策后下发带buffer_id
的命令冲洗处理该报文,通常的处理命令为重走pipeline。
openflow中有如下两种方式可以发送带有buffer_id
的报文:
- 下发Packet-Out消息。消息中可以选择是否带有
buffer_id
,如果不带(即buffer_id=NO_BUFFER
)则直接从OutPort指定的端口发包;如果带有该buffer_id
,则Packet-Out消息中的OutPort将会被忽略,转为指向保留端口TABLE,则标识将缓存在该交换机中的该报文重走pipeline,送入到第一个table,往往是table 0。 - 下发Flow-Mod消息。同样,消息中可以选择是否带有
buffer_id
,如果不带则相当于只下发流表/组表;如果带,则意味着该报文同时下发两条指令:首先下发流表/组表的添加,然后下发Packet-Out消息默认OutPort为TABLE,也就是重走pipeline。
我们可以在交换机中设置缓冲区的大小,当缓存的报文大于缓冲区的大小将会被丢弃。
一个报文一个buffer_id
,也就是说当有多个报文进到交换机,尽管是同一类报文,比如都是同一个ping包(同样的源ip和目的ip),那么每个包都会有一个不同的buffer_id
。其实,说到这,问题就来了。比如突然流量打的很大,而且都是同一种报文,那么第一个包上到控制器后,还没处理完成,之后的报文还会继续上到控制器,这对控制器的压力将会很大,类似一种攻击了。所以这个时候我觉得一种报文一个buffer_id
的处理会更为科学,同一个流只在第一个报文上到控制器,剩下的缓存在交换机端,缓存区满了就丢弃,一旦控制器下发命令就让所有同一个buffer_id
的报文重走pipeline。
然而,到底是一个buffer_id
一个报文还是一类报文的行为好像不是openflow协议规定的内容,而是交换机厂商自己不同的实现。
参考:
openflow-spec-v1.3.0