icmpv6: add RDNSS field support for send route advertise
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
parent
d9e009cb46
commit
ec2b74df77
@ -202,6 +202,13 @@ config NET_ICMPv6_PREFIX_8
|
||||
Advertisement message. This is the last of the 8-values. The
|
||||
default for all eight values is fc00::0.
|
||||
|
||||
config NET_ICMPv6_ROUTER_RDNSS
|
||||
bool "Fill the RDNSS into Router Advertisement"
|
||||
default n
|
||||
---help---
|
||||
Fill the RDNSS from the netdb DNS Server into the Router
|
||||
Advertisement.
|
||||
|
||||
endif # NET_ICMPv6_ROUTER_MANUAL
|
||||
endif # NET_ICMPv6_ROUTER
|
||||
|
||||
|
@ -28,11 +28,13 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/net/netstats.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/icmpv6.h>
|
||||
#include <nuttx/net/dns.h>
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
#include "inet/inet.h"
|
||||
@ -41,6 +43,16 @@
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_ROUTER
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct rdnss_add_dns_nameserver_s
|
||||
{
|
||||
FAR struct icmpv6_rdnss_s *rdnss;
|
||||
int nservers;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -92,6 +104,44 @@ static inline void ipv6addr_mask(FAR uint16_t *dest, FAR const uint16_t *src,
|
||||
}
|
||||
#endif /* !CONFIG_NET_ICMPv6_ROUTER_MANUAL */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: icmpv6_radvertise_fill_rndss
|
||||
*
|
||||
* Description:
|
||||
* Copy an IPv6 DNS address into RDNSS field
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - RDNSS context infomation
|
||||
* addr - DNS server address
|
||||
* addrlen - length of DNS server address
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 is success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_ROUTER_RDNSS
|
||||
static int icmpv6_radvertise_fill_rndss(FAR void *arg,
|
||||
FAR struct sockaddr *addr,
|
||||
FAR socklen_t addrlen)
|
||||
{
|
||||
FAR struct rdnss_add_dns_nameserver_s *rdnss_context = arg;
|
||||
FAR struct sockaddr_in6 *addr6;
|
||||
|
||||
if (addr->sa_family == AF_INET6)
|
||||
{
|
||||
FAR uint8_t *server = rdnss_context->rdnss->servers;
|
||||
|
||||
addr6 = (FAR struct sockaddr_in6 *)addr;
|
||||
net_ipv6addr_copy(server + 16 * rdnss_context->nservers,
|
||||
&addr6->sin6_addr);
|
||||
rdnss_context->nservers++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NET_ICMPv6_ROUTER_RDNSS */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -120,6 +170,10 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||
FAR struct icmpv6_srclladdr_s *srcaddr;
|
||||
FAR struct icmpv6_mtu_s *mtu;
|
||||
FAR struct icmpv6_prefixinfo_s *prefix;
|
||||
#ifdef CONFIG_NET_ICMPv6_ROUTER_RDNSS
|
||||
FAR struct icmpv6_rdnss_s *rdnss;
|
||||
struct rdnss_add_dns_nameserver_s rndss_context;
|
||||
#endif
|
||||
net_ipv6addr_t srcv6addr;
|
||||
uint16_t lladdrsize;
|
||||
uint16_t l3size;
|
||||
@ -136,9 +190,6 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||
|
||||
icmpv6_linkipaddr(dev, srcv6addr);
|
||||
|
||||
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
|
||||
srcv6addr, g_ipv6_allnodes, 255, 0);
|
||||
|
||||
/* Set up the ICMPv6 Router Advertise response */
|
||||
|
||||
adv = IPBUF(IPv6_HDRLEN);
|
||||
@ -198,6 +249,37 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||
ipv6addr_mask(prefix->prefix, dev->d_ipv6addr, dev->d_ipv6netmask);
|
||||
#endif /* CONFIG_NET_ICMPv6_ROUTER_MANUAL */
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6_ROUTER_RDNSS
|
||||
rdnss = (FAR struct icmpv6_rdnss_s *)
|
||||
((FAR uint8_t *)prefix +
|
||||
sizeof(struct icmpv6_prefixinfo_s));
|
||||
rndss_context.rdnss = rdnss;
|
||||
rndss_context.nservers = 0;
|
||||
|
||||
dns_foreach_nameserver(icmpv6_radvertise_fill_rndss, &rndss_context);
|
||||
|
||||
if (rndss_context.nservers > 0)
|
||||
{
|
||||
rdnss->opttype = ICMPv6_OPT_RDNSS;
|
||||
rdnss->optlen = 1 + 2 * rndss_context.nservers;
|
||||
rdnss->reserved = 0;
|
||||
|
||||
/* RFC8106: The value of Lifetime SHOULD by default be at least
|
||||
* 3 * MaxRtrAdvInterval and the MaxRtrAdvInterval default value
|
||||
* is 600 seconds.
|
||||
*/
|
||||
|
||||
rdnss->lifetime[0] = 0;
|
||||
rdnss->lifetime[1] = HTONS(1800);
|
||||
|
||||
l3size += 8 * rdnss->optlen;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ipv6_build_header(IPv6BUF, l3size, IP_PROTO_ICMP6,
|
||||
srcv6addr, g_ipv6_allnodes, 255, 0);
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||
|
Loading…
Reference in New Issue
Block a user