open flow tunnel extension on lagopus vswitch

21
OpenFlow tunnel extension on Lagopus vswitch Dec 16, 2015 Masaru OKI @masaru0714

Upload: masaru-oki

Post on 08-Feb-2017

887 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Open flow tunnel extension on lagopus vswitch

OpenFlow tunnel extensionon Lagopus vswitch

Dec 16, 2015Masaru OKI @masaru0714

Page 2: Open flow tunnel extension on lagopus vswitch

OpenFlow General Tunnel Support

OpenFlow 1.4に向けて提案された拡張

● actionにencap, decapを追加し、フローエントリを使ってトンネリングを実現

● gre protocol, gre key, vxlen vniなどのmatchとset-fieldを追加

● 実装されないと仕様に入らない

→入らないまま現在に至る

● OpenFlow 1.5で定数がかぶっていて、reviseが必要

● LagopusはOpenFlow 1.3用に作ってあるので、ひとまずそのまま適用してみる○ トンネル対象はGRE, MPLS PW, VXLAN

Page 3: Open flow tunnel extension on lagopus vswitch

decap, encap

例としてGRE tunnelのケース。push, popに似ている。

ethernet IP GRE tunneled ethrenet packet

ethrenet packet

decap etherdecap ip

decap gre

encap greencap ipencap ether

Page 4: Open flow tunnel extension on lagopus vswitch

ofp_action_decap

struct ofp_action_decap {uint16_t type;uint16_t len;uint32_t cur_pkt_type;uint32_t new_pkt_type:uint8_t pad[4];

};

decap前のパケット種別。validate用と定義されているが、 decap対象と考える。(OFPHTN_ONF<<16) | OFPHTO_ETHERNET→ Ethernetヘッダをdecapする。(OFPHTN_ETHERTYPE<<16) | ETHERTYPE_IP→ IPv4ヘッダをdecapする。(OFPHTN_IPPROTO<<16) | IPPROTO_GRE→ GREヘッダをdecapする。

decap後のパケット種別。decap後のpayloadをどう解釈するかの指定。例:GREをdecapしたあとがL2なのかIPなのかを指定する。(OFPHTN_ONF<<16) | OFPHTO_USE_NEXT_PROTO→ decap前のヘッダに書かれたプロトコル情報を使う

Page 5: Open flow tunnel extension on lagopus vswitch

ofp_action_encap

struct ofp_action_encap {uint16_t type;uint16_t len;uint32_t packet_type;struct ofp_ed_prop_header props[0];

};

encap後のパケット種別。(OFPHTN_IPPROTO<<16) | IPPROTO_GRE→ GREヘッダをencapする。IPv4, Etherなどdecapと同様に順にencapする。CRCなどは適宜計算する。

encapに伴う属性を追加で指定できる。OFPPPT_PROP_PORT_NAMEを指定すると、フローエントリの投入タイミングで logical portを作成。統計情報の取得ができるようになる。

Page 6: Open flow tunnel extension on lagopus vswitch

decap, encapとpacket_type

decap, encapすると非Ethernetのパケット構造に変化する。

ethernet IP GRE tunneled ethrenet packet

ethrenet packet

IP GRE tunneled ethrenet packet

GRE tunneled ethrenet packet

OFPHTN_ONFOFPHTO_ETHERNET

OFPHTN_ETHERTYPEETHERTYPE_IP

OFPHTN_IP_PROTOIPPROTO_GRE

OFPHTN_ONFOFPHTO_ETHERNET

Page 7: Open flow tunnel extension on lagopus vswitch

拡張されたmatch field

ここでも一例としてGREのものを並べる。IPPROTO_GREのときのみmatchできる。

● OFPXMT_OFB_GRE_FLAGS● OFPXMT_OFB_GRE_VER● OFPXMT_OFB_GRE_PROTOCOL● OFPXMT_OFB_GRE_KEY● OFPXMT_OFB_GRE_SEQNUM

matchおよびset-fieldで指定できる。keyはmaskつきmatchが可能。

Page 8: Open flow tunnel extension on lagopus vswitch

GRE header

● RFC2890(ver0)では、checksum, key, sequence等はoptional● RFC2637 (ver1)PPTP用拡張では、checksumなし、keyは必須でlengthとidに分割

C言語風に書くと、

struct {uint16_t flags;uint16_t ptype;uint32_t key;uint32_t seq_num;uint32_t ack_num;

};

flagsによって省略されてるかがわかる。それによりヘッダサイズが変わる。

ver0: 32bit keyver1: 上位16bitがlengthで下位16bitがcall ID

下位3bitがバージョン

Page 9: Open flow tunnel extension on lagopus vswitch

Lagopus dataplaneの実装状況

● encap○ ether, ipv4, udp, vxlan, gre, mpls

● decap○ ether, ipv4, udp, vxlan, gre, mpls

● match field○ gre_flags, gre_ver, gre_protocol, gre_key, vxlan_flags, vxlan_vni (IPv4,UDP,MPLSは既存のみ )

● set-field○ gre_flags, gre_ver, gre_protocol, gre_key, vxlan_flags, vxlan_vni (IPv4,UDP,MPLSは既存のみ )

GRE,VXLAN,MPLS PWならtunnelできるようになった! と言えそうですが課題が山積み。

Page 10: Open flow tunnel extension on lagopus vswitch

encapの課題(GREの場合)

● seq_numをつけるか省くかが、flags次第○ encap実行時にはわからない

○ わからないとヘッダサイズが不明なので encapできない

○ encapするまえにset-field gre_flagsすることはできない

● ver=1ならchecksumは省くが、0の場合つけるか省くかはflags次第○ encap実行時には以下同文

● ver=0の場合keyを省くこともできるがflags次第○ 以下同文

● Linux gretapではver=0でkeyあり

● 解決案○ 案1: key必須, seq_numなしで固定とする。

○ 案2: encapにflagsを渡せるような拡張を施す ?○ 案3: packet_typeをver別に細かく規定する ?

Page 11: Open flow tunnel extension on lagopus vswitch

set-fieldの課題(GREの場合)

● keyは4バイトとなっている。

● ver=1の拡張GREでは、keyの上位16bitはpayload lengthとなっている

● set-fieldで4バイト書くためにpayload lenghtを知る必要があるがOFではできない

● maskつきset-fieldはOpenFlow 1.5で拡張されている。

● LagopusはOpenFlow 1.3用として作っていて、まだ対応していない。○ 案1: がんばってmaskつきset-fieldに対応する

○ 案2: 2byte keyのset-fieldをできるような (EXT-382にはない)拡張を施す

● ただしLinux gretapではver=0のためmaskつきset-fieldは未使用

Page 12: Open flow tunnel extension on lagopus vswitch

encapの課題(GREに限らず)

● encap後のipv4_srcとeth_srcは?○ eth_srcはNICに紐づくが、outputするまではどのportを使うか不明。いつ、だれが埋める ?

■ 案1: コントローラがport_statsしてencapのフローエントリ投入前に把握する

■ 案2: Lagopusが勝手に埋める (set-fieldされていたら勝手に上書きする orz)■ 案3: 「特定ポートのMAC」をcopy-fieldする(OF1.3にはないactionですが)■ 案4: 事前に調べておいた値でフローエントリを作成する (ipv4_srcもこれでいける )

○ arpは誰がどうやって答える ? (デモ程度なら静的でもよい )■ 案1: コントローラががんばる

■ 案2: Linux kernelにぶん投げてお任せ (hybrid有効にするとtap経由で送受信できる )■ 案3: register等を駆使してOFでがんばる (OF1.3ではできませんが……)

● encap後のipv4_dstとeth_dstは?○ ipv4_dstはトンネルの接続先なので NW設計時に決まる。staticにset-fieldしてもらっていい。

○ eth_dstは通常NWではgateway ipからarpしてMACを得る。さて……?■ Linux kernelがarpするならその結果をどうにかして拾えれば ……

Page 13: Open flow tunnel extension on lagopus vswitch

decapの課題(GREに限らず)

● GREやVXLANだからといって全部decapしていいわけじゃない

● 自分宛でないパケットをdecapするのはまずい

● 自分宛であることをOpenFlowでどうやって調べることができる? (できない)○ 案1: コントローラがport情報からMACを得て、matchするもののみdecapするフローエントリを作る

○ 案2: 「自分のMACアドレス」を意味するmatch fieldを増やす

○ 案3: packet_typeに自分宛であるか示すフラグを増やす

○ 案4: 事前にNW設計した自分の IP宛のみdecapするフローエントリを作る

Page 14: Open flow tunnel extension on lagopus vswitch

Lagopus dataplane Tunnel実装の制約 (Dec 2015)

● decap○ GREは拡張GRE(ver=1)かつseqなし固定、MPLS PWはCW/ACH未対応

● encap○ GREは拡張GRE(ver=1)かつseqなし固定、MPLS PWはCW/ACH未対応

○ logical port作成には未対応

○ ipv4_dst, eth_dstはケアしないので静的に設定するかコントローラががんばる

● match○ 自ホスト宛を示すmatchはないので、全部受けるか静的かコントローラががんばる

● set-field○ gre keyはmaskつきset-fieldに対応させた

● その他全体的に○ まだチェックが甘いので想定外のパケットを受け取ると死ぬ可能性あり

Page 15: Open flow tunnel extension on lagopus vswitch

Tunnel実装の動作デモ環境

2ポート接続、片方をGRE tunnelにする。1ホストで実現するためnetnsを活用。

Host

Lagopus

NET0

NET1

GRE172.21.1.1/24

172.21.1.2/24

veth110.1.0.1

veth010.1.0.2

veth2 veth3

Page 16: Open flow tunnel extension on lagopus vswitch

Tunnelデモ: Linux側設定

Network NamespaceにそれぞれI/Fを割り振り、片方にGREを設定。

sudo ip netns add NET0sudo ip netns add NET1sudo ip link set veth1 netns NET0sudo ip link set veth3 netns NET1sudi ip netns exec NET0 arp -i veth1 -s 10.1.0.2 xx:xx:xx:xx:xx:xx pubsudo ip netns exec NET0 ip addr add 10.1.0.1/24 dev veth1sudo ip netns exec NET0 ip link add gr0 type gretap key 1 local 10.1.0.1 remote 10.1.0.2sudo ip netns exec NET0 ip addr add 172.21.1.1/24 dev gr0sudo ip netns exec NET1 ip addr add 172.21.1.2/24 dev veth3

sudo ip netns exec NET0 ping 172.21.1.2で応答がないことを確認

Page 17: Open flow tunnel extension on lagopus vswitch

Tunnelデモ: Lagopus側設定

lagoshから流し込むlagopus.confはごくふつうの2ポートブリッジ。rawsock版。

lagosh --dsl-encodeでDSL形式にする。

channel ch { dst-addr 127.0.0.1; }controller ctl { channel ch; }interface i0 { type ethernet-rawsock; device veth0; }interface i1 { type ethernet-rawsock; device veth2; }port p1 { interface i0; }port p2 { interface i1; }bridge br0 { controller ctl; port p1 1; port p2 2; }

Page 18: Open flow tunnel extension on lagopus vswitch

Tunnelデモ: フローエントリ

2ポート間のパケットを相互転送、ただし片方はGREトンネルを経由する。

下記内容をRyuアプリケーションとして記述する。

in_port=1,eth_type=ipv4,ipv4_src=10.1.0.1,ipv4_dst=10.1.0.2,ip_proto=gre,gre_key=1,apply_actions=decap(ether,ip),decap(ip,gre),decap(gre,next),output:2

in_port=2,apply_actions=encap(gre),set-field:1->gre_key,encap(ip),set-field:10.1.0.2->ipv4_src,set-field:10.1.0.1->ipv4_dst,encap(ether),set-field:xx:xx:xx:xx:xx:xx->eth_src,set-field:xx:xx:xx:xx:xx:xx->eth_dst,output:1

Page 19: Open flow tunnel extension on lagopus vswitch

Tunnelデモ

lagopus起動

sudo lagopus -C ./tunnel.dsl

Ryu起動

ryu-manager ./tunnel-demo.py

pingは通る?

sudo ip netns exec NET1 ping 172.21.1.1sudo ip netns exec NET0 ping 172.21.1.2

Page 20: Open flow tunnel extension on lagopus vswitch

GREトンネル越しのPingが通った!! (Dec 16, 16:35JST)

Page 21: Open flow tunnel extension on lagopus vswitch

ひっかかった点

● veth0(lagopus側GRE)のMACアドレスをLinuxに覚えてもらう方法○ 今回はveth0に10.1.0.2/24を振って、カーネルにARP返答してもらいました

● フローエントリのMACアドレス(veth0, veth1ともに)○ 今回は調べて直接書きました

● GREのverとかkeyとか○ 合わないと当然通信できない。 set-fieldできるがデフォルトもなるだけ揃えた

● encapしたIPヘッダのsum○ 合っていないとLinux側で捨てられる

○ encapで内部管理のethertypeを設定忘れ、チェックサム再計算が動いてなかった

○ 受け側でnetstat -w -sするとwith invalid headersの数字が増えていたため判明