Mailing List Archive

ripd tests for multicast flag -- is that correct?
Hi,

I'm just doing some testing of my PtP patch, and I noticed that ripd
has code in several places that looks like this:

if (version == RIPv2 && if_is_multicast (ifp))

So it seems that RIPv2 is disabled if the interface does not
have the IFF_MULTICAST flag turned on.

Is this correct logic? My understanding was that the system should assume
that all broadcast and point-to-point interfaces are capable of multicast.

According to the linux iproute tools "IP Command Reference" manual
(located in /usr/share/doc/iproute-2.4.7/ip-cref.ps on my linux system):

* MULTICAST -- is an advisory flag indicating that the interface is
aware of multicasting i.e. sending packets to some subset of
neighbouring nodes. Broadcasting is a particular case of
multicasting, where the multicast group consists of all nodes on the
link. It is important to emphasize that software must not interpret
the absence of this flag as the inability to use multicasting on this
interface. Any POINTOPOINT and BROADCAST link is multicasting by
definition, because we have direct access to all the neighbours and,
hence, to any part of them. Certainly, the use of high bandwidth
multicast transfers is not recommended on broadcast-only links because
of high expense, but it is not strictly prohibited.

So what's the correct approach? I notice that ripd and ripngd are
the only two protocol daemons to test for the multicast flag...

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
You are right. A point-to-point interface is multicast aware.
if_is_multicast should be replaced by if_is_multicast or ptp.

Vincent

PS: The issue is with the point-to-multipoint (NBMA) interfaces such as
X25, Frame Relay or ATM. These interfaces should not have the ptp flag.



Andrew J. Schorr wrote:

>Hi,
>
>I'm just doing some testing of my PtP patch, and I noticed that ripd
>has code in several places that looks like this:
>
> if (version == RIPv2 && if_is_multicast (ifp))
>
>So it seems that RIPv2 is disabled if the interface does not
>have the IFF_MULTICAST flag turned on.
>
>Is this correct logic? My understanding was that the system should assume
>that all broadcast and point-to-point interfaces are capable of multicast.
>
>According to the linux iproute tools "IP Command Reference" manual
>(located in /usr/share/doc/iproute-2.4.7/ip-cref.ps on my linux system):
>
> * MULTICAST -- is an advisory flag indicating that the interface is
> aware of multicasting i.e. sending packets to some subset of
> neighbouring nodes. Broadcasting is a particular case of
> multicasting, where the multicast group consists of all nodes on the
> link. It is important to emphasize that software must not interpret
> the absence of this flag as the inability to use multicasting on this
> interface. Any POINTOPOINT and BROADCAST link is multicasting by
> definition, because we have direct access to all the neighbours and,
> hence, to any part of them. Certainly, the use of high bandwidth
> multicast transfers is not recommended on broadcast-only links because
> of high expense, but it is not strictly prohibited.
>
>So what's the correct approach? I notice that ripd and ripngd are
>the only two protocol daemons to test for the multicast flag...
>
>-Andy
>_______________________________________________
>Quagga-dev mailing list
>Quagga-dev@lists.quagga.net
>http://lists.quagga.net/mailman/listinfo/quagga-dev
>
>
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Thu, May 13, 2004 at 05:46:58PM +0200, Vincent Jardin wrote:
> You are right. A point-to-point interface is multicast aware.
> if_is_multicast should be replaced by if_is_multicast or ptp.
>
> Vincent
>
> PS: The issue is with the point-to-multipoint (NBMA) interfaces such as
> X25, Frame Relay or ATM. These interfaces should not have the ptp flag.

So is this the proper fix?

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Thu, May 13, 2004 at 05:46:58PM +0200, Vincent Jardin wrote:
> You are right. A point-to-point interface is multicast aware.
> if_is_multicast should be replaced by if_is_multicast or ptp.
>
> Vincent
>
> PS: The issue is with the point-to-multipoint (NBMA) interfaces such as
> X25, Frame Relay or ATM. These interfaces should not have the ptp flag.

Actually, the patch causes problems with ripd when using point-to-point
interfaces that do not have assigned subnets (i.e. netmask is /32 and
we're identifying the interface by the peer address). In those cases,
the setsockopt_multicast_ipv4() function call in
ripd/rip_interface.c:rip_interface_multicast_set() is failing.

I'm guessing that code should be using the connected->address
instead of connected->destination address in the setsockopt_multicast_ipv4()
call. Does anybody know?

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
You are right. A point-to-point interface is multicast
aware. if_is_multicast should be replaced by if_is_multicast or ptp.

This sounds like a statement about Linux, rather than something which
must be generally true. Multicast support on p2p links requires the
ability to join groups on the receiver and have only joined groups
delivered.

On all modern systems, p2p links will have this ability. But testing
for 'interface is multicast capable' is the right thing, if that's the
question. If Linux has p2p interfaces that don't set the multicast
flag (and that isn't considered a bug in Linux, or it's useful to have
quagga work on unfixed systems, which is clearly the case), then the
if_is_multicast() function should probably have an #ifdef linux that
works around this.

--
Greg Troxel <gdt@ir.bbn.com>
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
I object to this change; on BSD systems IFF_MULTICAST really means
what it says. But putting that in ifdef linux would be ok with me -
the point of the function is after all to abstract "can we do
multicast on this interface" across operating systems.

--
Greg Troxel <gdt@ir.bbn.com>
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Sun, May 16, 2004 at 11:17:48AM -0400, Greg Troxel wrote:
> This sounds like a statement about Linux, rather than something which
> must be generally true. Multicast support on p2p links requires the
> ability to join groups on the receiver and have only joined groups
> delivered.
>
> On all modern systems, p2p links will have this ability. But testing
> for 'interface is multicast capable' is the right thing, if that's the
> question. If Linux has p2p interfaces that don't set the multicast
> flag (and that isn't considered a bug in Linux, or it's useful to have
> quagga work on unfixed systems, which is clearly the case), then the
> if_is_multicast() function should probably have an #ifdef linux that
> works around this.

So on BSD, is it fair to say that the interface is multicast capable
if and only if the IFF_MULTICAST flag is set? If so, that is clearly
different from modern linux, where all PtP and broadcast links should be
assumed to be capable of multicast, regardless of that flag.

I agree that the if_is_multicast function should be patched based
on whether the given platform really requires the IFF_MULTICAST flag,
but I do not have the autoconf knowledge to do this the right way.

By the way, my primary concern was testing the impact of my PtP patch
on ripd. If anybody has a ripd config that gets RIPv2 multicast to work
properly on linux over a PtP link using /32 addressing where a subnet
has not been assigned (but instead the IP addresses have been borrowed
from other interfaces), I would appreciate a copy. I just get
errors from the setsockopt IP_MULTICAST_IF call in rip_interface_multicast_set.
I'm not clear whether this is a configuration problem, a bug in the
code, or an unsupported scenario.

Thanks,
Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
> So on BSD, is it fair to say that the interface is multicast capable
> if and only if the IFF_MULTICAST flag is set? If so, that is clearly
> different from modern linux, where all PtP and broadcast links should be
> assumed to be capable of multicast, regardless of that flag.

I believe this is the case. Sometimes new Ethernet drivers work w/o
multicast support first, although this is not considered a good
situation. (It seems odd to me to have a flag to signify a
capability, and then have it defined to not really mean anything, but
that's irrelevant to how quagga should handle the situation.)

> I agree that the if_is_multicast function should be patched based
> on whether the given platform really requires the IFF_MULTICAST flag,
> but I do not have the autoconf knowledge to do this the right way.

So far it seems that treating an interface as multicast-capable even
if IFF_MULTICAST is not set is behavior seen only on Linux, so

#ifdef linux
/*
* IFF_MULTICAST doesn't mean what it says on Linux; all broadcast and
* p2p interfaces are multicast capable.
*/
use the or of three flags
#else
check just IFF_MULTICAST
#endif

would seem to be the way to go. I don't see how autoconf could
actually test for this. If other systems are found to have this
behavior we can then figure out what to do.

> By the way, my primary concern was testing the impact of my PtP
> patch on ripd. If anybody has a ripd config that gets RIPv2
> multicast to work properly on linux over a PtP link using /32
> addressing where a subnet has not been assigned (but instead the IP
> addresses have been borrowed from other interfaces), I would
> appreciate a copy. I just get errors from the setsockopt
> IP_MULTICAST_IF call in rip_interface_multicast_set. I'm not clear
> whether this is a configuration problem, a bug in the code, or an
> unsupported scenario.

No clues (my only ppp link has dedicated addresses from a /30, but has
/32 netmasks, and both ends are NetBSD), other than to read the kernel
source or run gdb on the kernel to see where the error is generated.
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Sun, May 16, 2004 at 03:43:38PM -0400, Greg Troxel wrote:
> (It seems odd to me to have a flag to signify a
> capability, and then have it defined to not really mean anything, but
> that's irrelevant to how quagga should handle the situation.)

Actually, I think that's overstating the case. My understanding is
that the flag's presence definitely indicates multicast capability
under linux. It's just that broadcast and point-to-point links
are automatically capable of multicast, so the flag is not necessary
in those cases. So, as discussed, the proper test on linux
is (ifp->flags & (IFF_MULTICAST|IFF_BROADCAST|IFF_POINTOPOINT)).
I guess the point is that IFF_MULTICAST can be used to indicate
multicast capabilities for interfaces that are neither broadcast
nor PtP links (e.g. perhaps NBMA links).

> No clues (my only ppp link has dedicated addresses from a /30, but has
> /32 netmasks, and both ends are NetBSD), other than to read the kernel
> source or run gdb on the kernel to see where the error is generated.

I'd still appreciate seeing a working PtP RIPv2 multicast config, even
if not linux. Are you running RIPv2 over that link using multicast?

Thanks,
Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
Actually, I think that's overstating the case. My understanding is

Indeed - I misunderstood. So there are clear semantics, and I merely
find them odd :-) (IMHO, because Quagga has to reconstruct the
'obvious' semantics from the rules about Broadcast/p2p interfaces
always being MC capable.)

I'd still appreciate seeing a working PtP RIPv2 multicast config, even
if not linux. Are you running RIPv2 over that link using multicast?

I'm running ospf and ripng, both of which work fine (pre-patch), but I
need the routes to work solidly so it's a bit awkward to test. I just
tried starting ripd on both ends, figuring that they would exchange
some routes and not others and that my system wouldn't end up hosed,
and got

May 16 18:56:54 foo ripd[14154]: Can't setsockopt IP_MULTICAST_IF to
fd 5
May 16 18:56:54 foo ripd[14154]: Can't bind socket: Invalid argument
May 16 18:57:30 foo ripd[14154]: Can't bind socket: Invalid argument
May 16 18:57:30 foo ripd[14154]: Can't setsockopt IP_MULTICAST_IF to
fd 5
May 16 18:57:30 foo ripd[14154]: Can't bind socket: Invalid argument

on on the other end just

Can't setsockopt IP_MULTICAST_IF to fd 9

on the other.

So it seems I may be having the same issue. One end is quagga-current
from January, and the other from April.


Is the multicast ioctl done with the destination address, or the local
one? I got the impression from somewhere that the destination addr
was used; this might have worked if it was within the 'prefix' of the
link.


Here's a trace from ripd. In /var/log/messages:

May 16 19:04:12 fnord ripd[26827]: old umask 23 127
May 16 19:04:13 fnord ripd[26827]: Can't setsockopt IP_MULTICAST_IF to fd 9
May 16 19:04:14 fnord ripd[26827]: Can't setsockopt IP_MULTICAST_IF to fd 9
May 16 19:04:18 fnord ripd[26827]: Terminating on signal

and from ktrace(1):

26827 ripd CALL socket(0x2,0x2,0)
26827 ripd RET socket 9
26827 ripd CALL setsockopt(0x9,0xffff,0x20,0xbfbfd3b0,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0xffff,0x4,0xbfbfd3a0,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0xffff,0x200,0xbfbfd3b0,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0,0x9,0xbfbfd340,0x4)
26827 ripd RET setsockopt -1 errno 49 Can't assign requested address
26827 ripd CALL gettimeofday(0xbfbfc63c,0)
26827 ripd RET gettimeofday 0
26827 ripd CALL getpid
26827 ripd RET getpid 26827/0x68cb
26827 ripd CALL sendto(0x3,0xbfbfcab8,0x49,0,0,0)
26827 ripd GIO fd 3 wrote 73 bytes
"<28>May 16 19:04:13 ripd[26827]: Can't setsockopt IP_MULTICAST_IF to f\
d 9"
26827 ripd RET sendto 73/0x49
26827 ripd CALL sendto(0x9,0xbfbfd44c,0x18,0,0xbfbfd3f4,0x10)
26827 ripd GIO fd 9 wrote 24 bytes
"\^A\^B\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\^P"
26827 ripd RET sendto 24/0x18
26827 ripd CALL close(0x9)
26827 ripd RET close 0

....

26827 ripd CALL socket(0x2,0x2,0)
26827 ripd RET socket 9
26827 ripd CALL setsockopt(0x9,0xffff,0x20,0xbfbfd360,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0xffff,0x4,0xbfbfd350,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0xffff,0x200,0xbfbfd360,0x4)
26827 ripd RET setsockopt 0
26827 ripd CALL setsockopt(0x9,0,0x9,0xbfbfd2f0,0x4)
26827 ripd RET setsockopt -1 errno 49 Can't assign requested address
26827 ripd CALL gettimeofday(0xbfbfc5ec,0)
26827 ripd RET gettimeofday 0
26827 ripd CALL getpid
26827 ripd RET getpid 26827/0x68cb
26827 ripd CALL sendto(0x3,0xbfbfca68,0x49,0,0,0)
26827 ripd GIO fd 3 wrote 73 bytes
"<28>May 16 19:04:14 ripd[26827]: Can't setsockopt IP_MULTICAST_IF to f\
d 9"
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Sun, May 16, 2004 at 07:08:18PM -0400, Greg Troxel wrote:
> Indeed - I misunderstood. So there are clear semantics, and I merely
> find them odd :-) (IMHO, because Quagga has to reconstruct the
> 'obvious' semantics from the rules about Broadcast/p2p interfaces
> always being MC capable.)

Actually, I agree with you. I think the linux behavior is rather strange.

> May 16 18:56:54 foo ripd[14154]: Can't setsockopt IP_MULTICAST_IF to
> fd 5
> May 16 18:56:54 foo ripd[14154]: Can't bind socket: Invalid argument
> May 16 18:57:30 foo ripd[14154]: Can't bind socket: Invalid argument
> May 16 18:57:30 foo ripd[14154]: Can't setsockopt IP_MULTICAST_IF to
> fd 5
> May 16 18:57:30 foo ripd[14154]: Can't bind socket: Invalid argument

Yes, I'm seeing the same setsockopt error. I used to get the bind
error with 0.96.4, but I believe it has been fixed if you grab a
more current release.

> Is the multicast ioctl done with the destination address, or the local
> one? I got the impression from somewhere that the destination addr
> was used; this might have worked if it was within the 'prefix' of the
> link.

You are correct, the setsockopt call is using the destination address.
That certainly doesn't work on my system either, I was just wondering if it
was working somewhere else. Under linux, I suspect the problem might
be fixed by passing the ifindex argument to setsockopt_multicast_ipv4
(the 5th argument, currently 0 in the call from rip_interface_multicast_set,
could be changed to (connected ? connected->ifp->ifindex : 0)).

But the code in lib/sockopt.c:setsockopt_multicast_ipv4 uses the ifindex
(instead of the address) only on linux. Is it true that linux is the only
platform to support that capability in the setsockopt call? If all platforms
supported using the ifindex, then the solution might be simple.

(By the way, my PtP patch enhances that error message to show the address
and interface name, so debugging is much easier.)

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Thu, 13 May 2004, Andrew J. Schorr wrote:

> * MULTICAST -- is an advisory flag indicating that the interface is
> aware of multicasting i.e. sending packets to some subset of
> neighbouring nodes. Broadcasting is a particular case of
> multicasting, where the multicast group consists of all nodes on the
> link. It is important to emphasize that software must not interpret
> the absence of this flag as the inability to use multicasting on this
> interface. Any POINTOPOINT and BROADCAST link is multicasting by
> definition, because we have direct access to all the neighbours and,
> hence, to any part of them. Certainly, the use of high bandwidth
> multicast transfers is not recommended on broadcast-only links because
> of high expense, but it is not strictly prohibited.
>
> So what's the correct approach? I notice that ripd and ripngd are
> the only two protocol daemons to test for the multicast flag...

One option is to sanitise the interface flags in zebra when we get
new interface events from kernel, so we could have:

#ifdef LINUX
if ( CHECK_FLAG (ifp->flags, IFF_BROADCAST)
|| CHECK_FLAG (ifp->flags, IFF_POINTTOPOINT))
set_flag (ifp->flags, IFF_MULTICAST);
#endif LINUX

Indeed, we'd only need to modify netlink_interface and
netlink_link_change AFAICT.

> -Andy

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
Another megabytes the dust.
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Mon, May 17, 2004 at 01:57:00PM +0100, Paul Jakma wrote:
>
> One option is to sanitise the interface flags in zebra when we get
> new interface events from kernel, so we could have:
>
> #ifdef LINUX
> if ( CHECK_FLAG (ifp->flags, IFF_BROADCAST)
> || CHECK_FLAG (ifp->flags, IFF_POINTTOPOINT))
> set_flag (ifp->flags, IFF_MULTICAST);
> #endif LINUX
>
> Indeed, we'd only need to modify netlink_interface and
> netlink_link_change AFAICT.

That seems like a good approach, unless one wants the "show interface"
display insize zebra to match what the O/S tools (ip & ifconfig) show.

By the way, what's the proper CPP test: #ifdef LINUX or #ifdef GNU_LINUX?
Both seem to appear in the quagga source, does it matter which is used?

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Mon, 17 May 2004, Andrew J. Schorr wrote:

> That seems like a good approach, unless one wants the "show
> interface" display insize zebra to match what the O/S tools (ip &
> ifconfig) show.

Well, they would match, just we will explicitely print out an
implicit flag on linux.

I'd rather have the interfaces be consistently abstracted on the
various platforms than have to have various checks for different
platforms done by each daemon - even if by way of lib/. Eg, lib/if.c
should, as much as is sanely possibly, deal with a consistent,
cross-platform abstraction provided by zebra.

> By the way, what's the proper CPP test: #ifdef LINUX or #ifdef
> GNU_LINUX? Both seem to appear in the quagga source, does it matter
> which is used?

I dont see where LINUX is defined. GNU_LINUX is defined by the
configure script.

> -Andy

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
Conscience doth make cowards of us all.
-- Shakespeare
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Mon, May 17, 2004 at 02:52:13PM +0100, Paul Jakma wrote:
> I'd rather have the interfaces be consistently abstracted on the
> various platforms than have to have various checks for different
> platforms done by each daemon - even if by way of lib/. Eg, lib/if.c
> should, as much as is sanely possibly, deal with a consistent,
> cross-platform abstraction provided by zebra.

That makes sense to me.

Frankly, I'm not sure why most of the if_is_*() functions even exist;
shouldn't they just be macros (except for if_is_operative which
is nontrivial)?

> I dont see where LINUX is defined. GNU_LINUX is defined by the
> configure script.

I don't know where or whether it is defined, but it is referenced in
several places:

./zebra/connected.c:#if ! defined (MUSICA) && ! defined (LINUX)
./zebra/zebra_rib.c:#if defined (MUSICA) || defined (LINUX)
./ripngd/ripngd.c:#if defined (MUSICA) || defined (LINUX)
./ripngd/ripngd.c:#if defined (MUSICA) || defined (LINUX)
./ospf6d/ospf6_asbr.c:#if defined (MUSICA) || defined (LINUX)
./ospf6d/ospf6_asbr.c:#if defined (MUSICA) || defined (LINUX)

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Mon, 17 May 2004, Andrew J. Schorr wrote:

> That makes sense to me.
>
> Frankly, I'm not sure why most of the if_is_*() functions even
> exist; shouldn't they just be macros (except for if_is_operative
> which is nontrivial)?

Hmm.. possibly. I doubt it makes much difference these days.

> ./zebra/connected.c:#if ! defined (MUSICA) && ! defined (LINUX)
> ./zebra/zebra_rib.c:#if defined (MUSICA) || defined (LINUX)
> ./ripngd/ripngd.c:#if defined (MUSICA) || defined (LINUX)
> ./ripngd/ripngd.c:#if defined (MUSICA) || defined (LINUX)
> ./ospf6d/ospf6_asbr.c:#if defined (MUSICA) || defined (LINUX)
> ./ospf6d/ospf6_asbr.c:#if defined (MUSICA) || defined (LINUX)

I'm not sure where it is defined. Maybe in glibc.

> -Andy

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
warning: do not ever send email to spam@dishone.st
Fortune:
There are no accidents whatsoever in the universe.
-- Baba Ram Dass
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Mon, May 17, 2004 at 07:46:52PM -0400, Greg Troxel wrote:
> No, that makes sense. Therefore this is hard, and ifindex is the
> right way to go. We need an autoconf test for whether you can do
> that, perhaps hardwired by os version in configure, and then perhaps
> this can only work on such systems.
>
> The BSD stack doesn't want you to reuse IP addresses in the original
> plan, but perhaps it has been frobbed enough that it is ok now
> (ifindex primacy). Linux seems to be in the same place.

Yup, I think ifindex is the way to go. The attached patch should fix
the problem in ripd, but the hard part is to do the autoconf stuff
to get lib/sockopt.c:setsockopt_multicast_ipv4() to use the ifindex
on platforms that support it. The current code uses the ifindex for
linux only -- are there any other platforms that support it?

On linux, there's a struct ip_mreqn that looks like this:

struct ip_mreqn
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_address; /* local IP address of interface */
int imr_ifindex; /* Interface index */
};

The struct ip_mreq seems to be the same, but without the final imr_ifindex
field. Does *BSD have a struct ip_mreqn with the imr_ifindex field?

This is not available for IPV4 on Solaris 8 (but the IPV6 structures
do have an ipv6mr_interface field). The Solaris 10 multicast info
at docs.sun.com seems to indicate that it is still not supported.

http://docs.sun.com/db/doc/817-4415/6mjum5sgi?a=view

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
I can't believe what I read in the code!

In NetBSD 1.6.2ish sys/netinet/ip_output.c, the following is called to
find the interface to process a setsockopt of IP_MULTICAST_IF.
So passing in the ifindex in network order as the address would seem
to work.

Clearly this needs some autoconf stuff to select this behavior. I
should read RFC1724, but haven't yet.

/*
* following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
*/
static struct ifnet *
ip_multicast_if(a, ifindexp)
struct in_addr *a;
int *ifindexp;
{
int ifindex;
struct ifnet *ifp;

if (ifindexp)
*ifindexp = 0;
if (ntohl(a->s_addr) >> 24 == 0) {
ifindex = ntohl(a->s_addr) & 0xffffff;
if (ifindex < 0 || if_index < ifindex)
return NULL;
ifp = ifindex2ifnet[ifindex];
if (ifindexp)
*ifindexp = ifindex;
} else {
INADDR_TO_IFP(*a, ifp);
}
return ifp;
}


in setmoptions:

case IP_MULTICAST_IF:
/*
* Select the interface for outgoing multicast packets.
*/
if (m == NULL || m->m_len != sizeof(struct in_addr)) {
error = EINVAL;
break;
}
addr = *(mtod(m, struct in_addr *));
/*
* INADDR_ANY is used to remove a previous selection.
* When no interface is selected, a default one is
* chosen every time a multicast packet is sent.
*/
if (in_nullhost(addr)) {
imo->imo_multicast_ifp = NULL;
break;
}
/*
* The selected interface is identified by its local
* IP address. Find the interface and confirm that
* it supports multicasting.
*/
ifp = ip_multicast_if(&addr, &ifindex);
if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
error = EADDRNOTAVAIL;
break;
}
imo->imo_multicast_ifp = ifp;
if (ifindex)
imo->imo_multicast_addr = addr;
else
imo->imo_multicast_addr.s_addr = INADDR_ANY;
break;


so this is the EADDRNOTAVAIL that we are seeing, I think.
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Tue, May 18, 2004 at 07:25:07PM -0400, Greg Troxel wrote:
> I can't believe what I read in the code!
>
> In NetBSD 1.6.2ish sys/netinet/ip_output.c, the following is called to
> find the interface to process a setsockopt of IP_MULTICAST_IF.
> So passing in the ifindex in network order as the address would seem
> to work.
>
> Clearly this needs some autoconf stuff to select this behavior. I
> should read RFC1724, but haven't yet.
>
> /*
> * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
> */

That's pretty cool. The RFC says pretty much the same thing as the code:

Unnumbered interfaces are supported in this version. Since the IP Address
that the neighbor uses may be unknown to the system, a pseudo-address is
used to identify these interfaces. The pseudo- address is in the class A
network 0.0.0.0, and the host number (the least significant 24 bits of the
address) are the ifIndex value of the relevant IP Interface.

Strangely, though, the RFC is entitled "RIP Version 2 MIB Extension",
so it is in that context that this is being discussed.

In fact, the OSPFv2 RFC has very similar language for how to describe
point-to-point interfaces in section 12.4.1.1:

For numbered point-to-point networks, the Link Data should specify the IP
interface address. For unnumbered point-to-point networks, the Link Data
field should specify the interface's MIB-II [Ref8] ifIndex value.

So I guess this has become a standard approach for dealing with situations
where there's no IP address to identify the interface.

-Andy
Re: ripd tests for multicast flag -- is that correct? [ In reply to ]
On Tue, 18 May 2004, Greg Troxel wrote:

> I can't believe what I read in the code!
>
> In NetBSD 1.6.2ish sys/netinet/ip_output.c, the following is called to
> find the interface to process a setsockopt of IP_MULTICAST_IF.
> So passing in the ifindex in network order as the address would seem
> to work.

Hmm.. I just hit this problem (I have the same address attached to
multiple interfaces) and came across this thread. I'm going to fix
ripd.c and rip_interface.c to pass the ifindex, which should cure my
problem..

how can we test for this behaviour though? You'd need a wee test case
to have autoconf compile and run to see whether setsockopt of above
worked.

possibly just a static OS version test would be better.

> Clearly this needs some autoconf stuff to select this behavior. I
> should read RFC1724, but haven't yet.

regards,
--
Paul Jakma paul@clubi.ie paul@jakma.org Key ID: 64A2FF6A
Fortune:
Such a fine first dream!
But they laughed at me; they said
I had made it up.