summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2017-05-12 15:48:35 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2017-05-15 13:49:50 +0200
commit6142bb37a594183bfc8989d598bc1913a30f7c03 (patch)
treef6b22aa4ad3c600bc4b62cad3a953b01a426678b
parentsd-radv: Implement Router Advertisement timeout handling (diff)
downloadsystemd-6142bb37a594183bfc8989d598bc1913a30f7c03.tar.xz
systemd-6142bb37a594183bfc8989d598bc1913a30f7c03.zip
icmp6-util: Bind Router Advertisement socket
Reuse and refactor the functionality already present for Router Solicitations in order to create a socket for sending Router Advertisements. Anticipate reception of incoming Router Solicitations by setting the ICMPv6 filter accordingly. Also set the unicast hop limit to 255 for ICMPv6 sockets as unicast Router Advertisments are to be sent in response to Router Solicitations. Update the Router Solicitation test case code with a function definition in order to keep the test case working.
-rw-r--r--src/libsystemd-network/icmp6-util.c45
-rw-r--r--src/libsystemd-network/icmp6-util.h1
-rw-r--r--src/libsystemd-network/test-ndisc-rs.c5
3 files changed, 41 insertions, 10 deletions
diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
index c2e4b0e9e3..f1cb0bc8a0 100644
--- a/src/libsystemd-network/icmp6-util.c
+++ b/src/libsystemd-network/icmp6-util.c
@@ -41,12 +41,9 @@
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
-int icmp6_bind_router_solicitation(int index) {
- struct icmp6_filter filter = { };
- struct ipv6_mreq mreq = {
- .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
- .ipv6mr_interface = index,
- };
+static int icmp6_bind_router_message(const struct icmp6_filter *filter,
+ const struct ipv6_mreq *mreq) {
+ int index = mreq->ipv6mr_interface;
_cleanup_close_ int s = -1;
char ifname[IF_NAMESIZE] = "";
static const int zero = 0, one = 1, hops = 255;
@@ -56,9 +53,11 @@ int icmp6_bind_router_solicitation(int index) {
if (s < 0)
return -errno;
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
- r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));
+ r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter));
+ if (r < 0)
+ return -errno;
+
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq));
if (r < 0)
return -errno;
@@ -78,7 +77,7 @@ int icmp6_bind_router_solicitation(int index) {
if (r < 0)
return -errno;
- r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops));
if (r < 0)
return -errno;
@@ -102,6 +101,32 @@ int icmp6_bind_router_solicitation(int index) {
return r;
}
+int icmp6_bind_router_solicitation(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
+int icmp6_bind_router_advertisement(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
struct sockaddr_in6 dst = {
.sin6_family = AF_INET6,
diff --git a/src/libsystemd-network/icmp6-util.h b/src/libsystemd-network/icmp6-util.h
index 2b4dbc76ce..5cf63cb2c5 100644
--- a/src/libsystemd-network/icmp6-util.h
+++ b/src/libsystemd-network/icmp6-util.h
@@ -22,4 +22,5 @@
#include <net/ethernet.h>
int icmp6_bind_router_solicitation(int index);
+int icmp6_bind_router_advertisement(int index);
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c
index d9669488be..e212b8a967 100644
--- a/src/libsystemd-network/test-ndisc-rs.c
+++ b/src/libsystemd-network/test-ndisc-rs.c
@@ -193,6 +193,11 @@ int icmp6_bind_router_solicitation(int index) {
return test_fd[0];
}
+int icmp6_bind_router_advertisement(int index) {
+
+ return -ENOSYS;
+}
+
static int send_ra(uint8_t flags) {
uint8_t advertisement[] = {
0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,