From 056d704cf9adc0f077b8fea6a1175c6fe99e214a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 3 Aug 2018 13:22:36 -0600 Subject: [PATCH] This commit brings in a fragmentary, experimental implementation of NETLINK sockets. There is not too much to that socket support on this initial commit, just the netlink socketer framework. However, I decided to bring it into master because there is a enough that I would not want to lose what is in place. And since it is dependent on CONFIG_EXPERIMENATL, its presence on master should be innocuous. Squashed commit of the following: net/netlink: Mark netlink support as EXPERIMENTAL. net/netlink/netlink_sockif.c: Add netlink_getpeername to the socket interface. net: Add getpeeername() support for netlink sockets. include/netpacket/netlink.h: Add a few more definitions and structures used at the NetLink interface. Still missing many. net/netlink: Add basic framework for Netlink socket support. include/: Add basic Netlink definitions. --- drivers/audio/wm8776.c | 2 +- include/netpacket/netlink.h | 323 +++++++++++++++++++ include/sys/socket.h | 4 +- net/Kconfig | 2 +- net/Makefile | 1 + net/README.txt | 1 + net/net_initialize.c | 7 + net/netlink/Kconfig | 26 ++ net/netlink/Make.defs | 46 +++ net/netlink/netlink.h | 156 ++++++++++ net/netlink/netlink_conn.c | 246 +++++++++++++++ net/netlink/netlink_sockif.c | 585 +++++++++++++++++++++++++++++++++++ net/socket/net_sockif.c | 7 + 13 files changed, 1403 insertions(+), 3 deletions(-) create mode 100644 include/netpacket/netlink.h create mode 100644 net/netlink/Kconfig create mode 100644 net/netlink/Make.defs create mode 100644 net/netlink/netlink.h create mode 100644 net/netlink/netlink_conn.c create mode 100644 net/netlink/netlink_sockif.c diff --git a/drivers/audio/wm8776.c b/drivers/audio/wm8776.c index 518a7945a2..d6531e0c1f 100644 --- a/drivers/audio/wm8776.c +++ b/drivers/audio/wm8776.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/audio/wm8776.c * - * Copyright 2017,2018 Sony Video & Sound Products Inc. + * Copyright 2017, 2018 Sony Video & Sound Products Inc. * Author: Masayuki Ishikawa * * Based on drivers/audio/wm8904.c diff --git a/include/netpacket/netlink.h b/include/netpacket/netlink.h new file mode 100644 index 0000000000..8e52eeaa04 --- /dev/null +++ b/include/netpacket/netlink.h @@ -0,0 +1,323 @@ +/**************************************************************************** + * include/netpacket/netlink.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NETPACKET_NETLINK_H +#define __INCLUDE_NETPACKET_NETLINK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Netlink socket protocols *************************************************/ +/* The AF_NETLINK family offers multiple protocol subsets. Each interfaces + * to a different kernel component and has a different messaging subset. The + * subset is referenced by the protocol field in the socket call: + * + * int socket(AF_NETLINK, SOCK_DGRAM or SOCK_RAW, protocol) + * + * Ref. Wikipedia.org + */ + +#define NETLINK_ROUTE 0 /* Routing/device hook for user-space + * routing daemons */ +#define NETLINK_FIREWALL 1 /* Interface to receive packets from + * the firewall */ +#define NETLINK_NFLOG 2 /* netfilter/iptables ULOG */ +#define NETLINK_ARPD 3 /* Interface to manage the ARP table */ +#define NETLINK_AUDIT 4 /* Interface to auditing sub-system */ +#define NETLINK_IP6_FW 5 /* Interface to transport packets from + * netfilter to user-space. */ +#define NETLINK_ROUTE6 6 +#define NETLINK_TAPBASE 7 +#define NETLINK_NETFILTER 8 +#define NETLINK_TCPDIAG 9 +#define NETLINK_XFRM 10 /* Interface to IPsec security databases + * for key-manager daemons using the Internet + * Key Exchange protocol. */ +#define NETLINK_USERSOCK 11 /* Reserved for user mode socket protocols */ + +/* NETLINK_ROUTE protocol message types *************************************/ +/* Link layer: + * + * RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK + * Create, remove or get information about a specific network interface. + * These messages contain an ifinfomsg structure followed by a series + * of rtattr structures. + */ + +#define RTM_NEWLINK 0 +#define RTM_DELLINK 1 +#define RTM_GETLINK 2 +#define RTM_SETLINK 3 + +/* Address settings: + * + * RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR + * Add, remove or receive information about an IP address associated with + * an interface. These messages contain an ifaddrmsg structure, optionally + * followed by rtattr routing attributes. + */ + +#define RTM_NEWADDR 4 +#define RTM_DELADDR 5 +#define RTM_GETADDR 6 + +/* Routing tables: + * + * RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE + * Create, remove or receive information about a network route. These + * messages contain an rtmsg structure with an optional sequence of + * rtattr structures following. + * + * For RTM_GETROUTE, setting rtm_dst_len and rtm_src_len to 0 means you + * get all entries for the specified routing table. For the other fields, + * except rtm_table and rtm_protocol, 0 is the wildcard. + */ + +#define RTM_NEWROUTE 7 +#define RTM_DELROUTE 8 +#define RTM_GETROUTE 9 + +/* Neighbor cache: + * + * RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH + * Add, remove or receive information about a neighbor table entry (e.g., + * an ARP entry). The message contains an ndmsg structure. + */ + +#define RTM_NEWNEIGH 10 +#define RTM_DELNEIGH 11 +#define RTM_GETNEIGH 12 + +/* Routing rules: + * + * RTM_NEWRULE, RTM_DELRULE, RTM_GETRULE + * Add, delete or retrieve a routing rule. Carries a struct rtmsg + */ + +#define RTM_NEWRULE 13 +#define RTM_DELRULE 14 +#define RTM_GETRULE 15 + +/* Queuing discipline settings: + * + * RTM_NEWQDISC, RTM_DELQDISC, RTM_GETQDISC + * Add, remove or get a queuing discipline. The message contains a + * struct tcmsg and may be followed by a series of attributes. + */ + +#define RTM_NEWQDISC 16 +#define RTM_DELQDISC 17 +#define RTM_GETQDISC 18 + +/* Traffic classes used with queues: + * + * RTM_NEWTCLASS, RTM_DELTCLASS, RTM_GETTCLASS + * Add, remove or get a traffic class. These messages contain a struct + * tcmsg as described above. + */ + +#define RTM_NEWTCLASS 19 +#define RTM_DELTCLASS 20 +#define RTM_GETTCLASS 21 + +/* Traffic filters: + * + * RTM_NEWTFILTER, RTM_DELTFILTER, RTM_GETTFILTER + * Add, remove or receive information about a traffic filter. These + * messages contain a struct tcmsg as described above. + */ + +#define RTM_NEWTFILTER 22 +#define RTM_DELTFILTER 23 +#define RTM_GETTFILTER 24 + +/* Others: */ + +#define RTM_NEWACTION 25 +#define RTM_DELACTION 26 +#define RTM_GETACTION 27 +#define RTM_NEWPREFIX 28 +#define RTM_GETPREFIX 29 +#define RTM_GETMULTICAST 30 +#define RTM_GETANYCAST 31 +#define RTM_NEWNEIGHTBL 32 +#define RTM_GETNEIGHTBL 33 +#define RTM_SETNEIGHTBL 34 + +/* Definitions associated with struct sockaddr_nl ***************************/ +/* Flags values */ + +#define NLM_F_REQUEST 0x0001 /* It is request message. */ +#define NLM_F_MULTI 0x0002 /* Multipart message, terminated by NLMSG_DONE */ +#define NLM_F_ACK 0x0004 /* Reply with ack, with zero or error code */ +#define NLM_F_ECHO 0x0008 /* Echo this request */ +#define NLM_F_DUMP_INTR 0x0010 /* Dump was inconsistent due to sequence change */ +#define NLM_F_DUMP_FILTERED 0x0020 /* Dump was filtered as requested */ + +/* Modifiers to GET request */ + +#define NLM_F_ROOT 0x0100 /* specify tree root */ +#define NLM_F_MATCH 0x0200 /* return all matching */ +#define NLM_F_ATOMIC 0x0400 /* atomic GET */ +#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) + +/* Modifiers to NEW request */ + +#define NLM_F_REPLACE 0x0100 /* Override existing */ +#define NLM_F_EXCL 0x0200 /* Do not touch, if it exists */ +#define NLM_F_CREATE 0x0400 /* Create, if it does not exist */ +#define NLM_F_APPEND 0x0800 /* Add to end of list */ + +/* Modifiers to DELETE request */ + +#define NLM_F_NONREC 0x0100 /* Do not delete recursively */ + +/* Flags for ACK message */ + +#define NLM_F_CAPPED 0x0100 /* request was capped */ +#define NLM_F_ACK_TLVS 0x0200 /* extended ACK TVLs were included */ + +/* Definitions for struct rtattr ********************************************/ +/* Macros to handle rtattributes */ + +#define RTA_ALIGNTO 4 +#define RTA_ALIGN(len) (((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1)) +#define RTA_OK(rta,len) \ + ((len) >= (int)sizeof(struct rtattr) && \ + (rta)->rta_len >= sizeof(struct rtattr) && \ + (rta)->rta_len <= (len)) +#define RTA_NEXT(rta,attrlen) \ + ((attrlen) -= RTA_ALIGN((rta)->rta_len), \ + (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) +#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) +#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) +#define RTA_DATA(rta) ((FAR void *)(((FAR char *)(rta)) + RTA_LENGTH(0))) +#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) + +/* Definitions for struct ifaddrmsg ****************************************/ +/* ifa_flags definitions: ifa_flags is a flag word of IFA_F_SECONDARY for + * secondary address (old alias interface), IFA_F_PERMANENT for a permanent + * address set by the user and other undocumented flags. + */ + +#define IFA_F_SECONDARY 0x01 +#define IFA_F_PERMANENT 0x02 + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +/* Netlink socket address type. */ + +struct sockaddr_nl +{ + sa_family_t nl_family; /* AF_NETLINK */ + uint16_t nl_pad; /* Zero */ + uint32_t nl_pid; /* Port ID */ + uint32_t nl_groups; /* Multicast groups mask */ +}; + +/* Packet structure. The Netlink message header, struct nlmsghdr, must be + * prepared by the caller. The Netlink socket generally works in a SOCK_RAW- + * like mode (even if SOCK_DGRAM was used to create it). + * + * The data portion then contains a subsystem-specific message that may be + * further nested. + */ + +struct nlmsghdr +{ + uint32_t nlmsg_len; /* Length of message including header */ + uint16_t nlmsg_type; /* Message content */ + uint16_t nlmsg_flags; /* Additional flags */ + uint32_t nlmsg_seq; /* Sequence number */ + uint32_t nlmsg_pid; /* Sending process port ID */ + /* Data follows */ +}; + +/* RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK + * + * Create, remove or get information about a specific network interface. + * These messages contain an ifinfomsg structure followed by a series + * of rtattr structures. + * + * These attributes should be manipulated using only the RTA_* + */ + +struct rtattr +{ + uint16_t rta_len; /* Length of option */ + uint16_t rta_type; /* Type of option */ + /* Data follows */ +}; + +struct ifinfomsg +{ + uint8_t ifi_family; /* AF_UNSPEC */ + uint16_t ifi_type; /* Device type */ + int16_t ifi_index; /* Unique interface index */ + uint32_t ifi_flags; /* Device flags */ + uint32_t ifi_change; /* Change mask, must always be 0xffffffff */ +}; + +/* RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR + * + * Add, remove or receive information about an IP address associated with + * an interface. These messages contain an ifaddrmsg structure, optionally + * followed by rtattr routing attributes. + */ + +struct ifaddrmsg +{ + uint8_t ifa_family; /* Address type: AF_INET or AF_INET6 */ + uint8_t ifa_prefixlen; /* Prefix length of address */ + uint8_t ifa_flags; /* Address flags. See IFA_F_* definitions */ + uint8_t ifa_scope; /* Address scope */ + int16_t ifa_index; /* Unique interface index */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __INCLUDE_NETPACKET_NETLINK_H */ diff --git a/include/sys/socket.h b/include/sys/socket.h index 838c80f3bc..b15040f1cc 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -62,6 +62,7 @@ #define PF_BLUETOOTH 5 /* Bluetooth sockets */ #define PF_IEEE802154 6 /* Low level IEEE 802.15.4 radio frame interface */ #define PF_PKTRADIO 7 /* Low level packet radio interface */ +#define PF_NETLINK 8 /* Netlink IPC socket */ /* Supported Address Families. Opengroup.org requires only AF_UNSPEC, * AF_UNIX, AF_INET and AF_INET6. @@ -76,6 +77,7 @@ #define AF_BLUETOOTH PF_BLUETOOTH #define AF_IEEE802154 PF_IEEE802154 #define AF_PKTRADIO PF_PKTRADIO +#define AF_NETLINK PF_NETLINK /* The socket created by socket() has the indicated type, which specifies * the communication semantics. @@ -194,7 +196,7 @@ * return: int */ -/* Protocol-level socket operations */ +/* Protocol-level socket operations. */ #define SOL_IP 1 /* See options in include/netinet/ip.h */ #define SOL_IPV6 2 /* See options in include/netinet/ip6.h */ diff --git a/net/Kconfig b/net/Kconfig index fdee07d5bf..fc0ee0717f 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -87,7 +87,6 @@ config NET_SLIP_PKTSIZE 256 MSS, but restrict transfers to 128 bytes (possibly by modifying the MSS value in the TCP connection structure). - config NET_GUARDSIZE int "Driver I/O guard size" default 2 @@ -307,6 +306,7 @@ source "net/socket/Kconfig" source "net/inet/Kconfig" source "net/pkt/Kconfig" source "net/local/Kconfig" +source "net/netlink/Kconfig" source "net/tcp/Kconfig" source "net/udp/Kconfig" source "net/bluetooth/Kconfig" diff --git a/net/Makefile b/net/Makefile index a9a26970f1..2e50dbefb8 100644 --- a/net/Makefile +++ b/net/Makefile @@ -65,6 +65,7 @@ include neighbor/Make.defs include igmp/Make.defs include pkt/Make.defs include local/Make.defs +include netlink/Make.defs include tcp/Make.defs include udp/Make.defs include sixlowpan/Make.defs diff --git a/net/README.txt b/net/README.txt index 30de5341d8..c1fa72eab0 100644 --- a/net/README.txt +++ b/net/README.txt @@ -20,6 +20,7 @@ Directory Structure +- loopback - Local loopback +- neighbor - Neighbor Discovery Protocol (IPv6) +- netdev - Socket network device interface + +- netlink - Netlink IPC socket interface +- pkt - "Raw" packet socket support +- sixlowpan - 6LoWPAN implementation +- socket - BSD socket interface diff --git a/net/net_initialize.c b/net/net_initialize.c index e8a3b440d2..036cdd2c88 100644 --- a/net/net_initialize.c +++ b/net/net_initialize.c @@ -60,6 +60,7 @@ #include "bluetooth/bluetooth.h" #include "ieee802154/ieee802154.h" #include "local/local.h" +#include "netlink/netlink.h" #include "igmp/igmp.h" #include "route/route.h" #include "usrsock/usrsock.h" @@ -160,6 +161,12 @@ void net_setup(void) local_initialize(); #endif +#ifdef CONFIG_NET_NETLINK + /* Initialize the Netlink IPC support */ + + netlink_initialize(); +#endif + #ifdef NET_TCP_HAVE_STACK /* Initialize the listening port structures */ diff --git a/net/netlink/Kconfig b/net/netlink/Kconfig new file mode 100644 index 0000000000..816384397c --- /dev/null +++ b/net/netlink/Kconfig @@ -0,0 +1,26 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config NET_NETLINK + bool "Netlink socket support" + default n + depends on EXPERIMENTAL + ---help--- + Enable support for Nelink-like IPC sockets that will permit user- + space applications to interact with network services. + + This logic is a WIP. Currenlty only fragmentary support is + available, not enough to actually do antything of consequence. + Hence, the feature depends on EXPERIMENTAL. + +if NET_NETLINK + +config NET_NETLINK_CONNS + int "Number of netlink connections" + default 4 + ---help--- + Maximum number of netlink connections (all tasks). + +endif # NET_NETLINK diff --git a/net/netlink/Make.defs b/net/netlink/Make.defs new file mode 100644 index 0000000000..7b3f7e7ce6 --- /dev/null +++ b/net/netlink/Make.defs @@ -0,0 +1,46 @@ +############################################################################ +# net/netlink/Make.defs +# +# Copyright (C) 2018 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Logic specific to IPv6 Neighbor Discovery Protocol + +ifeq ($(CONFIG_NET_NETLINK),y) + +SOCK_CSRCS += netlink_sockif.c netlink_conn.c + +# Include netlink build support + +DEPPATH += --dep-path netlink +VPATH += :netlink +endif diff --git a/net/netlink/netlink.h b/net/netlink/netlink.h new file mode 100644 index 0000000000..2dfe8024e7 --- /dev/null +++ b/net/netlink/netlink.h @@ -0,0 +1,156 @@ +/**************************************************************************** + * net/netlink/netlink.h + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __NET_NETLINK_NETLINK_H +#define __NET_NETLINK_NETLINK_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include "devif/devif.h" +#include "socket/socket.h" + +#ifdef CONFIG_NET_NETLINK + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Type Definitions + ****************************************************************************/ + +struct netlink_conn_s +{ + dq_entry_t node; /* Supports a doubly linked list */ + uint8_t crefs; /* Reference counts on this instance */ + + /* Defines the list of netlink callbacks */ + + FAR struct devif_callback_s *list; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +EXTERN const struct sock_intf_s g_netlink_sockif; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: netlink_initialize() + * + * Description: + * Initialize the User Socket connection structures. Called once and only + * from the networking layer. + * + ****************************************************************************/ + +void netlink_initialize(void); + +/**************************************************************************** + * Name: netlink_alloc() + * + * Description: + * Allocate a new, uninitialized netlink connection structure. This is + * normally something done by the implementation of the socket() API + * + ****************************************************************************/ + +FAR struct netlink_conn_s *netlink_alloc(void); + +/**************************************************************************** + * Name: netlink_free() + * + * Description: + * Free a netlink connection structure that is no longer in use. This should + * be done by the implementation of close(). + * + ****************************************************************************/ + +void netlink_free(FAR struct netlink_conn_s *conn); + +/**************************************************************************** + * Name: netlink_nextconn() + * + * Description: + * Traverse the list of allocated netlink connections + * + * Assumptions: + * This function is called from netlink device logic. + * + ****************************************************************************/ + +FAR struct netlink_conn_s *netlink_nextconn(FAR struct netlink_conn_s *conn); + +/**************************************************************************** + * Name: netlink_active() + * + * Description: + * Find a connection structure that is the appropriate connection for the + * provided netlink address + * + * Assumptions: + * + ****************************************************************************/ + +struct sockaddr_nl; /* Forward reference */ +FAR struct netlink_conn_s *netlink_active(FAR struct sockaddr_nl *addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_NET_NETLINK */ +#endif /* __NET_NETLINK_NETLINK_H */ diff --git a/net/netlink/netlink_conn.c b/net/netlink/netlink_conn.c new file mode 100644 index 0000000000..46b873d674 --- /dev/null +++ b/net/netlink/netlink_conn.c @@ -0,0 +1,246 @@ +/**************************************************************************** + * net/netlink/netlink_conn.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "netlink/netlink.h" + +#ifdef CONFIG_NET_NETLINK + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The array containing all netlink connections. */ + +static struct netlink_conn_s g_netlink_connections[CONFIG_NET_NETLINK_CONNS]; + +/* A list of all free netlink connections */ + +static dq_queue_t g_free_netlink_connections; +static sem_t g_free_sem; + +/* A list of all allocated netlink connections */ + +static dq_queue_t g_active_netlink_connections; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _netlink_semtake() and _netlink_semgive() + * + * Description: + * Take/give semaphore + * + ****************************************************************************/ + +static void _netlink_semtake(FAR sem_t *sem) +{ + int ret; + + /* Take the semaphore (perhaps waiting) */ + + while ((ret = net_lockedwait(sem)) < 0) + { + /* The only case that an error should occur here is if + * the wait was awakened by a signal. + */ + + DEBUGASSERT(ret == -EINTR || ret == -ECANCELED); + } +} + +static void _netlink_semgive(FAR sem_t *sem) +{ + (void)nxsem_post(sem); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: netlink_initialize() + * + * Description: + * Initialize the User Socket connection structures. Called once and only + * from the networking layer. + * + ****************************************************************************/ + +void netlink_initialize(void) +{ + int i; + + /* Initialize the queues */ + + dq_init(&g_free_netlink_connections); + dq_init(&g_active_netlink_connections); + nxsem_init(&g_free_sem, 0, 1); + + for (i = 0; i < CONFIG_NET_NETLINK_CONNS; i++) + { + FAR struct netlink_conn_s *conn = &g_netlink_connections[i]; + + /* Mark the connection closed and move it to the free list */ + + memset(conn, 0, sizeof(*conn)); + dq_addlast(&conn->node, &g_free_netlink_connections); + } +} + +/**************************************************************************** + * Name: netlink_alloc() + * + * Description: + * Allocate a new, uninitialized netlink connection structure. This is + * normally something done by the implementation of the socket() API + * + ****************************************************************************/ + +FAR struct netlink_conn_s *netlink_alloc(void) +{ + FAR struct netlink_conn_s *conn; + + /* The free list is protected by a semaphore (that behaves like a mutex). */ + + _netlink_semtake(&g_free_sem); + conn = (FAR struct netlink_conn_s *)dq_remfirst(&g_free_netlink_connections); + if (conn) + { + /* Make sure that the connection is marked as uninitialized */ + + memset(conn, 0, sizeof(*conn)); + + /* Enqueue the connection into the active list */ + + dq_addlast(&conn->node, &g_active_netlink_connections); + } + + _netlink_semgive(&g_free_sem); + return conn; +} + +/**************************************************************************** + * Name: netlink_free() + * + * Description: + * Free a netlink connection structure that is no longer in use. This should + * be done by the implementation of close(). + * + ****************************************************************************/ + +void netlink_free(FAR struct netlink_conn_s *conn) +{ + /* The free list is protected by a semaphore (that behaves like a mutex). */ + + DEBUGASSERT(conn->crefs == 0); + + _netlink_semtake(&g_free_sem); + + /* Remove the connection from the active list */ + + dq_rem(&conn->node, &g_active_netlink_connections); + + /* Reset structure */ + + memset(conn, 0, sizeof(*conn)); + + /* Free the connection */ + + dq_addlast(&conn->node, &g_free_netlink_connections); + _netlink_semgive(&g_free_sem); +} + +/**************************************************************************** + * Name: netlink_nextconn() + * + * Description: + * Traverse the list of allocated netlink connections + * + * Assumptions: + * This function is called from netlink device logic. + * + ****************************************************************************/ + +FAR struct netlink_conn_s *netlink_nextconn(FAR struct netlink_conn_s *conn) +{ + if (conn == NULL) + { + return (FAR struct netlink_conn_s *)g_active_netlink_connections.head; + } + else + { + return (FAR struct netlink_conn_s *)conn->node.flink; + } +} + +/**************************************************************************** + * Name: netlink_active() + * + * Description: + * Find a connection structure that is the appropriate connection for the + * provided netlink address + * + * Assumptions: + * + ****************************************************************************/ + +FAR struct netlink_conn_s *netlink_active(FAR struct sockaddr_nl *addr) +{ + FAR struct netlink_conn_s *conn = NULL; +#warning "Missing logic for NETLINK active" + return NULL; +} + +#endif /* CONFIG_NET_NETLINK */ diff --git a/net/netlink/netlink_sockif.c b/net/netlink/netlink_sockif.c new file mode 100644 index 0000000000..5b9e3b5040 --- /dev/null +++ b/net/netlink/netlink_sockif.c @@ -0,0 +1,585 @@ +/**************************************************************************** + * net/netlink/netlink_sockif.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "netlink/netlink.h" + +#ifdef CONFIG_NET_NETLINK + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int netlink_setup(FAR struct socket *psock, int protocol); +static sockcaps_t netlink_sockcaps(FAR struct socket *psock); +static void netlink_addref(FAR struct socket *psock); +static int netlink_bind(FAR struct socket *psock, + FAR const struct sockaddr *addr, socklen_t addrlen); +static int netlink_getsockname(FAR struct socket *psock, + FAR struct sockaddr *addr, FAR socklen_t *addrlen); +static int netlink_getpeername(FAR struct socket *psock, + FAR struct sockaddr *addr, FAR socklen_t *addrlen); +static int netlink_listen(FAR struct socket *psock, int backlog); +static int netlink_connect(FAR struct socket *psock, + FAR const struct sockaddr *addr, socklen_t addrlen); +static int netlink_accept(FAR struct socket *psock, FAR struct sockaddr *addr, + FAR socklen_t *addrlen, FAR struct socket *newsock); +#ifndef CONFIG_DISABLE_POLL +static int netlink_poll(FAR struct socket *psock, FAR struct pollfd *fds, + bool setup); +#endif +static ssize_t netlink_send(FAR struct socket *psock, + FAR const void *buf, size_t len, int flags); +static ssize_t netlink_sendto(FAR struct socket *psock, FAR const void *buf, + size_t len, int flags, FAR const struct sockaddr *to, + socklen_t tolen); +static ssize_t netlink_recvfrom(FAR struct socket *psock, FAR void *buf, + size_t len, int flags, FAR struct sockaddr *from, + FAR socklen_t *fromlen); +static int netlink_close(FAR struct socket *psock); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct sock_intf_s g_netlink_sockif = +{ + netlink_setup, /* si_setup */ + netlink_sockcaps, /* si_sockcaps */ + netlink_addref, /* si_addref */ + netlink_bind, /* si_bind */ + netlink_getsockname, /* si_getsockname */ + netlink_getpeername, /* si_getpeername */ + netlink_listen, /* si_listen */ + netlink_connect, /* si_connect */ + netlink_accept, /* si_accept */ +#ifndef CONFIG_DISABLE_POLL + netlink_poll, /* si_poll */ +#endif + netlink_send, /* si_send */ + netlink_sendto, /* si_sendto */ +#ifdef CONFIG_NET_SENDFILE + NULL, /* si_sendfile */ +#endif + netlink_recvfrom, /* si_recvfrom */ + netlink_close /* si_close */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: inet_setup + * + * Description: + * Called for socket() to verify that the provided socket type and + * protocol are usable by this address family. Perform any family- + * specific socket fields. + * + * Input Parameters: + * psock A pointer to a user allocated socket structure to be initialized. + * protocol (see sys/socket.h) + * + * Returned Value: + * Zero (OK) is returned on success. Otherwise, a negater errno value is + * returned. + * + ****************************************************************************/ + +static int netlink_setup(FAR struct socket *psock, int protocol) +{ + int domain = psock->s_domain; + int type = psock->s_type; + int ret; + + if (domain == PF_NETLINK && (type == SOCK_RAW || type == SOCK_DGRAM)) + { + ret = OK; + } + else + { + return -ENETDOWN; + } + + psock->s_conn = NULL; + return ret; +} + +/**************************************************************************** + * Name: netlink_sockcaps + * + * Description: + * Return the bit encoded capabilities of this socket. + * + * Input Parameters: + * psock - Socket structure of the socket whose capabilities are being + * queried. + * + * Returned Value: + * The non-negative set of socket capabilities is returned. + * + ****************************************************************************/ + +static sockcaps_t netlink_sockcaps(FAR struct socket *psock) +{ + return 0; +} + +/**************************************************************************** + * Name: netlink_addref + * + * Description: + * Increment the reference count on the underlying connection structure. + * + * Input Parameters: + * psock - Socket structure of the socket whose reference count will be + * incremented. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void netlink_addref(FAR struct socket *psock) +{ + FAR struct netlink_conn_s *conn; + + DEBUGASSERT(psock != NULL && psock->s_conn != NULL); + + conn = psock->s_conn; + DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255); + conn->crefs++; +} + +/**************************************************************************** + * Name: netlink_bind + * + * Description: + * netlink_bind() gives the socket 'conn' the local address 'addr'. 'addr' + * is 'addrlen' bytes long. Traditionally, this is called "assigning a name + * to a socket." When a socket is created with socket, it exists in a name + * space (address family) but has no name assigned. + * + * Input Parameters: + * conn netlink socket connection structure + * addr Socket local address + * addrlen Length of 'addr' + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately + * + * EACCES + * The address is protected, and the user is not the superuser. + * EADDRINUSE + * The given address is already in use. + * EINVAL + * The socket is already bound to an address. + * ENOTSOCK + * psock is a descriptor for a file, not a socket. + * + * Assumptions: + * + ****************************************************************************/ + +static int netlink_bind(FAR struct socket *psock, + FAR const struct sockaddr *addr, socklen_t addrlen) +{ +#warning Missing logic for NETLINK bind + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_getsockname + * + * Description: + * The getsockname() function retrieves the locally-bound name of the + * specified socket, stores this address in the sockaddr structure pointed + * to by the 'addr' argument, and stores the length of this address in the + * object pointed to by the 'addrlen' argument. + * + * If the actual length of the address is greater than the length of the + * supplied sockaddr structure, the stored address will be truncated. + * + * If the socket has not been bound to a local name, the value stored in + * the object pointed to by address is unspecified. + * + * Input Parameters: + * conn netlink socket connection structure + * addr sockaddr structure to receive data [out] + * addrlen Length of sockaddr structure [in/out] + * + ****************************************************************************/ + +static int netlink_getsockname(FAR struct socket *psock, + FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ +#warning Missing logic for NETLINK getsockname + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_getpeername + * + * Description: + * The netlink_getpeername() function retrieves the remote-connected name + * of the specified packet socket, stores this address in the sockaddr + * structure pointed to by the 'addr' argument, and stores the length of + * this address in the object pointed to by the 'addrlen' argument. + * + * If the actual length of the address is greater than the length of the + * supplied sockaddr structure, the stored address will be truncated. + * + * If the socket has not been bound to a local name, the value stored in + * the object pointed to by address is unspecified. + * + * Parameters: + * psock Socket structure of the socket to be queried + * addr sockaddr structure to receive data [out] + * addrlen Length of sockaddr structure [in/out] + * + * Returned Value: + * On success, 0 is returned, the 'addr' argument points to the address + * of the socket, and the 'addrlen' argument points to the length of the + * address. Otherwise, a negated errno value is returned. See + * getpeername() for the list of appropriate error numbers. + * + ****************************************************************************/ + +static int netlink_getpeername(FAR struct socket *psock, + FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ +#warning Missing logic for NETLINK getsockname + return -EOPNOTSUPP; +//return -EAFNOSUPPORT; +} + +/**************************************************************************** + * Name: netlink_listen + * + * Description: + * To accept connections, a socket is first created with psock_socket(), a + * willingness to accept incoming connections and a queue limit for + * incoming connections are specified with psock_listen(), and then the + * connections are accepted with psock_accept(). For the case of AFINET + * and AFINET6 sockets, psock_listen() calls this function. The + * psock_listen() call applies only to sockets of type SOCK_STREAM or + * SOCK_SEQPACKET. + * + * Input Parameters: + * psock Reference to an internal, bound socket structure. + * backlog The maximum length the queue of pending connections may grow. + * If a connection request arrives with the queue full, the client + * may receive an error with an indication of ECONNREFUSED or, + * if the underlying protocol supports retransmission, the request + * may be ignored so that retries succeed. + * + * Returned Value: + * On success, zero is returned. On error, a negated errno value is + * returned. See list() for the set of appropriate error values. + * + ****************************************************************************/ + +static int netlink_listen(FAR struct socket *psock, int backlog) +{ +#warning Missing logic for NETLINK listen + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_connect + * + * Description: + * Perform a netlink connection + * + * Input Parameters: + * psock A reference to the socket structure of the socket to be connected + * addr The address of the remote server to connect to + * addrlen Length of address buffer + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int netlink_connect(FAR struct socket *psock, + FAR const struct sockaddr *addr, + socklen_t addrlen) +{ +#warning Missing logic for NETLINK connect + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_accept + * + * Description: + * The netlink_accept function is used with connection-based socket + * types (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first + * connection request on the queue of pending connections, creates a new + * connected socket with mostly the same properties as 'sockfd', and + * allocates a new socket descriptor for the socket, which is returned. The + * newly created socket is no longer in the listening state. The original + * socket 'sockfd' is unaffected by this call. Per file descriptor flags + * are not inherited across an inet_accept. + * + * The 'sockfd' argument is a socket descriptor that has been created with + * socket(), bound to a local address with bind(), and is listening for + * connections after a call to listen(). + * + * On return, the 'addr' structure is filled in with the address of the + * connecting entity. The 'addrlen' argument initially contains the size + * of the structure pointed to by 'addr'; on return it will contain the + * actual length of the address returned. + * + * If no pending connections are present on the queue, and the socket is + * not marked as non-blocking, inet_accept blocks the caller until a + * connection is present. If the socket is marked non-blocking and no + * pending connections are present on the queue, inet_accept returns + * EAGAIN. + * + * Input Parameters: + * psock Reference to the listening socket structure + * addr Receives the address of the connecting client + * addrlen Input: allocated size of 'addr', Return: returned size of 'addr' + * newsock Location to return the accepted socket information. + * + * Returned Value: + * Returns 0 (OK) on success. On failure, it returns a negated errno + * value. See accept() for a desrciption of the approriate error value. + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static int netlink_accept(FAR struct socket *psock, FAR struct sockaddr *addr, + FAR socklen_t *addrlen, FAR struct socket *newsock) +{ +#warning Missing logic for NETLINK accept + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_poll + * + * Description: + * The standard poll() operation redirects operations on socket descriptors + * to this function. + * + * Input Parameters: + * psock - An instance of the internal socket structure. + * fds - The structure describing the events to be monitored. + * setup - true: Setup up the poll; false: Teardown the poll + * + * Returned Value: + * 0: Success; Negated errno on failure + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int netlink_poll(FAR struct socket *psock, FAR struct pollfd *fds, + bool setup) +{ +#warning Missing logic for NETLINK poll + return -EOPNOTSUPP; +} +#endif + +/**************************************************************************** + * Name: netlink_send + * + * Description: + * The netlink_send() call may be used only when the socket is in + * a connected state (so that the intended recipient is known). + * + * Input Parameters: + * psock An instance of the internal socket structure. + * buf Data to send + * len Length of data to send + * flags Send flags (ignored) + * + * Returned Value: + * On success, returns the number of characters sent. On error, a negated + * errno value is returned (see send() for the list of appropriate error + * values. + * + ****************************************************************************/ + +static ssize_t netlink_send(FAR struct socket *psock, + FAR const void *buf, + size_t len, int flags) +{ +#warning Missing logic for NETLINK send + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_sendto + * + * Description: + * If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET) + * socket, the parameters to and 'tolen' are ignored (and the error EISCONN + * may be returned when they are not NULL and 0), and the error ENOTCONN is + * returned when the socket was not actually connected. + * + * Input Parameters: + * psock A reference to the socket structure of the socket to be connected + * buf Data to send + * len Length of data to send + * flags Send flags (ignored) + * to Address of recipient + * tolen The length of the address structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static ssize_t netlink_sendto(FAR struct socket *psock, FAR const void *buf, + size_t len, int flags, + FAR const struct sockaddr *to, socklen_t tolen) +{ +#warning Missing logic for NETLINK sendto + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_recvfrom + * + * Description: + * recvfrom() receives messages from a socket, and may be used to receive + * data on a socket whether or not it is connection-oriented. + * + * If from is not NULL, and the underlying protocol provides the source + * address, this source address is filled in. The argument fromlen + * initialized to the size of the buffer associated with from, and modified + * on return to indicate the actual size of the address stored there. + * + * Input Parameters: + * psock A pointer to a NuttX-specific, internal socket structure + * buf Buffer to receive data + * len Length of buffer + * flags Receive flags (ignored) + * from Address of source (may be NULL) + * fromlen The length of the address structure + * + ****************************************************************************/ + +static ssize_t netlink_recvfrom(FAR struct socket *psock, FAR void *buf, + size_t len, int flags, + FAR struct sockaddr *from, + FAR socklen_t *fromlen) +{ +#warning Missing logic for NETLINK recvfrom + return -EOPNOTSUPP; +} + +/**************************************************************************** + * Name: netlink_close + * + * Description: + * Performs the close operation on an NETLINK socket instance + * + * Input Parameters: + * psock Socket instance + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately. + * + * Assumptions: + * + ****************************************************************************/ + +static int netlink_close(FAR struct socket *psock) +{ + FAR struct netlink_conn_s *conn = psock->s_conn; + int ret; + + /* Perform some pre-close operations for the NETLINK socket type. */ + + /* Is this the last reference to the connection structure (there + * could be more if the socket was dup'ed). + */ + + if (conn->crefs <= 1) + { + /* Yes... inform user-space daemon of socket close. */ +#warning Missing logic + + /* Free the connection structure */ + + conn->crefs = 0; + netlink_free(psock->s_conn); + + if (ret < 0) + { + /* Return with error code, but free resources. */ + + nerr("ERROR: netlink_close failed: %d\n", ret); + return ret; + } + } + else + { + /* No.. Just decrement the reference count */ + + conn->crefs--; + } + + return OK; +} + +#endif /* CONFIG_NET_NETLINK */ diff --git a/net/socket/net_sockif.c b/net/socket/net_sockif.c index ec3d56c412..ef9dfbceed 100644 --- a/net/socket/net_sockif.c +++ b/net/socket/net_sockif.c @@ -47,6 +47,7 @@ #include "inet/inet.h" #include "local/local.h" +#include "netlink/netlink.h" #include "pkt/pkt.h" #include "bluetooth/bluetooth.h" #include "ieee802154/ieee802154.h" @@ -103,6 +104,12 @@ FAR const struct sock_intf_s * break; #endif +#ifdef CONFIG_NET_NETLINK + case PF_NETLINK: + sockif = &g_netlink_sockif; + break; +#endif + #ifdef CONFIG_NET_PKT case PF_PACKET: sockif = &g_pkt_sockif;