From 3a8c3dd7d0331c2da7c14aa33c48d512300d6e09 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 1 Aug 2011 21:59:04 +0400 Subject: lib: remove unused variable * sockopt.c (getsockopt_ifindex): "ifindex" was never used --- lib/sockopt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 55c6226b..6ab97689 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -451,8 +451,6 @@ getsockopt_ipv4_ifindex (struct msghdr *msgh) int getsockopt_ifindex (int af, struct msghdr *msgh) { - int ifindex = 0; - switch (af) { case AF_INET: @@ -465,7 +463,7 @@ getsockopt_ifindex (int af, struct msghdr *msgh) #endif default: zlog_warn ("getsockopt_ifindex: unknown address family %d", af); - return (ifindex = 0); + return 0; } } -- cgit v1.2.1 From 69bf3a39931ce61a92fb04d8888b4655fd5620a2 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Thu, 18 Aug 2011 20:22:17 +0400 Subject: 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 --- lib/sockopt.c | 77 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 32 deletions(-) (limited to 'lib/sockopt.c') 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) { -- cgit v1.2.1 From e0afa6f44a77a89a543a03284c9f63af7b057c08 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 19 Aug 2011 22:25:23 +0400 Subject: lib: fix omission in the previous commit to lib/sockopt.c * sockopt.c (setsockopt_ipv4_multicast_if): fix missed line in the previous commit. --- lib/sockopt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 1f9f5275..6e1feece 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -313,6 +313,7 @@ setsockopt_ipv4_multicast_if(int sock, #ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX struct ip_mreqn mreqn; + memset (&mreqn, 0, sizeof(mreqn)); mreqn.imr_ifindex = ifindex; return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn)); -- cgit v1.2.1 From ee7e75d38bdb139b10f3a1d35209758409db7fb5 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Fri, 19 Aug 2011 23:00:30 +0400 Subject: lib: futher simplification of setsockopt_ipv4_multicast() * sockopt.c (setsockopt_ipv4_multicast): check for wrong optname with assert(), rather than return an error. --- lib/sockopt.c | 108 ++++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 64 deletions(-) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 6e1feece..8a1eec12 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -214,42 +214,31 @@ setsockopt_ipv4_multicast(int sock, struct ip_mreqn mreqn; int ret; - switch (optname) - { - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - memset (&mreqn, 0, sizeof(mreqn)); + assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); + memset (&mreqn, 0, sizeof(mreqn)); - if (mcast_addr) - mreqn.imr_multiaddr.s_addr = mcast_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[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, &mreqn.imr_multiaddr, - 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, - (void *)&mreqn, sizeof(mreqn)); - } - return ret; - break; - - default: - /* Can out and give an understandable error */ - errno = EINVAL; - return -1; - break; + if (mcast_addr) + mreqn.imr_multiaddr.s_addr = mcast_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[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, &mreqn.imr_multiaddr, + 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, + (void *)&mreqn, sizeof(mreqn)); } + return ret; /* Example defines for another OS, boilerplate off other code in this function, AND handle optname as per other sections for consistency !! */ @@ -263,40 +252,31 @@ setsockopt_ipv4_multicast(int sock, struct ip_mreq mreq; int ret; + assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); + m.s_addr = htonl(ifindex); - switch (optname) + 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)) { - 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[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, &mreq.imr_multiaddr, - 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, - (void *)&mreq, sizeof(mreq)); - } - return ret; - break; - - default: - /* Can out and give an understandable error */ - errno = EINVAL; - return -1; - break; + /* see above: handle possible problem when interface comes back up */ + 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, &mreq.imr_multiaddr, + 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, + (void *)&mreq, sizeof(mreq)); } + return ret; + #else #error "Unsupported multicast API" #endif /* #if OS_TYPE */ -- cgit v1.2.1 From 10d04cdb4198b69073ea0cdd4c26a64d6697b33e Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Mon, 22 Aug 2011 11:39:35 +0400 Subject: lib: use "protocol-independed API" from RFC3678, if that is available (This commit is based on the patch from BZ#420, and should fix that bug.) * configure.ac: detect availability of that API * sockopt.c (setsockopt_ipv4_multicast): use it for join/leave IPv4 multicast groups --- lib/sockopt.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 8a1eec12..9ff15ca6 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -209,17 +209,35 @@ setsockopt_ipv4_multicast(int sock, unsigned int mcast_addr, unsigned int ifindex) { +#ifdef HAVE_RFC3678 + struct group_req gr; + struct sockaddr_in *si; + int ret; + memset (&gr, 0, sizeof(gr)); + si = (struct sockaddr_in *)&gr.gr_group; + gr.gr_interface = ifindex; + si->sin_family = AF_INET; +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN + si->sin_len = sizeof(struct sockaddr_in); +#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ + si->sin_addr.s_addr = mcast_addr; + ret = setsockopt(sock, IPPROTO_IP, (optname == IP_ADD_MEMBERSHIP) ? + MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); + if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) + { + setsockopt(sock, IPPROTO_IP, MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr)); + ret = setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void *)&gr, sizeof(gr)); + } + return ret; -#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX +#elif defined(HAVE_STRUCT_IP_MREQN_IMR_IFINDEX) && !defined(__FreeBSD__) struct ip_mreqn mreqn; int ret; assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); memset (&mreqn, 0, sizeof(mreqn)); - if (mcast_addr) - mreqn.imr_multiaddr.s_addr = mcast_addr; - + mreqn.imr_multiaddr.s_addr = mcast_addr; mreqn.imr_ifindex = ifindex; ret = setsockopt(sock, IPPROTO_IP, optname, -- cgit v1.2.1 From 6d0732c8abad7ace509d033a41814ea03a3a1b16 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 28 Sep 2011 14:23:35 +0400 Subject: IPv6 transport class suppport IPv6 supports the same concept of differentiated service for routing protocols as IPv4, but like too many things, the standards committee decided that having two names for the same thing wasn't good enough and introduced a third more generic term transport class. The socket option to set transport class works the same as IPv4, but the arguments are different. * lib/sockopt.[ch] * setsockopt_ipv6_tclass(): new function * bgpd/bgp_network.c * bgp_connect(): set socket option * bgp_listener(): set socket option * ospf6d/ospf6_network.c * ospf6_set_transport_class(): new function * ospf6_serv_sock(): set socket option * ripngd/ripngd.c * ripng_make_socket(): set socket option --- lib/sockopt.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 9ff15ca6..63858408 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -179,8 +179,19 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) return pktinfo->ipi6_ifindex; } -#endif /* HAVE_IPV6 */ +int +setsockopt_ipv6_tclass(int sock, int tclass) +{ + int ret; + + ret = setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof (tclass)); + if (ret < 0) + zlog_warn ("Can't set IPV6_TCLASS option for fd %d to %#x: %s", + sock, tclass, safe_strerror(errno)); + return ret; +} +#endif /* HAVE_IPV6 */ /* * Process multicast socket options for IPv4 in an OS-dependent manner. -- cgit v1.2.1 From ad61af67b548fa787d4c1da0024ba30f8c3b19c8 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 12 Oct 2011 15:07:34 +0400 Subject: lib: compile even without IPV6_TCLASS --- lib/sockopt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/sockopt.c') diff --git a/lib/sockopt.c b/lib/sockopt.c index 63858408..be22827f 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -183,12 +183,14 @@ getsockopt_ipv6_ifindex (struct msghdr *msgh) int setsockopt_ipv6_tclass(int sock, int tclass) { - int ret; + int ret = 0; +#ifdef IPV6_TCLASS /* RFC3542 */ ret = setsockopt (sock, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof (tclass)); if (ret < 0) zlog_warn ("Can't set IPV6_TCLASS option for fd %d to %#x: %s", sock, tclass, safe_strerror(errno)); +#endif return ret; } #endif /* HAVE_IPV6 */ -- cgit v1.2.1