LagopusでPPPoEを
使えるか考えてみた件
Jun 27, 2016
Masaru OKI @masaru0714
Lagopus?
● オープンソースのOpenFlowソフトウェアスイッチ。
● OpenFlow 1.3仕様に準拠。
● パケットヘッダのdecap, encap機能が拡張されている。
● 対応するヘッダは限定されている。0.2.7での対応は下記。
● eth, ipv4, udp, gre, vxlan, mpls
● ソースコードを少し書き足せば、他のヘッダにも対応できる。
PPPoE?
● フレッツ接続でおなじみのプロトコル。
● Ethernet上でPPP(Point-to-Point Protocol)通信する。
● PPPにより下記のような機能・情報が接続相手より提供される。
○ IDおよびパスワードによる認証
○ IPアドレス付与
○ ネームサーバーアドレス
○ default route (gateway IPアドレス)
LagopusでPPPoE?
パケットヘッダのdecap, encapでPPPoEヘッダを扱えれば、
LagopusでPPPoEを終端させることができるのでは!?
実現イメージ
Lagopus PCフレッツ
PPPoE
フレッツから付与
されたIPアドレス
ローカルネットワーク
例えば
192.168.0.1/24
例えば
192.168.0.2/24
PPPoEパケットフォーマットと処理対象
MAC DA MAC SA 0x8863 PPPoE
MAC DA MAC SA 0x8864 PPP LCP
MAC DA MAC SA 0x8864 PPP IPCP
MAC DA MAC SA 0x8864 PPP IPv4 Payload
OpenFlowコントローラに処理してもらう。
Lagopusでの処理対象
Lagopusでやらせたいパケットの変更(送信時)
● PPPヘッダをencap(あるいはpush)させ、eth_typeを0x8864(PPPoE)に変更
● MAC DAをフレッツ網の対向に変更、MAC SAを自分のMACに変更
○ default routeへのルーティング
● IPv4 srcをPPPで取得した自IPアドレスに変更、TCP/UDP srcも変更
○ NAT
MAC DA MAC SA 0x0800
PPP
IPv4 Payload
MAC DA MAC SA 0x8864 IPv4 Payload
Lagopusでやらせたいパケットの変更(受信時)
● PPPヘッダをdecap(あるいはpop)させ、eth_typeを0x0800(IP)に変更
● IPv4 dsrをPCのIPアドレスに変更、TCP/UDP dstも変更
○ NAT
● MAC DAをPCのものに、MAC SAは自分のものに変更
○ routing
○ 自前でやってもいい。 IPを書き換えた後OFPP_NORMALでroutingできるはず。
MAC DA MAC SA 0x8864 PPP IPv4 Payload
MAC DA MAC SA 0x0800 IPv4 Payload
コントローラのプログラミング量が意外と(?)多い
● Packet-In, Packet-Out
○ PPPoEセッション管理(PADI, PADO, PADR, PADS, PADT)
○ PPPセッション管理(LCP, IPCP)
● flow_mod - アドレス・ポートマッピング(NAT)
○ 末端のPCのソースポートはセッションごとにばらばらのため、 reactive型の処理にせざるを得ない。
○ Lagopusが改めてフレッツに送信する際に書き換えるソースポートの値の管理も必要。
○ TCPの通信が終了したら速やかにフローエントリを削除する必要がある。
● クライアントPCへのIPアドレス、default route、DNS情報提供(DHCP)
○ ひとまずあとまわしにして、いまは考えない。
○ 別マシンでdhcpdなど動かして、Lagopusに向けてパケットを送るよう情報を渡すことにする。
Lagopusに投入するフローエントリ
● イメージです。
● proactiveなもの
○ in_port=flets,eth_type=0x8863→コントローラへPacket-In
○ in_port=flets,eth_type=0x8864,ppp_proto=lcp→コントローラへPacket-In
○ in_port=flets,eth_type=0x8864,ppp_proto=ipcp→コントローラへPacket-In
○ in_port=PC,eth_type=IPv4,ip_proto=tcp→コントローラへPacket-In
● reactiveなもの(proactiveなものよりpriority highにする)
○ in_port=PC,eth_type=IPv4,ip_proto=tcp,tcp_src=???
→tcp_src,ipv4_srcを書き換えpppヘッダをつけてMAC DA,MAC SAも書き換えてoutput:flets
○ in_port=flets,eth_type=0x8864,ppp_proto=ip,ip_proto=tcp,tcp_dst=???
→pppヘッダを削ってtcp_dst,ipv4_dstを書き換えMAC DA,MAC SAも書き換えてoutput:PC
ここまでやってできあがるものはなに?
どうやら、そこらで売ってるブロードバンドルータの中身相当の開発になる、ようだ。
まだ組み上げていないけれど。
足りてないことも多い気がするけれど。(UIとか接続状況確認とか)
プロトコル処理はPythonでがんばってもらうとして、なんとかなりそうな気がしている。
これが動いたら、自宅のフレッツの終端をLagopusにするんだ……。
応用
できあがってもいないのに応用まで考えてみる。
処理を汎用で組むので、PPPoEの受け側(AC)を作成することもできるだろう。
なんらか間に挟まって単にフィルタリングさせることもきっとできる。
まとめ
● LagopusはOpenFlowソフトウェアスイッチで改造も容易
● PPPoEの処理はコントローラと二人三脚で実現できそう
● 実現できればいろいろな応用も考えられる
実装がんばります!

LagopusでPPPoEを使えるか考えてみた件