Posted on Wed Sep 07 09:32:35 +0900 2011 by nabeken
PCルータをOpenBSDで新調した話。冗長化は未完。
2011年7月29日(金)の午前2時ごろ、当ネットワークのサーバ側セグメントのPCルータが ハードウェア障害を起こし、全サービスが停止しました。 (実際にはメール、DNS、LDAPは海外のVPSでセカンダリを動かしていたので全滅ではなかった)
予め取得していたUSBメモリのディスクイメージを新規USBメモリに流し込み、 手元の余っていたノートパソコンへ刺して代替機として発送、交換し復旧しました。
使用していたハードウェアは私が始めて組んだマシンで、ちょうど10年経過したところです。 よく働いてくれました。
該当箇所は冗長化しておらず、ハードウェア交換と冗長化が急務でした。 また、現在はIX2015でPPPoEを喋っていますがIX2015で今後も運用するのは厳しいと判断したため、 このリプレイスも必要でした。
さて、IPv4とIPv6に対応した冗長化が必要です。keepalivedの独自対応したVRRPかOpenBSD由来のCARPか…
独自対応がどうも気持ちが悪いのでOpenBSD + CARPで冗長化することにしました。 (FreeBSDにしなかったのはOpenBSDつかってみたかったから)
問題はハードウェアの選定です。
ありました。
アキバを巡回していたらMini-ITXでNICが2つ載っているマザーを2つ見つけました。
どちらも同じJ&W製のマザーでした(今後要チェックです)。 IntelとAMDを選ぶことになります。今回はIntel(H61M-USB3)を選びました。
USBメモリにOpenBSDを入れて構築することにします。
CDROMはないのでPXEブートでインストールしました。 IX2015でPXEブートの設定を入れてみました。
config# ip dhcp profile XXXX config-dhcp-XXXX# next-server 10.X.X.X (tftpサーバのIPアドレス) config-dhcp-XXXX# bootfile pxeboot (OpenBSDの配布物のpxeboot)
インストール後(かつ、カーネル再構築後)の dmesg は以下。
OpenBSD 4.9 (GENERIC.MP) #2: Thu Sep 1 22:43:51 JST 2011 root@gw-openbsd.osaka.tknetworks.org:/usr/src/gw-openbsd/sys/arch/amd64/compile/GENERIC.MP real mem = 2082504704 (1986MB) avail mem = 2013044736 (1919MB) mainbus0 at root bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xe92d0 (104 entries) bios0: vendor American Megatrends Inc. version "4.6.4" date 04/27/2011 bios0: MINIX MINIX H61-USB3 acpi0 at bios0: rev 2 acpi0: sleep states S0 S3 S4 S5 acpi0: tables DSDT FACP APIC SSDT MCFG HPET ASPT acpi0: wakeup devices PS2K(S3) PS2M(S3) BR20(S3) EUSB(S4) USBE(S4) PEX0(S4) PEX1(S4) PEX2(S4) PEX3(S4) PEX4(S4) PEX5(S4) PEX6(S4) PEX7(S4) GBE_(S4) P0P1(S4) P0P2(S4) P0P3(S4) P0P4(S4) SLPB(S0) PWRB(S3) acpitimer0 at acpi0: 3579545 Hz, 24 bits acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat cpu0 at mainbus0: apid 0 (boot processor) cpu0: Intel(R) Pentium(R) CPU G620T @ 2.20GHz, 2195.32 MHz cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,SSE3,PCLMUL,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,XSAVE,NXE,LONG cpu0: 256KB 64b/line 8-way L2 cache cpu0: apic clock running at 99MHz cpu1 at mainbus0: apid 2 (application processor) cpu1: Intel(R) Pentium(R) CPU G620T @ 2.20GHz, 2195.02 MHz cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,SBF,SSE3,PCLMUL,MWAIT,DS-CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,POPCNT,XSAVE,NXE,LONG cpu1: 256KB 64b/line 8-way L2 cache ioapic0 at mainbus0: apid 0 pa 0xfec00000, version 20, 24 pins acpimcfg0 at acpi0 addr 0xe0000000, bus 0-255 acpihpet0 at acpi0: 14318179 Hz acpiprt0 at acpi0: bus 0 (PCI0) acpiprt1 at acpi0: bus -1 (BR20) acpiprt2 at acpi0: bus 2 (PEX0) acpiprt3 at acpi0: bus 3 (PEX1) acpiprt4 at acpi0: bus 4 (PEX2) acpiprt5 at acpi0: bus -1 (PEX3) acpiprt6 at acpi0: bus 5 (PEX4) acpiprt7 at acpi0: bus -1 (PEX5) acpiprt8 at acpi0: bus -1 (PEX6) acpiprt9 at acpi0: bus -1 (PEX7) acpiprt10 at acpi0: bus 1 (P0P1) acpiprt11 at acpi0: bus -1 (P0P2) acpiprt12 at acpi0: bus -1 (P0P3) acpiprt13 at acpi0: bus -1 (P0P4) acpicpu0 at acpi0: C3, C3, C1, PSS acpicpu1 at acpi0: C3, C3, C1, PSS acpibtn0 at acpi0: SLPB acpibtn1 at acpi0: PWRB cpu0: unknown i686 model 0x2a, can't get bus clock cpu0: Enhanced SpeedStep 2195 MHz: speeds: 2200, 2100, 2000, 1900, 1800, 1700, 1600 MHz pci0 at mainbus0 bus 0 pchb0 at pci0 dev 0 function 0 vendor "Intel", unknown product 0x0100 rev 0x09 ppb0 at pci0 dev 1 function 0 vendor "Intel", unknown product 0x0101 rev 0x09: apic 0 int 16 (irq 11) pci1 at ppb0 bus 1 em0 at pci1 dev 0 function 0 "Intel PRO/1000 MT (82574L)" rev 0x00: apic 0 int 16 (irq 11), address 00:XX:XX:XX:XX:XX vga1 at pci0 dev 2 function 0 vendor "Intel", unknown product 0x0102 rev 0x09 wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation) wsdisplay0: screen 1-5 added (80x25, vt100 emulation) intagp at vga1 not configured vendor "Intel", unknown product 0x1c3a (class communications subclass miscellaneous, rev 0x04) at pci0 dev 22 function 0 not configured ehci0 at pci0 dev 26 function 0 vendor "Intel", unknown product 0x1c2d rev 0x05: apic 0 int 16 (irq 11) usb0 at ehci0: USB revision 2.0 uhub0 at usb0 "Intel EHCI root hub" rev 2.00/1.00 addr 1 azalia0 at pci0 dev 27 function 0 vendor "Intel", unknown product 0x1c20 rev 0x05: apic 0 int 22 (irq 10) azalia0: codecs: Realtek/0x0892, Intel/0x2805, using Realtek/0x0892 audio0 at azalia0 ppb1 at pci0 dev 28 function 0 vendor "Intel", unknown product 0x1c10 rev 0xb5: apic 0 int 17 (irq 5) pci2 at ppb1 bus 2 ppb2 at pci0 dev 28 function 1 vendor "Intel", unknown product 0x1c12 rev 0xb5: apic 0 int 16 (irq 11) pci3 at ppb2 bus 3 ppb3 at pci0 dev 28 function 2 vendor "Intel", unknown product 0x1c14 rev 0xb5: apic 0 int 18 (irq 3) pci4 at ppb3 bus 4 bge0 at pci4 dev 0 function 0 "Broadcom BCM57788" rev 0x01, BCM57780 A1 (0x57780001): apic 0 int 18 (irq 3), address 00:e0:b6:XX:XX:XX brgphy0 at bge0 phy 1: BCM57780 10/100/1000baseT PHY, rev. 1 ppb4 at pci0 dev 28 function 4 vendor "Intel", unknown product 0x1c18 rev 0xb5: apic 0 int 17 (irq 5) pci5 at ppb4 bus 5 bge1 at pci5 dev 0 function 0 "Broadcom BCM57788" rev 0x01, BCM57780 A1 (0x57780001): apic 0 int 16 (irq 11), address 00:e0:b6:XX:XX:XX brgphy1 at bge1 phy 1: BCM57780 10/100/1000baseT PHY, rev. 1 ehci1 at pci0 dev 29 function 0 vendor "Intel", unknown product 0x1c26 rev 0x05: apic 0 int 23 (irq 7) usb1 at ehci1: USB revision 2.0 uhub1 at usb1 "Intel EHCI root hub" rev 2.00/1.00 addr 1 pcib0 at pci0 dev 31 function 0 vendor "Intel", unknown product 0x1c5c rev 0x05 vendor "Intel", unknown product 0x1c22 (class serial bus subclass SMBus, rev 0x05) at pci0 dev 31 function 3 not configured isa0 at pcib0 isadma0 at isa0 com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo pckbc0 at isa0 port 0x60/5 pckbd0 at pckbc0 (kbd slot) pckbc0: using irq 1 for kbd slot wskbd0 at pckbd0: console keyboard, using wsdisplay0 pcppi0 at isa0 port 0x61 spkr0 at pcppi0 lpt0 at isa0 port 0x378/4 irq 7 fdc0 at isa0 port 0x3f0/6 irq 6 drq 2 mtrr: Pentium Pro MTRR support uhub2 at uhub0 port 1 "Intel product 0x0024" rev 2.00/0.00 addr 2 uplcom0 at uhub2 port 4 "Prolific Technology Inc. USB-Serial Controller" rev 1.10/3.00 addr 3 ucom0 at uplcom0 uhub3 at uhub1 port 1 "Intel product 0x0024" rev 2.00/0.00 addr 2 umass0 at uhub3 port 3 configuration 1 interface 0 "ADATA ADATA USB Flash Drive" rev 2.00/1.00 addr 3 umass0: using SCSI over Bulk-Only scsibus0 at umass0: 2 targets, initiator 0 sd0 at scsibus0 targ 1 lun 0: <ADATA, USB Flash Drive, 0.00> SCSI2 0/direct removable sd0: 7509MB, 512 bytes/sec, 15378432 sec total vscsi0 at root scsibus1 at vscsi0: 256 targets softraid0 at root root on sd0a swap on sd0b dump on sd0b carp: carp0 demoted group carp by 1 to 129 (carpdev) carp: carp1 demoted group carp by 1 to 130 (carpdev) pppoe (data): input for unknown session 0x54b, sending PADT carp: carp1 demoted group carp by -1 to 129 (carpdev) carp: carp0 demoted group carp by -1 to 128 (carpdev) carp1: state transition: BACKUP -> MASTER pppoe0: received unexpected PADO pppoe0: received unexpected PADO pppoe0: received unexpected PADO pppoe0: received unexpected PADO pppoe0: received unexpected PADO pppoe0: received unexpected PADO pppoe0: received unexpected PADO carp0: state transition: BACKUP -> MASTER
3つのネットワークのルータにします(VLANでもいい気もしますが…)。
まずは冗長構成がない場合の論理構成:
-------------- The Internet -------------- | | (pppoe0 on bge0) | | | | | +-----+ | | | gw0 |-----[em0]-------| +-------+ | +-----+ |--------| rt57i |--------| クライアント | | +-------+ | | (bge1) | | | ------------- サーバ
gw0とgw1で冗長構成にします。
------------------------------------------- The Internet ------+--------------------------+--------- | | | | | | +--+--+ +--+--+ | | gw0 | | gw1 +-----------+ | +--+-++ +--+--+ | +-------+ | | | (carp1) | |--------| rt57i |------| クライアント | +------------------------|--------------+ +-------+ | | | | | (carp0) | ------+--------------------------+--------- サーバ
2011/09現在、gw1の手配が間にあっていないため実際はgw0だけの構成になっています。
carp[01]の何れかでfailoverが発生するとBACKUPへ切り替える
障害が起きたcarpだけ切り替わっても意味がないため。
failover時はPPPoEもfailoverする
failoverを検知してPPPoEのコネクションを張りなおす。
failover時はその他雑多なdaemonも切り替える
OpenVPN, Quagga, miredo, birdなど。
冗長構成はまだできていないので、これは次回の宿題。
まずは hostname.if(5) を設定しまくります。
gw0# cat /etc/hostname.bge0 up gw0# cat /etc/hostname.bge1 inet 192.168.0.1 255.255.255.0 inet6 2001:db8:a::1 64 gw0# cat /etc/hostname.carp0 advbase 1 advskew 0 vhid 1 carpdev bge1 pass secret inet 192.168.0.10 255.255.255.0 inet6 2001:db8:a::10 64 gw0# cat /etc/hostname.em0 inet 192.168.5.1 255.255.255.0 inet6 2001:db8:b::1 64 gw0# cat /etc/hostname.carp1 advbase 1 advskew 0 vhid 2 carpdev em0 pass secret inet 192.168.5.10 255.255.255.0 inet6 2001:db8:b::10 64 gw1# cat /etc/hostname.bge0 up gw1# cat /etc/hostname.bge1 inet 192.168.0.2 255.255.255.0 inet6 2001:db8:a::2 64 gw1# cat /etc/hostname.carp0 advbase 1 advskew 100 vhid 1 carpdev bge1 pass secret inet 192.168.0.10 255.255.255.0 inet6 2001:db8:a::10 64 gw1# cat /etc/hostname.em0 inet 192.168.5.2 255.255.255.0 inet6 2001:db8:b::2 64 gw1# cat /etc/hostname.carp1 advbase 1 advskew 100 vhid 2 carpdev em0 pass secret inet 192.168.5.10 255.255.255.0 inet6 2001:db8:b::10 64
gw0, gw1で/etc/sysctl.confを設定します。 一部値は Network Tuning and Performance Guide (OpenBSD) を参考にしました。
net.inet.ip.forwarding=1 net.inet.ip.mforwarding=1 net.inet.gre.allow=1 net.inet6.ip6.forwarding=1 net.inet6.ip6.mforwarding=1 net.inet6.ip6.accept_rtadv=0 net.inet.carp.preempt=1 net.inet.carp.log=3 net.inet.ip.ifq.maxlen=1024 kern.bufcachepercent=90
ユーザランドのppp + pppoe構成だと速度が50Mbps〜を越えると割り込み、 コンテキストスイッチが爆発し通信が詰まっていることが判明しました。
pppoe(8)で 40Mbps〜70Mbps 時のvmstat:
procs memory page disk traps cpu r b w avm fre flt re pi po fr sr sd0 int sys cs us sy id 0 0 0 265248 1334864 74 0 0 0 0 0 0 46 668 113 0 0 100 0 0 0 265248 1334864 77 0 0 0 0 0 0 43 655 118 0 0 100 0 0 0 265248 1334864 405 0 0 0 0 0 0 46 760 112 0 0 100 0 0 0 265248 1334864 74 0 0 0 0 0 0 3141 50811 11431 1 10 89 0 0 0 265248 1334864 74 0 0 0 0 0 0 8091 132264 29514 4 21 75 0 0 0 265252 1334860 74 0 0 0 0 0 0 6750 102647 24246 2 18 80 2 0 0 265252 1334860 82 0 0 0 0 0 0 7168 109002 25727 3 21 76 0 0 0 265252 1334860 403 0 0 0 0 0 0 5331 81630 18822 2 11 87 0 0 0 265252 1334860 74 0 0 0 0 0 0 45 667 110 0 0 100 0 0 0 265252 1334860 73 0 0 0 0 0 0 39 629 111 0 0 100
次項のパッチ当て、再構築した時のpppoe(4)で 40Mbps〜 時のvmstat:
procs memory page disk traps cpu r b w avm fre flt re pi po fr sr sd0 int sys cs us sy id 1 0 0 14012 1908544 7 0 0 0 0 0 0 4568 51 18 0 5 95 0 0 0 14012 1908544 14 0 0 0 0 0 0 3041 49 17 0 1 99 0 0 0 14012 1908544 11 0 0 0 0 0 0 3816 55 20 0 1 99 0 0 0 14012 1908544 7 0 0 0 0 0 0 3354 35 15 0 1 99 0 0 0 14012 1908544 7 0 0 0 0 0 0 4541 35 16 0 3 97 0 0 0 14012 1908544 7 0 0 0 0 0 0 7326 60 20 0 4 96 0 0 0 14012 1908544 7 0 0 0 0 0 0 7161 43 20 0 6 94 0 0 0 14012 1908544 11 0 0 0 0 0 0 6642 47 20 0 3 97
pppoe(8)で見られた数値はまったく見られず、 高負荷状態ではカーネルモードPPPoEが安定していることがわかります。
OpenBSD 4.9のpppoe(4)には問題("splassert: assertwaitok: want -1 have 1")が報告されています。 すでに -current もしくは 5.0 では修正されています。 今回は パッチ を 4.9 へバックポートしてカーネルを再構築しました。 ついでにconfigに option PPPOE_TERM_UNKNOWN_SESSIONS を追加しました。
# cd /usr/src # wget http://ftp.iij.ad.jp/pub/OpenBSD/4.9/sys.tar.gz # tar zxvf sys.tar.gz # wget 'http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_spppsubr.c.diff?r1=1.87;r2=1.84' -O if_spppsubr.patch # patch -p1 < if_spppsubr.patch # cd sys/arch/amd64/conf # config GENERIC.MP # cd ../compile/GENERIC.MP # make clean && make depend && make # make install
設定は /etc/hostname.pppoe0 で行ないます。
# cat /etc/hostname.pppoe0 inet 0.0.0.0 255.255.255.255 NONE pppoedev bge0 authproto chap authname 'user' authkey 'secret' up dest 0.0.0.1 !/sbin/route add default -ifp pppoe0 0.0.0.1
destがないと動きません。
# sh /etc/netstart pppoe0
PF本(第2版) をOpenBSDプロジェクトへの寄付も兼ねて電子書籍版を購入しました。 4.9のpfはデフォルトでkeep stateなため注意が必要です。
systat(1)でI/Fの様子が見れるのはうれしい。
# systat -w 1 ifstat 1 # systat -w 1 state 1
参考文献:
packagesからインストールします。
Linuxでいうtapデバイスを使うにはtun(4)を作成する際に link0 フラグを渡す必要があります。 link0 フラグを渡すとそれまでの設定を失なうので注意。
# ifconfig tun0 create # ifconfig tun0 link0
OpenVPNの設定ファイルでは dev-type tap にして dev tun0 にすると自動で link0 をフラグを立ててくれます。 場合によっては立ててくれないので自分で立てる必要があります。
OpenVPNは hostname.if 経由で起動させると便利です。
# cat /etc/hostname.tun1 up link0 !/usr/local/sbin/openvpn --config /etc/openvpn/openvpn.conf --daemon inet6 fe80::1 64 inet6 2001:db8::1 64
デフォルトでは /dev/tun[0-4] までしかありません。 tun100 が欲しければ作成する必要があります。
# cd /dev # ./MAKEDEV tun100
USBシリアル変換を経由したシリアルコンソールを用意しました。 私の環境ではbmobileが提供するイオンSIMを経由したメンテナンス回線を用意し、 リモートメンテナンスができるようにしています。 月額980円で3G経由のメンテナンス回線を用意できるのは魅力的です。
(正確にはbmobile経由でさくらのVPS上に構築したOpenVPNに接続しIPv6ネットワークに参加しています)
シリアルコンソールは /etc/ttys (ttys(5))で設定します。
ttyU0 "/usr/libexec/getty std.9600" vt220 on secure
設定後、 init(8) をリスタートさせます。
# kill -HUP 1
別のマシンから cu(1) を使って接続できることを確認します。
# cu -l cuaU0
このPPPoE failoverは ユーザランドでの検証 です。カーネルモードでは未検証ですが、ユーザランドでは動いていたので 載せておきます(せっかくなので)。
ppp.confの設定が重要。PPPoEではモデムのキャリアセンスが使えないため enable lqr と set lqrperiod 5 が必須。 これがないとlink downが検知できずに自動再接続機能が働きません。 詳細は PPPoE Client を参照。
/etc/ifstated.conf
# cat /etc/ifstated.conf # $OpenBSD: ifstated.conf,v 1.6 2005/02/07 06:08:10 david Exp $ # This is a sample config for a pair of firewalls with two interfaces # # carp0 and carp1 have ip addresses on 192.168.3.0/24 and 192.168.6.0/24 # respectively. # net.inet.carp.preempt must be enabled (set to 1) for this to work correctly. # Uncomment one of the following lines to force primary/backup status. # init-state primary # init-state backup carp_up = "carp0.link.up && carp1.link.up" carp_down = "!carp0.link.up && !carp1.link.up" #carp_sync = "carp0.link.up && carp1.link.up || \ # !carp0.link.up && !carp1.link.up" state auto { if $carp_up set-state primary if $carp_down set-state backup } state primary { init { # PPPoE # bird # quagga # miredo run "[ -S /var/run/pppoe ] || /usr/sbin/ppp -nat -ddial pppoe" } if $carp_down set-state backup } state backup { init { # PPPoE # bird # quagga # miredo run "[ -S /var/run/pppoe ] && /usr/sbin/pppctl -p '' /var/run/pppoe bye all" } if $carp_up set-state primary }
PPPoE Serverは ppp(8) + pppoe(8) で作成できます。
まず、 /etc/ppp/ppp.conf を設定します。デフォルトの /etc/ppp/ppp.conf.sample をコピーします。 最下部の以下の pppoe の設定があります。これを使用します。
CHAP認証を使用します。ユーザ名とパスワードは /etc/ppp/ppp.secret に保存します。例:
user password
# A PPPoE (PPP over Ethernet) setup may look like this: # pppoe: set device "!/usr/sbin/pppoe -i pcn0" set mtu max 1492 set mru max 1492 set speed sync disable acfcomp protocomp deny acfcomp set ifaddr 192.168.1.1 192.168.1.10-192.168.1.20 enable ipv6cp enable chap
設定ができたら起動します。 -p で名前に対応する ppp.conf のプロファイル名を指定できます。
# pppoe -i pcn0 -p pppoe -s
PPPoE Client は ppp(8) + pppoe(8) のユーザランドのものと pppoe(4) のカーネルモードの2つがあります。
OpenBSD 4.9 の pppoe(4) が腐っているため使用するにはパッチを当てる必要があります。
今回はさっくり検証したかったため ppp(8) + pppoe(8) でPPPoE Clientを作成しました。 本番ではpppoe(4)を使っています。
まず、 /etc/ppp/ppp.conf を設定します。デフォルトの /etc/ppp/ppp.conf.sample をコピーします。 最下部に以下の pppoe の設定があります。これを使用します。
set device の引数に pppoe(8) を渡します。これらもわかるように pppoe(8) はユーザが直接呼ぶものではありません。 -i へ与える引数は適宜調整してください。
set server は pppctl(8) で外部から制御するためのソケットファイルを指定します。
set authname と set authkey はそれぞれユーザ名とパスワードです。
enable lqr と set lqrperiod 5 はキャリアセンスに頼らないlink-detection。PPPoEには必須。
defaultのプロファイルから set device, set speed を削除します。
# A PPPoE (PPP over Ethernet) setup may look like this: # pppoe: set device "!/usr/sbin/pppoe -i bge0" set mtu max 1492 set mru max 1492 set speed sync set server /var/run/pppoe "" 0177 set authname "user" set authkey "password" set lqrperiod 5 set timeout 60 set reconnect 3 28000 set redial 3 28000 disable acfcomp protocomp deny acfcomp enable lqr
設定ができれば ppp(8) を呼びます。 -ddial pppoe で /etc/ppp/ppp.conf 内の pppoe プロファイルが呼び出されます。
# ppp -ddial pppoe # ifconfig tun0 tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1454 priority: 0 groups: tun status: active inet 192.168.1.14 --> 192.168.1.1 netmask 0xffffffff inet6 fe80::2e0:b6ff:fe07:69e%tun0 -> prefixlen 64 scopeid 0x8
pppctl(8) を使って外から呼ぶ。
# pppctl -p '' /var/run/pppoe show iface
おまけおしまい。
次回はカーネルモードPPPoEのfailoverを含めた冗長構成に挑戦します。