Mailing List Archive

Re: [resource-agents] `findif` could be rewritten in shell (#53)
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:

findif()
{
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=
BRDCAST="$OCF_RESKEY_broadcast"

# 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.

match="$OCF_RESKEY_ip"

# 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
127.*)
set -- `ip -o -f inet route list match $match table local scope host`
# prints "local" as first word
shift
esac
fi
# 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 ;;
esac

NIC=$3
NETMASK=${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@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
Re: [resource-agents] `findif` could be rewritten in shell (#53) [ In reply to ]
Hi Lars

I added IPv6 correspondence to a script of Lars.

I am corresponding to the contents of the following ML.
http://www.gossamer-threads.com/lists/linuxha/dev/76429

-------------
#!/bin/bash
findif()
{
local match
NIC= NETMASK=
BRDCAST="$OCF_RESKEY_broadcast"
match="$OCF_RESKEY_ip"
network="inet"
echo $match | grep -qs ":"
if [ $? = 0 ];then
network="inet6"
fi

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`
else
set -- `ip -o -f inet6 route list match $match`
fi
if [ $# = 0 ] ; then
case $OCF_RESKEY_ip in
127.*)
set -- `ip -o -f $network route list match $match table local scope host`
shift;;
*::1)
set -- `ip -o -f $network route list match $match table local`
shift;;
esac
fi
[ $# = 0 ] && return 1
case $1 in
*/*) : OK ;;
*)
return 1 ;;
esac
NIC=$3
NETMASK=${1#*/}
if [ $network = "inet" ] ; then
set -- `ip -o -f $network addr show dev $NIC primary`
[ "$5" = brd ] && BRDCAST=$6
: == DEBUG == brd $BRDCAST ==
fi
return 0
}

# try it:
set -vx
OCF_RESKEY_ip=192.168.133.222 findif
OCF_RESKEY_ip=127.1.2.3/27 findif
-------------

Regards,
Tomo


> 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:
>
> findif()
> {
> 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=
> BRDCAST="$OCF_RESKEY_broadcast"
>
> # 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.
>
> match="$OCF_RESKEY_ip"
>
> # 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
> 127.*)
> set -- `ip -o -f inet route list match $match table local scope host`
> # prints "local" as first word
> shift
> esac
> fi
> # 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 ;;
> esac
>
> NIC=$3
> NETMASK=${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@lists.linux-ha.org
> http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
> Home Page: http://linux-ha.org/


_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
Re: [resource-agents] `findif` could be rewritten in shell (#53) [ In reply to ]
On Mon, Feb 06, 2012 at 09:51:46PM +0900, nozawat wrote:
> Hi Lars
>
> I added IPv6 correspondence to a script of Lars.

Which is nice, thank you ;-)
but useless :(
unless we also want to rewrite the currently written in C
IPv6addr resource agent ...

Which would also be nice, from my point of view.
But I'm not sure if that is feasable.

Cheers,

--
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
Re: [resource-agents] `findif` could be rewritten in shell (#53) [ In reply to ]
Hi Lars,

Thank you for your comment.

An allotment of the same IP is not made now when IP is assigned to a
loopback device in IPv6addr; have a problem.

Which of IPaddr2 and IPv6addr do you think to revise it to solve this problem?

Mori-san asks it about this in the following ML.
http://www.gossamer-threads.com/lists/linuxha/dev/76429

Regards,
Tomo

2012年2月7日20:06 Lars Ellenberg <lars.ellenberg@linbit.com>:
> On Mon, Feb 06, 2012 at 09:51:46PM +0900, nozawat wrote:
>> Hi Lars
>>
>> I added IPv6 correspondence to a script of Lars.
>
> Which is nice, thank you ;-)
> but useless :(
> unless we also want to rewrite the currently written in C
> IPv6addr resource agent ...
>
> Which would also be nice, from my point of view.
> But I'm not sure if that is feasable.
>
> Cheers,
>
> --
> : Lars Ellenberg
> : LINBIT | Your Way to High Availability
> : DRBD/HA support and consulting http://www.linbit.com
> _______________________________________________________
> Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
> http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
> Home Page: http://linux-ha.org/
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/