最近、LVS(UltraMonkey)の設定をしていた時に気付いたことがあったのでメモ。
この時は、事情でVLAN なインタフェース(例: eth0.123)にをつかって、LVSの DR(Direct Route)モードで設定を行う必要があった。
この場合、振り分け先のサーバ(ldirectord.cf の real= 行に記述するサーバ。いわゆる「リアルサーバ」)上に lo:0 にも /32 で VIP を設定する必要がある。
これに伴い、lo:0 が持っている VIP への ARP リクエストを無視させる/ARPを出す時にVIPを使わないように制限する必要があるので、
/etc/sysctl.conf
に、例えばこんな感じの設定を行う必要がある。
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2
参考情報としては、例えば
の「Real Servers」あたりを参照のこと。
さて、ここからが本題である。
上記の eth0 の部分が、VLAN 123 に対応するインタフェースで eth0.123 だったらどうなるか?
そのまま書いてしまうと、token の部分の要素のセパレータの . (ピリオド)と、eth0 と VLAN番号の間の . (ピリオド)が被っているので /proc/sys 以下にマッピングされるときに、
net.ipv4.conf.eth0.123.arp_ignore
なら
/proc/sys/net/ipv4/conf/eth0/123/arp_ignore
と変換されてしまい、エラーになる。クォートもできないようだ。
そこで、man sysctl を良く読んでみると、
SYSCTL(8) System Administration SYSCTL(8)
NAME
sysctl - configure kernel parameters at runtime
SYNOPSIS
sysctl [options] [variable[=value]] [...] sysctl -p [file or regexp]
[...]
DESCRIPTION
sysctl is used to modify kernel parameters at runtime. The parameters
available are those listed under /proc/sys/. Procfs is required for
sysctl support in Linux. You can use sysctl to both read and write
sysctl data.
PARAMETERS
variable
The name of a key to read from. An example is kernel.ostype.
The '/' separator is also accepted in place of a '.'.
と書いてある。特に最後の赤字で強調した行に注目。
全体としてどういう仕様になるのか、いまいちあいまいなのだが、とにかく . (ピリオド)の代わりに / (スラッシュ)も使えるように見える。
実際やってみると、上記のパターンであれば、
net.ipv4.conf.all.arp_ignore = 1
net/ipv4/conf/eth0.1110/arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net/ipv4/conf/eth0.1110/arp_announce = 2
の2行目と4行目のように書いてやればよく、挙動としては、最初にあらわれた / (スラッシュ)か . (ピリオド)が、トークンの部分の要素のセパレータとして使われる。…ので、上記は正常に反映できるし、これは行ごとにばらばらでよい。
余談だが、sysctl は(Ubuntuでは) procps パッケージに含まれており、当該部分の処理は、sysctl.c の
73 static void slashdot(char *restrict p, char old, char new)の 76行目で strpbrk(3)関数に "/." (スラッシュとピリオド)を渡しているところが対応する。
74 {
75 int warned = 1;
76 p = strpbrk(p, "/.");
77 if (!p)
78 /* nothing -- can't be, but oh well */
79 return;
80 if (*p == new)
(procps のバージョンは 1:3.3.3-2ubuntu3)
実は、strpbrk なんて初めて知ったのだが、man してみると以下の通り。
STRPBRK(3) Linux Programmer's Manual STRPBRK(3)
NAME
strpbrk - search a string for any of a set of characters
SYNOPSIS
#include <string.h>
char *strpbrk(const char *s, const char *accept);
DESCRIPTION
The strpbrk() function locates the first occurrence in the string s of
any of the characters in the string accept.
:
第2引数の文字列に含まれる任意の文字が、第一引数に渡した文字列中に最初にあらわれる位置を返す…と。
いや、Cの標準ライブラリも奥が深いですね...