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/
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/