net/netlink: Add RTM preifx notify support
Signed-off-by: meijian <meijian@xiaomi.com>
This commit is contained in:
parent
8eaefd2424
commit
4702a09538
5 changed files with 160 additions and 0 deletions
|
@ -704,6 +704,36 @@ struct rtmsg
|
|||
uint32_t rtm_flags;
|
||||
};
|
||||
|
||||
/* Structures used in prefix information. */
|
||||
|
||||
struct prefixmsg
|
||||
{
|
||||
uint8_t prefix_family;
|
||||
uint8_t prefix_pad1;
|
||||
uint16_t prefix_pad2;
|
||||
int32_t prefix_ifindex;
|
||||
uint8_t prefix_type;
|
||||
uint8_t prefix_len;
|
||||
uint8_t prefix_flags;
|
||||
uint8_t prefix_pad3;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PREFIX_UNSPEC,
|
||||
PREFIX_ADDRESS,
|
||||
PREFIX_CACHEINFO,
|
||||
__PREFIX_MAX
|
||||
};
|
||||
|
||||
#define PREFIX_MAX (__PREFIX_MAX - 1)
|
||||
|
||||
struct prefix_cacheinfo
|
||||
{
|
||||
uint32_t preferred_time;
|
||||
uint32_t valid_time;
|
||||
};
|
||||
|
||||
/* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* | Header | Pad | Payload | Pad |
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <nuttx/net/dns.h>
|
||||
|
||||
#include "devif/devif.h"
|
||||
#include "netlink/netlink.h"
|
||||
#include "neighbor/neighbor.h"
|
||||
#include "utils/utils.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
@ -450,6 +451,8 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
|
|||
{
|
||||
icmpv6_setaddresses(dev, ipv6->srcipaddr,
|
||||
prefixopt->prefix, prefixopt->preflen);
|
||||
netlink_ipv6_prefix_notify(dev, RTM_NEWPREFIX,
|
||||
prefixopt);
|
||||
}
|
||||
|
||||
/* Notify any waiting threads */
|
||||
|
|
|
@ -116,6 +116,12 @@ config NETLINK_VALIDATE_POLICY
|
|||
VALIDATE_POLICY is used to make sure the parameters
|
||||
you pass in are valid.
|
||||
|
||||
config NETLINK_DISABLE_NEWPREFIX
|
||||
bool "Disable RTM_NEWPREFIX support"
|
||||
default n
|
||||
---help---
|
||||
RTM_NEWPREFIX is used to set netdev prefix.
|
||||
|
||||
endif # NETLINK_ROUTE
|
||||
|
||||
config NETLINK_NETFILTER
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <netpacket/netlink.h>
|
||||
#include <nuttx/queue.h>
|
||||
#include <nuttx/net/icmpv6.h>
|
||||
#include <nuttx/net/netlink.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
@ -48,6 +49,7 @@
|
|||
# define netlink_device_notify_ipaddr(dev, type, domain, addr, preflen)
|
||||
# define netlink_route_notify(route, type, domain)
|
||||
# define netlink_neigh_notify(neigh, type, domain)
|
||||
# define netlink_ipv6_prefix_notify(dev, type, pinfo)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NETLINK
|
||||
|
@ -552,6 +554,21 @@ void netlink_route_notify(FAR const void *route, int type, int domain);
|
|||
void netlink_neigh_notify(FAR const void *neigh, int type, int domain);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlink_ipv6_prefix_notify()
|
||||
*
|
||||
* Description:
|
||||
* Perform the RA prefix for the NETLINK_ROUTE protocol.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NETLINK_DISABLE_NEWPREFIX) || !defined(CONFIG_NET_IPV6)
|
||||
# define netlink_ipv6_prefix_notify(dev, type, pinfo)
|
||||
#else
|
||||
void netlink_ipv6_prefix_notify(FAR struct net_driver_s *dev, int type,
|
||||
FAR const struct icmpv6_prefixinfo_s *pinfo);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nla_next
|
||||
*
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <net/route.h>
|
||||
#include <netpacket/netlink.h>
|
||||
|
@ -179,6 +180,32 @@ struct getaddr_recvfrom_rsplist_s
|
|||
struct getaddr_recvfrom_response_s payload;
|
||||
};
|
||||
|
||||
struct getprefix_recvfrom_addr_s
|
||||
{
|
||||
struct rtattr attr;
|
||||
net_ipv6addr_t addr;
|
||||
};
|
||||
|
||||
struct getprefix_recvfrom_cache_s
|
||||
{
|
||||
struct rtattr attr;
|
||||
struct prefix_cacheinfo pci;
|
||||
};
|
||||
|
||||
struct getprefix_recvfrom_response_s
|
||||
{
|
||||
struct nlmsghdr hdr;
|
||||
struct prefixmsg pmsg;
|
||||
struct getprefix_recvfrom_addr_s prefix;
|
||||
struct getprefix_recvfrom_cache_s pci;
|
||||
};
|
||||
|
||||
struct getprefix_recvfrom_rsplist_s
|
||||
{
|
||||
sq_entry_t flink;
|
||||
struct getprefix_recvfrom_response_s payload;
|
||||
};
|
||||
|
||||
/* netdev_foreach() callback */
|
||||
|
||||
struct nlroute_sendto_request_s
|
||||
|
@ -1249,6 +1276,58 @@ static int netlink_get_addr(NETLINK_HANDLE handle,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_NETLINK_DISABLE_NEWADDR) && defined(CONFIG_NET_IPV6)
|
||||
static FAR struct netlink_response_s *
|
||||
netlink_fill_ipv6prefix(FAR struct net_driver_s *dev, int type,
|
||||
FAR const struct icmpv6_prefixinfo_s *pinfo)
|
||||
{
|
||||
FAR struct getprefix_recvfrom_rsplist_s *alloc;
|
||||
FAR struct getprefix_recvfrom_response_s *resp;
|
||||
|
||||
DEBUGASSERT(dev != NULL && pinfo != NULL);
|
||||
|
||||
alloc = kmm_zalloc(sizeof(struct getprefix_recvfrom_rsplist_s));
|
||||
if (alloc == NULL)
|
||||
{
|
||||
nerr("ERROR: Failed to allocate response buffer.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the response buffer */
|
||||
|
||||
resp = &alloc->payload;
|
||||
|
||||
resp->hdr.nlmsg_len = sizeof(struct getprefix_recvfrom_response_s);
|
||||
resp->hdr.nlmsg_type = type;
|
||||
resp->hdr.nlmsg_flags = 0;
|
||||
resp->hdr.nlmsg_seq = 0;
|
||||
resp->hdr.nlmsg_pid = 0;
|
||||
|
||||
resp->pmsg.prefix_family = AF_INET6;
|
||||
#ifdef CONFIG_NETDEV_IFINDEX
|
||||
resp->pmsg.prefix_ifindex = dev->d_ifindex;
|
||||
#endif
|
||||
resp->pmsg.prefix_len = pinfo->optlen;
|
||||
resp->pmsg.prefix_type = pinfo->opttype;
|
||||
|
||||
resp->prefix.attr.rta_len = RTA_LENGTH(sizeof(net_ipv6addr_t));
|
||||
resp->prefix.attr.rta_type = PREFIX_ADDRESS;
|
||||
net_ipv6addr_copy(resp->prefix.addr, pinfo->prefix);
|
||||
|
||||
resp->pci.attr.rta_len = RTA_LENGTH(sizeof(struct prefix_cacheinfo));
|
||||
resp->pci.attr.rta_type = PREFIX_CACHEINFO;
|
||||
|
||||
resp->pci.pci.preferred_time = NTOHS(pinfo->plifetime[0]) << 16;
|
||||
resp->pci.pci.preferred_time |= NTOHS(pinfo->plifetime[1]);
|
||||
resp->pci.pci.valid_time = NTOHS(pinfo->vlifetime[0]) << 16;
|
||||
resp->pci.pci.valid_time |= NTOHS(pinfo->vlifetime[1]);
|
||||
|
||||
/* Finally, return the response */
|
||||
|
||||
return (FAR struct netlink_response_s *)alloc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -1582,4 +1661,29 @@ void netlink_neigh_notify(FAR const void *neigh, int type, int domain)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netlink_ipv6_prefix_notify()
|
||||
*
|
||||
* Description:
|
||||
* Perform the RA prefix for the NETLINK_ROUTE protocol.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_NETLINK_DISABLE_NEWADDR) && defined(CONFIG_NET_IPV6)
|
||||
void netlink_ipv6_prefix_notify(FAR struct net_driver_s *dev, int type,
|
||||
FAR const struct icmpv6_prefixinfo_s *pinfo)
|
||||
{
|
||||
FAR struct netlink_response_s *resp;
|
||||
|
||||
resp = netlink_fill_ipv6prefix(dev, type, pinfo);
|
||||
if (resp == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
netlink_add_broadcast(RTNLGRP_IPV6_PREFIX, resp);
|
||||
netlink_add_terminator(NULL, NULL, RTNLGRP_IPV6_PREFIX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NETLINK_ROUTE */
|
||||
|
|
Loading…
Reference in a new issue