Multicast problems

Ian FREISLICH ianf at clue.co.za
Mon Jun 18 11:44:10 UTC 2007


"Bruce M. Simpson" wrote:
> Ian FREISLICH wrote:
> > Hi
> >
> > I have a problem with quagga running on a CURRENT (15 June).  It
> > appears that it's registering the multicast address on the wrong
> > interface.  In fact, no matter which network I tell quagga to use
> > as the OSPF network, it always registers the multicast addresses
> > on the same incorrect vlan.  It works with a May 24 kernel. 
> >   
> 
> What is the format of the IP_ADD_MEMBERSHIP call used by the version of 
> Quagga you are running to join the OSPF group?

/* Join to the OSPF ALL SPF ROUTERS multicast group. */
int
ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
                           unsigned int ifindex)
{
  int ret;
  
  ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
                                   p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
                                   ifindex);

So it looks like it's getting the ifindex from somewhere.  This
calls a routine which if I have parsed the configure results correctly
executes the following code:

#else /* #if OS_TYPE */ 
  /* standard BSD API */

  struct in_addr m;
  struct ip_mreq mreq;
  int ret;

#ifdef HAVE_BSD_STRUCT_IP_MREQ_HACK
  if (ifindex)
    m.s_addr = htonl(ifindex);
  else
#endif
    m = if_addr;

  switch (optname)
    {
    case IP_MULTICAST_IF:
      return setsockopt (sock, IPPROTO_IP, optname, (void *)&m, sizeof(m)); 
      break;

    case IP_ADD_MEMBERSHIP:
    case IP_DROP_MEMBERSHIP:
      memset (&mreq, 0, sizeof(mreq));
      mreq.imr_multiaddr.s_addr = mcast_addr;
      mreq.imr_interface = m;
      
      ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq));
      if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
        {
          /* see above: handle possible problem when interface comes back up */
          char buf[2][INET_ADDRSTRLEN];
          zlog_info("setsockopt_multicast_ipv4 attempting to drop and "
                    "re-add (fd %d, ifaddr %s, mcast %s, ifindex %u)",
                    sock,
                    inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])),
                    inet_ntop(AF_INET, &mreq.imr_multiaddr,
                              buf[1], sizeof(buf[1])), ifindex);
          setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
                      (void *)&mreq, sizeof(mreq));
          ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                            (void *)&mreq, sizeof(mreq));
        }
      return ret;
      break;


> Does it use 'struct ip_mreqn' ?
> Does it use IP_ADD_SOURCE_MEMBERSHIP or IP_BLOCK_SOURCE ioctls?

It looks like it just uses IP_ADD_MEMBERSHIP.  HAVE_BSD_STRUCT_IP_MREQ_HACK
is defined.  I really don't know anything about how it should be
doing this to say whether the above code is correct.

If you can point me to a manual page that describes mcast membership
options to setsockopt() I can try to fix or debug this further.  It
looks like the ip(4) manual is out of date or incomplete in this
regard.  I'll do some more digging in the mean time anyway.

Ian

--
Ian Freislich



More information about the freebsd-current mailing list