分からないところがあれば、多分、前項「Xenネットワークの操作とカスタマイズ」を読むと分かるだろう。基本的に、作業前にはすべてのゲストドメインをシャットダウンしておく。また、各例の説明の最後にはマシンを再起動することにしているが、マシンは立ち上げたまま、
root# service xend stop root# service libvirtd restart root# service xend start
で代用することができる場合もある。また、非Xenカーネルをインストールしていない場合、dom0 のネットワーク設定を変更するためには、その前にネットワークを仮想ブリッジの状態から実体の状態に戻しておく必要がある。手順をまちとめると、
root# /etc/xen/scripts/network-bridge stop <-- ネットワークインターフェイスの実体化 <-- ここで dom0 のネットワーク設定をいじる --> root# service network restart <-- dom0のネットワークの再起動(変更の反映) root# /etc/xen/scripts/network-bridge start <-- ネットワークインターフェイスの仮想化
ただし、既に /etc/xen/xend-config.sxp ファイルの `(network-script xxxx)' を書き換えている場合は、`network-bridge' のところはそれに合わせて。(基礎知識は「xenbrX の追加と動作の明確化」で確認のこと)
なお、以下、ゲストドメインの定義を libvirt 形式 XMLファイルを使って調整する場合に、例として /etc/xen/xml/ というディレクトリを使用しているが、そんなサブディレクトリはデフォルトでは存在しない。同じにしたければ root 権限で作成しておけばいいが、他の任意の場所でもまったく構わない。
 libvirtd の作る、CPU処理能力を浪費するマスカレードスイッチ virbr0 をやめ、マシン内部の仮想ネットワークを単純なひとつのサブネットとして形作る。
libvirtd の作る、CPU処理能力を浪費するマスカレードスイッチ virbr0 をやめ、マシン内部の仮想ネットワークを単純なひとつのサブネットとして形作る。
カスタマイズ方法も至って単純で、単に (1) xend 側ではゲストドメインそれぞれを xenbr0 につなぎ込ませるように定義を修正し、(2) libvirtd のオートスタートブリッジ "default" を無効にして、両サービスを再起動するかマシン自体をリブートするだけだ。
virt-manager の言いなりで構築したゲストドメインは virbr0 につながっているので、ゲストドメインの定義を修正する。
[xm形式で調整する場合]
例えば、/etc/xen/centos51u ファイルの;
vif = [ "mac=00:16:3e:17:d4:87,bridge=virbr0" ]
という定義行を
vif = [ "mac=00:16:3e:17:d4:87,bridge=xenbr0" ]
に変える。
[libvirt 形式の XMLダンプファイル で調整する場合]
例えば /etc/xen/xml/centos51u.xml で修正するなら、
<interface type='bridge'> <mac address='00:16:3e:17:d4:87'/> <source bridge='virbr0'/>
という部分を
<interface type='bridge'>
  <mac address='00:16:3e:17:d4:87'/>
  <source bridge='xenbr0'/>
と書き換えて、`virsh define /etc/xen/xml/centos51u.xml' によりドメイン定義プールに上書き登録。
より確実な xend のブリッジ作成動作を得るため /etc/xen/xend-config.sxp の
(network-script network-bridge)
を
(network-script network-bridge-custom)
に書き換え、/etc/xen/scripts/network-bridge-custom というファイル (パーミション root:root 755) を作る。その内容が下記。この実装方法では IPフォワーディングは最小限に制限したいので、antispoof を yes にする;
#!/bin/sh
dir=$(dirname $0)
 
${dir}/network-bridge "$@" vifnum=0 bridge=xenbr0 netdev=eth0 antispoof=yes
どのゲストドメインでも virbr0 を使うつもりがないのなら、virbr0 の自動起動を無効化する。
root# virsh net-destroy default root# virsh net-autostart default --disable
最後に、マシン自体を再起動し、各ゲストドメイン上で eth0 の IP を適宜設定しなおす。
 シンプルな単一サブネットの xend ブリッジの他に、敢えて外界とは通信できない内部専用サブネットワークを作る。 libvirt による virbrX はそれ自体がいわば dom0 のダミーインターフェイスなので、次に紹介する dummy0 を別途作成する方法よりも簡単に構築できる。なお、virbr をルータとして作る場合にはゲストOS自体のデフォルトゲートウェイは virbrX (ここでは virbr1) の IPアドレスとするものだが、当設定での virbr はルーティング機能を持たないので、マシンの物理インターフェイス peth0 の外にある本物のゲートウェイを指定することになる。
シンプルな単一サブネットの xend ブリッジの他に、敢えて外界とは通信できない内部専用サブネットワークを作る。 libvirt による virbrX はそれ自体がいわば dom0 のダミーインターフェイスなので、次に紹介する dummy0 を別途作成する方法よりも簡単に構築できる。なお、virbr をルータとして作る場合にはゲストOS自体のデフォルトゲートウェイは virbrX (ここでは virbr1) の IPアドレスとするものだが、当設定での virbr はルーティング機能を持たないので、マシンの物理インターフェイス peth0 の外にある本物のゲートウェイを指定することになる。
以下、第1 DomU の定義名が centos51u、第2 DomU が centos51u2 だと仮定して説明する
[xm形式で調整する場合]
/etc/xen/centos51u ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:87,bridge=xenbr0","mac=00:16:3e:17:d4:88,bridge=virbr1" ]
/etc/xen/centos51u2 ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:97,bridge=xenbr0","mac=00:16:3e:17:d4:98,bridge=virbr1" ]
[libvirt 形式の XMLダンプファイル で調整する場合]
/etc/xen/xml/centos51u.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:87'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:88'/> <source bridge='virbr1'/> <script path='vif-bridge'/> </interface>
/etc/xen/xml/centos51u2.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:97'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:98'/> <source bridge='virbr1'/> <script path='vif-bridge'/> </interface>
そして、両 XML ファイルからゲストドメインを再登録;
root# virsh define /etc/xen/xml/centos51u.xml root# virsh define /etc/xen/xml/centos51u2.xml
より確実な xend のブリッジ作成動作を得るため /etc/xen/xend-config.sxp の
(network-script network-bridge)
を
(network-script network-bridge-custom)
に書き換え、/etc/xen/scripts/network-bridge-custom というファイル (パーミション root:root 755) を作る。その内容が下記。libvirt がどうしても設定したがる DNS, DHCP がらみのカーネルパケットフィルタがあるのでそのクリーンナップも盛り込む。ただし、antispoof=yes にすると FORWARD チェーンは network-bridge スクリプトが自ずと一旦フラッシュするので、わざわざクリアする必要はない。また、例のように、xenbr が作成された後に、この構成では必要のない IPフォワーディングカーネルパラメータを無効にしてもよい。
#!/bin/sh
dir=$(dirname $0)
libvirtbr=virbr1
 
# Some clean-up of iptables rules inserted by libvirtd.
iptables -D INPUT -i $libvirtbr -p udp -m udp --dport 53 -j ACCEPT &>/dev/null
iptables -D INPUT -i $libvirtbr -p tcp -m tcp --dport 53 -j ACCEPT &>/dev/null
iptables -D INPUT -i $libvirtbr -p udp -m udp --dport 67 -j ACCEPT &>/dev/null
iptables -D INPUT -i $libvirtbr -p tcp -m tcp --dport 67 -j ACCEPT &>/dev/null
 
${dir}/network-bridge "$@" vifnum=0 bridge=xenbr0 netdev=eth0 antispoof=yes
echo 0 >/proc/sys/net/ipv4/ip_forward
| network-bridge-custom スクリプトセット (Ver.0.3.0)前述の「xenbrX 仮想ルータの無駄を省く」なども盛り込んで汎用的なものにしたスクリプトを作った。 
 共通ルーティンを別ファイルに分けたので、使用するには必ず network-bridge-custom と network-bridge-util を /etc/xen/scripts/ に置き、上記のようにパーミションに整える。また、virnetinfo.py を必ず PATH の通った場所 (/usr/local/bin/ など) に置いてほしい。設定や network-bridge 呼び出しの調整は network-bridge-custom の方で行い、それ以外はいじらなくてよい。 最後の route.conf は Linux のルーティングテーブルを設定するためのパラメータファイルで、ルーティング設定が不要ならなくても構わない。このファイルの中身は 、network-bridge-util の中の set_route() ファンクションに引数としてファイルのパスを付けてコールすることよって実行させることができる。使うのなら、route.conf には `ip route' または `ip rule' の後に続くコマンド文字列を並べておく。つまり、書き方は RedHat 系の /etc/sysconfig/network-scripts/route-eth* と rule-eth* の古い書き方と同じだ。ただし、もうちょっと便利なように `#' で始まる行と空行は無視されるようにした。 具体的な使い方は、後述の「単純ブリッジとLAN用L3スイッチ(非NATのvirbrX)」のところで触れている。 (virnetinfo.py を使わない古いバージョンはこれ。) 
 | 
/etc/virnet/virnet1.xml ファイルをテキストエディタで新規に作成する。
<network> <name>virnet1</name> <bridge name="virbr1" stp="off" forwardDelay='0' /> <ip address="192.168.200.1" netmask="255.255.255.0"> </ip> </network>
root# virsh net-define /etc/virnet/virnet1.xml root# virsh net-autostart virnet1
どのゲストドメインでも virbr0 を使うつもりがないのなら、virbr0 の自動起動を無効化する。
root# virsh net-destroy default root# virsh net-autostart default --disable
最後に、マシン自体を再起動する。そして各ゲストを起動させるのだが、ゲストが RedHat系OS (特に Red Hat Enterprise Linux) の場合は起動途中で kudzu が新しい仮想NIC を発見して「どうするか」と訊いてくることがある。その時は y キーを叩いて eth1 を設定してやりたいので、ドメインの起動は virt-manager から行ったほうがよい。起動したら、各ゲストドメイン上で eth0, eth1 のネットワーク設定ファイル類をきちんと整える。
 これは他の記事でよく目にする構築法だが、構築するのに手間がかかる、ちょっと時代遅れのやり方。実インターフェイスの存在しない xenbr を作らせるためには、あらかじめホストOS上でダミーインターフェイスをデバイスとして作成しておかなければならないからだ。結果的に得られる動作は、構築のラクな前記の「単純ブリッジと内部専用L2スイッチ」と同じだ。
これは他の記事でよく目にする構築法だが、構築するのに手間がかかる、ちょっと時代遅れのやり方。実インターフェイスの存在しない xenbr を作らせるためには、あらかじめホストOS上でダミーインターフェイスをデバイスとして作成しておかなければならないからだ。結果的に得られる動作は、構築のラクな前記の「単純ブリッジと内部専用L2スイッチ」と同じだ。
このサンプルは、本当に NIC が 2枚差しのマシンでも、dummy0 を作る過程を省くだけで作業の見本になるはずだ。
第1 DomU の定義名が centos51u、第2 DomU が centos51u2 だと仮定して話を進める。
きっぱりとマシンを再起動して、非Xenカーネルで立ち上げる。そしてまず、ホストOS の /etc/modprobe.conf に下記の定義を加える。こういう時のため (だけじゃないが) に dummy.ko というカーネルネットワークモジュールが存在する。
alias dummy0 dummy options dummy numdummies=1
次に /etc/sysconfig/network-scripts/ifcfg-dummy0 ファイルを下記の要領で作成する。MACADDR の値は、 00:00:00:00:00:00 などにしてしまうと eth1 を通じたゲストドメインと dom0 との通信が成り立たない。実在の機器の MACアドレスとぶつからないよう、xenmacgen.py スクリプトを使ってランダムに発生させた XenSource 管轄範囲のアドレスを使用するといいだろう。
DEVICE=dummy0 TYPE=Ethernet ONBOOT=yes BOOTPROTO=static IPADDR=192.168.200.1 NETMASK=255.255.255.0 MACADDR=00:16:3e:6f:5c:17 USERCTL=no IPV6INIT=no PEERDNS=no
インターフェイスが立ち上がることを確認する;
root# ifup dummy0 root# ifconfig dummy0
引き続き非XenカーネルのホストOS上で行う。 /etc/xen/xend-config.sxp の
(network-script network-bridge)
を
(network-script network-bridge-custom)
に書き換え、/etc/xen/scripts/network-bridge-custom というファイル (パーミション root:root 755) を作る。内容が下記。この実装方法では IPフォワーディングは最小限に制限したいので antispoof は yes にする。また、例のように、xenbr が作成された後に、この構成では不要の IPフォワーディングカーネルパラメータを無効にしてもよい。
#!/bin/sh
dir=$(dirname $0)
 
${dir}/network-bridge "$@" vifnum=0 bridge=xenbr0 netdev=eth0 antispoof=yes
${dir}/network-bridge "$@" vifnum=1 bridge=xenbr1 netdev=dummy0 antispoof=yes
echo 0 >/proc/sys/net/ipv4/ip_forward
[xm形式で調整する場合]
/etc/xen/centos51u ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:87,bridge=xenbr0","mac=00:16:3e:17:d4:88,bridge=xenbr1" ]
/etc/xen/centos51u2 ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:97,bridge=xenbr0","mac=00:16:3e:17:d4:98,bridge=xenbr1" ]
[libvirt 形式の XMLダンプファイル で調整する場合]
/etc/xen/xml/centos51u.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:87'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:88'/> <source bridge='xenbr1'/> <script path='vif-bridge'/> </interface>
/etc/xen/xml/centos51u2.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:97'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:98'/> <source bridge='xenbr1'/> <script path='vif-bridge'/> </interface>
両 XML ファイルからゲストドメインを再登録;
root# virsh define /etc/xen/xml/centos51u.xml root# virsh define /etc/xen/xml/centos51u2.xml
どのゲストドメインでも virbr0 を使うつもりがないのなら、virbr0 の自動起動を無効化する。
root# virsh net-destroy default root# virsh net-autostart default --disable
仕上げにマシン自体を再起動する。今度はもちろん Xenカーネルで立ち上げる。そして各ゲストを起動させるのだが、ゲストが RedHat系OS の場合 (特に Red Hat Enterprise Linux) は、起動途中で kudzu が新しい仮想NIC を発見して「どうするか」と訊いてくることがある。その時に y キーなどを叩いて eth1 を設定してやれるよう、ドメインの起動は virt-manager から行ったほうがよい。起動したら、各ゲストドメイン上で eth0, eth1 のネットワーク設定ファイル類をきちんと整える。
 bonding によって冗長化した dom0 のネットワークインターフェイスを、単純ブリッジとしてゲストドメインに提供する。せっかくなので、ここでは物理マシンに NIC が 3つ装備されていると仮定し、eth0 と eth2 との bonding インターフェイス bond0 をメイン仮想ブリッジ、単体の eth1 をサブ的なブリッジ (いわば裏LAN) としてゲストに提供するシナリオにする。
bonding によって冗長化した dom0 のネットワークインターフェイスを、単純ブリッジとしてゲストドメインに提供する。せっかくなので、ここでは物理マシンに NIC が 3つ装備されていると仮定し、eth0 と eth2 との bonding インターフェイス bond0 をメイン仮想ブリッジ、単体の eth1 をサブ的なブリッジ (いわば裏LAN) としてゲストに提供するシナリオにする。
第1 DomU の定義名が centos51u、第2 DomU が centos51u2 だと仮定して話を進める。
ホストOS 上での bonding インターフェイス作成については、ここでは細かく触れない。kernel-doc パッケージをインストールするとコピーされる /usr/share/doc/kernel-doc-x.x.x/Documentation/networking/bonding.txt を読むといいだろう。ここにも、CentOS 5.3 (kernel-2.6.18-164.el5) の bonding.txt のコピーを置いておく。
きっぱりとマシンを再起動して、非Xenカーネルで立ち上げる。そして、bonding インターフェイスを作成、設定しておく。
引き続き非XenカーネルのホストOS上で行う。 /etc/xen/xend-config.sxp の
(network-script network-bridge)
を
(network-script network-bridge-custom)
に書き換え、/etc/xen/scripts/network-bridge-custom というファイル (パーミション root:root 755) を作る。内容が下記。この実装方法では IPフォワーディングは最小限に制限したいので antispoof は yes にする。また、例のように、Xenブリッジが作成された後に、この構成では不要の IPフォワーディングカーネルパラメータを無効にしてもよい。
#!/bin/sh
dir=$(dirname $0)
 
${dir}/network-bridge-bonding "$@" bridge=bond0 netdev=bond0 antispoof=yes
${dir}/network-bridge "$@" bridge=xenbr0 netdev=eth1 antispoof=yes
echo 0 >/proc/sys/net/ipv4/ip_forward
[xm形式で調整する場合]
/etc/xen/centos51u ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:87,bridge=bond0","mac=00:16:3e:17:d4:88,bridge=xenbr0" ]
/etc/xen/centos51u2 ファイルの vif 定義行;
vif = [ "mac=00:16:3e:17:d4:97,bridge=bond0","mac=00:16:3e:17:d4:98,bridge=xenbr0" ]
[libvirt 形式の XMLダンプファイル で調整する場合]
/etc/xen/xml/centos51u.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:87'/> <source bridge='bond0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:88'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface>
/etc/xen/xml/centos51u2.xml の <interface type='bridge'> ブロックを追加;
<interface type='bridge'> <mac address='00:16:3e:17:d4:97'/> <source bridge='bond0'/> <script path='vif-bridge'/> </interface> <interface type='bridge'> <mac address='00:16:3e:17:d4:98'/> <source bridge='xenbr0'/> <script path='vif-bridge'/> </interface>
両 XML ファイルからゲストドメインを再登録;
root# virsh define /etc/xen/xml/centos51u.xml root# virsh define /etc/xen/xml/centos51u2.xml
どのゲストドメインでも virbr0 を使うつもりがないのなら、virbr0 の自動起動を無効化する。
root# virsh net-destroy default root# virsh net-autostart default --disable
仕上げにマシン自体を再起動する。今度はもちろん Xenカーネルで立ち上げる。そして各ゲストを起動させるのだが、ゲストが RedHat系OS の場合 (特に Red Hat Enterprise Linux) は、起動途中で kudzu が新しい仮想NIC を発見して「どうするか」と訊いてくることがある。その時に y キーなどを叩いて eth1 を設定してやれるよう、ドメインの起動は virt-manager から行ったほうがよい。起動したら、各ゲストドメイン上で eth0, eth1 のネットワーク設定ファイル類をきちんと整える。
下図のような構造を実現する。構築はかなり面倒くさいが、それだけの価値はある。まずはとにかく図を見ていただこう。これは Fedora Core 8 を dom0 にしたものなので、RHEL/CentOS 5.x をホストOS にする場合は eth0 を xenbr0 に読み替えるなどしていただきたい。
 実マシンには NIC がふたつある。第1 NIC はインターネットへのゲートウェイになっている NAT ルータにつながり、第2 NIC は内部 LAN の諸セグメントとのルーティングを行う非NAT ルータ (現実的には L3 スイッチ等) につながっているとする。
実マシンには NIC がふたつある。第1 NIC はインターネットへのゲートウェイになっている NAT ルータにつながり、第2 NIC は内部 LAN の諸セグメントとのルーティングを行う非NAT ルータ (現実的には L3 スイッチ等) につながっているとする。
dom0 の eth0 (RHEL/CentOS 5.x では xenbr0) は Xen の network-bridge によって作り、virbr0 は libvirt を使って作る。
virbr0 を NAT ルータにしてしまえば構築は非常にラクだが、そもそも NAT ルータには、送信元アドレスが化ける という欠点がある。図の `To/From other segments' の向こう側にいるサーバなりクライアントなりが centos51u の例えば HTTPD にアクセスしてきた場合、centos51u のログには全て「192.168.122.1 からのアクセス」として記録されてしまうのだ。それではログの用を成さない。また、iptables なりでアクセス制限を掛けようとする際にも困る。そこで、virbr0 は非NAT のルータ (L3スイッチ) として生成し、 dom0 内でルーティングテーブルを操って dom0 を Linux ルータ として機能させようという仕業だ。上図の [FORWARD] で示した点線からも分かるように、ゲストドメインの eth0 と eth1 とでは用途を分離し、下記のようなアクセス規則となることを目指す;
| dom0のIF | domUのIF | 通信可否 | |
| eth0 | <--> | eth0 | 可能 | 
| eth0 | <--> | eth1 | 不能 | 
| eth1 | <--> | eth0 | 不能 | 
| eth1 | <--> | eth1 | 可能 | 
各 Xen ドメインのデフォルトゲートウェイは以下のように定義することにする。DomU#N として示したゲストドメインは、ゲストドメイン centos51u と同様に拡張可能という意味で付け加えたにすぎず、説明からは省く;
| ドメイン | Default GW | 各ドメインにとっての GW Dev | 
| dom0 | 192.168.1.254 | eth0 | 
| centos51u | 192.168.1.254 | eth0 | 
ただでさえ話が込み入っているので、少しでも単純化するため、筆者の作成した network-bridge-custom セットをベースに説明を進める。
 
当例に則った作成済みセット+設定ファイル類:
肝心なのは <forward> ブロックの mode 属性 (バージョンによっては `type')。
<forward mode='route' dev='eth1'/>
これによって、virbr0 は NAT ルータでなく、いわゆる L3スイッチとなる。より正確に言うと、ブリッジの素性は mode='nat' の時と違いがあるわけではないのだが、生成時に iptables の MASQUERADE ルールが登録されず、eth1 <--> virbr0 の FORWARD の ACCEPT ルールだけが登録されるようになる。ファイルが作成できたら、定義プールに登録 (あるいは再登録) するとともに、libvirtd 起動時に自動的に生成されるようにする。
既に virbr0 (virnet0) が稼働している場合はまず
root# virsh net-destroy virnet0
を行ってから、
root# virsh net-define /etc/virnet/virnet0.xml root# virsh net-autostart virnet0
domU 定義ファイル centos51u.xml を /etc/xen/xml/ (ディレクトリパスは任意) に作る。肝心なのはふたつの <interface> ブロック。
<interface type='bridge'> <--WAN用インターフェイス生成ブロック <source bridge='eth0'/> <mac address='00:16:3e:5c:00:26'/> <script path='/etc/xen/scripts/vif-bridge'/> </interface> <interface type='bridge'> <--LAN用インターフェイス生成ブロック <source bridge='virbr0'/> <mac address='00:16:3e:56:b2:5a'/> <script path='/etc/xen/scripts/vif-bridge'/> </interface>
LAN用インターフェイスのほうも <script> の path 属性は vif-bridge にする。vif-route にすると、幾つかのルーティングテーブルエントリ (未解析...) が登録されるとともに、sysctl の値 /proc/sys/net/ipv4/conf/vif1.1/proxy_arp が 1 にセットされるが、有効にしたところでルーティング設定が極めて単純になるというわけでもないので、 vif-bridge にしておいたほうがすっきりする。proxy_arp の説明はこの後の 「(3-2) dom0のルーティング設定」参照。
定義ファイルが完成したら、ドメイン定義プールに登録する;
root# virsh define /etc/xen/xml/centos51u.xml
network-bridge-custom の内容を項目ごとに順を追って説明しよう。
function do_bridge () {
    ## This is the very heart of network-bridge script.
    ${dir}/network-bridge "$@" bridge=eth0 netdev=eth0 antispoof=no
}
network-bridge-custom の最も中心的な仕事がこれ。xend ブリッジの作成だ。bridge= は RHEL/CentOS 5.x では xenbr0 を指定しなければならない。各ブリッジは自ホスト発でないパケットも扱うことになるため antispoof は no。
disable_ipfwd
/proc/sys/net/ipv4/ip_forward の値を `0' にするルーティン。 今回はもちろん `1' のままになっていなければならないが、このファンクションは mode=nat または mode=route の libvirt ブリッジが存在する場合は発動されないので、特にコメントアウトする必要はない。
"# Additional routing configuration" のセクションは次項にて。
set_route /etc/xen/route.conf
によって、/etc/xen/route.conf ファイルが set_route() ファンクションに読み取られてルーティングテーブルが設定される (set_route() は network-bridge-util の中で定義してあるシェルファンクション)。見てもらえば分かるように、route.conf に並べてあるのは iproute2 のコマンド `ip route replace' または `ip rule add' の後ろに嵌め込むコマンド文字列だ。この構築例での route.conf は、パケットの送信元ネットワーク毎のルーティングテーブル (wanside, lanside, virside の 3つ) を作って、それぞれの中にパケットの宛先毎のルーティング規則を登録している。
Linux のルーティング操作に馴染みのない人は "Linux Advanced Routing & Traffic Control HOWTO" の 第4章 だけでも読んでおくといいだろう。JF に日本語訳もある。
route.conf に書いてある引数が `ip route' の引数なのか `ip rule' の引数なのかを調べる条件式 (network-bridge-util の中) は、筆者が自分で使うであろうコマンドやその記述慣習に基づいたもので、使用するコマンドやパラメータの書き方の癖によっては合わないかもしれない。set_route() ファンクションの条件部分を適宜調整してほしい。
ルーティング設定は /etc/sysconfig/network-scripts/route-<IF_NAME> ファイルや rule-<IF_NAME> に書いておく方法もあるが、それらが実行されるシステム起動時には virbrX はまだ存在しないということをお忘れなく。
dom0 によるネットワークトラフィックの扱いには、sysctl のネットワーク関連カーネルパラメータも関係してくる。そのひとつが、network-bridge-custom の最後に書いてある次の行だ;
sysctl -w net.ipv4.conf.eth1.rp_filter=1 &>/dev/null
ここで eth1 に対して有効にしている rp_filter (Reverse Patch filter ) パラメータは、実際のパケットの送信元アドレスがルーティングテーブルに定義してあるネットワークインターフェイスとその取り扱いアドレスにきちんと合致し、なお且つこちらからの返答パケットがその同じインターフェイスから出て行くことが妥当かどうか検査し、合致しなければパケットを破棄するというもの。Oskar Andreasson の Ipsysctl Tutorial に解説されている。dom0 のルーティングに大きく関係する sysctl 変数には、この他に、少なくとも以下のものがある。(<IF_NAME> は `eth0' のようなそれぞれのインターフェイスデバイス名を指す);
値を設定するには、例の rp_filter のように network-bridge-custom に書くか、/etc/sysctl.conf に書いておく。 ちなみに、proxy_arp や accept_redirects の値をインターフェイス毎にひとつひとつ調べるのは面倒くさいが、下記のようにコマンドすればいっぺんに分かる;
root# grep [0-9] /proc/sys/net/ipv4/conf/*/proxy_arp
もうひとつ、事前に必ずやっておかなければならないことがある。ルーティングテーブルの入れ物を作っておく作業だ。当設定例においては、以下の行を /etc/iproute2/rt_tables ファイルに追加しておく。ただし ID番号はこの通りである必要はない;
100 wanside 101 lanside 102 virside
ここまでの作業を全てやり終えたら、ホストマシンを一旦リブートする。ホストOS が再び立ち上がり libvirtd と xend が活性化された後には、Xen ブリッジ eth0 (または xenbr0) と libvirt ブリッジ virbr0 ができ、必要なルーティングテーブルも出来上がっているはずだ。当例に関係のあるルーティングテーブルを確認するためのコマンドは;
root# ip route show root# ip rule show root# ip route list table wanside root# ip route list table lanside root# ip route list table virside
最初の図解のところで示した通り、ゲストドメイン centos51u 自体のデフォルトゲートウェイは WAN側ルータを向いている。そうでなくデフォルトゲートウェイを virbr0 (192.168.122.1) にしている場合、この作業は不要だ。
設定は簡単。そのゲストドメインがオートスタートになっていない場合は `virsh start centos51u' などで立ち上げておく。そしてゲストドメインに仮想コンソールでログイン;
root# virsh console centos51u
そうしたら、ゲストドメイン自体の /etc/sysconfig/network-scripts/route-eth1 ファイル (root:root 644) を、下記の内容で作成する;
192.168.0.0/24 dev eth1 via 192.168.122.1
設定を反映するため、ゲストドメイン上で `service network restart' でネットワークだけを再起動するか、そのゲストドメインをリブートする。
図の左上の [LAN Switch] にあたるものには、「ゲストドメイン (192.168.122.0/24) へ行くには 192.168.0.3 (dom0 の eth1) をゲートウェイにせよ」というルーティングエントリが必要だ。今スイッチがなく、暫定的に単独の Linux PC で試してみたければ、その試験PC をハブ等で Xen物理マシンの eth1 と接続しておき、試験PC に下記のようにしてルートを追加してやればいい;
root# ip route add 192.168.122.0/24 via 192.168.0.3