Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
ASAMAP 開発秘話
 浅間 正和 @ 有限会社 銀座堂
はじめに…
•   本資料は Paris MAP(http://tools.ietf.org/html/draft-ietf-
    softwire-map-01)を実装した際の設計や大変だった
    こと等を説明するものです
•   Paris MAP は MAP-E と MAP-T の両方に対応する
    “One solution” として提案されていましたが Jul 29 -
    Aug 3, 2012 に Vancouver で開催された IETF84 にて
    “Two solutions” として分けることが合意されました
    ☞    MAP-E → MAP(Standard track)
    ☞    MAP-T → MAP-T(Experimental track)
•   本資料上は Paris MAP のことを単に MAP としていま
    すので予めご了承ください
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 を複数の顧客で共有可能
超簡単!こんなかんじで Mapping!




 CE
超簡単!こんなかんじで Mapping!




 CE   2001:db8:112:3400::/56
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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 と一致!
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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 の場合
超簡単!こんなかんじで 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!
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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
超簡単!こんなかんじで 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
作戦
•   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 する
作戦
 •   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
作戦
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;
}
作戦
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);
        ...
}
作戦
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);
        ...
}
作戦
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);
        ...
}
MAP-T と MAP-E の混在構成
                      default-forwarding-mode translation


                                     BR




                            Provider IPv6 Network




                                                                  CE
                 CE

                                                       destination address 側の
         MAP-T                                             mapping rule の
                                                       forwarding mode が適用
         MAP-E
                                                                される
forwarding-mode encapsulation                        forwarding-mode translation
なんで routing で kick させるのか?
•   MAP-T では IPv6 header の next header field をみて
    MAP か否かを判定できない
    ☞   MAP-E の場合は IPv6 header の next header field
        が IPIP(0x04)であれば MAP と判定できる
•   MAP-T は MAP-E と異なり必ず BR/CE がひとつの
    IPv6 address を持つわけではない
    ☞   BR は IID に IPv4 destination address を埋め込む
    ☞   CE も IPv4 prefix を割り当てられる構成の場合
        IID は複数の値を取り得る
☞     ということで XFRM は使えない…
☞     Netfilter という手もあるけど読みたくない…
Fragment いろいろ




            IPv4 Header               IPv4 Header
 20 byte                    20 byte
           (offset 1472)                 (offset 0)

                             8 byte   UDP Header




                                                                     ?
              DATA
                                                    1500 byte



                                                                CE
528 byte
           (1473 2000)


                                         DATA
                          1472 byte
                                       (1 1472)
IPv4 Header                IPv4 Header


 Fragment いろいろ
                                                                                              20 byte                     20 byte
                                                                                                        (offset 1472)                  (offset 0)

                                                                                                                           8 byte   UDP Header
                                                                                                           DATA




                                                                                                                                                    1500 byte
                                                                                             528 byte
                                                                                                        (1473 2000)


                                                                                                                                        DATA
                                                                                                                        1472 byte
                                                                                                                                      (1 1472)




 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

            IPv4 Header                IPv4 Header                             IPv4 Header               IPv4 Header                IPv4 Header
 20 byte                     20 byte                                20 byte                   20 byte                     20 byte
           (offset 1432)                  (offset 0)                            (offset 1472)              (offset 1432)                  (offset 0)
                                                                                                           DATA


                                                       1460 byte




                                                                                                                                                    1460 byte
              DATA            8 byte   UDP Header                                DATA         40 byte                      8 byte   UDP Header
568 byte                                                           528 byte                             (1433 1472)
           (1433 2000)                                                        (1473 2000)

                                           DATA                                                                                         DATA
                           1432 byte                                                                                    1432 byte
                                         (1 1432)                                                                                     (1 1432)




 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

           IPv6 Frag Hdr               IPv6 Frag Hdr                           IPv4 Header              IPv6 Frag Hdr               IPv6 Frag Hdr
  8 byte                      8 byte                                20 byte                    8 byte                      8 byte
            (offset 1232)                 (offset 0)                            (offset 1472)               (offset 1232)                 (offset 0)
                                       IPv4 Header                                                                                  IPv4 Header
                                                       1280 byte




                                                                                                                                                    1280 byte
              DATA           20 byte                                             DATA                      DATA           20 byte
796 byte                                 (offset 0)                 528 byte                  268 byte                                 (offset 0)
           (1205 2000)                                                        (1473 2000)               (1205 1472)
                              8 byte   UDP Header                                                                          8 byte   UDP Header



                                           DATA                                                                                         DATA
                           1204 byte                                                                                    1204 byte
                                         (1 1204)                                                                                     (1 1204)
IPv4 Header                IPv4 Header


 Fragment いろいろ
                                                                                                20 byte                     20 byte
                                                                                                          (offset 1472)                  (offset 0)

                                                                                                                             8 byte   UDP Header
                                                                                                             DATA




                                                                                                                                                      1500 byte
                                                                                               528 byte
                                                                                                          (1473 2000)


                                                                                                                                          DATA
                                                                                                                          1472 byte
                                                                                                                                        (1 1472)




 40 byte   IPv6 Header       40 byte   IPv6 Header                    40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

            IPv4 Header                IPv4 Header                               IPv4 Header               IPv4 Header                IPv4 Header
 20 byte                     20 byte                                  20 byte                   20 byte                     20 byte
           (offset 1432)                  (offset 0)                              (offset 1472)              (offset 1432)                  (offset 0)
                                                                                                             DATA


                                                       1460 byte




                                                                                                                                                      1460 byte
              DATA            8 byte   UDP Header                                  DATA         40 byte                      8 byte   UDP Header
568 byte                                                             528 byte                             (1433 1472)
           (1433 2000)                                                          (1473 2000)

                                           DATA                                                                                           DATA
                           1432 byte                                                                                      1432 byte

                                                                   IPv4 stack で fragment
                                         (1 1432)                                                                                       (1 1432)




 40 byte   IPv6 Header       40 byte   IPv6 Header                    40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

           IPv6 Frag Hdr               IPv6 Frag Hdr                             IPv4 Header              IPv6 Frag Hdr               IPv6 Frag Hdr
  8 byte                      8 byte                                  20 byte                    8 byte                      8 byte
            (offset 1232)                 (offset 0)                              (offset 1472)               (offset 1232)                 (offset 0)
                                       IPv4 Header                                                                                    IPv4 Header
                                                       1280 byte




                                                                                                                                                      1280 byte
              DATA           20 byte                                               DATA                      DATA           20 byte
796 byte                                 (offset 0)                   528 byte                  268 byte                                 (offset 0)
           (1205 2000)                                                          (1473 2000)               (1205 1472)
                              8 byte   UDP Header                                                                            8 byte   UDP Header



                                           DATA                                                                                           DATA
                           1204 byte                                                                                      1204 byte

                                                                   IPv6 stack で fragment
                                         (1 1204)                                                                                       (1 1204)
IPv4 Header                IPv4 Header


 Fragment いろいろ
                                                                                              20 byte                     20 byte
                                                                                                        (offset 1472)                  (offset 0)

                                                                                                                           8 byte   UDP Header
                                                                                                           DATA




                                                                                                                                                    1500 byte
                                                                                             528 byte
                                                                                                        (1473 2000)




       BR/CE で
                                                                                                                                        DATA

                                                                        BR/CE で                                         1472 byte
                                                                                                                                      (1 1472)



    reassemble 実施                                                  reassemble 未実施
 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

            IPv4 Header                IPv4 Header                             IPv4 Header               IPv4 Header                IPv4 Header
 20 byte                     20 byte                                20 byte                   20 byte                     20 byte
           (offset 1432)                  (offset 0)                            (offset 1472)              (offset 1432)                  (offset 0)
                                                                                                           DATA


                                                       1460 byte




                                                                                                                                                    1460 byte
              DATA            8 byte   UDP Header                                DATA         40 byte                      8 byte   UDP Header
568 byte                                                           528 byte                             (1433 1472)
           (1433 2000)                                                        (1473 2000)

                                           DATA                                                                                         DATA
                           1432 byte                                                                                    1432 byte
                                         (1 1432)                                                                                     (1 1432)




 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

           IPv6 Frag Hdr               IPv6 Frag Hdr                           IPv4 Header              IPv6 Frag Hdr               IPv6 Frag Hdr
  8 byte                      8 byte                                20 byte                    8 byte                      8 byte
            (offset 1232)                 (offset 0)                            (offset 1472)               (offset 1232)                 (offset 0)
                                       IPv4 Header                                                                                  IPv4 Header
                                                       1280 byte




                                                                                                                                                    1280 byte
              DATA           20 byte                                             DATA                      DATA           20 byte
796 byte                                 (offset 0)                 528 byte                  268 byte                                 (offset 0)
           (1205 2000)                                                        (1473 2000)               (1205 1472)
                              8 byte   UDP Header                                                                          8 byte   UDP Header



                                           DATA                                                                                         DATA
                           1204 byte                                                                                    1204 byte
                                         (1 1204)                                                                                     (1 1204)
IPv4 Header                IPv4 Header


 Fragment いろいろ
                                                                                              20 byte                     20 byte
                                                                                                        (offset 1472)                  (offset 0)

                                                                                                                           8 byte   UDP Header
                                                                                                           DATA




                                                                                                                                                    1500 byte
                                                                                             528 byte
                                                                                                        (1473 2000)


                                                                                                                                        DATA
                                                                                                                        1472 byte
                                                                                                                                      (1 1472)




 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

            IPv4 Header                IPv4 Header                             IPv4 Header               IPv4 Header                IPv4 Header
 20 byte                     20 byte                                20 byte                   20 byte                     20 byte
           (offset 1432)                  (offset 0)                            (offset 1472)              (offset 1432)                  (offset 0)
                                                                                                           DATA


                                                       1460 byte




                                                                                                                                                    1460 byte
              DATA            8 byte   UDP Header                                DATA         40 byte                      8 byte   UDP Header
568 byte                                                           528 byte                             (1433 1472)
           (1433 2000)                                                        (1473 2000)

                                           DATA                                                                                         DATA
                           1432 byte                                                                                    1432 byte
                                         (1 1432)                                                                                     (1 1432)




 40 byte   IPv6 Header       40 byte   IPv6 Header                  40 byte   IPv6 Header     40 byte   IPv6 Header       40 byte   IPv6 Header

           IPv6 Frag Hdr               IPv6 Frag Hdr                           IPv4 Header              IPv6 Frag Hdr               IPv6 Frag Hdr
  8 byte                      8 byte                                20 byte                    8 byte                      8 byte
            (offset 1232)                 (offset 0)                            (offset 1472)               (offset 1232)                 (offset 0)
                                       IPv4 Header                                                                                  IPv4 Header
                                                       1280 byte




                                                                                                                                                    1280 byte
              DATA           20 byte                                             DATA                      DATA           20 byte
796 byte                                 (offset 0)                 528 byte                  268 byte                                 (offset 0)
           (1205 2000)                                                        (1473 2000)               (1205 1472)
                              8 byte   UDP Header                                                                          8 byte   UDP Header




                           1204 byte
                                           DATA
                                         (1 1204)
                                                                   ←これにしてます。                                            1204 byte
                                                                                                                                        DATA
                                                                                                                                      (1 1204)
Fragment いろいろ
•   なんで BR/CE で reassemble してるのか?
    ☞   IPv4 fragment packet の TCP/UDP/ICMP header を
        含まない packet はそれだけでは PSID がわから
        ないので encapsulation できない(decapsulation
        時も validation できない)
    ☞   TCP/UDP/ICMP header 付き packet の header を
        cache させる方法も考えられるけどめんどい
    ☞   IPv4 の reassemble は Linux kernel で提供されて
        いるのでそちらを利用
    ☞   IPv6 の reassemble は Linux kernel の機能を簡単
        に利用できなそうだったので full scratch で実装
Fragment いろいろ
 •   なんで IPv6 stack で fragment してるのか?
     ☞    それがいちばん簡単だったから
     ☞    IPv6 の最小 MTU である 1280 に設定しているの
          で通らない可能性はないはず

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);
        ...
}
Port restricted NAPT の実装
 •   ひとつの 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 で実装しちゃえ
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
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
MAP-T の Checksum 再計算
 •   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
今後のはなし
•   MAP-T 捨てたい…
    ☞   ていうか XFRM を使う方法に戻したい…
    ☞   IPv6 address を持つようになるので PMTUd が出
        来るようになるはず
    ☞   IPv6 stack を local に上っていく場合は Linux
        kernel の IPv6 reassemble 機能も利用できるよう
        になるはず
•   IPv6 packet の最大 size を設定できるようにしたい
    ☞   1280 byte hard coding はさすがに…?
•   IPv4 stack での fragment にも対応したほうが良い?
    ☞   ちょっと調べた感じではけっこうめんどそう…
参考
•   MAP 対応 Vyatta(ASAMAP)仮置き場
    ☞    http://enog.jp/~masakazu/vyatta/map/  
•   Mapping of Address and Port with Encapsulation (MAP)  
    ☞    http://tools.ietf.org/html/draft-ietf-softwire-map  
•   Mapping of Address and Port using Translation (MAP-T)  
    ☞    http://tools.ietf.org/html/draft-ietf-softwire-map-t  
•   Generic Packet Tunneling in IPv6 Specification 
    ☞    http://tools.ietf.org/html/rfc2473  
•   IP/ICMP Translation Algorithm  
    ☞    http://tools.ietf.org/html/rfc6145  

More Related Content

ASAMAP 開発秘話

  • 1. ASAMAP 開発秘話 浅間 正和 @ 有限会社 銀座堂
  • 2. はじめに… • 本資料は Paris MAP(http://tools.ietf.org/html/draft-ietf- softwire-map-01)を実装した際の設計や大変だった こと等を説明するものです • Paris MAP は MAP-E と MAP-T の両方に対応する “One solution” として提案されていましたが Jul 29 - Aug 3, 2012 に Vancouver で開催された IETF84 にて “Two solutions” として分けることが合意されました ☞ MAP-E → MAP(Standard track) ☞ MAP-T → MAP-T(Experimental track) • 本資料上は Paris MAP のことを単に MAP としていま すので予めご了承ください
  • 3. 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 を複数の顧客で共有可能
  • 6. 超簡単!こんなかんじで 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
  • 7. 超簡単!こんなかんじで 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 と一致!
  • 8. 超簡単!こんなかんじで 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
  • 9. 超簡単!こんなかんじで 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
  • 10. 超簡単!こんなかんじで 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
  • 11. 超簡単!こんなかんじで 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 の場合
  • 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 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!
  • 13. 超簡単!こんなかんじで 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
  • 14. 超簡単!こんなかんじで 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
  • 15. 超簡単!こんなかんじで 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
  • 16. 超簡単!こんなかんじで 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
  • 17. 作戦 • 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 する
  • 18. 作戦 • 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
  • 19. 作戦 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; }
  • 20. 作戦 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); ... }
  • 21. 作戦 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); ... }
  • 22. 作戦 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); ... }
  • 23. MAP-T と MAP-E の混在構成 default-forwarding-mode translation BR Provider IPv6 Network CE CE destination address 側の MAP-T mapping rule の forwarding mode が適用 MAP-E される forwarding-mode encapsulation forwarding-mode translation
  • 24. なんで routing で kick させるのか? • MAP-T では IPv6 header の next header field をみて MAP か否かを判定できない ☞ MAP-E の場合は IPv6 header の next header field が IPIP(0x04)であれば MAP と判定できる • MAP-T は MAP-E と異なり必ず BR/CE がひとつの IPv6 address を持つわけではない ☞ BR は IID に IPv4 destination address を埋め込む ☞ CE も IPv4 prefix を割り当てられる構成の場合 IID は複数の値を取り得る ☞ ということで XFRM は使えない… ☞ Netfilter という手もあるけど読みたくない…
  • 25. Fragment いろいろ IPv4 Header IPv4 Header 20 byte 20 byte (offset 1472) (offset 0) 8 byte UDP Header ? DATA 1500 byte CE 528 byte (1473 2000) DATA 1472 byte (1 1472)
  • 26. IPv4 Header IPv4 Header Fragment いろいろ 20 byte 20 byte (offset 1472) (offset 0) 8 byte UDP Header DATA 1500 byte 528 byte (1473 2000) DATA 1472 byte (1 1472) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header 20 byte 20 byte 20 byte 20 byte 20 byte (offset 1432) (offset 0) (offset 1472) (offset 1432) (offset 0) DATA 1460 byte 1460 byte DATA 8 byte UDP Header DATA 40 byte 8 byte UDP Header 568 byte 528 byte (1433 1472) (1433 2000) (1473 2000) DATA DATA 1432 byte 1432 byte (1 1432) (1 1432) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv6 Frag Hdr IPv6 Frag Hdr IPv4 Header IPv6 Frag Hdr IPv6 Frag Hdr 8 byte 8 byte 20 byte 8 byte 8 byte (offset 1232) (offset 0) (offset 1472) (offset 1232) (offset 0) IPv4 Header IPv4 Header 1280 byte 1280 byte DATA 20 byte DATA DATA 20 byte 796 byte (offset 0) 528 byte 268 byte (offset 0) (1205 2000) (1473 2000) (1205 1472) 8 byte UDP Header 8 byte UDP Header DATA DATA 1204 byte 1204 byte (1 1204) (1 1204)
  • 27. IPv4 Header IPv4 Header Fragment いろいろ 20 byte 20 byte (offset 1472) (offset 0) 8 byte UDP Header DATA 1500 byte 528 byte (1473 2000) DATA 1472 byte (1 1472) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header 20 byte 20 byte 20 byte 20 byte 20 byte (offset 1432) (offset 0) (offset 1472) (offset 1432) (offset 0) DATA 1460 byte 1460 byte DATA 8 byte UDP Header DATA 40 byte 8 byte UDP Header 568 byte 528 byte (1433 1472) (1433 2000) (1473 2000) DATA DATA 1432 byte 1432 byte IPv4 stack で fragment (1 1432) (1 1432) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv6 Frag Hdr IPv6 Frag Hdr IPv4 Header IPv6 Frag Hdr IPv6 Frag Hdr 8 byte 8 byte 20 byte 8 byte 8 byte (offset 1232) (offset 0) (offset 1472) (offset 1232) (offset 0) IPv4 Header IPv4 Header 1280 byte 1280 byte DATA 20 byte DATA DATA 20 byte 796 byte (offset 0) 528 byte 268 byte (offset 0) (1205 2000) (1473 2000) (1205 1472) 8 byte UDP Header 8 byte UDP Header DATA DATA 1204 byte 1204 byte IPv6 stack で fragment (1 1204) (1 1204)
  • 28. IPv4 Header IPv4 Header Fragment いろいろ 20 byte 20 byte (offset 1472) (offset 0) 8 byte UDP Header DATA 1500 byte 528 byte (1473 2000) BR/CE で DATA BR/CE で 1472 byte (1 1472) reassemble 実施 reassemble 未実施 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header 20 byte 20 byte 20 byte 20 byte 20 byte (offset 1432) (offset 0) (offset 1472) (offset 1432) (offset 0) DATA 1460 byte 1460 byte DATA 8 byte UDP Header DATA 40 byte 8 byte UDP Header 568 byte 528 byte (1433 1472) (1433 2000) (1473 2000) DATA DATA 1432 byte 1432 byte (1 1432) (1 1432) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv6 Frag Hdr IPv6 Frag Hdr IPv4 Header IPv6 Frag Hdr IPv6 Frag Hdr 8 byte 8 byte 20 byte 8 byte 8 byte (offset 1232) (offset 0) (offset 1472) (offset 1232) (offset 0) IPv4 Header IPv4 Header 1280 byte 1280 byte DATA 20 byte DATA DATA 20 byte 796 byte (offset 0) 528 byte 268 byte (offset 0) (1205 2000) (1473 2000) (1205 1472) 8 byte UDP Header 8 byte UDP Header DATA DATA 1204 byte 1204 byte (1 1204) (1 1204)
  • 29. IPv4 Header IPv4 Header Fragment いろいろ 20 byte 20 byte (offset 1472) (offset 0) 8 byte UDP Header DATA 1500 byte 528 byte (1473 2000) DATA 1472 byte (1 1472) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header IPv4 Header 20 byte 20 byte 20 byte 20 byte 20 byte (offset 1432) (offset 0) (offset 1472) (offset 1432) (offset 0) DATA 1460 byte 1460 byte DATA 8 byte UDP Header DATA 40 byte 8 byte UDP Header 568 byte 528 byte (1433 1472) (1433 2000) (1473 2000) DATA DATA 1432 byte 1432 byte (1 1432) (1 1432) 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header 40 byte IPv6 Header IPv6 Frag Hdr IPv6 Frag Hdr IPv4 Header IPv6 Frag Hdr IPv6 Frag Hdr 8 byte 8 byte 20 byte 8 byte 8 byte (offset 1232) (offset 0) (offset 1472) (offset 1232) (offset 0) IPv4 Header IPv4 Header 1280 byte 1280 byte DATA 20 byte DATA DATA 20 byte 796 byte (offset 0) 528 byte 268 byte (offset 0) (1205 2000) (1473 2000) (1205 1472) 8 byte UDP Header 8 byte UDP Header 1204 byte DATA (1 1204) ←これにしてます。 1204 byte DATA (1 1204)
  • 30. Fragment いろいろ • なんで BR/CE で reassemble してるのか? ☞ IPv4 fragment packet の TCP/UDP/ICMP header を 含まない packet はそれだけでは PSID がわから ないので encapsulation できない(decapsulation 時も validation できない) ☞ TCP/UDP/ICMP header 付き packet の header を cache させる方法も考えられるけどめんどい ☞ IPv4 の reassemble は Linux kernel で提供されて いるのでそちらを利用 ☞ IPv6 の reassemble は Linux kernel の機能を簡単 に利用できなそうだったので full scratch で実装
  • 31. Fragment いろいろ • なんで IPv6 stack で fragment してるのか? ☞ それがいちばん簡単だったから ☞ IPv6 の最小 MTU である 1280 に設定しているの で通らない可能性はないはず 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); ... }
  • 32. Port restricted NAPT の実装 • ひとつの 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 で実装しちゃえ
  • 33. 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
  • 34. 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
  • 35. MAP-T の Checksum 再計算 • 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
  • 36. 今後のはなし • MAP-T 捨てたい… ☞ ていうか XFRM を使う方法に戻したい… ☞ IPv6 address を持つようになるので PMTUd が出 来るようになるはず ☞ IPv6 stack を local に上っていく場合は Linux kernel の IPv6 reassemble 機能も利用できるよう になるはず • IPv6 packet の最大 size を設定できるようにしたい ☞ 1280 byte hard coding はさすがに…? • IPv4 stack での fragment にも対応したほうが良い? ☞ ちょっと調べた感じではけっこうめんどそう…
  • 37. 参考 • MAP 対応 Vyatta(ASAMAP)仮置き場 ☞ http://enog.jp/~masakazu/vyatta/map/   • Mapping of Address and Port with Encapsulation (MAP)   ☞ http://tools.ietf.org/html/draft-ietf-softwire-map   • Mapping of Address and Port using Translation (MAP-T)   ☞ http://tools.ietf.org/html/draft-ietf-softwire-map-t   • Generic Packet Tunneling in IPv6 Specification  ☞ http://tools.ietf.org/html/rfc2473   • IP/ICMP Translation Algorithm   ☞ http://tools.ietf.org/html/rfc6145  

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n