nozawat at gmail
Feb 6, 2012, 4:51 AM
Post #2 of 4
Re: [resource-agents] `findif` could be rewritten in shell (#53)
[In reply to]
I added IPv6 correspondence to a script of Lars.
I am corresponding to the contents of the following ML.
echo $match | grep -qs ":"
if [ $? = 0 ];then
if [ $network = "inet" ] ; then
[ -n "$OCF_RESKEY_cidr_netmask" ] && match=$match/$OCF_RESKEY_cidr_netmask
set -- `ip -o -f inet route list match $match scope link`
set -- `ip -o -f inet6 route list match $match`
if [ $# = 0 ] ; then
case $OCF_RESKEY_ip in
set -- `ip -o -f $network route list match $match table local scope host`
set -- `ip -o -f $network route list match $match table local`
[ $# = 0 ] && return 1
case $1 in
*/*) : OK ;;
return 1 ;;
if [ $network = "inet" ] ; then
set -- `ip -o -f $network addr show dev $NIC primary`
[ "$5" = brd ] && BRDCAST=$6
: == DEBUG == brd $BRDCAST ==
# try it:
> Taking this to the mailing list as well, to give it a wider audience ...
> On Tue, Jan 31, 2012 at 07:56:56AM -0800, b-a-t wrote:
> > Referring to the #52 I got the idea that shell script for finding
> > interface by IP address could be better solution than parsing routing
> > table in C.
> > For (most) Linux distributions 'ip' command is a part of the standard installation and:
> > <pre>
> > # ip route get 10.0.0.220
> > 10.0.0.220 dev eth1 src 10.0.0.106
> > </pre>
> > gives better and more portable results.
> > For FreeBSD(and Solaris I guess):
> We can ignore non-Linux for IPaddr2, that is already linux specific.
> > Even parsing of '/proc/net/route' is easier in shell, so I see no good
> > reason for quite complex and not flexible C binary for these
> > purpose(except the speed, possibly).
> > If this idea gets support I can try to write such a replacement.
> "once upon a time" I started something like that already,
> just for fun. But then left it alone for quite some time,
> because, well, if it ain't broken, don't fix it...
> I'm not sure why we would care to specify an explicit broadcast address,
> so we probably should not try to guess it (the kernel knows better, anyways)
> and only put it into the command line if it really was passed in via
> configuration parameters, in case there actually is a use case for that.
> findif seems to have a few heuristics, which seem to override the input?
> Not sure here.
> There is also the hack-ish "LVS support" stuff in the script,
> we need to make sure that does not break.
> Nor any other aspect of "unusual" usage.
> Anyways, it may be a starting point:
> local match
> # FIXME: if all is specified, why would we try to second guess?
> # just use the input, and if it fails, it fails?
> # non-local, "return" values
> NIC= NETMASK=
> # FIXME just make sure you drop the "brd $BRDCAST"
> # from the ip addr add command if $BRDCAST is empty,
> # and the kernel will do the right thing. Or so me thinks...
> # Also see below, where we try to second guess BRDCAST.
> # ip actually does not care if the mask is cidr or dotted quad,
> # as long as it is a mask.
> # No mask implies "/32" (for the match, only).
> # The "match" in "ip route list match ..." will find the best (longest prefix) route.
> [ -n "$OCF_RESKEY_cidr_netmask" ] && match=$match/$OCF_RESKEY_cidr_netmask
> # FIXME: what if the guessed nic,
> # and the requested nic, do not match?
> # Would tools/findif.c have ignored the input in that case?
> # Should the RA return $OCF_ERR_CONFIGURED in that case?
> ### FIXME ### [ -n "$OCF_RESKEY_nic" ] && match="$match dev $OCF_RESKEY_nic"
> # Only routes with scope link.
> set -- `ip -o -f inet route list match $match scope link`
> if [ $# = 0 ] ; then
> # possibly need to add special case for 127.x.y.z
> # at least tools/findif.c has one
> case $OCF_RESKEY_ip in
> set -- `ip -o -f inet route list match $match table local scope host`
> # prints "local" as first word
> # Still nothing? Too bad.
> [ $# = 0 ] && return 1
> # paranoia
> case $1 in
> */*) : OK ;;
> # No slash should only happen for table local, no mask
> # (or /32), and address already present, and even then
> # it should not show up as first line of output...
> # If we cannot guess the netmask, you need to specify it.
> return 1 ;;
> : == DEBUG == $NIC / $NETMASK ==
> # Do we really need to guess the broadcast? Why?
> # We could try to guess it from the primary address on the nic
> # but actually that seems pointless?
> set -- `ip -o -f inet addr show dev $NIC primary`
> # this really should have worked, always!?
> # for 127.x.y.z, there usually won't be a broadcast address
> [ "$5" = brd ] && BRDCAST=$6
> : == DEBUG == brd $BRDCAST ==
> return 0
> # try it:
> set -vx
> OCF_RESKEY_ip=10.9.9.99 findif
> OCF_RESKEY_ip=127.1.2.3/27 findif
> : Lars Ellenberg
> : LINBIT | Your Way to High Availability
> : DRBD/HA support and consulting http://www.linbit.com
> Linux-HA-Dev: Linux-HA-Dev [at] lists
> Home Page: http://linux-ha.org/
Linux-HA-Dev: Linux-HA-Dev [at] lists
Home Page: http://linux-ha.org/