matsumoto


Scheme入門者です。

C言語の入門書を大学時代に、最近 プログラミングGaucheを読み終えましたが理解度はいまいちです。。

「何か作りたい」という単純な動機で勉強を始めました。

何卒、宜しくお願い致します m(_ _)m


何をするか

何か作りながら体当たりで勉強していきたいと思います。

仕事・私生活共に何かツールが必要になる事が無いので、無理矢理ネタを考えて

需要は気にせず作って公開させて頂きます。

突っ込み頂けると幸いです◎


SchemeでOpenFlow

OpenFlowコントローラのフレームワークTremaのGaucheバインディングを作っています。

Scheme版Learning Switch(L2SWのような物)を実装して、とりあえず動いたので公開します。

コントローラの書き方

OpenFlowコントローラはSchemeでメッセージハンドラを記述するだけです。

(controller
  (define (switch-ready datapath_id)  ;; switch-readyハンドラを定義
    ...  )

  (define (packet-in datapath_id message)  ;; packet-inハンドラを定義
    ...  )
)

(launch)

例:Learnig Switchを実装

Learning SwitchをSchemeで書いて動いたので記載しておきます。

<learning-switch.scm>

#!/usr/bin/gosh

(use net.trema)

(controller
  (define *fdb* (make-hash-table 'string=?))

  (define (flow-mod datapath_id message action)
    (send-flow-mod-add datapath_id 
                       (exact-match-from message)
                       action))

  (define (flood datapath_id message)
    (send-packet-out datapath_id message (make-action-output *ofpp-flood*)))

  (define (packet-in datapath_id message)
    (hash-table-put! *fdb* (ref message 'macsa) (ref message 'in-port))
    (let ((port_no (hash-table-get *fdb* (ref message 'macda) #f)))
      (if port_no 
        (let ((act (make-action-output port_no)))
          (flow-mod datapath_id message act)
          (send-packet-out datapath_id message act))
        (flood datapath_id message)))))

(launch)

これをTremaの仮想ネットワーク機能を使って動作確認します。

仮想ネットワーク機能を使うために以下定義ファイルを作成します。

<trema.conf>

vswitch("lsw") {
  datapath_id "0xabc"
}

vhost("host1") {
  ip "192.168.2.1"
  netmask "255.255.255.0"
  mac "00:00:00:01:01:01"
}

vhost("host2") {
  ip "192.168.2.2"
  netmask "255.255.255.0"
  mac "00:00:00:01:01:02"
}

link "lsw", "host1"
link "lsw", "host2"

 ※ホスト"host1"、"host2"を仮想OpenFlowスイッチ"lsw"に接続している単純な構成です。

この仮想ネットワーク上で先のコントローラを実行します。

$ trema run ./learning-switch.scm -c trema.conf

host1〜host2間でパケットを送り合って、各ホストの送信/受信パケット数とスイッチのフローエントリを確認します。

$ trema send_packets --source host1 --dest host2
$ trema send_packets --source host2 --dest host1
$ trema send_packets --source host1 --dest host2
$ trema dump_flows lsw
NXST_FLOW reply (xid=0x4):
 cookie=0x2, duration=2.592s, table=0, n_packets=0, n_bytes=0, idle_timeout=60,priority=65535,
 udp,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:01:01:01,dl_dst=00:00:00:01:01:02,nw_src=192.168.2.1,nw_dst=192.168.2.2,
 nw_tos=0,tp_src=1,tp_dst=1 actions=output:1
 cookie=0x1, duration=27.574s, table=0, n_packets=0, n_bytes=0, idle_timeout=60,priority=65535,
 udp,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:01:01:02,dl_dst=00:00:00:01:01:01,nw_src=192.168.2.2,nw_dst=192.168.2.1,
 nw_tos=0,tp_src=1,tp_dst=1 actions=output:2
$ trema show_stats host1
Sent packets:
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.2.2,1,192.168.2.1,1,2,100
Received packets:
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.2.1,1,192.168.2.2,1,1,50
$ trema show_stats host2
Sent packets:
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.2.1,1,192.168.2.2,1,1,50
Received packets:
ip_dst,tp_dst,ip_src,tp_src,n_pkts,n_octets
192.168.2.2,1,192.168.2.1,1,2,100

一応、動いているようです。

上記Learning Switchを実装できるだけの最低限の機能しか出来ていませんが、少しずつ増やしていこうと思います。

現時点のソースコードはこちらに置いておきます。↓

https://docs.google.com/file/d/0B2y3-FwtZJ9VN3RCTG5kb01TOUE/edit?usp=sharing

※Makefileやconfigureスクリプトの書き方がいまいちわからず、、自環境用に手入力で修正しないとインストールできないと思います。。


Last modified : 2013/07/21 04:38:51 UTC