情報畑でつかまえてロゴ
本サイトは NTTテクノクロスが旬の IT をキーワードに
IT 部門が今知っておきたい最新テクノロジーに関する情報をお届けするサイトです

DPDKでSmartNICを扱うrte_flowについて ~DPDK入門 第16回~

ネットワークパケット処理におけるヘテロジニアスコンピューティングに関連してSmartNICについてご紹介します

はじめに

こんにちは、NTTテクノクロスの山下です。前回は高機能なNICであるSmartNICについてご紹介しましたが、今回はSmartNICに関連したDPDK機能であるrte_flowについてご紹介します。

SmartNICをより効果的に使うためには

前回ブログでご紹介したとおり、SmartNICを利用することにより、ホスト側のパケット処理負荷を下げることができます。
ネットワークから到着するパケットのパターンが固定的であり、パケットを処理するルールも固定的であればよいのですが、そうでない場合にはSmartNICを外から制御する必要性があります。

例えば、大量パケット送信によりサービス停止をねらうDoS(Denial of Service)攻撃をホストが受けた場合、攻撃者からのパケットを遮断する必要があります。具体的には特定のIPアドレスから受信したパケットについてはパケットドロップ(破棄)するようにSmartNICに指示する必要があります

今回のブログではDPDKアプリケーションから、SmartNICを制御するライブラリとしてrte_flowについてご紹介します。

rte_flowとは

rte_flowは、DPDKの機能の一つでSmartNICへのオフロードを指示するためのライブラリです。

正式名称としては「generic flow API」です。

SmartNICはいろいろなベンダから販売されており、制御用のAPIもベンダごとに異なります。

一例としてIntel社製のSmartNICのflow制御(SmartNICが送受信するパケットに処理方法の指示を与えることをそう呼びます)には「flow director」を利用することができます。

ただ、そうなるとアプリケーションとしてはA社のSmartNICとB社のSmartNICで呼び出し方が異なるため、呼び分けをしなければならず、それは、プログラム設計・製造・試験、あるいは運用まで含めても、とても大変です。

このような事情があるため、DPDKでは、ベンダに特化しない汎用的(generic)なflow制御APIとしてrte_flowを提供しています。rte_flowの概要を図1に示します。

                            図1. rte_flow概要

以下の動画では、アリババグループにおいてMellanox NICとrte_flowによるflow制御を利用することにより

性能を向上させた例について解説しています。数年前の動画ですが、参考になるところが多いと思います。

rte_flowの概念

rte_flowを利用する場合、以下の2つの大切な概念があります。

1) Matching Pattern どういう条件のパケットをマッチしたと判定するか、条件を指定します
2) Action 1)でマッチしたパケットにどのような処理を行うかを指定します


Matching Patternとしてはおおよそ50のネットワークプロトコルが指定可能です。Actionも50程度用意されており、例えば、ドロップしたり、特定のビットフィールドを書き換えたり、特定のキューにキューイングしたり、様々なアクションが実行可能です。また、複数のアクションが指定可能なので、どのアクションをどの順序で適用していくかをプログラム上で指定することが可能です。

上記の1と2の組み合わせをflow ruleと呼びます。1つのDPDKポートに複数のflow ruleを適用することができます。図2に概念を示します。

rte_flowのプログラムイメージ

rte_flowのプログラムイメージをサンプルに沿って説明します。

このサンプルでは、ネットワークから到着しVLAN IDが100であるパケットをドロップし、それ以外のパケットをDPDKアプリケーションに渡します。

プログラムの処理は大まかには以下の流れになります。

1.変数宣言とflow属性(今回は受信パケット(Ingress)に適用)の設定

2.Matching Patternの設定(今回はVLAN IDが100であるパケット)

3.Actionの設定(今回はパケットドロップ)

4.flow rule検証とflow rule生成

▼ サンプル

                                                 //1.変数の宣言とflow rule属性の設定
struct rte_flow_attr attr = { .ingress = 1 };                      //受信方向のパケットに適用
struct rte_flow_item pattern[MAX_PATTERNS];
struct rte_flow_action actions[MAX_ACTIONS];
struct rte_flow_item_eth eth;                                //ethernetタイプの宣言
struct rte_flow_item_vlan vlan;                               //vlanタイプの宣言
struct rte_flow *flow;                                     //flow rule生成後のflow ruleへのポインタ
struct rte_flow_error error;                                 //エラー情報格納変数

//2.Matching Patternの設定 pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;        pattern[0].spec = ð                 //ethernetについては全アドレスにマッチ vlan.vid = 100; //VLAN ID 100についてマッチ
pattern[1] = RTE_FLOW_ITEM_TYPE_VLAN; pattern[1].spec = &vlan;                  pattern[2].type = RTE_FLOW_ITEM_TYPE_END;
//3.Actionの設定 actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;      //マッチするパケットについてはドロップする actions[1].type = RTE_FLOW_ACTION_TYPE_END;

//4.flow検証とflow生成
if (!rte_flow_validate(port_id, &attr, pattern, actions, &error))    //flow検証がエラーとならないかチェック flow = rte_flow_create(port_id, &attr, pattern, actions, &error);    //flow生成実行

サンプルで利用しているrte_flowの代表的なAPIを以下に説明します。

▼ flow rule検証

int
rte_flow_validate(uint16_t port_id,     //DPDKポートID
const struct rte_flow_attr *attr,           //flow rule属性
const struct rte_flow_item pattern[],       //Matching Pattern
const struct rte_flow_action actions[],     //Action
struct rte_flow_error *error);


flow ruleが正しい書式に沿っているかを検証します。以下で説明するflow rule生成の前にはflow rule検証を実行するのが通例です。

▼ flow rule生成

struct rte_flow *
rte_flow_create(uint16_t port_id,           //DPDKポートID
const struct rte_flow_attr *attr,           //flow rule属性
const struct rte_flow_item pattern[],       //Matching Pattern
const struct rte_flow_action *actions[],    //Action
struct rte_flow_error *error);


flowを作成します。flow作成をすることによって、SmartNICに対してflow ruleが適用され始めます。

▼ flow rule削除

int
rte_flow_destroy(uint16_t port_id,          //DPDKポートID
struct rte_flow *flow,                      //削除対象のflow rule
struct rte_flow_error *error);


flow ruleを指定して削除します。flow ruleを削除することによって、SmartNICにおいて指定したflow ruleの適用が停止されます。

▼ flow rule一括削除

int
rte_flow_flush(uint16_t port_id,      //DPDKポートID     
struct rte_flow_error *error);


DPDKポートを指定して、flow ruleを一括削除します。

rte_flowを利用するメリット・注意点

最後に、rte_flowを利用するメリット・注意点について個人の所感を表にまとめます。

メリット 処理をオフロードできるので、DPDKアプリケーションで処理しなければならないパケット量あるいは処理量が少なくなります
リアルタイムにSmartNICの処理を変更することができます
SmartNICごとの制御APIの違いを意識しなくて良いです
注意点 1 ベンダや機器ごとにサポートしている機能(Matching PatternやAction)が異なり、すべてのMatching PatternやActionをサポートしているとは限りません
2 SmartNICがサポートしている機能があっても、rte_flowでその機能がサポートされていないとDPDKアプリケーションから利用できません

おわりに

今回はDPDKにおいてSmartNICを制御する技術の一つであるrte_flowについてご紹介しました。本記事の連載に関して何か問い合わせがございましたら、以下に連絡下さい。よろしくお願いします。

本件に関するお問い合わせ

NTTテクノクロス
フューチャーネットワーク事業部

山下英之

お問い合わせ

連載シリーズ
DPDK入門
著者プロフィール
山下 英之
山下 英之

[著者プロフィール]
フューチャーネットワーク事業部 第一ビジネスユニット
山下 英之(YAMASHITA HIDEYUKI)