mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 17:48:54 +08:00
icmpv6: add RDNSS field support for send route advertise
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
committed by
Alan Carvalho de Assis
parent
d9e009cb46
commit
ec2b74df77
@@ -202,6 +202,13 @@ config NET_ICMPv6_PREFIX_8
|
|||||||
Advertisement message. This is the last of the 8-values. The
|
Advertisement message. This is the last of the 8-values. The
|
||||||
default for all eight values is fc00::0.
|
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_MANUAL
|
||||||
endif # NET_ICMPv6_ROUTER
|
endif # NET_ICMPv6_ROUTER
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <nuttx/net/netconfig.h>
|
#include <nuttx/net/netconfig.h>
|
||||||
#include <nuttx/net/netstats.h>
|
#include <nuttx/net/netstats.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
#include <nuttx/net/icmpv6.h>
|
#include <nuttx/net/icmpv6.h>
|
||||||
|
#include <nuttx/net/dns.h>
|
||||||
|
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
#include "inet/inet.h"
|
#include "inet/inet.h"
|
||||||
@@ -41,6 +43,16 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6_ROUTER
|
#ifdef CONFIG_NET_ICMPv6_ROUTER
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct rdnss_add_dns_nameserver_s
|
||||||
|
{
|
||||||
|
FAR struct icmpv6_rdnss_s *rdnss;
|
||||||
|
int nservers;
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* 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 */
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -120,6 +170,10 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
FAR struct icmpv6_srclladdr_s *srcaddr;
|
FAR struct icmpv6_srclladdr_s *srcaddr;
|
||||||
FAR struct icmpv6_mtu_s *mtu;
|
FAR struct icmpv6_mtu_s *mtu;
|
||||||
FAR struct icmpv6_prefixinfo_s *prefix;
|
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;
|
net_ipv6addr_t srcv6addr;
|
||||||
uint16_t lladdrsize;
|
uint16_t lladdrsize;
|
||||||
uint16_t l3size;
|
uint16_t l3size;
|
||||||
@@ -136,9 +190,6 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
icmpv6_linkipaddr(dev, srcv6addr);
|
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 */
|
/* Set up the ICMPv6 Router Advertise response */
|
||||||
|
|
||||||
adv = IPBUF(IPv6_HDRLEN);
|
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);
|
ipv6addr_mask(prefix->prefix, dev->d_ipv6addr, dev->d_ipv6netmask);
|
||||||
#endif /* CONFIG_NET_ICMPv6_ROUTER_MANUAL */
|
#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 */
|
/* Update device buffer length */
|
||||||
|
|
||||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||||
|
|||||||
Reference in New Issue
Block a user