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/