diff options
author | Patrik Flykt <patrik.flykt@linux.intel.com> | 2017-05-12 15:48:35 +0200 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2017-05-15 13:49:50 +0200 |
commit | 6142bb37a594183bfc8989d598bc1913a30f7c03 (patch) | |
tree | f6b22aa4ad3c600bc4b62cad3a953b01a426678b | |
parent | sd-radv: Implement Router Advertisement timeout handling (diff) | |
download | systemd-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.c | 45 | ||||
-rw-r--r-- | src/libsystemd-network/icmp6-util.h | 1 | ||||
-rw-r--r-- | src/libsystemd-network/test-ndisc-rs.c | 5 |
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, |