Weitere ähnliche Inhalte Ähnlich wie MAP 実装してみた (20) Mehr von Masakazu Asama (6) Kürzlich hochgeladen (12) MAP 実装してみた1. Pari s
MAP 実装してみた
浅間 正和 @ 有限会社 銀座堂
2. MAP とは?
• 現在 IETF Softwire WG で標準化が進められている
IPv6 Network 上で IPv4 Service を展開するための
Protocol のひとつ
☞ http://tools.ietf.org/html/draft-ietf-softwire-map
• IPv4 Packet を IPv6 Header で Capsule 化する MAP-E
(Encapsulation)と IPv4 Packet の IPv4 Header を IPv6
Header に書き換える MAP-T (Translation)の 2 種類
が存在
• Provider Network 側に変換 Table を持つ Address and
Port 変換装置を持たない(Stateless)
• ひとつの IPv4 Address を複数の顧客で共有可能
3. MAP 以外の IPv4 over IPv6 プロトコル
*5
*1 *2 *3 *3 *4
Lightweight
464XLAT DS-Lite MAP-T MAP-E 4rd
4over6
Trans
or Trans Encap Trans Encap Hybrid Encap
Encap
Stateful
or Stateful Stateful Stateless Stateless Stateless Stateless
Stateless
Mesh ready N N Y Y Y N
Calculated Calculated Calculated
Address Assigned by Assigned by
- from from from
mapping concentrator concentrator
domain rule domain rule domain rule
IETF WG v6ops softwire softwire softwire softwire softwire
*1 http://tools.ietf.org/html/draft-ietf-v6ops-464xlat
*2 http://tools.ietf.org/html/rfc6333
*3 http://tools.ietf.org/html/draft-ietf-softwire-map
*4 http://tools.ietf.org/html/draft-ietf-softwire-4rd
*5 http://tools.ietf.org/html/draft-cui-softwire-b4-translated-ds-lite
4. Translation or Encapsulation
Translation Encapsulation
IPv4 header IPv4 header
The Internet TCP header TCP header
Payload Payload
IPv6 to IPv4 IPv4 to IPv6 Decapsulation Encapsulation
BR
Translation Translation
IPv6 header
IPv6 header
IPv4 header
Provider IPv6 Network TCP header
TCP header
Payload
Payload
IPv4 to IPv6 IPv6 to IPv4
CE
Translation Translation Encapsulation Decapsulation
IPv4 header IPv4 header
Customer Network TCP header TCP header
Payload Payload
5. Translation or Encapsulation
• Translation の利点
✓ Provider IPv6 Network で IPv6 の ACL や QoS を
設定することができる
✓ Encapsulation に比べて MTU がほんのちょっと
だけ大きくなる
• Encapsulation の利点
✓ IPv4 Header 情報を欠落させることなく Provider
IPv6 Network 内を透過させることができる
✓ とてつもなくめんどくさい Checksum 再計算を
する必要がない
参考) http://www.ietf.org/proceedings/interim/2011/09/26/softwire/slides/softwire-17.pdf
6. Stateful or Stateless
Stateful (Ex. DS-Lite) Stateless (Ex. MAP)
AFTR BR
Protocol Src Addr Src Port Map Addr Map Port Dst Addr Dst Port
TCP 192.168.1.11 49152 192.0.2.11 49152 198.51.100.11 80
TCP 192.168.2.11 49152 192.0.2.12 49153 203.0.113.11 25
UDP 192.168.2.22 49153 192.0.2.12 49154 203.0.113.22 53
B4 CE
7. Stateful or Stateless
• Stateful の利点
✓ Stateless と比較してより少ない IPv4 Address で
IPv4 Service を提供可能
• Stateless の利点
✓ 悪意のある利用者に Port 番号を占有されてし
まう心配がない
✓ Provider 側で状態を持つ必要がないため Stateful
と比較して安価に装置を実装可能
✓ Anycast 等の既存の冗長性確保技術が利用可能
✓ Port 割り当ての Log を保管する必要がない
参考) http://tools.ietf.org/html/draft-ietf-softwire-stateless-4v6-motivation
8. Mesh or Hub and spoke
BR
Provider IPv6 Network
Mesh
CE
CE
Customer Network
Customer Network
9. Mesh or Hub and spoke
BR
Provider IPv6 Network
Hub and spoke
CE
CE
Customer Network
Customer Network
12. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
13. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致!
14. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致! EA-bits length 分切り取る
0x1234
15. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致! EA-bits length 分切り取る
0x1234
切り取った分を
Rule IPv4 prefix に
左から埋める
192.0.2.18
16. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致! EA-bits length 分切り取る
0x1234
切り取った分を
残りは
Rule IPv4 prefix に
Port-set ID
左から埋める
192.0.2.18 0x34
17. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致! EA-bits length 分切り取る
0x1234 Port-set
切り取った分を min max
残りは
Rule IPv4 prefix に Port-range #1 0x1340 0x134f
Port-set ID
左から埋める Port-range #2 0x2340 0x234f
192.0.2.18 0x34 : : :
Port-range #15 0xf340 0xf34f
※ Port-set ID Offset が 4bit の場合
18. 超簡単!こんなかんじで Mapping!
Mapping Rule Table
Rule IPv6 Rule IPv4 EA-bits
BR address = 2001:db8::1 (MAP-E) prefix prefix length
BR prefix = 2001:db8::/64 (MAP-T)
Rule #1 2001:db8:100::/40 192.0.2.0/24 16
Rule #2 2001:db8:200::/40 198.51.100.0/24 16
CE 2001:db8:112:3400::/56
Rule #1 と一致! EA-bits length 分切り取る
0x1234 Port-set
切り取った分を min max
残りは
Rule IPv4 prefix に Port-range #1 0x1340 0x134f
Port-set ID
左から埋める Port-range #2 0x2340 0x234f
192.0.2.18 0x34 : : :
Port-range #15 0xf340 0xf34f
= 0xc0000212
※ Port-set ID Offset が 4bit の場合
32bits 16bits
2001:db8:112:3400:c0:2:1200:3400 = My Addr!
19. 超簡単!こんなかんじで Mapping!
IPv6 dst addr 2001:db8::1
203.0.113.80 = 0xcb007150 IPv6 src addr 2001:db8:112:3400:c0:2:1200:3400
IPv6 dst addr 2001:db8::cb:71:5000:0 IPv4 dst addr 203.0.113.80
IPv6 src addr 2001:db8:112:3400:c0:2:1200:3400 IPv4 src addr 192.0.2.18
TCP dst port 80 TCP dst port 80
TCP src port 4928 TCP src port 4928
MAP-T の場合 MAP-E の場合
CE src port は Port-set から
空いているものを使う
IPv4 dst addr 203.0.113.80
IPv4 src addr 192.168.1.11
TCP dst port 80
TCP src port 49152
20. 超簡単!こんなかんじで Mapping!
IPv4 dst addr 203.0.113.80
IPv4 src addr 192.0.2.18
TCP dst port 80
TCP src port 4928
src addr と src port の
BR validation を実施
MAP-T の場合 MAP-E の場合
IPv6 dst addr 2001:db8::cb:71:5000:0 IPv6 dst addr 2001:db8::1
IPv6 src addr 2001:db8:112:3400:c0:2:1200:3400 IPv6 src addr 2001:db8:112:3400:c0:2:1200:3400
TCP dst port 80 IPv4 dst addr 203.0.113.80
TCP src port 4928 IPv4 src addr 192.0.2.18
TCP dst port 80
TCP src port 4928
21. 超簡単!こんなかんじで Mapping!
IPv4 dst addr 192.0.2.18
IPv4 src addr 203.0.113.80
TCP dst port 4928
TCP src port 80
② IPv4 dst addr と dst port ① Mapping Rule Table から
からIPv6 dst addr 計算 BR IPv4 dst addr を Key に探索
MAP-T の場合 MAP-E の場合
IPv6 dst addr 2001:db8:112:3400:c0:2:1200:3400 IPv6 dst addr 2001:db8:112:3400:c0:2:1200:3400
IPv6 src addr 2001:db8::cb:71:5000:0 IPv6 src addr 2001:db8::1
TCP dst port 4928 IPv4 dst addr 192.0.2.18
TCP src port 80 IPv4 src addr 203.0.113.80
TCP dst port 4928
TCP src port 80
22. 超簡単!こんなかんじで Mapping!
IPv6 dst addr 2001:db8:112:3400:c0:2:1200:3400
IPv6 src addr 2001:db8::1
IPv6 dst addr 2001:db8:112:3400:c0:2:1200:3400 IPv4 dst addr 192.0.2.18
IPv6 src addr 2001:db8::cb:71:5000:0 IPv4 src addr 203.0.113.80
TCP dst port 4928 TCP dst port 4928
TCP src port 80 TCP src port 80
MAP-T の場合 MAP-E の場合
CE NAPT Table から IPv4 dst
addr と dst port を求める
IPv4 dst addr 192.168.1.11
IPv4 src addr 203.0.113.80
TCP dst port 49152
TCP src port 80
23. 作戦
• Linux Kernel に map という名前の Virtual Network
Interface を実装
• iproute2 を改造し map Interface を作ったり削除した
りできるようにする
• Map Rule Table にある IPv4 network address 宛を map
Interface に routing することで IPv4 → IPv6 への変換
処理を Kick する
• 自分自身の IPv6 address 宛を map Interface に routing
することで IPv6 → IPv4 への変換処理を Kick する
☞ 自分自身の IPv6 Address は長いし必ずひとつし
かないので map Interface が自動で routing する
24. 作戦
• BR の場合の設定はこんなかんじ
# ip map add map0 role br ¥
br-address 2001:db8::1/64 ¥
default-forwarding-mode (translation|encapsulation)
# ip map add-rule dev map0 ¥
ipv6-prefix 2001:db8:100::/40 ¥
ipv4-prefix 192.0.2.0/24 ¥
ea-length 16
# ip route add 192.0.2.0/24 dev map0
• CE の場合の設定はこんなかんじ
# ip map add map0 role ce tunnel-source eth1 ¥
br-address 2001:db8::/64 ¥
default-forwarding-mode (translation|encapsulation)
# ip map add-rule dev map0 ¥
ipv6-prefix 2001:db8:100::/40 ¥
ipv4-prefix 192.0.2.0/24 ¥
ea-length 16
# ip route add 0.0.0.0/0 dev map0
25. 作戦
static const struct net_device_ops map_netdev_ops = {
...
.ndo_start_xmit = map_transmit,
...
};
static netdev_tx_t
map_transmit(struct sk_buff *skb, struct net_device *dev)
{
struct map *m = netdev_priv(dev);
...
switch (ntohs(skb->protocol)) {
case ETH_P_IP:
map_v4v6(skb, m);
break;
case ETH_P_IPV6:
map_v6v4(skb, m);
break;
...
}
return NETDEV_TX_OK;
}
26. 作戦
int
map_trans_forward_v6v4(struct sk_buff *skb, struct map *m,
__be32 *saddr4, __be32 *daddr4)
{
...
skb_pull(skb, hsize);
skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IP);
...
}
int
map_trans_forward_v4v6(struct sk_buff *skb, struct map *m,
struct map_rule *mr)
{
...
skb_pull(skb, orig_iph.ihl * 4);
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IPV6);
...
}
27. 作戦
int
map_encap_forward_v6v4(struct sk_buff *skb, struct map *m,
__be32 *saddr4, __be32 *daddr4)
{
...
skb_pull(skb, hsize);
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IP);
...
}
int
map_encap_forward_v4v6(struct sk_buff *skb, struct map *m,
struct map_rule *mr)
{
...
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IPV6);
...
}
28. 作戦
int
map_trans_forward_v6v4(struct sk_buff *skb, struct map *m,
__be32 *saddr4, __be32 *daddr4)
{
...
netif_rx(skb);
...
}
int
map_trans_forward_v4v6(struct sk_buff *skb, struct map *m,
struct map_rule *mr)
{
...
dst = ip6_route_output(net, NULL, &fl6);
dst_metric_set(dst, RTAX_MTU, 1280);
...
skb_dst_set(skb, dst);
...
ip6_local_out(skb);
...
}
29. めんどくさいはなし(1)
• ひとつの IPv4 Address を複数の顧客で共有する場合
map Interface に IPv4 Address を設定するとマズい
☞ 例えば自分自身の Address が 192.0.2.18 の状況
で通信したい相手の Address も同じ 192.0.2.18
の場合 map Interface に 192.0.2.18 が設定されて
いると自分自身宛と勘違いしちゃいそう
• でも map Interface に IPv4 Address がないと iptables の
NAT 使えなそう
• つうかそもそも Port restricted NAPT どうしよう
☞ なんかおもしろそうだし map Interface に NAPT
Full Scratch で実装しちゃえ
30. Port restricted NAPT の実装
1 session につき 1 map_napt_node 構造体変数を allocate
TCP の場合は FIN/RST を捕捉した時点で free
UDP/ICMP の場合は timeout した時点で free
struct map_napt_node
struct hlist_node nn_hash_lup0
WAN 側の情報からの探索用 struct hlist_node nn_hash_lup1
LAN 側の情報からの探索用 struct hlist_node nn_hash_crat
struct list_head nn_list WAN 側の情報
新しい node を作るときの重複チェック用
__be32 raddr
有効期限切れ node のチェック用 LAN 側の情報
__be32 laddr
struct map __be32 maddr
: : __be16 rport CE 自身の情報
struct hlist_head napt_hash_lup0[...] __be16 lport
struct hlist_head napt_hash_lup1[...] __be16 mport
struct hlist_head napt_hash_crat[...] __u8 proto
struct list_head napt_list __u8 flags
: : unsigned long last_used
31. Port restricted NAPT の実装
IPv4 dst addr 203.0.113.1 IPv4 dst addr 198.51.100.1
IPv4 src addr 192.0.2.18 IPv4 src addr 192.0.2.18
TCP dst port 80 TCP dst port 80
TCP src port 4928 TCP src port 4928
CE src port は dst addr で
Unique
IPv4 dst addr 203.0.113.1 IPv4 dst addr 198.51.100.1
IPv4 src addr 192.168.1.11 IPv4 src addr 192.168.1.11
TCP dst port 80 TCP dst port 80
TCP src port 49152 TCP src port 49153
Host
32. めんどくさいはなし(2)
• MAP-T の Checksum 再計算めちゃくちゃめんどい
• ICMP Echo が TTL 切れとかで ICMP Error で帰ってく
る場合;まず内側の IP Header を Mapping Rule Table
から Address を求めて書き換えて Checksum 再計算…
src addr 192.0.2... src addr 2001:db8:...
IPv4 hdr IPv6 hdr
dst addr 198.51.100... dst addr 2001:db8:...
type/code error type/code error
ICMPv4 hdr ICMPv6 hdr
⇄
checksum 0x1665 checksum 0x33aa
src addr 198.51.100... src addr 2001:db8:...
IPv4 hdr IPv6 hdr
dst addr 203.0.113... dst addr 2001:db8:...
type/code echo type/code echo
ICMPv4 hdr ICMPv6 hdr
checksum 0x821c checksum 0x5713
33. 最新情報
• Jul 29 - Aug 3, 2012 に Vancouver で開催された IETF 84
で MAP-T と MAP-E は別物ということになり MAP-E
が Standard で MAP-T が Experimental ということにな
りました
☞ MAP-T と MAP-E を別の Protocol とするかそれ
とも MAP-T と MAP-E でひとつの Protocol とす
るかは多数決でも決着がつかなかったため最後
は coin-toss で決着つけたらしい…
• ということで現在の MAP の draft は MAP-E のみとな
るよう書き換えられています
• ちなみに本実装は IETF83 @ Paris のときのもの
34. 参考
• MAP 対応 Vyatta(ASAMAP)仮置き場
☞ http://enog.jp/~masakazu/vyatta/map/
• Mapping of Address and Port (MAP)
☞ http://tools.ietf.org/html/draft-ietf-softwire-map
• Generic Packet Tunneling in IPv6 Specification
☞ http://tools.ietf.org/html/rfc2473
• IP/ICMP Translation Algorithm
☞ http://tools.ietf.org/html/rfc6145
• IPv6 Addressing of IPv4/IPv6 Translators
☞ http://tools.ietf.org/html/rfc6052
Hinweis der Redaktion \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n