OVS-DPDK 流表查詢詳解

2023-03-15 18:01:25

一圖勝千言:

 

 

 

 

flow和miniflow

在介紹之前先說一些概念:裡面有兩個結構很重要,一個是flow一個是miniflow這裡介紹一下他們的資料結構和建構函式。

flow:

flow的特點是8位元組對齊的,儲存報文相關欄位和其他原資料,用於匹配流表,資料包含四個層次:
  1. metadata: 入埠號,暫存器等資訊
  2. l2: 源目的mac,vlan和mpls等資訊
  3. l3: ipv4/ipv6源目的ip,ttl等資訊
  4. l4: 源目的埠號,icmp code和type等資訊。
flow的壞處就是佔用了很大的位元組,並且有很多欄位都是0,在2.8版本中flow的大小是672位元組。
 

miniflow

miniflow是flow的壓縮版,因為flow佔用位元組很大,比如可以支援ARP,IP等報文,填充了arp欄位,icmp報文就是空的了,浪費了很多資訊。過程中用到hash作為key,也是根據miniflow計算hash值,不是用的flow。
struct miniflow {
    struct flowmap map;
};
struct flowmap {
    map_t bits[FLOWMAP_UNITS];
};
miniflow其包含兩部分內容:
  1. struct flowmap map;是bit陣列,使用其中的bit表示flow中哪個8位元組存在有效資料,flow中佔多少個8位元組,那麼就需要map中多個個bit,並且按照64bit向上取整。
  2. 第二部分是有效資料,有效資料動態分配,根據struct flowmap map;中1bit數個數進行分配,大小為bit數*8位元組,該部分直接跟在map後面。該部分儲存在netdev_flow_key結構中的buf陣列。
miniflow資料結構:
//flow是8位元組對齊的,除8得到flow中包含8位元組的個數
#define FLOW_U64S (sizeof(struct flow) / sizeof(uint64_t))

//map大小為8位元組,MAP_T_BITS 為64位元
typedef unsigned long long map_t;
#define MAP_T_BITS (sizeof(map_t) * CHAR_BIT)

//每位表示一個u64,FLOWMAP_UNITS 表示最少需要幾個64位元
#define FLOWMAP_UNITS DIV_ROUND_UP(FLOW_U64S, MAP_T_BITS)

struct flowmap {
    map_t bits[FLOWMAP_UNITS];
};

struct miniflow {
    struct flowmap map;
    /* Followed by:
     *     uint64_t values[n];
     * where 'n' is miniflow_n_values(miniflow). */
};

struct netdev_flow_key {
    uint32_t hash;     
    uint32_t len;     
    struct miniflow mf;  // bits
    uint64_t buf[FLOW_MAX_PACKET_U64S];  // 就是上邊所說的value
};

// 有些欄位是互斥的
#define FLOW_MAX_PACKET_U64S (FLOW_U64S                                   \
    /* Unused in datapath */  - FLOW_U64_SIZE(regs)                       \
                              - FLOW_U64_SIZE(metadata)                   \
    /* L2.5/3 */              - FLOW_U64_SIZE(nw_src)  /* incl. nw_dst */ \
                              - FLOW_U64_SIZE(mpls_lse)                   \
    /* L4 */                  - FLOW_U64_SIZE(tp_src)                     \
                             )