diff options
| author | Dmitrij Tejblum <tejblum@yandex-team.ru> | 2011-08-18 20:22:17 +0400 | 
|---|---|---|
| committer | Denis Ovsienko <infrastation@yandex.ru> | 2011-09-27 21:37:35 +0400 | 
| commit | 69bf3a39931ce61a92fb04d8888b4655fd5620a2 (patch) | |
| tree | e49dae20b1dbc0d1ee37121cd45c75d94290bdd1 /lib | |
| parent | ea4021984f9eec3f2a85551ae0822e1dff0ed2bc (diff) | |
lib: simplify interface of setsockopt_multicast_ipv4().
* sockopt.[ch] (setsockopt_ipv4_multicast): ifindex is now mandatory (all
  non-ancient OSes can use it anyway), and if_addr parameter (the address
  of the interface) is now gone. (setsockopt_ipv4_multicast_if):
  IP_MULTICAST_IF processing moved to this new function
* ospf_network.c (ospf_if_add_allspfrouters, ospf_if_drop_allspfrouters,
  ospf_if_add_alldrouters, ospf_if_drop_alldrouters, ospf_if_ipmulticast),
  rip_interface.c (ipv4_multicast_join, ipv4_multicast_leave,
  rip_interface_new): adapt to the new interface
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sockopt.c | 77 | ||||
| -rw-r--r-- | lib/sockopt.h | 10 | 
2 files changed, 49 insertions, 38 deletions
| diff --git a/lib/sockopt.c b/lib/sockopt.c index 6ab97689..1f9f5275 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -184,7 +184,7 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh)  /*   * Process multicast socket options for IPv4 in an OS-dependent manner. - * Supported options are IP_MULTICAST_IF and IP_{ADD,DROP}_MEMBERSHIP. + * Supported options are IP_{ADD,DROP}_MEMBERSHIP.   *   * Many operating systems have a limit on the number of groups that   * can be joined per socket (where each group and local address @@ -204,22 +204,18 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh)   * allow leaves, or implicitly leave all groups joined to down interfaces.   */  int -setsockopt_multicast_ipv4(int sock,  +setsockopt_ipv4_multicast(int sock,  			int optname,  -			struct in_addr if_addr /* required */,  			unsigned int mcast_addr, -			unsigned int ifindex /* optional: if non-zero, may be -						  used instead of if_addr */) +			unsigned int ifindex)  {  #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX -  /* This is better because it uses ifindex directly */    struct ip_mreqn mreqn;    int ret;    switch (optname)      { -    case IP_MULTICAST_IF:      case IP_ADD_MEMBERSHIP:      case IP_DROP_MEMBERSHIP:        memset (&mreqn, 0, sizeof(mreqn)); @@ -227,23 +223,19 @@ setsockopt_multicast_ipv4(int sock,        if (mcast_addr)  	mreqn.imr_multiaddr.s_addr = mcast_addr; -      if (ifindex) -	mreqn.imr_ifindex = ifindex; -      else -	mreqn.imr_address = if_addr; +      mreqn.imr_ifindex = ifindex;        ret = setsockopt(sock, IPPROTO_IP, optname,  		       (void *)&mreqn, sizeof(mreqn));        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)", +	  char buf[1][INET_ADDRSTRLEN]; +	  zlog_info("setsockopt_ipv4_multicast attempting to drop and " +		    "re-add (fd %d, mcast %s, ifindex %u)",  		    sock, -		    inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])),  		    inet_ntop(AF_INET, &mreqn.imr_multiaddr, -			      buf[1], sizeof(buf[1])), ifindex); +			      buf[0], sizeof(buf[0])), ifindex);  	  setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,  		     (void *)&mreqn, sizeof(mreqn));  	  ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -264,26 +256,17 @@ setsockopt_multicast_ipv4(int sock,    /* #elif  defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */    /* Add your favourite OS here! */ -#else /* #if OS_TYPE */  +#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) /* #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; +  m.s_addr = htonl(ifindex);    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)); @@ -294,13 +277,12 @@ setsockopt_multicast_ipv4(int sock,        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)", +	  char buf[1][INET_ADDRSTRLEN]; +	  zlog_info("setsockopt_ipv4_multicast attempting to drop and " +		    "re-add (fd %d, 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); +			      buf[0], sizeof(buf[0])), ifindex);  	  setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,  		      (void *)&mreq, sizeof(mreq));  	  ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @@ -315,10 +297,41 @@ setsockopt_multicast_ipv4(int sock,        return -1;        break;      } +#else +  #error "Unsupported multicast API"  #endif /* #if OS_TYPE */  } +/* + * Set IP_MULTICAST_IF socket option in an OS-dependent manner. + */ +int +setsockopt_ipv4_multicast_if(int sock, +			unsigned int ifindex) +{ + +#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX +  struct ip_mreqn mreqn; + +  mreqn.imr_ifindex = ifindex; +  return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn)); + +  /* Example defines for another OS, boilerplate off other code in this +     function */ +  /* #elif  defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */ +  /* Add your favourite OS here! */ +#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) +  struct in_addr m; + +  m.s_addr = htonl(ifindex); + +  return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m)); +#else +  #error "Unsupported multicast API" +#endif +} +    static int  setsockopt_ipv4_ifindex (int sock, int val)  { diff --git a/lib/sockopt.h b/lib/sockopt.h index cb05c6fb..69309e00 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -82,13 +82,11 @@ extern int setsockopt_ipv6_multicast_loop (int, int);    (((af) == AF_INET) : SOPT_SIZE_CMSG_IFINDEX_IPV4() \                      ? SOPT_SIZE_CMSG_PKTINFO_IPV6()) -extern int setsockopt_multicast_ipv4(int sock, int optname,  -			             struct in_addr if_addr -					 /* required: interface to join on */, +extern int setsockopt_ipv4_multicast_if(int sock, +			             unsigned int ifindex); +extern int setsockopt_ipv4_multicast(int sock, int optname,                                       unsigned int mcast_addr, -			             unsigned int ifindex -					 /* optional: if non-zero, may be used -					 	instead of if_addr */); +			             unsigned int ifindex);  extern int setsockopt_ipv4_tos(int sock, int tos);  /* Ask for, and get, ifindex, by whatever method is supported. */ | 
