ネットワークの状況に応じて制御するアプリケーションを開発するためには、ネットワークや機器の状態の変化などのイベントをアプリケーションが即座に把握したくなると思います。例えば、回線使用率が増加したときや回線の遅延が著しく大きくなったときには、ネットワーク全体で経路の自動最適化を行ないたい、あるいは特定のインターフェイスがダウンしたり経路情報がなくなった場合には、あらかじめ指定したポリシーを自動的に投入したい、といった実装です。従来だと SNMP Trap や SNMP MIB を定期的にポーリングしたりする手法を利用してきましたが、onePK には便利なリスナー機能の API が用意されています。
リスナー機能の API
onePK のリスナー機能の API では、監視したい対象、しきい値、そして Callback ルーチンなどが指定できます。これを利用することで、ポーリングでネットワークや機器の状態を確認するプログラムを組み込まなくても、状態変化に伴う制御アプリケーションが比較的容易に開発できます。例えば、指定したインターフェイスで、回線使用率が 60% を超えた場合、指定した Callback ルーチンを実行させる、といった動作を定義することができます。
onePK SDK 1.2 で提供されている代表的なリスナー機能には、次のようなものがあります。
- インターフェイスのカウンタ値に対するリスナー機能:
指定したインターフェイスのカウンタが指定したしきい値を超えた時、もしくは下回った時に Callback ルーチンが実行されます。 - インターフェイスのステータスに対するリスナー機能:
指定したインターフェイスの状態の変化を検知した時に Callback ルーチンが実行されます。 - ルーティング テーブルに対するリスナー機能:
引数で指定したプレフィックスのルーティング エントリの変動を監視し、変化を検知した時に Callback ルーチンが実行されます。 - Syslog メッセージに対するイベント リスナー機能:
引数で指定した syslog メッセージが出た時にCallback ルーチンが実行されます。syslog メッセージの指定は正規表現で行なえます。 - onePK の制御用のセッションに対するリスナー機能:
制御用のセッションがタイムアウトなどで切断された時に Callback ルーチンが実行されます。セッションには再送タイマーと再送回数の設定も API から可能ですが、それらのリトライを繰り返した後セッションは切断され、このイベントが発生します。
プログラムの基本手順
インターフェイスのカウンタ値に対するリスナー機能 を利用する場合の例を、C 言語で紹介しておきます。
まず、しきい値をフィルタという形で定義します。以下の例では iffilter という変数になります。このフィルタを定義する onep_interface_statistics_filter_new の API では、監視する対象(以下の例では受信ブロードキャスト パケットのカウンタ)や、評価方法、しきい値などを引数として指定しています。
rc = onep_interface_statistics_filter_new(
ONEP_IF_STAT_RX_PKTS_BCAST, //監視するカウンタ
ONEP_OP_EQ, //評価方法
10, //しきい値
ONEP_INTERFACE_STATISTICS_TYPE_VALUE, //数値の取り扱い
&ifFilter); //インターフェースのフィルタ
次に、onep_interface_add_statistics_listner の API で、対象とするインターフェイス、Callback ルーチン、そしてフィルタなどを引数として設定し、リスナーを登録します。以下の例では、if_statistics_change_handler というサブルーチンを Callback ルーチンとして指定しています。
rc = onep_interface_add_statistics_listener(intf, if_statistics_change_handler,
ifFilter, NULL, &statChgEvtId);
最初は少しとっつきにくいかもしれませんが、慣れてしまえば非常に便利な機能です。
その他の イベントのリスナー機能のサンプル プログラムが以下のサイトにありますので、ぜひご覧ください。
C言語:https://developer.cisco.com/media/onepk_c_tutorials/EventsTutorial/events.html
Java:https://developer.cisco.com/media/onepk_java_tutorials/Events/events.html#Events
Python:https://developer.cisco.com/media/onepk_python_tutorials/Events/events.html#Events
実際に作ってみた
私はこのリスナー機能を使って、回線障害時や回線負荷が一定負荷を越えた場合に、ダイキストラ アルゴリズムにてネットワーク経路を自動的に最適化する onePK アプリケーションをデモ用に開発しました。そのプログラムの内容は以下になります。
この自作の経路制御アプリケーションを使って、迂回動作が期待通りに動いたときには、嬉しくて思わず叫んでしまいました。
実は開発当初は結構苦労しました。というのは、リスナー機能を利用して様々な物を監視させていると、実際に回線障害やトポロジ変更が起こったとき、複数のイベントが同時に発生し、複数の Callback ルーチンの割り込み処理が競合することになるからです。この回避策として、Callback ルーチン側で、割り込み処理の競合をハンドリングするためのロジックを追加しました。これで、期待した動作となりました。
以下が私が開発したデモ用のアプリケーションです。矢印はトラフィックの量を表現しています。最初、クライアントとシステム3 の間の通信は R3-R6-R9-R8-R7 の経路を通っていますが、R6 と R9 の間の回線負荷が80% を超えると、自動的に R5 経由に迂回します。
これまで IP 経路制御というと、OSPF や BGP などの標準的なダイナミック ルーティング アルゴリズムを使っての最適経路制御しか選択肢がありませんでした。しかし onePK でソフトウェアを開発することで、独自の経路制御やポリシー制御が実現可能であることが実証できました。
また経路制御以外の様々な IOS 機能についても、何らかのイベント発生時に syslog メッセージを出すものであれば、syslog のリスナー機能が本当に便利です。例えば OSPF や BGP の Neighbor ダウンの検知のほか、Catalyst スイッチを onePK に対応させることで、BroadcastStorm 検知や Error Disable といった事象が発生したときに適切な制御を自動で実行できるアプリケーションを開発できます。EEM にてカスタムな syslog を設定して、それと組み合わせればさらに複雑な制御も実現できると思います。
皆さんも、独自なアルゴリズムやポリシーで自動制御するアプリケーションの開発にチャレンジして、感動を味わってみませんか?