Unnumbered PPPoE を考える

直前のエントリとは激しく毛色が違うのが mura クオリティ。

自宅ネットワークを楽しい実験場にすべく /28 をくれる ISP を使おうと色々調べていたら、ルータ間の接続において unnumbered なる手法があることを知った。
ぐぐって一番最初にヒットするページの説明はこんな感じ。他の多くのページも大して変わらんような説明をしている。

unnumberedとは、他のネットワークに接続するルータのWAN側ポートにIPアドレスを割り当てず、2台のルータを見かけ上1台のルータのように扱う接続方式。unnumberedで運用されているルータはLAN側にのみIPアドレスを持つ。

http://e-words.jp/w/unnumbered.html

が、その辺の Unnumbered PPPoE を使えと言っている ISP で PPPoE をしてみると、 IPCP で割り当て IP アドレス空間のネットワークアドレス (183.180.30.0/28 なら 183.180.30.0) が降ってきて、 WAN 側インターフェイスに付与される。これは正しいのだろうか。
また、 PC ルータで Unnumbered PPPoE をしている blog などを見ていると、ダミーの IP アドレスに書き換えたり、 IP アドレスをもぎ取ってしまったりするようだ。
素直に考えるとこれでは ICMP が戻っていかないような気がするが、ググってみてもいまいちパッとしなかったので、自分で検証してみた。

実験環境のネットワーク構成

諸般の事情により PPPoE しているホストは手元にないので、 epair(4) の片方に IP Addr を付与して、もう一方を bridge(4) にて gif(4) と結んで EtherIP で手元まで飛ばしている。
細かいことだが、 ICMP を送出しているホストのグローバル IP アドレスと gif(4) のトンネル先が同一だったりするが、手元ホストでは FreeBSD の vimage によりネットワークスタックを複数用意しているので別ホストになるよう構成されている。

まあグダグダ言ってないで *BSD な野郎は以下の図を見て把握しちゃってください。
Linux な人は OpenVZ みたいなので仮想化されてるらしい、へーとか思ってください。あと em0 は eth0 に読み替えましょう。*1


  • em0: オペレーション用裏口へ
  • em1: フレッツ網に直結
  • tun0: emobile へ userland ppp している

ThinkPad X60 の jail の外から ping を飛ばすと tun0 の先の emobile 端末から The Internet を渡り、 PPPoE に包まれて i110Rb-1h に入り、 PPPoE を解かれたと思ったら今度は EtherIP に包まれて ThinkPad X60 上の jail である vnet1 に飛ばされます。
きゃー vimage と gif(4) + bridge(4) すてきー。

PPPoE インターフェイスにダミーの IP アドレスをつける

まずは、ダミーのアドレスをつけて試してみる。
以下のように、 mpd5 の mpd.conf に set iface addrs !local !remote とか書いてやると強制的に IP アドレスを指定できる。

mura@unsigned:pts/4> cat /usr/local/etc/mpd5/mpd.conf
startup:
        # configure mpd users
        set user admin admin admin
        # configure the console
        set console self 127.0.0.1 5005
        set console open
        # configure the web server
        set web self 127.0.0.1 5006
        set web open
        # logging
        log +bund -bund2 +link -fsm -auth -auth2 -lcp -lcp2 -ipcp -ipcp2 -chat -phys -phys2 -phys3

default:
        load ipq

ipq:
        create bundle static IPQb
        set iface route default
        set ipcp enable req-pri-dns req-sec-dns
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        # XXX
        set iface addrs !10.10.10.10 !10.10.10.11

        create link static IPQl pppoe
        set link action bundle IPQb
        set auth authname hogehoge
        set auth password piyopiyo
        set link max-redial 0
        set link mtu 1454
        set link keep-alive 10 60
        set pppoe iface em1
        #set pppoe service ""
        open

mura@unsigned:pts/4> 

設定中なので煮詰め方が足りないのはご愛嬌。
これで mpd5 を立ち上げると以下のような interface と routing table になる。

mura@unsigned:pts/4> ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:xx:xx:xx
        inet 172.24.0.3 netmask 0xfffffc00 broadcast 172.24.3.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:yy:yy:yy
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 
        inet6 ::1 prefixlen 128 
        inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
        tunnel inet 183.180.30.1 --> 114.48.180.126
        options=1<ACCEPT_REV_ETHIP_VER>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 82:d4:4f:d2:91:0c
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: gif0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 5 priority 128 path cost 55
        member: epair0a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 7 priority 128 path cost 14183
epair0a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:07:0a
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:08:0b
        inet 183.180.30.1 netmask 0xfffffff0 broadcast 183.180.30.15
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
        inet 10.10.10.10 --> 10.10.10.11 netmask 0xffffffff 
mura@unsigned:pts/4> netstat -rn -f inet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            10.10.10.11        UGS         0       17    ng0
10.10.10.10        link#4             UHS         0        0    lo0
10.10.10.11        link#4             UH          0        0    ng0
x.x.x.x            172.24.0.1         UGHS        2     6104    em0
127.0.0.1          link#3             UH          0        0    lo0
172.24.0.0/22      link#1             U           0       56    em0
172.24.0.3         link#1             UHS         0        0    lo0
183.180.30.0/28    link#8             U           0     9654 epair0
183.180.30.1       link#8             UHS         0        0    lo0
mura@unsigned:pts/4> 

default gateway がダミーのプライベート IP アドレスになっている。キモいキモい。

でもこれで通信できちゃうんですよねー。

halfrack@halfrack>ping -c 3 183.180.30.3
PING 183.180.30.3 (183.180.30.3): 56 data bytes
64 bytes from 183.180.30.3: icmp_seq=0 ttl=56 time=180.955 ms
64 bytes from 183.180.30.3: icmp_seq=1 ttl=56 time=177.146 ms
64 bytes from 183.180.30.3: icmp_seq=2 ttl=56 time=175.223 ms

--- 183.180.30.3 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 175.223/177.775/180.955/2.382 ms
halfrack@halfrack> 

ぽいんととぅーぽいんとと言うぐらいなので対向機器は 1つしかないから、てけとーな IP アドレスをつけといても通信出来ちゃうのでございます。

次は traceroute をしてみる。

halfrack@halfrack>traceroute 183.180.30.3
traceroute to 183.180.30.3 (183.180.30.3), 64 hops max, 52 byte packets
 1  eM60-254-194-6.emobile.ad.jp (60.254.194.6)  114.823 ms  69.267 ms  69.714 ms
 2  eM60-254-194-21.emobile.ad.jp (60.254.194.21)  69.764 ms  69.517 ms  69.794 ms
 3  218.231.128.37.ep.eaccess.ne.jp (218.231.128.37)  69.756 ms  69.455 ms  69.708 ms
 4  210.173.176.25 (210.173.176.25)  89.605 ms  69.746 ms *
 5  * ae0.core1.yokohama.vectant.ne.jp (163.139.129.82)  63.855 ms  79.602 ms
 6  163-139-60-66.rv.vectant.ne.jp (163.139.60.66)  70.013 ms *  106.602 ms
 7  Kna3BfmFL1.vectant.ne.jp (163.139.125.225)  69.924 ms  69.430 ms  70.285 ms
 8  * * *
 9  183-180-30-3.ipq.jp (183.180.30.3)  218.210 ms  239.549 ms  379.798 ms
halfrack@halfrack> 

予想通り PPPoE インターフェイスと思しきところで ICMP が戻ってこない。
PPPoE セッションを張っているホスト上で tcpdump して原因を調べてみる。

unsigned# tcpdump -n -i ng0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 96 bytes
20:36:19.446438 IP 114.48.180.126.36109 > 183.180.30.3.33456: UDP, length 24
20:36:19.446634 IP 10.10.10.10 > 114.48.180.126: ICMP time exceeded in-transit, length 36
20:36:24.486502 IP 114.48.180.126.36109 > 183.180.30.3.33457: UDP, length 24
20:36:24.486665 IP 10.10.10.10 > 114.48.180.126: ICMP time exceeded in-transit, length 36
20:36:29.446132 IP 114.48.180.126.36109 > 183.180.30.3.33458: UDP, length 24
20:36:29.446298 IP 10.10.10.10 > 114.48.180.126: ICMP time exceeded in-transit, length 36
20:36:34.508685 IP 114.48.180.126.36109 > 183.180.30.3.33459: UDP, length 24
20:36:34.509173 IP 183.180.30.1 > 114.48.180.126:  etherip 68
20:36:34.596171 IP 114.48.180.126 > 183.180.30.1:  etherip 72
20:36:34.596547 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33459 unreachable, length 36
20:36:34.825496 IP 114.48.180.126.36109 > 183.180.30.3.33460: UDP, length 24
20:36:34.825825 IP 183.180.30.1 > 114.48.180.126:  etherip 68
20:36:34.926418 IP 114.48.180.126 > 183.180.30.1:  etherip 72
20:36:34.926732 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33460 unreachable, length 36
20:36:35.206263 IP 114.48.180.126.36109 > 183.180.30.3.33461: UDP, length 24
20:36:35.206585 IP 183.180.30.1 > 114.48.180.126:  etherip 68
20:36:35.296188 IP 114.48.180.126 > 183.180.30.1:  etherip 72
20:36:35.296511 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33461 unreachable, length 36
^C
19 packets captured
19 packets received by filter
0 packets dropped by kernel
unsigned# 

これまた予想通り、ダミーの IP アドレスで ICMP を返そうとしている。
当然、まともな ISP であれば Egress filter で叩き落とされる。

というわけで、interface にダミーの IP アドレスをつけて運用すると、該当部分でダミーの IP アドレスで ICMP が戻り、上流の ISP 内部で叩き落とされ ICMP を返せないということになる。
まあこりゃ当たり前だな。

というわけで、なんにも考えずにダミーの IP アドレスをつけるのはかなり良くない感じ。

PPPoE インターフェイスに IP アドレスをつけない

次は、その辺の用語解説サイトの説明通りにアドレスを付けずにやってみる。

これを試すため ng0 に振られている アドレスをもぎとってしまう。もぎ取っただけだと当然 no route とか言われるので、 interface 指定で default route を指定してやる。
これで外に出て行くことが出来る。

unsigned# ifconfig ng0 delete
unsigned# route add default -interface ng0

これにより以下のような IP アドレスとルーティングテーブルが出来上がる。

mura@unsigned:pts/4> ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:xx:xx:xx
        inet 172.24.0.3 netmask 0xfffffc00 broadcast 172.24.3.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:yy:yy:yy
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 
        inet6 ::1 prefixlen 128 
        inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
        tunnel inet 183.180.30.1 --> 114.48.180.126
        options=1<ACCEPT_REV_ETHIP_VER>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 82:d4:4f:d2:91:0c
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: gif0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 5 priority 128 path cost 55
        member: epair0a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 7 priority 128 path cost 14183
epair0a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:07:0a
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:08:0b
        inet 183.180.30.1 netmask 0xfffffff0 broadcast 183.180.30.15
ng0: flags=89d1<UP,POINTOPOINT,RUNNING,NOARP,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1454
mura@unsigned:pts/4> netstat -rn -f inet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            ng0                US          0      230    ng0
x.x.x.x            172.24.0.1         UGHS        2     5115    em0
127.0.0.1          link#3             UH          0        0    lo0
172.24.0.0/22      link#1             U           0       56    em0
172.24.0.3         link#1             UHS         0        0    lo0
183.180.30.0/28    link#8             U           0     9605 epair0
183.180.30.1       link#8             UHS         0        0    lo0
mura@unsigned:pts/4> 

ng0 に IP アドレスがついてなくてキモい。 default gateway が IP アドレスではないのもキモい。

無事に IP アドレスをもぎ取れたので、外から内側 I/F にぶら下がるホストへ ping してみる。

halfrack@halfrack>ping -c 3 183.180.30.3                                      ~
PING 183.180.30.3 (183.180.30.3): 56 data bytes
64 bytes from 183.180.30.3: icmp_seq=0 ttl=56 time=992.483 ms
64 bytes from 183.180.30.3: icmp_seq=1 ttl=56 time=979.032 ms
64 bytes from 183.180.30.3: icmp_seq=2 ttl=56 time=946.262 ms

--- 183.180.30.3 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 946.262/972.592/992.483/19.411 ms
halfrack@halfrack>                                                            ~

通る。当たり前のように見えるが、 ppp の両端に IP アドレスがついていなくても通信が可能ということを示している。

次に、 traceroute してみる。

halfrack@halfrack>traceroute 183.180.30.3                                     ~
traceroute to 183.180.30.3 (183.180.30.3), 64 hops max, 52 byte packets
 1  eM60-254-194-6.emobile.ad.jp (60.254.194.6)  301.402 ms  389.149 ms  529.519 ms
 2  eM60-254-194-21.emobile.ad.jp (60.254.194.21)  479.653 ms  469.410 ms  730.094 ms
 3  * 218.231.128.37.ep.eaccess.ne.jp (218.231.128.37)  396.350 ms  508.412 ms
 4  210.173.176.25 (210.173.176.25)  529.748 ms  499.365 ms  519.855 ms
 5  ae0.core1.yokohama.vectant.ne.jp (163.139.129.82)  569.617 ms  799.451 ms  1019.636 ms
 6  163-139-60-66.rv.vectant.ne.jp (163.139.60.66)  739.912 ms  949.788 ms  789.571 ms
 7  Kna3BfmFL1.vectant.ne.jp (163.139.125.225)  539.952 ms  549.357 ms  1480.098 ms
 8  * * *
 9  183-180-30-3.ipq.jp (183.180.30.3)  1030.251 ms  1209.331 ms  1029.775 ms
halfrack@halfrack>                                                            ~

これまた予想通り unnumbered な interface から ICMP unreachable が戻ってこない。

何が起きているのか PPPoE をしているインターフェイス上で tcpdump してみる。

unsigned# tcpdump -n -i ng0
tcpdump: WARNING: ng0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 96 bytes
18:48:18.875724 IP 0.0.0.0.11026 > 133.243.238.244.123: NTPv4, Client, length 48
18:48:32.578945 IP 114.48.180.126.35913 > 183.180.30.3.33456: UDP, length 24
18:48:32.579154 IP 0.0.0.0 > 114.48.180.126: ICMP time exceeded in-transit, length 36
18:48:36.904894 IP 114.48.180.126.35913 > 183.180.30.3.33457: UDP, length 24
18:48:36.905055 IP 0.0.0.0 > 114.48.180.126: ICMP time exceeded in-transit, length 36
18:48:41.920005 IP 114.48.180.126.35913 > 183.180.30.3.33458: UDP, length 24
18:48:41.920158 IP 0.0.0.0 > 114.48.180.126: ICMP time exceeded in-transit, length 36
18:48:46.926049 IP 114.48.180.126.35913 > 183.180.30.3.33459: UDP, length 24
18:48:46.926484 IP 183.180.30.1 > 114.48.180.126:  etherip 68
18:48:47.582166 IP 114.48.180.126 > 183.180.30.1:  etherip 72
18:48:47.582523 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33459 unreachable, length 36
18:48:48.457146 IP 114.48.180.126.35913 > 183.180.30.3.33460: UDP, length 24
18:48:48.457469 IP 183.180.30.1 > 114.48.180.126:  etherip 68
18:48:49.211211 IP 114.48.180.126 > 183.180.30.1:  etherip 72
18:48:49.211550 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33460 unreachable, length 36
18:48:49.683427 IP 114.48.180.126.35913 > 183.180.30.3.33461: UDP, length 24
18:48:49.683737 IP 183.180.30.1 > 114.48.180.126:  etherip 68
18:48:50.239615 IP 114.48.180.126 > 183.180.30.1:  etherip 72
18:48:50.239933 IP 183.180.30.3 > 114.48.180.126: ICMP 183.180.30.3 udp port 33461 unreachable, length 36
^C
20 packets captured
20 packets received by filter
0 packets dropped by kernel
unsigned# 

ICMP unreachable のソース IP アドレスが 0.0.0.0 になってしまっていて、上流で叩き落とされている。

というわけで、interface に IP アドレスをつけずに運用すると該当 interface で ICMP を返せないということになる。
こっちはあからさまに変な IP アドレスがソースになっているので、ダミーの IP アドレスをつけるよりは若干マシか。でも ICMP は返らない。

PPPoE インターフェイスに内部インターフェイスのネットワークアドレスをつける

普通に設定するとこうなる、配布したネットワークのネットワークアドレスを WAN 側につける方法をやってみる。
直上のルータ視点ではキモい。私の下流にあるネットワークでこんなことやってたら、なんだこの変態はとか思っちゃうね。
ただし、この場合はネットワークアドレスを使えと IPCP で言っているのは直上のルータ自身なので、確信犯であり問題ないっちゃー問題ない。

出来上がる routing table まわりはこんな感じ。

mura@unsigned:pts/4> ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:xx:xx:xx
        inet 172.24.0.3 netmask 0xfffffc00 broadcast 172.24.3.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:yy:yy:yy
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 
        inet6 ::1 prefixlen 128 
        inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
        tunnel inet 183.180.30.1 --> 114.48.42.245
        options=1<ACCEPT_REV_ETHIP_VER>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 82:d4:4f:d2:91:0c
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: gif0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 5 priority 128 path cost 55
        member: epair0a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 7 priority 128 path cost 14183
epair0a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:07:0a
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:08:0b
        inet 183.180.30.1 netmask 0xfffffff0 broadcast 183.180.30.15
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
        inet 183.180.30.0 --> 163.139.125.226 netmask 0xffffffff 
mura@unsigned:pts/4> netstat -rn -f inet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            163.139.125.226    UGS         0        9    ng0
x.x.x.x            172.24.0.1         UGHS        2     6941    em0
127.0.0.1          link#3             UH          0        0    lo0
163.139.125.226    link#4             UH          0        0    ng0
172.24.0.0/22      link#1             U           0       58    em0
172.24.0.3         link#1             UHS         0        0    lo0
183.180.30.0       link#4             UHS         0        0    lo0 =>
183.180.30.0/28    link#8             U           0     9711 epair0
mura@unsigned:pts/4> 

割と予想通り。 epair0b に 183.180.30.1/28 がついているのに、 ng0 に 183.180.30.0 がついているのがキモい。
細かいことですが、 gif の宛先が変わっているのは emobile の ppp を再接続したためなのでございます。

この構成で traceroute を叩くとこうなる。

halfrack@halfrack>traceroute 183.180.30.3
traceroute to 183.180.30.3 (183.180.30.3), 64 hops max, 52 byte packets
 1  eM60-254-194-6.emobile.ad.jp (60.254.194.6)  215.585 ms  359.161 ms  319.774 ms
 2  eM60-254-194-17.emobile.ad.jp (60.254.194.17)  339.752 ms  249.420 ms  299.849 ms
 3  218.231.128.33.ep.eaccess.ne.jp (218.231.128.33)  289.680 ms  389.488 ms  429.900 ms
 4  211.14.193.162 (211.14.193.162)  339.791 ms  279.469 ms  259.772 ms
 5  210.173.176.25 (210.173.176.25)  249.839 ms  259.662 ms  259.907 ms
 6  ae0.core1.yokohama.vectant.ne.jp (163.139.129.82)  259.526 ms  269.603 ms  269.756 ms
 7  163-139-60-66.rv.vectant.ne.jp (163.139.60.66)  279.732 ms  259.600 ms  249.619 ms
 8  Kna3BfmFL2.vectant.ne.jp (163.139.125.226)  279.954 ms  279.312 ms  279.613 ms
 9  183-180-30-0.ipq.jp (183.180.30.0)  249.944 ms  259.574 ms  249.673 ms
10  183-180-30-3.ipq.jp (183.180.30.3)  599.755 ms  569.734 ms  599.762 ms
halfrack@halfrack> 

183.180.30.0 ってのがちょっと変な感じである。が、それは事情を知っているからであって、 AS の外から見たら特に変なわけではない。*2

念のため、 PPPoE している PC ルータで tcpdump してみる。

unsigned# tcpdump -n -i ng0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 96 bytes
21:48:19.231200 IP 114.48.42.245.36239 > 183.180.30.3.33459: UDP, length 24
21:48:19.231440 IP 183.180.30.0 > 114.48.42.245: ICMP time exceeded in-transit, length 36
21:48:19.749863 IP 114.48.42.245.36239 > 183.180.30.3.33460: UDP, length 24
21:48:19.750040 IP 183.180.30.0 > 114.48.42.245: ICMP time exceeded in-transit, length 36
21:48:20.001694 IP 114.48.42.245.36239 > 183.180.30.3.33461: UDP, length 24
21:48:20.001819 IP 183.180.30.0 > 114.48.42.245: ICMP time exceeded in-transit, length 36
21:48:20.255551 IP 114.48.42.245.36239 > 183.180.30.3.33462: UDP, length 24
21:48:20.255972 IP 183.180.30.1 > 114.48.42.245:  etherip 68
21:48:20.583887 IP 114.48.42.245 > 183.180.30.1:  etherip 72
21:48:20.584295 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33462 unreachable, length 36
21:48:21.113081 IP 114.48.42.245.36239 > 183.180.30.3.33463: UDP, length 24
21:48:21.113409 IP 183.180.30.1 > 114.48.42.245:  etherip 68
21:48:21.432383 IP 114.48.42.245 > 183.180.30.1:  etherip 72
21:48:21.432711 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33463 unreachable, length 36
21:48:21.690251 IP 114.48.42.245.36239 > 183.180.30.3.33464: UDP, length 24
21:48:21.690574 IP 183.180.30.1 > 114.48.42.245:  etherip 68
21:48:22.015542 IP 114.48.42.245 > 183.180.30.1:  etherip 72
21:48:22.015862 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33464 unreachable, length 36
^C
18 packets captured
18 packets received by filter
0 packets dropped by kernel
unsigned# 

想定通り 183.180.30.0 から ICMP を返している。よさげな感じ。

というわけで、この ISP では、上流でネットワークアドレスを叩き落としたりはしていないようです。
まあ、 IPCP で配布しておいて叩き落とされたらそりゃねーよという感じではある。
聞くところによると、他の ISP でもこの手のアドレスは特にフィルタされていない様子。*3

よって、外側インターフェイスに内側インターフェイスのネットワークアドレスをつけても正しく動作すると言える。
この PPPoE 箱の両端で MTU が違っても、 ICMP unreachable がきちんと返って Path MTU Discovery により正しく対処される。

PPPoE インターフェイスに内部インターフェイスのアドレスをつける

http://www.cisco.com/JP/support/public/ht/tac/100/1007779/20-j.shtml
この Cisco の文章を参考に他の interface のアドレスを借りてみる。

mpd.conf には以下の行が含まれるようにした。

set iface addrs !183.180.30.1 !163.139.125.226

set iface addrs !183.180.30.1 0.0.0.0/0 としたかったがうまく動かない。 IPCP で降ってくる remote の IP アドレスが変化しないかぎりこれで問題ないので、とりあえずはこれで試すこととする。

mpd5 を立ち上げるとこんな感じになる。

mura@unsigned:pts/4> ifconfig
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:xx:xx:xx
        inet 172.24.0.3 netmask 0xfffffc00 broadcast 172.24.3.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=19b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4>
        ether 00:16:17:yy:yy:yy
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 
        inet6 ::1 prefixlen 128 
        inet 127.0.0.1 netmask 0xff000000 
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1280
        tunnel inet 183.180.30.1 --> 114.48.42.245
        options=1<ACCEPT_REV_ETHIP_VER>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 82:d4:4f:d2:91:0c
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        member: gif0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 5 priority 128 path cost 55
        member: epair0a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                ifmaxaddr 0 port 7 priority 128 path cost 14183
epair0a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:07:0a
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:c0:e4:00:08:0b
        inet 183.180.30.1 netmask 0xfffffff0 broadcast 183.180.30.15
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
        inet 183.180.30.1 --> 163.139.125.226 netmask 0xffffffff 
mura@unsigned:pts/4> netstat -rn -f inet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            163.139.125.226    UGS         0      135    ng0
x.x.x.x            172.24.0.1         UGHS        2     8492    em0
127.0.0.1          link#3             UH          0        0    lo0
163.139.125.226    link#4             UH          0        0    ng0
172.24.0.0/22      link#1             U           0       58    em0
172.24.0.3         link#1             UHS         0        0    lo0
183.180.30.0/28    link#8             U           0     9875 epair0
183.180.30.1       link#4             UHS         0        0    lo0
mura@unsigned:pts/4> 

183.180.30.1 が 2箇所に出てきていて、一瞬きめーとか思ってしまうが、よく考えてみると tunnel のソース IP アドレスがかぶるのは別に変でもないか。
gif(4) とか掘るとこのような状況は普通に発生する。
ちなみに、 dmesg へ変なメッセージが出たりとかも特にありません。

さてはて traceroute してみる。

halfrack@halfrack>traceroute 183.180.30.3
traceroute to 183.180.30.3 (183.180.30.3), 64 hops max, 52 byte packets
 1  eM60-254-194-6.emobile.ad.jp (60.254.194.6)  226.553 ms  369.391 ms  419.609 ms
 2  eM60-254-194-17.emobile.ad.jp (60.254.194.17)  339.788 ms  369.692 ms  361.827 ms
 3  218.231.128.33.ep.eaccess.ne.jp (218.231.128.33)  358.698 ms  390.786 ms  408.192 ms
 4  211.14.193.162 (211.14.193.162)  379.724 ms  379.483 ms  399.838 ms
 5  210.173.176.25 (210.173.176.25)  370.055 ms  379.496 ms  399.607 ms
 6  163.139.129.90 (163.139.129.90)  379.763 ms  379.254 ms  380.037 ms
 7  163-139-127-102.rv.vectant.ne.jp (163.139.127.102)  389.575 ms  399.555 ms  409.558 ms
 8  Kna2BfmFL8.vectant.ne.jp (163.139.127.121)  381.474 ms  419.477 ms  399.837 ms
 9  183-180-30-1.ipq.jp (183.180.30.1)  379.693 ms  409.248 ms  419.839 ms
10  183-180-30-3.ipq.jp (183.180.30.3)  849.617 ms  849.553 ms  849.771 ms
halfrack@halfrack> 

案の定 183.180.30.1 で ICMP が返ってくるのであった。よさげな挙動。

確認するまでもないような気がするが tcpdump してみる。

unsigned# tcpdump -n -i ng0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 96 bytes
23:03:43.636139 IP 114.48.42.245.36394 > 183.180.30.3.33459: UDP, length 24
23:03:43.636385 IP 183.180.30.1 > 114.48.42.245: ICMP time exceeded in-transit, length 36
23:03:44.432154 IP 114.48.42.245.36394 > 183.180.30.3.33460: UDP, length 24
23:03:44.432310 IP 183.180.30.1 > 114.48.42.245: ICMP time exceeded in-transit, length 36
23:03:44.851397 IP 114.48.42.245.36394 > 183.180.30.3.33461: UDP, length 24
23:03:44.851537 IP 183.180.30.1 > 114.48.42.245: ICMP time exceeded in-transit, length 36
23:03:45.199738 IP 114.48.42.245.36394 > 183.180.30.3.33462: UDP, length 24
23:03:45.200156 IP 183.180.30.1 > 114.48.42.245:  etherip 68
23:03:45.702438 IP 114.48.42.245 > 183.180.30.1:  etherip 72
23:03:45.702808 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33462 unreachable, length 36
23:03:46.508943 IP 114.48.42.245.36394 > 183.180.30.3.33463: UDP, length 24
23:03:46.509269 IP 183.180.30.1 > 114.48.42.245:  etherip 68
23:03:46.976657 IP 114.48.42.245 > 183.180.30.1:  etherip 72
23:03:46.977005 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33463 unreachable, length 36
23:03:47.354937 IP 114.48.42.245.36394 > 183.180.30.3.33464: UDP, length 24
23:03:47.355249 IP 183.180.30.1 > 114.48.42.245:  etherip 68
23:03:47.813681 IP 114.48.42.245 > 183.180.30.1:  etherip 72
23:03:47.814030 IP 183.180.30.3 > 114.48.42.245: ICMP 183.180.30.3 udp port 33464 unreachable, length 36
^C
18 packets captured
18 packets received by filter
0 packets dropped by kernel
unsigned# 

するまでもなかった。

ところで、これって内側から外側に向けて traceroute しても 183.180.30.1 が出てくるんじゃないか、という予想が湧き起こるのは当然なので、実際に試してみる。

vnet1# ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet 127.0.0.1 netmask 0xff000000 
        inet6 ::1 prefixlen 128 
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
        nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
epair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        ether 02:00:00:00:0a:0b
        inet6 fe80::ff:fe00:a0b%epair0b prefixlen 64 scopeid 0x2 
        inet 183.180.30.3 netmask 0xfffffff0 broadcast 183.180.30.15
        nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
vnet1# traceroute -n 202.229.13.197
traceroute to 202.229.13.197 (202.229.13.197), 64 hops max, 52 byte packets
 1  183.180.30.1  308.150 ms  479.507 ms  459.978 ms
 2  163.139.127.121  539.732 ms  489.540 ms  429.537 ms
 3  163.139.127.126  510.116 ms  379.718 ms *
 4  163.139.127.101  347.757 ms  389.872 ms  379.512 ms
 5  163.139.128.54  340.041 ms  409.716 ms  379.965 ms
 6  210.173.176.18  459.691 ms  599.631 ms  399.557 ms
 7  202.239.114.222  419.797 ms  409.567 ms  480.250 ms
 8  203.138.72.2  402.384 ms  476.544 ms  439.852 ms
 9  202.239.117.18  499.679 ms  499.668 ms *
10  202.229.13.197  297.642 ms  540.253 ms  399.204 ms
vnet1# 

案の定の出てくるのであった。これは特に変な挙動でもないのでノータッチで。

まとめ

いやまあ、 ICMP を返せないといっても、 Path MTU black hole になるわけじゃなし、 MTU とかをうまく調節して自分のところでは ICMP Type 3 を出さないように運用すれば問題ないといえば問題ない。
それでも traceroute などで残念な気持ちになるし、 ICMP unreachable を返せないルータをグローバル空間に置くのはどうなのよと思うわけでございます。

また、 unnumbered でググってヒットする大半のページの説明は「間違っているか著しく誤解を招く表現である」と言える。アドレスつけてるじゃん。
Unnumbered なインターフェイスとは、他のインターフェイスの IP アドレスを借りて使っているインターフェイスのこと、ぐらいかなぁ。
そもそも WAN 側にネットワークアドレスをつけた場合 unnumbered なのかすら怪しい。

ネットワークアドレスを使っちゃうのはキモいんだけどちゃんと機能するので問題ない行為である、ということも分かった。
上流でフィルタされていないという条件はあるが、 NAT (not NAPT) の変換アドレスとしてネットワークアドレスやブロードキャストアドレスを使っちゃうことで、 /29 で 8個全部使う、といった手法を推奨している ISP もあるぐらいなので、フィルタされていることはあまりない様子。

さてはて、私はどちらの選択肢を選ぼうか。どちらも正しく動く。

  1. IPCP で降ってきたネットワークアドレスをおとなしく使う
  2. 内側 I/F のアドレスを借りて外側 I/F にもつけて正しい unnumbered を満喫する

内側と外側でアドレスが違う方がトラブルシューティングが楽そうなので、前者で行くかねぇ。

まあ IP アドレスをケチるために unnumbered なんてややこしいことをしているのがそもそもの問題なので、みんなで IPv6 に移行して IP アドレスをジャブジャブ使おうぜというわけですよ。(そこかよ)

*1:*BSD の世界では Ethernet driver によって network interface 名が変わります。

*2:183.180.30.0/22 とかかもしれないじゃない。まだピンと来ない人は CIDR やり直してくるといい。

*3:具体的には OCN とか。