datapath流表的查找函数是ovs_flow_tbl_lookup_stats
,在此之前,先看下datapath组织流表的方式。
最新2.6的ovs流表,已经不是最早单纯的精确匹配了,而是一种精确匹配+带掩码匹配合并在一起的方式,叫做megaflow,目的是减少datapath里精确流表的条目数。但在我看来,这种方式只是在yy,在大规模生产环境下,不会因为用了megaflow精确流表就会变得可控,反而增加了datapath匹配时的复杂度,降低了性能,使用精确匹配还是掩码匹配还是hybrid的方式,应该留给运维人员去选择。
struct flow_table {
struct table_instance __rcu *ti;
struct table_instance __rcu *ufid_ti;
struct mask_cache_entry __percpu *mask_cache;
struct mask_array __rcu *mask_array;
unsigned long last_rehash;
unsigned int count;
unsigned int ufid_count;
};
struct table_instance {
struct flex_array *buckets;
unsigned int n_buckets;
struct rcu_head rcu;
int node_ver;
u32 hash_seed;
bool keep_flows;
};
struct table_instance *ti 是传统的桶+链表的哈希表结构,其中桶基于struct flex_array
的结构体,该结构体是linux内核定义的,本文先不去分析
/*
* This is meant to replace cases where an array-like
* structure has gotten too big to fit into kmalloc()
* and the developer is getting tempted to use
* vmalloc().
*/
struct flex_array {
union {
struct {
int element_size;
int total_nr_elements;
int elems_per_part;
struct reciprocal_value reciprocal_elems;
struct flex_array_part *parts[];
};
/*
* This little trick makes sure that
* sizeof(flex_array) == PAGE_SIZE
*/
char padding[FLEX_ARRAY_BASE_SIZE];
};
};
除了struct table_instance
之外,struct flow_table
还增加了缓存机制,这张表是一张精确匹配和掩码匹配的合体,struct mask_array *mask_array
是一个掩码结构体struct sw_flow_mask
的数组,可以看到struct sw_flow_mask
分为两部分:掩码的范围struct sw_flow_key_range
以及流的keystruct sw_flow_key
struct sw_flow_key {
u8 tun_opts[255];
u8 tun_opts_len;
struct ip_tunnel_key tun_key; /* Encapsulating tunnel key. */
struct {
u32 priority;