2398 lines
90 KiB
C
2398 lines
90 KiB
C
/*
|
|
******************************************************************************
|
|
* HEADER FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_RCPL8_2024030303 $ $RCSfile: ipnet_h.h,v $ $Revision: 1.254.10.32 $
|
|
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_h.h,v $
|
|
* $Author: jren $ $Date: 2020-04-21 02:14:42 $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifndef IPNET_H_H
|
|
#define IPNET_H_H
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipnet_config.h"
|
|
|
|
#define IPNET_MAX_IF_EVENTCB 8
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipnet.h"
|
|
#include "ipnet_netif.h"
|
|
#ifdef IPCOM_USE_INET
|
|
#include "ipnet_ip4.h"
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
#include "ipnet_ip6.h"
|
|
#endif
|
|
#ifdef IPIPSEC2
|
|
#include <ipipsec.h>
|
|
#endif
|
|
#include "ipnet_nat_h.h"
|
|
|
|
#ifdef IPNET_USE_DIFFSERV
|
|
#include "ipnet_diffserv.h"
|
|
#include <ipcom_tree.h>
|
|
#endif
|
|
#include "ipnet_route.h"
|
|
#include "ipnet_signal.h"
|
|
#include "ipnet_timeout.h"
|
|
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_inet.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_mib2.h>
|
|
#include <ipcom_nae.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_pkt.h>
|
|
#include <ipcom_pqueue.h>
|
|
#include <ipcom_pqueue.h>
|
|
#include <ipcom_route.h>
|
|
#include <ipcom_slab.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_spinlock.h>
|
|
#include <ipcom_sysvar.h>
|
|
#include <ipcom_time.h>
|
|
|
|
#ifdef IPCOM_USE_JOB_QUEUE
|
|
#include <ipcom_job_queue.h>
|
|
#endif
|
|
|
|
#ifdef IPPPP
|
|
#include <ipppp_ipstack.h>
|
|
#endif
|
|
|
|
#include "ipnet_netlink_h.h"
|
|
#include "ipnet_rtnetlink_h.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPNET_FD_TO_SOCKET_EX(fd, sock, must_be_open) \
|
|
if (IP_UNLIKELY(fd < IPNET_SOCKET_STARTFD) \
|
|
|| IP_UNLIKELY(fd >= ipnet_conf_max_sockets) \
|
|
|| IP_UNLIKELY(IP_NULL == (sock = ipnet->sockets[fd])) \
|
|
|| (must_be_open && IP_UNLIKELY(IP_BIT_ISSET(sock->flags, IPNET_SOCKET_FLAG_CLOSED)))) \
|
|
{ \
|
|
IPCOM_WV_MARKER_2 (IPCOM_WV_NETD_IP4_DATAPATH_EVENT, IPCOM_WV_NETD_WARNING, \
|
|
1, 1, IPCOM_WV_NETDEVENT_WARNING, \
|
|
ipcom_socket, IPCOM_WV_NETD_NOSOCK, \
|
|
IPCOM_WV_IPNET_SOCK_MODULE, IPCOM_WV_NETD_SOCKET); \
|
|
IPNET_STATS(sock_ebadf++); \
|
|
return IPNET_ERRNO(EBADF); \
|
|
}
|
|
|
|
#define IPNET_FD_TO_SOCKET(fd, sock) IPNET_FD_TO_SOCKET_EX(fd, sock, IP_FALSE)
|
|
#define IPNET_FD_TO_OPEN_SOCKET(fd, sock) IPNET_FD_TO_SOCKET_EX(fd, sock, IP_TRUE)
|
|
|
|
#define IPNET_MAKE_ERRNO(err) -(err)
|
|
#define IPNET_ERRNO(err) IPNET_MAKE_ERRNO(IP_ERRNO_ ## err)
|
|
|
|
#define IPNET_DATA_SETU16(pkt,off,val16) *(Ip_u16*)(&(pkt)->data[off]) = (Ip_u16)(val16)
|
|
|
|
#define IPNET_TIMEVAL_TO_MSEC(tv) (((Ip_s64) (tv).tv_sec * 1000 + (tv).tv_usec / 1000))
|
|
|
|
/*
|
|
* Return a number N that where (size % align == 0) and N >= size
|
|
* i.e. the smallest size that has the specified alignment
|
|
* requirements
|
|
*/
|
|
#define IPNET_ALIGNED_SIZE(size, align) (((size) + (align) - 1) & ~((align) - 1))
|
|
|
|
/*
|
|
* This flag is set when the packet contains urgent data. The flag is
|
|
* used to pass information about MSG_OOB being set in
|
|
* send()/sendto()/sendmsg() while the packet is being transmitted
|
|
* through the stack command pipe.
|
|
*/
|
|
#define IPNET_PKT_FLAG_URGENT IPCOM_PKT_FLAG_LINK2
|
|
|
|
/*
|
|
* Store the offset to the urgent data and mark the packet as urgent
|
|
*/
|
|
#define IPNET_MARK_PKT_AS_URGENT(pkt) \
|
|
do { \
|
|
ipcom_pkt_set_int(pkt, IPNET_PKT_INFO_URGENT_OFFSET, (pkt)->end - (pkt)->start - 1, Ip_u16); \
|
|
IP_BIT_SET((pkt)->flags, IPNET_PKT_FLAG_URGENT); \
|
|
} while (0)
|
|
|
|
#ifdef IPCOM_FORWARDER_NAE
|
|
/*
|
|
* Each NAE is a single thread, so it does not have to lock against
|
|
* itself. However, the data lock is used for data that is located in
|
|
* shared memory when using NAE:s so the data must be protected from
|
|
* access by multiple NAE:s
|
|
*/
|
|
#define IPNET_DATA_LOCK(lock) ipcom_enter_critical_region()
|
|
#define IPNET_DATA_UNLOCK(lock) ipcom_exit_critical_region()
|
|
#else
|
|
#define IPNET_DATA_LOCK(lock) ipcom_spinlock_lock(&lock)
|
|
#define IPNET_DATA_UNLOCK(lock) ipcom_spinlock_unlock(&lock)
|
|
#endif
|
|
|
|
#define ipnet_copy_to_user(s1,s2,n) ipcom_copy_to_user(s1,s2,n)
|
|
#define ipnet_copy_from_user(s1,s2,n) ipcom_copy_from_user(s1,s2,n)
|
|
#define ipnet_in_checksum_memcpy(s1,s2,n) ipcom_in_checksum_memcpy(s1,s2,n)
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET show functions
|
|
*===========================================================================
|
|
*/
|
|
#if defined(IP_DEBUG) || defined(IPCOM_FORWARDER_NAE)
|
|
#define IPNET_USE_SHOW
|
|
#endif
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET privilege
|
|
*===========================================================================
|
|
*/
|
|
|
|
#define IPNET_PRIV_CHVR 1 /* Use has privilege to change the
|
|
current virtual router */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* routing socket optional code
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPNET_USE_ROUTESOCK
|
|
#define IPNET_ROUTESOCK(x) x
|
|
#else
|
|
#define IPNET_ROUTESOCK(x) IP_NOOP
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* netlink socket optional code
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPNET_USE_NETLINK
|
|
#define IPNET_NETLINKSOCK(x) x
|
|
#else
|
|
#define IPNET_NETLINKSOCK(x) IP_NOOP
|
|
#endif
|
|
|
|
#define IPNET_NETLINK_DEF_BUF_SZ 8192
|
|
#define IPNET_NETLINK_EXTRA_PAD 50
|
|
|
|
/*
|
|
*===========================================================================
|
|
* DEBUG/ASSERT
|
|
*===========================================================================
|
|
*/
|
|
|
|
#ifdef IPNET_DEBUG
|
|
/* #define IPNET_DEBUG_PRINTF -- Now handled per-file */
|
|
#define IPNET_DEBUG_LINE(x) x
|
|
#else
|
|
#define IPNET_DEBUG_LINE(x) IP_NOOP
|
|
#endif /* IPNET_DEBUG */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* pkt id
|
|
*===========================================================================
|
|
*/
|
|
#if defined(IPNET_DEBUG) || defined(IPNET_ASSERT)
|
|
|
|
#define IPNET_MEM_BEGIN_PAD 0xA110CA7E
|
|
#define IPNET_MEM_END_PAD 0x12DADE34
|
|
|
|
#endif /* IPNET_DEBUG */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* syslog
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPCOM_SYSLOG_PRIORITY
|
|
#undef IPCOM_SYSLOG_PRIORITY
|
|
#endif
|
|
#define IPCOM_SYSLOG_PRIORITY IPNET_SYSLOG_PRIORITY
|
|
|
|
#ifdef IPCOM_SYSLOG_FACILITY
|
|
#undef IPCOM_SYSLOG_FACILITY
|
|
#endif
|
|
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPNET
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET event semaphore
|
|
*===========================================================================
|
|
*/
|
|
/* Select stack daemon configuration */
|
|
#ifdef IPCOM_STACKD_POST_IMPL
|
|
/*
|
|
*===========================================================================
|
|
* IPCOM_STACKD_POST_IMPL
|
|
*===========================================================================
|
|
* Description: Notifies the external stack daemon that a stack event
|
|
* has occured.
|
|
* Parameters: new_timeout - IP_TRUE if called because a new timeout
|
|
* has occured.
|
|
* is_posted - IP_TRUE if this function returned IP_TRUE
|
|
* the last call and ipcom_stackd_event() has not
|
|
* since the last call.
|
|
* Returns: IP_TRUE if 'is_posted' should be IP_TRUE in the next
|
|
* call if this function is called more times
|
|
* from the same ipcom_stackd_event() run.
|
|
*
|
|
*/
|
|
IP_EXTERN Ip_bool IPCOM_STACKD_POST_IMPL(Ip_bool new_timeout, Ip_bool is_posted);
|
|
#define IPCOM_STACKD_POST(new_timeout) \
|
|
ipnet->task_posted = IPCOM_STACKD_POST_IMPL(new_timeout, ipnet->task_posted)
|
|
|
|
#else /* !IPCOM_STACKD_POST_IMPL */
|
|
|
|
#ifdef IPCOM_USE_JOB_QUEUE
|
|
#define IPCOM_STACKD_POST(new_timeout)
|
|
#else
|
|
/* The built-in daemon process is used */
|
|
#define IPCOM_STACKD_POST(new_timeout) \
|
|
if (!ipnet->task.wakeup_pending) \
|
|
{ \
|
|
ipnet->task.wakeup_pending = IP_TRUE; \
|
|
ipcom_pipe_try_send(ipnet->task.pipe, ipnet->task.wakeup_sig); \
|
|
}
|
|
#endif /* IPCOM_USE_JOB_QUEUE */
|
|
#endif /* IPCOM_STACKD_POST_IMPL */
|
|
|
|
|
|
/*
|
|
* Adjust the checksum to reflect that the TTL had been decremented.
|
|
*
|
|
* Flip the bits on the checksum, decrement the high byte of the
|
|
* checksum, fold in any carry, and then flip the bits back. Rather
|
|
* than convert the checksum to host byte order and then back to
|
|
* network byte order, just convert the increment to network byte
|
|
* order. Note: in 1's complement arithmetic, subtracting by x is the
|
|
* same as adding the 1's complement of x. So, in 16 bit arithmetic,
|
|
* rather than subtracting by (1<<8), we can add by (1<<8)^0xffff.
|
|
* Since it's all constants, that should be evaluated by the compiler
|
|
* at compile time.
|
|
*
|
|
* Doing the ^0xffff to initially flip the bits keeps the upper bits
|
|
* from also being flipped. Using the ~ operation at the end doesn't
|
|
* matter, because the upper bits get tossed when we assign it to the
|
|
* 16 bit sum field, so let the compiler do whatever is fastest.
|
|
*/
|
|
#define IP_INCREMENTAL_CHECKSUM(ip_hdr) \
|
|
do { \
|
|
int chksum; \
|
|
/* Calculate the incremental checksum update */ \
|
|
--ip_hdr->ttl; \
|
|
/* increment checksum high byte */ \
|
|
chksum = (int)(ip_hdr->sum ^ 0xFFFF) + \
|
|
(int)ip_htons((1<<8) ^ 0xFFFF); \
|
|
/* Fold the carry bit into the checksum */ \
|
|
ip_hdr->sum = (Ip_u16) ~(chksum + (chksum >> 16)); \
|
|
} while((0))
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* WindView
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPCOM_WV_INSTRUMENTATION
|
|
#define IPCOM_WV_MARKER_1(classId, eventLevel, eventOffset, eventTag, eventId, arg1, module, entity) \
|
|
ipcom_wv_marker_1(classId, eventLevel, eventOffset, eventTag, eventId, arg1, module, entity)
|
|
|
|
#define IPCOM_WV_MARKER_2(classId, eventLevel, eventOffset, eventTag, eventId, arg1, arg2, module, entity) \
|
|
ipcom_wv_marker_2(classId, eventLevel, eventOffset, eventTag, eventId, arg1, arg2, module, entity)
|
|
|
|
#define IPCOM_WV_EVENT_2(classId, eventLevel, eventOffset, eventTag, eventId, status, arg1, arg2, module, entity) \
|
|
ipcom_wv_event_2(classId, eventLevel, eventOffset, eventTag, eventId, status, arg1, arg2, module, entity)
|
|
#define IPCOM_WV_VAR1 wv_what
|
|
#define IPCOM_WV_VAR2 wv_tag
|
|
#define IPCOM_WV_DECLARE_VARS int IPCOM_WV_VAR1=0, IPCOM_WV_VAR2=0
|
|
#define IPCOM_WV_SET_VARS(eventTag, what) do { wv_what = what; wv_tag = eventTag; } while(0)
|
|
#else
|
|
#define IPCOM_WV_MARKER_1(classId, eventLevel, eventOffset, eventTag, eventId, arg1, module, entity) \
|
|
do {} while (0)
|
|
|
|
#define IPCOM_WV_MARKER_2(classId, eventLevel, eventOffset, eventTag, eventId, arg1, arg2, module, entity) \
|
|
do {} while (0)
|
|
|
|
#define IPCOM_WV_EVENT_2(classId, eventLevel, eventOffset, eventTag, eventId, status, arg1, arg2, module, entity) \
|
|
do {} while (0)
|
|
#define IPCOM_WV_VAR1
|
|
#define IPCOM_WV_VAR2
|
|
#define IPCOM_WV_DECLARE_VARS
|
|
#define IPCOM_WV_SET_VARS(eventTag, what)
|
|
#endif /* #ifdef IPCOM_WV_INSTRUMENTATION */
|
|
|
|
/* IPNET packet information types */
|
|
#define IPNET_PKT_INFO_SIG 64 /* Ipnet_sig */
|
|
#define IPNET_PKT_INFO_SOCK_SND_BUF 65 /* Ipnet_pkt_info_sock_snd_buf */
|
|
#define IPNET_PKT_INFO_URGENT_OFFSET 66 /* Ip_u16 */
|
|
#define IPNET_PKT_INFO_TUNNEL_IPSTART 67 /* int */
|
|
#define IPNET_PKT_INFO_NETEMU_SEQ_NUM 68 /* Ip_u32 */
|
|
#define IPNET_PKT_INFO_DPAF_PQ_INDEX 69 /* unsigned */
|
|
#define IPNET_PKT_INFO_TIMEOUT 70 /* Ip_u32 */
|
|
#define IPNET_PKT_INFO_PEER_INFO_PTR 71 /* Ipnet_peer_info* */
|
|
#define IPNET_PKT_INFO_IPSEC_CATEGORY 72 /* int */
|
|
#define IPNET_PKT_INFO_ZONE_ID 73 /* Ip_u32 */
|
|
#define IPNET_PKT_INFO_L4_CHKSUM_PTR 74 /* void* */
|
|
#define IPNET_PKT_INFO_ENCAP_UDP (75 | IPCOM_PKT_INFO_COPY) /* 8 bytes */
|
|
#define IPNET_PKT_INFO_ENCAP (76 | IPCOM_PKT_INFO_COPY) /* 4 bytes */
|
|
|
|
#define IPNET_PKT_INFO_GRE_KEY_OUTPUT (77 | IPCOM_PKT_INFO_COPY) /* Ip_u32 */
|
|
#define IPNET_PKT_INFO_SEND_SIG_VERIFIED (78 | IPCOM_PKT_INFO_COPY) /* void */
|
|
|
|
#define IPNET_PKT_INFO_DSTOPT_HOA (79 | IPCOM_PKT_INFO_COPY)/* struct Ip_in6_addr* */
|
|
#define IPNET_PKT_INFO_RTHDR2 (80 | IPCOM_PKT_INFO_COPY)/* struct Ip_in6_addr* */
|
|
|
|
#define IPNET_PKT_INFO_CLONEDPKT 81 /* struct Ipcom_pkt* */
|
|
#define IPNET_PKT_INFO_INGRESS_IFINDEX 82 /* unsigned */
|
|
|
|
#define IPNET_PKT_INFO_ENCAP_FLAGS_SET(v, p) (((v) << 8) | (p))
|
|
#define IPNET_PKT_INFO_ENCAP_FLAGS_GET_PROTO(f) ((f) & 0xFF)
|
|
#define IPNET_PKT_INFO_ENCAP_FLAGS_GET_VER(f) (((v) >> 8) & 0xFF)
|
|
|
|
#define IPNET_PKT_INFO_FLAGS_GET_SIZE(f) (((f) >> 24) & 0xFF)
|
|
|
|
#define IPCOM_INET6_MASK_LEN 16
|
|
#define IPCOM_INET_MASK_LEN 4
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/* Forward declaration */
|
|
struct Ipnet_netif_struct;
|
|
struct Ipnet_peer_info_struct;
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_pkt_udp
|
|
*===========================================================================
|
|
*/
|
|
#include "ipcom_align16.h"
|
|
typedef IP_PACKED1 struct Ipnet_pkt_udp_struct
|
|
{
|
|
Ip_u16 sport; /* Source port. */
|
|
Ip_u16 dport; /* Destination port. */
|
|
Ip_u16 ulen; /* UDP length. */
|
|
Ip_u16 sum; /* UDP checksum. */
|
|
}
|
|
IP_PACKED2 Ipnet_pkt_udp;
|
|
|
|
#define IPNET_UDP_HDR_SIZE (8) /* UDP header is 8 octets long */
|
|
|
|
|
|
/*
|
|
* RFC 3828 UDP-Lite packet
|
|
*/
|
|
typedef IP_PACKED1 struct Ipnet_pkt_udplite_struct
|
|
{
|
|
Ip_u16 sport; /* Source port. */
|
|
Ip_u16 dport; /* Destination port. */
|
|
Ip_u16 sum_cov; /* Octes covered by the checksum */
|
|
Ip_u16 sum; /* UDP-Lite checksum. */
|
|
}
|
|
IP_PACKED2 Ipnet_pkt_udplite;
|
|
|
|
#define IPNET_UDPLITE_HDR_SIZE (8) /* UDP header is 8 octets long */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_frame
|
|
*===========================================================================
|
|
*/
|
|
typedef IP_PACKED1 union Ipnet_pkt_union_union
|
|
{
|
|
#ifdef IPCOM_USE_INET
|
|
Ipnet_pkt_icmp icmp;
|
|
#endif
|
|
Ipnet_pkt_udp udp;
|
|
}
|
|
IP_PACKED2 IP_Ipnet_pkt_union;
|
|
#include "ipcom_align16.h"
|
|
|
|
|
|
/*
|
|
* Packet information describing how much of the socket send buffer
|
|
* this packet occupies
|
|
*/
|
|
typedef struct Ipnet_pkt_info_sock_snd_buf_struct
|
|
{
|
|
/*
|
|
* Pointer to the socket used to sent this packet. Direct pointer
|
|
* is OK since the socket will not be freed until the send buffer
|
|
* is ==0
|
|
*/
|
|
struct Ipnet_socket_struct *sock;
|
|
/*
|
|
* Number of bytes this packet has reserved in the send buffer. Is
|
|
* always >0
|
|
*/
|
|
int payload_len;
|
|
}
|
|
Ipnet_pkt_info_sock_snd_buf;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_init_f
|
|
*===========================================================================
|
|
* Description: Called last in the socket creation and can proviced custom
|
|
* initialization of the socket.
|
|
* Parameters: sock - The affected socket.
|
|
* user_context - IP_TRUE if called in the context of a user process
|
|
* IP_FALSE if called in the context of the kernel.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_init_f)(struct Ipnet_socket_struct *sock,
|
|
Ip_bool user_context);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_destroy_f
|
|
*===========================================================================
|
|
* Description: Called when the socket is going to be deleted.
|
|
* Can contain domain specific cleanups.
|
|
* Parameters: sock - The affected socket.
|
|
* Returns:
|
|
*
|
|
*/
|
|
typedef void (*Ipnet_sock_destroy_f)(struct Ipnet_socket_struct *sock);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_close_f
|
|
*===========================================================================
|
|
* Description: Called when the socket is beeing closed. Should be defined
|
|
* if special handling, not done by shutdown(sock, IP_SHUT_RDWR),
|
|
* is required.
|
|
* Parameters: sock - The affected socket.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_close_f)(struct Ipnet_socket_struct *sock);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_lookup_f
|
|
*===========================================================================
|
|
* Description: Returns the first socket that matches the specified parameters.
|
|
* Parameters: vr - The virtual route table the socket must match.
|
|
* proto - the protocol to match.
|
|
* local_addr - the local address to match or IP_NULL for any address.
|
|
* local_port - the local port to match or 0 for any port.
|
|
* peer_addr - the peer address to match or IP_NULL for any address.
|
|
* peer_port - the peer port to match or 0 for any port.
|
|
* first - [in] the socket descriptor to from where the scan should start
|
|
* [out] the socket descriptor to start the next search from.
|
|
* set to IP_NULL to start from 0.
|
|
* Returns: The matching socket or IP_NULL if no socket (from [*first..sock_max]
|
|
* matched.
|
|
*
|
|
*/
|
|
typedef struct Ipnet_socket_struct *
|
|
(*Ipnet_sock_lookup_f)(Ip_u16 vr, int proto,
|
|
IP_CONST void *local_addr, Ip_u16 local_port,
|
|
IP_CONST void *peer_addr, Ip_u16 peer_port);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_send_f
|
|
*===========================================================================
|
|
* Description: Send handler for the domain/type/protocol tuple
|
|
* Parameters: sock - The socket the packet beeing sent on.
|
|
* msg - Message structure with (unconnected sockets) destination
|
|
* address and (optional) auxillary data. Can be IP_NULL
|
|
* if the socket is connected and no auxillary data is
|
|
* needed. 'msg_flags' contains the flags passed
|
|
* in the 'flags' field to ipcom_sendmsg().
|
|
*
|
|
* pkt - The
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_send_f)(struct Ipnet_socket_struct *sock,
|
|
IP_CONST struct Ip_msghdr *msg,
|
|
Ipcom_pkt *pkt);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_bind_f
|
|
*===========================================================================
|
|
* Description: Binds a socket.
|
|
* Parameters: sock - The socket to bind.
|
|
* name - The socket name.
|
|
* namelen - The length of the name variable.
|
|
* user_context - IP_TRUE if called in the context of a user process
|
|
* IP_FALSE if called in the context of the kernel.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_bind_f)(struct Ipnet_socket_struct *sock,
|
|
IP_CONST struct Ip_sockaddr *name,
|
|
Ip_socklen_t namelen,
|
|
Ip_bool user_context);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_connect_f
|
|
*===========================================================================
|
|
* Description: Binds a socket.
|
|
* Parameters: sock - The socket to bind.
|
|
* name - The socket name.
|
|
* namelen - The length of the name variable.
|
|
* check_reuse - Set to IP_TRUE if the name should be checked
|
|
* for address reuse.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_connect_f)(struct Ipnet_socket_struct *sock,
|
|
IP_CONST struct Ip_sockaddr *to,
|
|
Ip_socklen_t tolen);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_shutdown_f
|
|
*===========================================================================
|
|
* Description: Shutdown read and/or write end of the socket, IPNET
|
|
* takes care of flagging the socket read/write end as shut,
|
|
* and notifies blocked sockets. Protocol specific things has
|
|
* to be done in this handler though (like sending FIN for TCP).
|
|
* Parameters: sock - The socket to shutdown.
|
|
* how - IP_SHUT_xxx constant.
|
|
* Returns:
|
|
*
|
|
*/
|
|
typedef void (*Ipnet_sock_shutdown_f)(struct Ipnet_socket_struct *sock, int how);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_accept_f
|
|
*===========================================================================
|
|
* Description: Accepts a socket.
|
|
* Parameters: sock - The socket to bind.
|
|
* name - The address of the accepted socket.
|
|
* namelen - The length of the name variable.
|
|
* Returns: >=0 = success (file descripto), <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_accept_f)(struct Ipnet_socket_struct *sock,
|
|
struct Ip_sockaddr *name,
|
|
Ip_socklen_t *namelen);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_listen_f
|
|
*===========================================================================
|
|
* Description: Puts a socket in listen mode.
|
|
* Parameters: sock - The socket to put in listen mode.
|
|
* backlog - The size of the socket backlog.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_listen_f)(struct Ipnet_socket_struct *sock,
|
|
int backlog);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_setopt_f
|
|
*===========================================================================
|
|
* Description: Handles socket option.
|
|
* Parameters: sock - The socket to set an option on.
|
|
* level - The protocol level that should be affected by the
|
|
* option.
|
|
* optname - The option name.
|
|
* optval - Data to set for the option.
|
|
* optlen - The length of the buffer pointed to by optval.
|
|
* Returns: 0 = success,
|
|
* -IP_ERRNO_EOPNOTSUPP = This handler does not implement this option,
|
|
* try other handlers
|
|
* <0 = error code (-IPNET_ERRNO_xxx), do not try other handlers
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_setopt_f)(struct Ipnet_socket_struct *sock,
|
|
int level,
|
|
int optname,
|
|
IP_CONST void *optval,
|
|
Ip_socklen_t optlen);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_getopt_f
|
|
*===========================================================================
|
|
* Description: Handles socket option.
|
|
* Parameters: sock - The socket to get an option from.
|
|
* level - The protocol level that should be affected by the
|
|
* option.
|
|
* optname - The option name.
|
|
* optval - Data to set for the option.
|
|
* optlen - The length of 'optval' when calling,
|
|
* number of bytes copied to 'optval' when returning.
|
|
* Returns: 0 = success,
|
|
* -IP_ERRNO_EOPNOTSUPP = This handler does not implement this option,
|
|
* try other handlers
|
|
* <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_getopt_f)(struct Ipnet_socket_struct *sock,
|
|
int level,
|
|
int optname,
|
|
void *optval,
|
|
Ip_socklen_t *optlen);
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_getname_f
|
|
*===========================================================================
|
|
* Description: Returns the local name (or address) of the socket.
|
|
* Parameters: sock - The socket to return the name for.
|
|
* name - Buffer where the name will be stored.
|
|
* namelen - The length of the 'name' buffer.
|
|
* is_local_name - Is set to IP_TRUE of the local name of the
|
|
* socket should be returned, IP_FALSE means that the peer name
|
|
* should be returned.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_getname_f)(struct Ipnet_socket_struct *sock,
|
|
struct Ip_sockaddr *name,
|
|
Ip_socklen_t *namelen,
|
|
Ip_bool is_local_name);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_ioctl_f
|
|
*===========================================================================
|
|
* Description: Handles IO control on the socket.
|
|
* Parameters: sock - The socket to get an option from.
|
|
* request - The IO control request.
|
|
* argp - Request specific data.
|
|
* Returns: 0 = success,
|
|
* <0 = error code (-IPNET_ERRNO_xxx)
|
|
* -IP_ERRNO_EOPNOTSUPP = This handler does not implement this option,
|
|
* try other handlers
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_sock_ioctl_f)(struct Ipnet_socket_struct *sock,
|
|
unsigned long request, void *argp);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_usr_sock_recv_f
|
|
*===========================================================================
|
|
* Description: Called in context of the receiving task. Proper
|
|
* locking must be done by the this function to
|
|
* safely extract the data from the socket.
|
|
* Parameters: sock - The socket to receive from.
|
|
* msg - 'msg_iov' contains the buffer(s) to where the
|
|
* received data should be copied.
|
|
* flags - IP_MSG_xxx flags.
|
|
* Returns: 0 = success, <0 = error code (-IPNET_ERRNO_xxx)
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_usr_sock_recv_f)(struct Ipnet_socket_struct *sock,
|
|
struct Ip_msghdr *msg,
|
|
int flags);
|
|
|
|
typedef struct Ipnet_pkt_result_struct
|
|
{
|
|
Ipcom_pkt * pkt;
|
|
/*
|
|
* The transient_err will generally be 0 for datagram sockets.
|
|
* However, for stream sockets, short writes may be possible if the
|
|
* Ipnet_usr_sock_pkts_from_iov_f function is interrupted by
|
|
* a signal or a deletion attempt.
|
|
*/
|
|
int transient_err; /* 0 or IP_ERRNO_EINTR or IP_ERRNO_EDOOM */
|
|
} Ipnet_pkt_result;
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_usr_sock_pkts_from_iov_f
|
|
*===========================================================================
|
|
* Description: Called in context of the sending task. Proper
|
|
* locking must be done by the this function if
|
|
* members of the socket are read or modified.
|
|
* Parameters: sock - The socket that will be use to send.
|
|
* msg - 'msg_iov' contains the buffer(s) to send.
|
|
* flags - IP_MSG_xxx flags.
|
|
* offset - Number of bytes into the msg->msg_iov buffers
|
|
* where the copy into packets should start.
|
|
* total_buf_len - the sum of the length of all
|
|
* msg->msg_iov buffers in 'msg'.
|
|
* prslt - Points to result structure where the constructed packet
|
|
* and transient error (if any) are returned.
|
|
* prslt->pkt->next points to the next packet in case
|
|
* more than one packet was allocated.
|
|
* Returns: <0 = error code (-IPNET_ERRNO_xxx)
|
|
* 0 = this operation released the socket lock, the
|
|
* sendmsg operation must be restarted
|
|
* >0 = number of bytes that have been allocated in the
|
|
* socket send buffer and copied into the
|
|
* packet(s) pointed to by prslt->pkt.
|
|
*
|
|
*/
|
|
typedef int (*Ipnet_usr_sock_pkts_from_iov_f)(struct Ipnet_socket_struct *sock,
|
|
IP_CONST struct Ip_msghdr *msg,
|
|
int flags,
|
|
int offset,
|
|
int total_buf_len,
|
|
Ipnet_pkt_result *prslt);
|
|
|
|
|
|
/*
|
|
* Socket operations for a domain/type/proto tuple, functions can be
|
|
* left as IP_NULL if that operation is not supported
|
|
*/
|
|
typedef struct Ipnet_sock_ops_struct
|
|
{
|
|
int domain; /* The domain this operations is valid for */
|
|
int type; /* The socket type operations is valid for */
|
|
int proto; /* The protocol or -1 for any protocol */
|
|
Ip_size_t extra_sock_space; /* Extra space to be allocated at the end of the socket */
|
|
Ip_size_t hdr_space; /* Minimum header space needed at by the domain/type/proto */
|
|
Ip_bool allow_async_send; /* IP_TRUE if this socket type allows asynchronous send */
|
|
Ipnet_sock_accept_f accept;
|
|
Ipnet_sock_bind_f bind;
|
|
Ipnet_sock_close_f close;
|
|
Ipnet_sock_connect_f connect;
|
|
Ipnet_sock_destroy_f destroy;
|
|
Ipnet_sock_getname_f getname;
|
|
Ipnet_sock_getopt_f getopt;
|
|
Ipnet_sock_init_f init;
|
|
Ipnet_sock_ioctl_f ioctl;
|
|
Ipnet_sock_listen_f listen;
|
|
Ipnet_sock_lookup_f lookup;
|
|
Ipnet_sock_send_f send;
|
|
Ipnet_sock_setopt_f setopt;
|
|
Ipnet_sock_shutdown_f shutdown;
|
|
|
|
Ipnet_usr_sock_recv_f usr_recv;
|
|
Ipnet_usr_sock_pkts_from_iov_f pkts_from_iov;
|
|
}
|
|
Ipnet_sock_ops;
|
|
|
|
|
|
|
|
/*
|
|
* Internal socket structure used by IPNET to implement IP_AF_INET and
|
|
* IP_AF_INET 6
|
|
*/
|
|
typedef struct Ipnet_sock_inet_ops_struct
|
|
{
|
|
Ipnet_sock_ops sock;
|
|
Ipnet_sock_bind_f network_bind;
|
|
Ipnet_sock_send_f network_send;
|
|
}
|
|
Ipnet_sock_inet_ops;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_dynhdrspc
|
|
*===========================================================================
|
|
* Description: Returns the number of octets that must be allocated to fit
|
|
* IP options and/or extension headers.
|
|
* Parameters: sock - The socket used to send the datagram.
|
|
* msg - The message data passed to ipcom_sendmsg().
|
|
* Returns: Number of extra octets that must be allocated.
|
|
*
|
|
*/
|
|
typedef Ip_size_t (*Ipnet_dynhdrspc)(struct Ipnet_socket_struct *sock,
|
|
IP_CONST struct Ip_msghdr *msg);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_is_sock_ready_cb
|
|
*===========================================================================
|
|
* Description: Callback that will determine if the specified socket
|
|
* is ready or not.
|
|
* Parameters: sock - a socket.
|
|
* lowat - minimum number of bytes that has to be
|
|
* available in the send/receive buffer in order to
|
|
* consider the socket to be writable/readable. 0
|
|
* means that the socket default value should be used.
|
|
* Returns: IP_TRUE if the socket is ready.
|
|
*
|
|
*/
|
|
typedef Ip_bool (*Ipnet_is_sock_ready_cb)(struct Ipnet_socket_struct *sock,
|
|
int lowat);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_transport_layer_rx_func
|
|
*===========================================================================
|
|
* Description: Handler for a specific IPv4/IPv6 payload protcol. The packet
|
|
* ownership is transfered to the handler.
|
|
* Parameters: dst - destination cache for the flow used by the packet.
|
|
* pkt - packat that is being delivered
|
|
* Returns:
|
|
*
|
|
*/
|
|
typedef void (*Ipnet_transport_layer_rx_func)(struct Ipnet_dst_cache_struct *dst,
|
|
Ipcom_pkt *pkt);
|
|
|
|
|
|
|
|
#ifdef IPCOM_FORWARDER_NAE
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_sock_nae_rx_func
|
|
*===========================================================================
|
|
* Description: Handler for reception on a specific
|
|
* socket. Applications running within a NAE would
|
|
* use this to get notification.
|
|
* Parameters: fd - socket matching the received packet.
|
|
* pkt - the received packet.
|
|
* ctx - user defined context data.
|
|
* Returns:
|
|
*
|
|
*/
|
|
typedef void (*Ipnet_sock_nae_rx_func)(int fd,
|
|
Ipcom_pkt *pkt,
|
|
void *ctx);
|
|
#endif
|
|
|
|
#ifdef IPCOM_ATOMIC_TAG_VIA_SPINLOCK
|
|
#define ipcom_nae_socket_atomic(sock) ipcom_nae_switch_to_lock(&sock->nae_lock)
|
|
#define ipcom_nae_socket_ordered(sock) ipcom_nae_switch_to_null()
|
|
#define ipcom_nae_socket_is_atomic(sock) ipcom_nae_is_locked(&sock->nae_lock)
|
|
#else
|
|
#define ipcom_nae_socket_atomic(sock) ipcom_nae_switch_to_atomic(sock->atomic_tag)
|
|
#define ipcom_nae_socket_ordered(sock) ipcom_nae_switch_to_ordered(sock->atomic_tag)
|
|
#define ipcom_nae_socket_is_atomic(sock) ipcom_nae_is_atomic(sock->atomic_tag)
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_socket
|
|
*===========================================================================
|
|
*/
|
|
typedef struct Ipnet_socket_struct
|
|
{
|
|
Ipcom_socket ipcom; /* Generic socket parameters */
|
|
Ipcom_atomic_t ref_count; /* Socket reference count */
|
|
Ip_u32 flags; /* Socket flags. */
|
|
int ops_handle; /* Handle for the socket
|
|
operations for this socket */
|
|
void *signal;
|
|
#ifdef IPCOM_FORWARDER_NAE
|
|
#ifdef IPCOM_ATOMIC_TAG_VIA_SPINLOCK
|
|
Ipcom_ipc_spinlock_t nae_lock;
|
|
#else
|
|
/*
|
|
* The tag parameter to use in ipcom_switch_to_atomic() before any
|
|
* member of this structure can be accessed.
|
|
*/
|
|
unsigned atomic_tag;
|
|
#endif
|
|
/*
|
|
* User specific data that will be passed verbatim to the
|
|
* nae_rx_action/nae_rx_notifier function.
|
|
* NOTE: must point to memory that is accessable by all NAE:s,
|
|
* i.e. shared memory.
|
|
*/
|
|
void *nae_action_ctx;
|
|
|
|
/*
|
|
* Must take care of the packet, it will not be queued on the
|
|
* socket if this handler is set. The 'nae_rx_action' contains
|
|
* the name of the function. The action handler is called via
|
|
* ipnet_sock_rx_action() which will locate the function with
|
|
* that name and store the address in the 'nae_rx_action_funcs'
|
|
* array. The NAE instance number is used as index in the array.
|
|
*/
|
|
char *nae_rx_action;
|
|
Ipnet_sock_nae_rx_func nae_rx_action_funcs[IPCOM_MAX_NAE];
|
|
|
|
/*
|
|
* Is called when the a new packet has been queued on the
|
|
* socket. The 'nae_rx_notifier' contains the name of the
|
|
* function. The action handler is called via
|
|
* ipnet_sock_rx_notifier() which will locate the function with
|
|
* that name and store the address in the 'nae_rx_notifier_funcs'
|
|
* array. The NAE instance number is used as index in the array.
|
|
*/
|
|
char *nae_rx_notifier;
|
|
Ipnet_sock_nae_rx_func nae_rx_notifier_funcs[IPCOM_MAX_NAE];
|
|
|
|
/*
|
|
* Action handler that TCP/SCTP listen socket will assign to all
|
|
* child sockets spawned from it.
|
|
*/
|
|
char *nae_rx_child_action;
|
|
|
|
#else
|
|
/*
|
|
* Address removal notifications cannot be used in a NAE since the
|
|
* address structures are per-NAE and the sockets are shared
|
|
* between NAE:s.
|
|
*/
|
|
struct Ipnet_socket_struct *addr_prev; /* Previous socket bound to the same address */
|
|
struct Ipnet_socket_struct *addr_next; /* Next socket bound to the same address */
|
|
void *addr_entry; /* Pointer to the address entry for the bind address */
|
|
#endif /* IPCOM_FORWARDER_NAE */
|
|
|
|
/*
|
|
* List of reachable sockets hashing to the same
|
|
* ipnet->reachable_sockets bucket.
|
|
*/
|
|
Ipcom_list reachable_list;
|
|
|
|
/*
|
|
* Points to the first socket in the 'ipnet->reachable_sockets'
|
|
* bucket that share the same socket lookup tuple. This pointer is
|
|
* IP_NULL if this is the only socket with a specific tuple.
|
|
*/
|
|
struct Ipnet_socket_struct *first_sibling;
|
|
|
|
Ip_u16 proto; /* Protocol */
|
|
Ip_u16 vr_index; /* The virtual router to use when sending/receiving packets on this socket */
|
|
|
|
Ip_u16 max_hdrspace; /* Maximum needed header space for network (IP) and transport layer. */
|
|
Ip_u16 chk_offset; /* Offset into the transport layer (TCP, UDP, e.t.c) where the
|
|
16 bit internet checksum should be stored, used if the flag
|
|
IPNET_SOCKET_FLAG_ADDCHECKSUM is set */
|
|
|
|
Ip_u16 sport; /* Source port. */
|
|
Ip_u16 dport; /* Destination port. */
|
|
struct Ip_sockaddr_storage last_to; /* Address of the node to which something was last sent on this socket */
|
|
Ip_u16 biggest_msg_size_in_sync; /* The biggest successfully send msg size in using synchronous mode */
|
|
Ip_u8 large_send_countdown; /* The count of successfully sending large msg on this socket.
|
|
If it is 0, must use synchronous send. */
|
|
|
|
#ifdef IPNET_USE_PER_SOCKET_VLAN_TAG
|
|
Ip_u16 vlan_tag; /* Bit 0-2 is priority,
|
|
bit 3 is priority tagging on/off
|
|
bit 4-15 is the VLAN tag */
|
|
#endif
|
|
Ip_u16 udplite_sum_cov; /* Number of bytes covered by the RFC3828 UDP-Lite
|
|
checksum. Must be 0 (all bytes), or >=8 */
|
|
|
|
Ip_u8 uni_hop_limit; /* The hop limit for unicast packtes */
|
|
Ip_u8 multi_hop_limit; /* The hop limit for multicast packtes */
|
|
Ip_u8 promisc_count; /* Number of times promisc mode has been entered on this socket */
|
|
Ip_u8 udp_encapsulation; /* UDP encapsulation method */
|
|
|
|
Ip_u32 bind_to_ifindex; /* The interface this socket is
|
|
bound to (with
|
|
IP_SO_BINDTODEVICE). ==0
|
|
-> not bound */
|
|
#ifdef IPNET_USE_RFC2890
|
|
Ip_u32 gre_key; /* GRE key for this socket */
|
|
#endif
|
|
int keep_alive_probe_delay; /* Number of seconds an TCP
|
|
connection must be idle
|
|
before the first keep-alive
|
|
probe is sent */
|
|
|
|
Ipcom_pkt_dtor pkt_dtor; /* Packet destruction that most
|
|
be used for packets sent
|
|
using this socket */
|
|
|
|
Ipnet_dynhdrspc dynamic_header_space;
|
|
|
|
int send_max_bytes; /* Max number of bytes that can be stored in the send buffer */
|
|
int recv_max_bytes; /* Max number of bytes that can be stored in the recieve buffer */
|
|
|
|
int snd_route_cache_id; /* Value of ipnet->route_cache_id at last successful send */
|
|
Ipcom_atomic_t snd_bytes; /* Bytes in send buffer */
|
|
Ipcom_atomic_t waiting_writers; /* Number of waiting writers on this socket */
|
|
|
|
Ipcom_pkt *snd_head; /* Output queue, only used if IP_MSG_MORE flag is used */
|
|
struct Ip_sockaddr *snd_to; /* Cached to address specified in a sendmsg() with IP_MSG_MORE */
|
|
|
|
/*
|
|
* Variables used by protocols that is datagram based, the TCP
|
|
* receive queue is found in 'tcb'
|
|
*/
|
|
Ipcom_spinlock rcv_lock; /* Must be locked when modifying
|
|
rcv_head, rcv_tail and
|
|
ipcom.rcv_bytes */
|
|
|
|
Ipcom_pkt *rcv_head; /* Input packet queue head, pkt->start is the offset
|
|
to the transport layer header. */
|
|
Ipcom_pkt *rcv_tail; /* Input packet queue tail. */
|
|
|
|
/*
|
|
* Synchronization objects used when receiving data
|
|
*/
|
|
struct Ip_timeval *rcv_timeout; /* Time that a blocking
|
|
ipcom_recv can bloc, IP_NULL
|
|
means infinite time */
|
|
#ifdef IPNET_USE_SO_CONNTIMEO
|
|
struct Ip_timeval *conn_timeout; /* Time that for connectWithTimeout */
|
|
#endif
|
|
|
|
/*
|
|
* List of struct Ipnet_sig_poll instances added by task(s) that
|
|
* are waiting for the socket to become readable, writable and/or
|
|
* exceptional
|
|
*/
|
|
Ipcom_list poll_list_head;
|
|
|
|
#ifdef IPTCP
|
|
struct Iptcp_tcb_struct *tcb; /* Transmission control block (used by TCP) */
|
|
void (*notify_cb)(struct Ipnet_socket_struct *sock, int event); /* See Iptcp_notifycb in iptcp.h */
|
|
#endif
|
|
#ifdef IPSCTP
|
|
struct Ipsctp_instance_struct *sctp_inst; /* Transmission control block (used by SCTP) */
|
|
#endif
|
|
|
|
#if defined(IP_PORT_VXWORKS) && defined(IPCOM_USE_SOCK_COMPAT)
|
|
void *select_ctx;
|
|
#ifdef IPNET_SO_WAKEUP_HOOK
|
|
void *windnet_so;
|
|
#endif
|
|
#endif
|
|
|
|
void *sock_end; /* The current end of the socket, used to set up layer specific space */
|
|
|
|
Ip_u32 timestamp_flag; /* Socket timestamp flag. */
|
|
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
Ipnet_ip4_socket *ip4;
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
Ipnet_ip6_socket *ip6;
|
|
#endif
|
|
#ifdef IPCOM_USE_PACKET
|
|
Ipnet_packet_socket *ps;
|
|
#endif
|
|
#ifdef IPNET_USE_NETLINKSOCK
|
|
Ipnet_netlink_socket *nl;
|
|
#endif
|
|
|
|
/* !NOTE! do not put any struct members below this point */
|
|
}
|
|
Ipnet_socket;
|
|
|
|
/* socket flags. */
|
|
/* Flags controlled by socket options */
|
|
#define IPNET_SOCKET_FLAG_REUSEADDR (1u << 0) /* Resuse of address is ok */
|
|
#define IPNET_SOCKET_FLAG_REUSEPORT (1u << 1) /* Resuse of port and address is ok */
|
|
#define IPNET_SOCKET_FLAG_DONTROUTE (1u << 2) /* Bypass routing for outgoing messages */
|
|
#define IPNET_SOCKET_FLAG_LOOP_MULTICAST (1u << 3) /* Loopback multicast packets sent from this host */
|
|
#define IPNET_SOCKET_FLAG_TCP_NODELAY (1u << 4) /* Nagle algorithm is OFF when this flag is set */
|
|
#define IPNET_SOCKET_FLAG_RECV_IF (1u << 5) /* Returns the recv if for datagram proto */
|
|
#define IPNET_SOCKET_FLAG_RECVPKTINFO (1u << 6) /* Returns extra information about received packets */
|
|
#define IPNET_SOCKET_FLAG_KEEPALIVE (1u << 7) /* Probe idle connection */
|
|
#define IPNET_SOCKET_FLAG_NONBLOCKING (1u << 8) /* Socket is in non-blocking mode */
|
|
#define IPNET_SOCKET_FLAG_ADDCHECKSUM (1u << 9) /* Pseudo header checksum should be added to outgoing packets */
|
|
#define IPNET_SOCKET_FLAG_OOBINLINE (1u << 10) /* Out-of-band data should be mixed with normal data */
|
|
#define IPNET_SOCKET_FLAG_SENDER_LINK_ADDR (1u << 11) /* Get link address of sender */
|
|
|
|
/* Socket long term state */
|
|
#define IPNET_SOCKET_FLAG_REACHABLE (1u << 12) /* Set if the socket can match incoming packets */
|
|
#define IPNET_SOCKET_FLAG_BOUND (1u << 13) /* Socket is bound (explicit or implicit) */
|
|
#define IPNET_SOCKET_FLAG_CONNECTING (1u << 14) /* Asynchronous connect in progress */
|
|
#define IPNET_SOCKET_FLAG_CONNECTED (1u << 15) /* Socket is connected */
|
|
|
|
#define IPNET_SOCKET_FLAG_READ_CLOSED (1u << 16) /* The read end of the socket is closed */
|
|
#define IPNET_SOCKET_FLAG_WRITE_CLOSED (1u << 17) /* The write end of the socket is closed */
|
|
#define IPNET_SOCKET_FLAG_PEER_WRITE_CLOSED (1u << 18) /* The peer has closed its write end */
|
|
#define IPNET_SOCKET_FLAG_CLOSED (1u << 19) /* The socket has been closed */
|
|
#define IPNET_SOCKET_FLAG_DONT_REBIND (1u << 20) /* Never rebind the socket regardless of source address */
|
|
|
|
#define IPNET_SOCKET_FLAG_MROUTE_CONTROL (1u << 23) /* This socket is used for multicast routing control */
|
|
#define IPNET_SOCKET_FLAG_DRAINABLE (1u << 24) /* Packets queued on this socket might be freed
|
|
in order to satisfy a packet allocation call */
|
|
#define IPNET_SOCKET_FLAG_GRE_KEY (1u << 25) /* Socket has a RFC 2890 key set */
|
|
|
|
/* Socket short term state */
|
|
#define IPNET_SOCKET_FLAG_PKTAVAIL_CB_PENDING (1u << 27) /* This socket want an IP_SOEVENT_CB_PKTAVAIL event when
|
|
the next packet is freed */
|
|
|
|
/* Misc. */
|
|
#define IPNET_SOCKET_FLAG_TIMESTAMPING (1u << 28)
|
|
#define IPNET_SOCKET_FLAG_DEBUG (1u << 29) /* Debug is enabled */
|
|
#define IPNET_SOCKET_FLAG_HAS_STICKY_OPT (1u << 30) /* At least 1 sticky option is set */
|
|
#define IPNET_SOCKET_FLAG_SENDMSG_ASYNCHRONOUS (1u << 31)
|
|
|
|
/* socket start index (0,1,2 are reserved) */
|
|
#define IPNET_SOCKET_STARTFD 3
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_socket_lookup_key
|
|
*===========================================================================
|
|
*/
|
|
typedef struct Ipnet_socket_lookup_key_struct
|
|
{
|
|
Ip_u32 vr; /* The virtual router the socket must be assigned to */
|
|
Ip_u16 domain; /* The domain this socket must be part of */
|
|
Ip_u16 proto; /* The protocol the socket must use */
|
|
Ip_u16 local_port; /* The local port the socket must bound to */
|
|
Ip_u16 peer_port; /* The peer port the socket must connected to */
|
|
union Ip_in_addr_union local_addr; /* The local address */
|
|
union Ip_in_addr_union peer_addr; /* The peer address */
|
|
}
|
|
Ipnet_socket_lookup_key;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_stats
|
|
*===========================================================================
|
|
* IPNET debug statistics useful for debugging the stack if things go wrong.
|
|
*/
|
|
#if defined(IPNET_DEBUG) || defined(IPNET_STATISTICS)
|
|
typedef struct Ipnet_stats_struct
|
|
{
|
|
int pkt_num_tcp_out_of_order_seg;
|
|
int pkt_num_ip4_reassembly_list;
|
|
int pkt_num_ip6_reassembly_list;
|
|
|
|
int pkt_input;
|
|
int pkt_input_err;
|
|
int pkt_input_opened_err;
|
|
int pkt_input_bound_to_other_if;
|
|
int pkt_input_queue_full;
|
|
int pkt_drain_ip4_reasm;
|
|
int pkt_drain_ip6_reasm;
|
|
int pkt_clone_nomem;
|
|
int pkt_frag_nomem;
|
|
int pkt_reasm_nomem;
|
|
int pkt_reasm_too_big;
|
|
int pkt_queue_enobufs;
|
|
int pkt_queue_emsgsize;
|
|
|
|
int pkt_output;
|
|
int pkt_output_drv;
|
|
int pkt_output_ewouldblock; /* errors other than non-blocking. */
|
|
int pkt_output_err; /* errors other than non-blocking. */
|
|
int pkt_output_queue;
|
|
int pkt_output_discard;
|
|
int pkt_output_delayed;
|
|
int pkt_output_sleep;
|
|
int pkt_output_requeue;
|
|
int pkt_output_fast_drv_ready;
|
|
|
|
int pkt_netif_output_done;
|
|
int pkt_netif_output_done_pkt;
|
|
int pkt_netif_output_done_discard;
|
|
int pkt_netif_output_delayed_queue;
|
|
int pkt_netif_output_delayed_wake;
|
|
int pkt_netif_output_user_wake;
|
|
int pkt_inputd_output;
|
|
int pkt_inputd_output_err;
|
|
int pkt_inputd_output_ewouldblock;
|
|
int pkt_inputd_output_err_nonetif;
|
|
|
|
int eth_input;
|
|
int eth_input_down;
|
|
int eth_input_arp;
|
|
int eth_input_arp_unknown;
|
|
int eth_input_arp_bad;
|
|
int eth_input_arp_reperr;
|
|
int eth_input_arp_reqother;
|
|
int eth_input_ip4;
|
|
int eth_input_ip6;
|
|
int eth_input_other;
|
|
int eth_output_ip4;
|
|
int eth_output_ip4_err;
|
|
int eth_output_ip4_drverr;
|
|
int eth_output_ip4_multierr;
|
|
int eth_output_ip6;
|
|
int eth_output_ip6_err;
|
|
int eth_output_ip6_drverr;
|
|
int eth_output_arp_req;
|
|
int eth_output_arp_req_nomem;
|
|
int eth_output_arp_rep;
|
|
|
|
#if defined(IPNET_USE_VLAN) || defined(IPNET_USE_VLAN_STACKING)
|
|
int vlan_input_no_match;
|
|
int vlan_input_down;
|
|
#ifdef IPNET_USE_VLAN_STACKING
|
|
int eth_output_vlan;
|
|
int eth_output_vlan_drverr;
|
|
#endif /* IPNET_USE_VLAN_STACKING */
|
|
#endif /* IPNET_USE_VLAN || IPNET_USE_VLAN_STACKING */
|
|
|
|
#ifdef IPNET_USE_BOND
|
|
int bond_input_no_match;
|
|
int bond_input_down;
|
|
#endif /* IPNET_USE_BOND */
|
|
|
|
int ip4_input;
|
|
int ip4_input_err;
|
|
int ip4_input_hdr_trunc;
|
|
int ip4_input_hdr_toolong;
|
|
int ip4_input_inval_len;
|
|
int ip4_input_inval_version;
|
|
int ip4_input_not_to_me;
|
|
int ip4_input_iph_badchksum;
|
|
int ip4_input_reasm_enobufs;
|
|
int ip4_input_time_exceeded;
|
|
int ip4_input_need_frag;
|
|
|
|
int ip4_output;
|
|
int ip4_output_blackhole;
|
|
int ip4_output_hdr_space;
|
|
int ip4_output_noroute;
|
|
int ip4_output_enobufs;
|
|
int ip4_output_link_err;
|
|
|
|
int icmp4_input;
|
|
int icmp4_input_echo_request;
|
|
int icmp4_input_dst_unreach;
|
|
int icmp4_input_dst_unreach_match;
|
|
int icmp4_input_dst_unreach_nomatch;
|
|
int icmp4_input_dst_unreach_badcode;
|
|
int icmp4_input_hdrsize;
|
|
int icmp4_input_badchksum;
|
|
int icmp4_input_hdrsize2;
|
|
int icmp4_send;
|
|
int icmp4_send_nomem;
|
|
|
|
int ip6_input;
|
|
int ip6_input_err;
|
|
int ip6_input_hdr_trunc;
|
|
int ip6_input_inval_len;
|
|
int ip6_input_inval_exthdr;
|
|
int ip6_input_not_to_me;
|
|
int ip6_input_too_big;
|
|
int ip6_input_time_exceeded;
|
|
int ip6_input_too_short;
|
|
int ip6_input_tcp_multicast;
|
|
int ip6_input_prot_err;
|
|
int ip6_input_hdr_no_next;
|
|
int ip6_input_raw;
|
|
|
|
int ip6_output;
|
|
int ip6_output_err;
|
|
int ip6_output_blackhole;
|
|
int ip6_output_hdr_space;
|
|
int ip6_output_noroute;
|
|
int ip6_output_nomem;
|
|
int ip6_output_enobufs;
|
|
int ip6_output_err_probe;
|
|
int ip6_output_link_err;
|
|
|
|
int icmp6_input;
|
|
int icmp6_input_err;
|
|
int icmp6_input_badchksum;
|
|
int icmp6_input_nomem;
|
|
|
|
int icmp6_send_nomem;
|
|
|
|
int udp4_input;
|
|
int udp4_input_ok;
|
|
int udp4_input_err;
|
|
|
|
int tcp4_input;
|
|
int tcp4_input_ok;
|
|
int tcp4_input_err;
|
|
|
|
int raw4_input;
|
|
int raw6_input;
|
|
int raw_input_badchksum;
|
|
|
|
int udp_input;
|
|
int udp_input_hdr_trunc;
|
|
int udp_input_badchksum;
|
|
int udp_input_sock_multicast;
|
|
int udp_input_sock_match;
|
|
int udp_input_sock_nomatch;
|
|
int udp_input_queue_pkt_ok;
|
|
int udp_input_queue_pkt_err;
|
|
int udp_input_multicast;
|
|
int udp_input_econnrefused;
|
|
int udp_output;
|
|
int udp_output_hdr_trunc;
|
|
int udp_output_eaddrinuse;
|
|
int udp_output_eafnosupport;
|
|
|
|
int sock_ebadf;
|
|
|
|
int sock_sendmsg;
|
|
|
|
int sock_recvmsg;
|
|
int sock_recvmsg_tcp_err;
|
|
int sock_recvmsg_err;
|
|
|
|
int usr_sock_recvmsg;
|
|
int usr_sock_recvmsg_ewouldblock;
|
|
|
|
int usr_iov_emsgsize;
|
|
int usr_iov_nomem;
|
|
|
|
int neigh_pending;
|
|
int neigh_pending_drop;
|
|
}
|
|
Ipnet_stats;
|
|
|
|
#define IPNET_STATS(xvar) ipnet->stats.xvar
|
|
#define IPNET_STAT_LINE(xline) xline
|
|
|
|
#else
|
|
#define IPNET_STATS(xvar) IP_NOOP
|
|
#define IPNET_STAT_LINE(xline) IP_NOOP
|
|
#endif
|
|
|
|
#ifdef IPNET_USE_DIFFSERV
|
|
typedef struct Ipnet_diffserv_data_struct
|
|
{
|
|
/* Array of diffserv handlers */
|
|
Ipnet_diffserv_handlers *handlers[IPNET_DIFFSERV_MAX_HANDLERS];
|
|
/* Database of meter/marker constructors */
|
|
Ipcom_hash *meter_marker_ctor_db;
|
|
#ifdef IPNET_DIFFSERV_CLASSIFIER_MODE_BA
|
|
/* Defines which marker/meter to use for each traffic class */
|
|
Ip_u32 mapping_active[8];
|
|
Ip_u8 ds_to_handler_map[256];
|
|
#else
|
|
/* The classifier used by diffserv */
|
|
Ipnet_classifier *classifier;
|
|
#endif
|
|
}
|
|
Ipnet_diffserv_data;
|
|
#endif /* IPNET_USE_DIFFSERV */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_inq
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
typedef struct Ipnet_input_queue_struct
|
|
{
|
|
/* Stack input queue. */
|
|
Ipcom_spinlock lock; /* Protects head, tail and count variables */
|
|
Ipcom_pkt *head; /* Head of the input queue (first packet to be processed) */
|
|
Ipcom_pkt *tail; /* Tail of the input queue (last packet to be processed) */
|
|
int count; /* Number of packets currently in the input queue */
|
|
#ifdef IPCOM_USE_JOB_QUEUE
|
|
Ipcom_singleton_job_t job; /* Job for processing this input queue */
|
|
#endif
|
|
}
|
|
Ipnet_inq;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_task
|
|
*===========================================================================
|
|
* Information that is per IPNET daemon task.
|
|
*/
|
|
typedef struct Ipnet_task_struct
|
|
{
|
|
Ipcom_pipe *pipe; /* Pipe the net-task polls for
|
|
stack requests */
|
|
Ipcom_pipe *rpipe; /* Pipe the net-task uses to send
|
|
responses. Used if the
|
|
sig->response_pipe is IP_NULL */
|
|
Ip_pid_t pid; /* PID of the ipnet daemon if
|
|
IPCOM_USE_JOB_QUEUE is
|
|
undefined. PID of the job
|
|
daemon if IPCOM_USE_JOB_QUEUE
|
|
is defined */
|
|
Ipnet_inq inq; /* Packet inqueue served by this
|
|
daemon */
|
|
#ifndef IPCOM_USE_JOB_QUEUE
|
|
volatile Ip_bool wakeup_pending; /* IP_TRUE if at least one wakeup
|
|
signal is pending */
|
|
Ipnet_sig *wakeup_sig;
|
|
Ip_u8 wakeup_sig_buf[sizeof(Ipnet_sig) - sizeof(union Ipnet_sig_data_u)];
|
|
#endif
|
|
}
|
|
Ipnet_task;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_slabs
|
|
*===========================================================================
|
|
* All the slab caches used by IPNET
|
|
*/
|
|
typedef struct Ipnet_slabs_struct
|
|
{
|
|
#ifdef IPNET_USE_PACKET_POOL
|
|
Ipcom_memory_cache *pkt_hdr;
|
|
Ipcom_memory_cache *pkt_buf_1500;
|
|
Ipcom_memory_cache *pkt_buf_3000;
|
|
Ipcom_memory_cache *pkt_buf_10000;
|
|
Ipcom_memory_cache *pkt_buf_65535;
|
|
#endif
|
|
#ifndef IPCOM_FORWARDER_NAE
|
|
Ipcom_memory_cache *socket;
|
|
Ipcom_memory_cache *bound_port;
|
|
#else
|
|
Ipcom_memory_cache *local_socket;
|
|
#endif
|
|
Ipcom_memory_cache *timer;
|
|
Ipcom_memory_cache *kioevent_softirq;
|
|
Ipcom_memory_cache *poll;
|
|
}
|
|
Ipnet_slabs;
|
|
|
|
/* #define IPNET_USE_EVENTLOG */
|
|
#ifdef IPNET_USE_EVENTLOG
|
|
struct Ipnet_events
|
|
{
|
|
Ipcom_eventlog log;
|
|
Ipcom_event sock;
|
|
Ipcom_event netif;
|
|
Ipcom_event drv;
|
|
Ipcom_event drv_wouldblock;
|
|
};
|
|
#endif
|
|
|
|
|
|
#ifdef IPNET_USE_PACKET_POOL
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_pkt_cache
|
|
*===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Maximum number of packets that are allowd to be in the packet pool
|
|
* cache. This number is a suggestion, the actual number used is
|
|
* stored in "ipnet->pkt_cache.cnt_mask".
|
|
*/
|
|
#define IPNET_PKT_CACHE_MAX_COUNT (1 << 5)
|
|
|
|
typedef struct Ipnet_pkt_cache_entry_struct
|
|
{
|
|
/*
|
|
* Protects the 'top' and 'stack' members.
|
|
*/
|
|
Ipcom_spinlock lock;
|
|
/*
|
|
* Index to the current top of stack. The stack is empty if 'top'
|
|
* == IPNET_PKT_CACHE_MAX_COUNT and fullt if 'top' == 0.
|
|
*/
|
|
unsigned top;
|
|
Ipcom_pkt *stack[IPNET_PKT_CACHE_MAX_COUNT];
|
|
}
|
|
Ipnet_pkt_cache_entry;
|
|
|
|
typedef struct Ipnet_pkt_cache_struct
|
|
{
|
|
/*
|
|
* Packets can be alloced by any task, it is therefore not
|
|
* possible to schedule a new timeout directly in
|
|
* ipcom_pkt_malloc() or ipcom_pkt_free() as that must be done
|
|
* from the IPNET task.
|
|
*/
|
|
Ipnet_softirq softirq;
|
|
/*
|
|
* GC timer for the packet pool cache. All cached packets will be
|
|
* freed back to the slab allocator if the packet cache has not
|
|
* been used since the last time this timer expired.
|
|
*/
|
|
Ipnet_timeout *tmo;
|
|
/*
|
|
* Packet header cache
|
|
*/
|
|
Ipnet_pkt_cache_entry hdrs;
|
|
/*
|
|
* Cache of packet header + packet buffer with an MTU of 1500.
|
|
*/
|
|
Ipnet_pkt_cache_entry pkts;
|
|
}
|
|
Ipnet_pkt_cache;
|
|
#endif /* IPNET_USE_PACKET_POOL */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_conf
|
|
*===========================================================================
|
|
* See <ipnet>/config/ipnet_config.c for a description of each variable.
|
|
*/
|
|
|
|
struct Ipnet_sock_conf
|
|
{
|
|
int anon_port_min;
|
|
int anon_port_max;
|
|
int default_send_buf_size;
|
|
int default_recv_buf_size;
|
|
int addr_notify;
|
|
};
|
|
|
|
struct Ipnet_route_conf
|
|
{
|
|
unsigned max_clone_count;
|
|
unsigned neigh_rate_period;
|
|
unsigned neigh_rate_limit;
|
|
};
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
struct Ipnet_inet_conf
|
|
{
|
|
Ip_bool sock_stream_dont_frag;
|
|
Ip_bool udp_checksum;
|
|
int icmp_rate_limit_bucket_size;
|
|
int icmp_rate_limit_interval;
|
|
#ifdef IPNET_USE_RFC3927
|
|
char *ll_if_list;
|
|
#endif
|
|
Ip_bool multicast_per_interface_filter;
|
|
Ip_bool random_ip_id;
|
|
};
|
|
#endif /* IPCOM_USE_INET */
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
struct Ipnet_inet6_conf
|
|
{
|
|
int icmp_rate_limit_bucket_size;
|
|
int icmp_rate_limit_interval;
|
|
};
|
|
#endif /* IPCOM_USE_INET6 */
|
|
|
|
struct Ipnet_conf
|
|
{
|
|
struct Ipnet_sock_conf sock;
|
|
struct Ipnet_route_conf route;
|
|
#ifdef IPCOM_USE_INET
|
|
struct Ipnet_inet_conf inet;
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
struct Ipnet_inet6_conf inet6;
|
|
#endif
|
|
};
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_data
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPNET_USE_NETLINK
|
|
struct Ipnet_rtnetlink_table;
|
|
#endif
|
|
|
|
typedef struct Ipnet_data_struct
|
|
{
|
|
/* Dynamic configuration */
|
|
struct Ipnet_conf conf;
|
|
|
|
Ipcom_memory_pool *memory_pool;
|
|
Ipnet_slabs slabs;
|
|
|
|
/* Timeout */
|
|
Ip_u32 sec_now; /* The current time with seconds as resolution */
|
|
Ip_s64 msec_now; /* The current time with milliseconds as resolution */
|
|
Ip_s64 msec_last; /* Used to update the sec_now correctly */
|
|
Ip_s64 msec_boot; /* Used to update the sec_now correctly */
|
|
Ipcom_pqueue *timeouts; /* Priority queue of timeouts */
|
|
Ip_bool update_internal_timer; /* IP_TRUE if the internal timer should be updated
|
|
when scheduleing the next timeout */
|
|
/*
|
|
* Static timeout to neighbor rate limit.
|
|
*/
|
|
Ipnet_timeout *neigh_rate_tmo;
|
|
|
|
/*
|
|
* The number of new created neighbors in one rate limit period.
|
|
*/
|
|
Ip_u32 neigh_current_number;
|
|
|
|
#ifdef IPCOM_USE_JOB_QUEUE
|
|
Ip_bool force_update_time; /* IP_TRUE if the internal time should be updated
|
|
when scheduleing the next timeout */
|
|
Ipcom_singleton_job_t timeout_job; /* Handle for timeout processing job */
|
|
#endif
|
|
#ifdef IPNET_DEBUG
|
|
Ip_size_t tmo_map_size;
|
|
Ipnet_cmd_tmo_handler_to_str *tmo_map;
|
|
#endif
|
|
|
|
/* Soft interrupts, softirq_xxx can only be modified with interrupts disabled */
|
|
Ipcom_spinlock softirq_lock; /* Protects all 'softirq_xxx' variables */
|
|
Ip_bool softirq_pending; /* Set to IP_TRUE if at least 1 soft interrupt is pending */
|
|
Ipnet_softirq *softirq_head; /* Points to the first soft interrupt to run */
|
|
Ipnet_softirq *softirq_tail; /* Points to the last soft interrupt to run */
|
|
#ifdef IPCOM_USE_JOB_QUEUE
|
|
Ipcom_singleton_job_t softirq_job; /* Handle for softirq processing job */
|
|
#endif
|
|
|
|
Ipnet_softirq drain_softirq; /* Static buffer to signal drain soft interrupts */
|
|
Ipnet_softirq pktavail_softirq; /* Static buffer to signal packet available soft interrupts */
|
|
Ipnet_softirq pktnew_softirq; /* Static buffer to that more packets must be added to the pool */
|
|
|
|
#ifdef IPNET_USE_PACKET_POOL
|
|
/* Packet pool */
|
|
Ipcom_spinlock pkt_pool_lock; /* Protects the slab caches
|
|
used to implement the pool */
|
|
unsigned pkt_pool_wait_cnt; /* Number of processes waiting
|
|
(on pkt_pool_sem) or about
|
|
to wait for more free
|
|
packets in this pool */
|
|
Ipcom_sem pkt_pool_sem; /* Semaphore used to put
|
|
processes to sleep while
|
|
they wait for more packets
|
|
to become available in
|
|
this pool. */
|
|
Ipnet_timeout *pkt_pool_tmo; /* Protected by the timeout
|
|
lock: next wakeup for
|
|
processes waiting for more
|
|
packets to become
|
|
available */
|
|
Ipnet_pkt_cache pkt_cache;
|
|
#ifdef IPNET_DEBUG
|
|
Ipcom_pkt *allocated_pkt_list; /* List of currently allocated packets */
|
|
#endif
|
|
#endif /* IPNET_USE_PACKET_POOL */
|
|
|
|
/*
|
|
* Size of the largest possible socket structure that this system
|
|
* may use.
|
|
*/
|
|
Ip_size_t largest_socket_size;
|
|
|
|
/*
|
|
* The socket structure must be freed by the network task. Sockets
|
|
* will not be freed while processing the IPNET_SIG_CLOSE signal
|
|
* if there is one more more packets sent in the context of the
|
|
* socket that still hasn't been freed. The packet destructor will
|
|
* in this case free the socket if the free call is processed by
|
|
* the stack task. If the free call is processed in another
|
|
* context, an IPNET_SIG_SOCKFREE_ASYNC will be sent and the
|
|
* socket will be set in 'async_socket_close_set'. Note that
|
|
* these member may only be accessed while holding the
|
|
* 'sockets_lock'.
|
|
*/
|
|
Ip_bool async_socket_close_pending;
|
|
Ip_fd_set async_socket_close_set;
|
|
Ip_u8 async_socket_close_sig[sizeof(Ipnet_sig) - sizeof(union Ipnet_sig_data_u)];
|
|
|
|
/*
|
|
* Mapping from socket descriptor used in the BSD socket API to
|
|
* the corresponding Ipnet_socket instance. 'sockets' is an array
|
|
* of length 'ipnet_conf_max_sockets'.
|
|
* Note for NAE builds: the memory pointed to by 'sockets' is
|
|
* located in memory shared by all NAE instances.
|
|
*/
|
|
Ipcom_spinlock sockets_lock; /* Lock that protects the 'sockets' member */
|
|
Ipnet_socket **sockets; /* Array of socket pointers, ipnet_conf_max_sockets entries */
|
|
|
|
/*
|
|
* 'reachable_sockets' is an array of list heads of length
|
|
* 'reachable_socket_len'. Each list contains zero or more
|
|
* Ipnet_socket instances chained with the 'reachable_list'
|
|
* member. A socket lookup is done by calculating a hash value
|
|
* based of source address/port, destination address/port, IP
|
|
* protocol and VR index. That hash value is used as an index into
|
|
* the reachable_sockets array. Each socket in the list is tested
|
|
* until a match is found or all sockets has been investigated (no
|
|
* matching socket).
|
|
* Note for NAE builds: the memory pointed to by
|
|
* 'reachable_sockets' is located in memory shared by all NAE
|
|
* instances.
|
|
*/
|
|
Ipcom_list *reachable_sockets;
|
|
Ip_size_t reachable_sockets_len;
|
|
|
|
/*
|
|
* 'bound_ports' is a list that contains zero or more
|
|
* Ipnet_bound_socket instances chained with the 'list'
|
|
* member. This structure keep track of which ports that are in
|
|
* use for a specific IP-protocol, socket domain and VR-index.
|
|
* Note for NAE builds: the memory pointed to by
|
|
* 'bound_ports' is located in memory shared by all NAE
|
|
* instances.
|
|
*/
|
|
Ipcom_list *bound_ports;
|
|
|
|
/*
|
|
* The PID of the process that sent the signal that we are
|
|
* currently processing. This is needed since the BSD socket API
|
|
* calls is handled by the network stack task on behalf of the
|
|
* task/process using the BSD socket API.
|
|
*/
|
|
Ip_pid_t effective_pid;
|
|
|
|
#if IPCOM_VR_MAX > 1
|
|
Ip_u16 effective_vr;
|
|
#endif
|
|
|
|
Ip_fd last_fd; /* Last returned fd */
|
|
|
|
Ip_u32 last_policy; /* Last assigned policy identifier */
|
|
|
|
#ifdef IPCOM_USE_PACKET
|
|
int num_packet_sock; /* Number of packet sockets currently active */
|
|
#endif
|
|
|
|
/* Router variables */
|
|
int route_cache_id; /* The current route cache ID, used to determine if a
|
|
cached router entry can still be valid */
|
|
|
|
Ipcom_hash *rtabs; /* Table where all route table head are stored */
|
|
Ipcom_hash *policy_routing_rules; /* Table with all policy routing lists (one for each domain/virtual router tuple) */
|
|
unsigned cloned_route_count; /* Total number of cloned routes */
|
|
|
|
Ipcom_hash *queue_db; /* Collection of queue constructors */
|
|
|
|
Ipnet_inq inq; /* Queue for RX packets + task that inputs them to the stack */
|
|
Ipnet_task task;
|
|
|
|
/* Link/interface layer. */
|
|
Ipcom_hash *netifs; /* Hash table that contains all attached interfaces */
|
|
#ifdef IPNET_USE_6OVER4
|
|
Ipnet_netif **netif_6over4; /* Array of active 6over4 interfaces */
|
|
int netif_6over4_count;
|
|
#endif
|
|
Ipcom_if_eventcb if_eventcb[IPNET_MAX_IF_EVENTCB];
|
|
#ifdef IPNET_USE_FAST_IFNAME_LOOKUP
|
|
Ipcom_hash *ifname_tab; /* Interface name hash table */
|
|
#endif /* IPNET_USE_FAST_IFNAME_LOOKUP */
|
|
#ifdef IPNET_USE_ROUTE_TABLE_NAMES
|
|
Ipcom_hash *rtab_names;
|
|
#endif /* IPNET_USE_ROUTE_TABLE_NAMES */
|
|
#ifdef IPNET_USE_ROUTE_COOKIES
|
|
Ipcom_hash *rtab_cookies;
|
|
#endif /* IPNET_USE_ROUTE_COOKIES */
|
|
|
|
Ip_u32 next_ifindex; /* The next ifindex to use */
|
|
|
|
Ipnet_if_attach_handler if_attach_handler; /* OS port specific to attach new devices to the stack */
|
|
|
|
/*
|
|
* Temporary storage to create log messages, anything stored here
|
|
* might be overwritten by any function.
|
|
*/
|
|
char log_buf[256];
|
|
|
|
/* Statistics */
|
|
#if defined(IPNET_DEBUG) || defined(IPNET_STATISTICS)
|
|
Ipnet_stats stats;
|
|
#endif
|
|
|
|
#if defined(IP_X_SIOCSDEBUG) || defined(IP_X_SIOCGDEBUG)
|
|
/*
|
|
* Value that can be manipulated via the
|
|
* IP_X_SIOCSDEBUG/IP_X_SIOCGDEBUG ioctl(). This value is not used
|
|
* anywhere in the stack. The indented usage is to create
|
|
* breakpoints that will only trigger if 'debug' has a specific
|
|
* value.
|
|
*/
|
|
int debug;
|
|
#endif
|
|
|
|
/* IP version 4 */
|
|
#ifdef IPCOM_USE_INET
|
|
Ipnet_ip4_data ip4;
|
|
/* Multicast routing */
|
|
#ifdef IPNET_USE_MCAST_ROUTING
|
|
Ipcom_hash *ip4_mcast;
|
|
#endif
|
|
#endif /* IPCOM_USE_INET */
|
|
|
|
/* IP version 6 */
|
|
#ifdef IPCOM_USE_INET6
|
|
Ipnet_ip6_data ip6;
|
|
#ifdef IPNET_USE_MCAST_ROUTING
|
|
Ipcom_hash *ip6_mcast;
|
|
#endif
|
|
#endif
|
|
|
|
/* PPP and PPPoE support */
|
|
#ifdef IPPPP
|
|
Ipppp_ipstack_data ppp;
|
|
#endif
|
|
|
|
/* Differentiated Services */
|
|
#ifdef IPNET_USE_DIFFSERV
|
|
Ipnet_diffserv_data diffserv;
|
|
#endif /* IPNET_USE_DIFFSERV */
|
|
|
|
/* NAT */
|
|
#ifdef IPNET_USE_NAT
|
|
Ipnet_nat_data nat;
|
|
#endif
|
|
|
|
/* Route/netlink sockets. */
|
|
#ifdef IPNET_USE_ROUTESOCK
|
|
int num_route_sock; /* Number of routing sockets. */
|
|
#endif
|
|
#ifdef IPNET_USE_NETLINKSOCK
|
|
int num_netlink_sock; /* Number of netlink sockets. */
|
|
struct Ip_rtnl_link_ops *rtnetlink_ops;
|
|
#endif
|
|
#ifdef IPNET_USE_NETLINK
|
|
void *netlink_data[IP_NETLINK_MAX];
|
|
#endif
|
|
|
|
/* MIB-2 */
|
|
#ifdef IPCOM_USE_MIB2
|
|
Ipcom_mib2_stats mib2;
|
|
#endif
|
|
|
|
/* VLAN stacking */
|
|
#ifdef IPNET_USE_VLAN_STACKING
|
|
Ip_u16 vlan_s_tpid;
|
|
Ip_u16 vlan_s_tpid_net; /* S-VLAN TPID in network order format */
|
|
#endif
|
|
|
|
#ifdef IPBRIDGE
|
|
struct Ipnet_bridge_st *bridge; /* Bridge control structure */
|
|
#endif
|
|
}
|
|
Ipnet_data;
|
|
|
|
|
|
/* Ipnet_data flags: */
|
|
#define IPNET_FLAG_IPV4_FORWARD_PKT 0x02 /* Set if IPv4 packets should be forward */
|
|
#define IPNET_FLAG_IPV6_FORWARD_PKT 0x04 /* Set if IPv6 packets should be forward */
|
|
#define IPNET_FLAG_PKTAVAIL_CB_PENDING 0x10 /* A non-blocking socket call, on a socket with a */
|
|
/* callback handler, failed due to no packets in
|
|
the packet pool */
|
|
#define IPNET_FLAG_IPV6_RFC4941_INIT 0x20 /* IPv6 privacy extension has been initialized */
|
|
|
|
/*
|
|
* Set to put IPNET in strict mode, unset for loose mode.
|
|
* Strict mode requires packet to enter on the correct interface to be
|
|
* considered local. Loose mode will accept the packet if any interface
|
|
* has the unicast address. Most OS:es uses loose mode.
|
|
*/
|
|
#define IPNET_FLAG_IPV4_STRICT_MODE 0x40 /* Set to enable ipv4 strict mode in ipnet stack */
|
|
#define IPNET_FLAG_IPV6_STRICT_MODE 0x80 /* Set to enable ipv6 strict mode in ipnet stack */
|
|
|
|
|
|
|
|
#ifdef IPCOM_FORWARDER_NAE
|
|
/*
|
|
* IPNET shared memory control block
|
|
*/
|
|
typedef struct Ipnet_shm_struct
|
|
{
|
|
/*
|
|
* Shared memory is initialized to all zeros, so this variable
|
|
* starts out as IP_FALSE.
|
|
*/
|
|
Ip_bool is_initialized;
|
|
|
|
/*
|
|
* Array of socket pointers. The length of the array is
|
|
* ipnet_conf_max_sockets.
|
|
*/
|
|
Ipnet_socket **sockets;
|
|
|
|
/*
|
|
* reachable_sockets is an array of list of sockets. A socket that
|
|
* is ready to accept ingress traffic is put into the list
|
|
* with index (socket_hash_val % reachable_sockets_len).
|
|
*/
|
|
Ipcom_list *reachable_sockets;
|
|
Ip_size_t reachable_sockets_len;
|
|
|
|
/*
|
|
* 'bound_ports' is the list of ports in use. Each port is
|
|
* represented by a Ipnet_bound_port structure.
|
|
*/
|
|
Ipcom_list *bound_ports;
|
|
|
|
/*
|
|
* Array of lists of Ipnet_peer_info entries.
|
|
*/
|
|
Ipcom_list *peer_info_buckets;
|
|
Ip_size_t peer_info_buckets_len;
|
|
} Ipnet_shm;
|
|
#endif /* IPCOM_FORWARDER_NAE */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipnet_lock_state
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IP_PORT_LKM
|
|
typedef struct Ipnet_lock_state_struct
|
|
{
|
|
Ip_bool has_write_lock;
|
|
Ip_bool has_snd_rcv_lock;
|
|
Ipnet_socket *sock;
|
|
}
|
|
Ipnet_lock_state;
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_EXTERN IP_FASTDATA Ipnet_data *ipnet;
|
|
IP_EXTERN IP_FASTDATA Ipnet_sock_ops **ipnet_sock_ops;
|
|
IP_EXTERN Ip_u32 ipnet_flags;
|
|
IP_EXTERN Ipcom_cmd_int_str_map ipnet_bool_map[];
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Driver/link upcalls
|
|
*===========================================================================
|
|
*/
|
|
|
|
/* Note: The caller must be IPNET code locked to call ipnet_kioevent() */
|
|
IP_PUBLIC void ipnet_kioevent(Ipnet_netif *netif, int command,
|
|
void *data, int fcflags);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET Internal
|
|
*===========================================================================
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_ipaddrlen
|
|
*===========================================================================
|
|
* Description: Returns the length of the IP address.
|
|
* Parameters: domain - domain for the neighbor.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_INLINE Ip_size_t
|
|
ipnet_ipaddrlen(int domain)
|
|
{
|
|
IPCOM_UNUSED_ARG(domain);
|
|
#ifdef IPCOM_USE_INET6
|
|
if (domain == IP_AF_INET6)
|
|
return sizeof(struct Ip_in6_addr);
|
|
#endif
|
|
|
|
return sizeof(struct Ip_in_addr);
|
|
}
|
|
|
|
|
|
|
|
IP_GLOBAL void
|
|
ipcom_pause_os_network_daemon(void);
|
|
IP_GLOBAL void
|
|
ipnet_pause_os_network_daemon(void);
|
|
IP_GLOBAL void
|
|
ipnet_resume_os_network_daemon(void);
|
|
|
|
#if IPCOM_VR_MAX > 1
|
|
#define ipnet_get_effective_vr() ipnet->effective_vr
|
|
#else
|
|
#define ipnet_get_effective_vr() 0
|
|
#endif
|
|
|
|
#define ipnet_get_effective_pid() ipnet->effective_pid
|
|
|
|
IP_GLOBAL void ipnet_try_free_mem(Ip_bool run_async);
|
|
|
|
IP_GLOBAL int ipnet_sysvar_get_as_int_vr(Ipnet_netif *netif,
|
|
IP_CONST char *snd,
|
|
IP_CONST char *name,
|
|
int default_val,
|
|
IP_CONST Ipcom_cmd_int_str_map *map,
|
|
int vr);
|
|
IP_GLOBAL int ipnet_sysvar_netif_get_as_int(int domain,
|
|
Ipnet_netif *netif,
|
|
IP_CONST char *name,
|
|
int default_val);
|
|
IP_GLOBAL int ipnet_sysvar_netif_get_as_int_ex(int domain,
|
|
Ipnet_netif *netif,
|
|
IP_CONST char *name,
|
|
int default_val,
|
|
IP_CONST Ipcom_cmd_int_str_map *map);
|
|
IP_GLOBAL Ip_u32 ipnet_sec_now(void);
|
|
IP_GLOBAL Ip_s64 ipnet_msec_now(void);
|
|
IP_GLOBAL Ip_bool ipnet_is_stack_task(void);
|
|
|
|
IP_GLOBAL Ipcom_pkt *ipnet_pkt_clone(Ipcom_pkt *pkt, int is_ipstart_valid);
|
|
|
|
IP_GLOBAL void * ipnet_sysctl_if_add_addrs_one(void *buf, Ipnet_netif *netif,
|
|
int domain, void *addrx, Ip_size_t *lenp);
|
|
|
|
IP_GLOBAL Ip_bool ipnet_has_priv(int priv);
|
|
IP_PUBLIC Ip_s64 ipnet_timeval_to_msec(struct Ip_timeval *tv);
|
|
|
|
#ifdef IPCOM_USE_MIB2
|
|
IP_GLOBAL Ipnet_netif *ipnet_ip6_socket_to_netif(struct Ipnet_socket_struct *sock);
|
|
#endif
|
|
|
|
#ifdef IPCOM_USE_MIB2_NEW
|
|
IP_GLOBAL void ipnet_eth_update_mib2_lastchange(Ipnet_neigh *n);
|
|
#endif
|
|
|
|
IP_GLOBAL Ip_u16 ipnet_sysctl_create_ifinfo(void *buf, Ipnet_netif *netif);
|
|
|
|
|
|
IP_GLOBAL Ip_u32 ipnet_stats_tcp_established(void);
|
|
|
|
IP_GLOBAL void
|
|
ipnet_loop_pkt_tx(Ipnet_dst_cache *dst,
|
|
Ipcom_pkt *pkt,
|
|
Ipnet_dst_cache_domain_ctor dst_cache_local_tx_ctor);
|
|
|
|
IP_GLOBAL Ipnet_dst_cache *
|
|
ipnet_ip4_dst_cache_get(Ip_u16 vr,
|
|
const struct Ip_in_addr *to,
|
|
const struct Ip_in_addr *from,
|
|
Ip_u8 tos,
|
|
unsigned egress_ifindex,
|
|
unsigned ingress_ifindex);
|
|
|
|
IP_GLOBAL int ipnet_fw_nat_ipsec_tx(Ipnet_dst_cache **dstp,
|
|
Ipcom_pkt **pktp,
|
|
Ip_bool do_nat);
|
|
|
|
IP_GLOBAL int ipnet_fw_nat_rx(Ipnet_dst_cache **dstp,
|
|
Ipcom_pkt **pktp,
|
|
Ip_bool do_nat,
|
|
Ip_bool fw_checked);
|
|
|
|
IP_GLOBAL void ipnet_conf_update(const char *fst,
|
|
const char *snd,
|
|
const char *name);
|
|
|
|
IP_GLOBAL int ipnet_ctrl_sig(Ipnet_sig *sig);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET socket
|
|
*===========================================================================
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_sock_make_next_sendmsg_synchronous
|
|
*===========================================================================
|
|
* Description: Makes sure that the next call to sendmsg() is
|
|
* synchronous so that proper error code is returned.
|
|
* Parameters: sock - a socket
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_INLINE void
|
|
ipnet_sock_make_next_sendmsg_synchronous(Ipnet_socket *sock)
|
|
{
|
|
/*
|
|
* This variable is compared to ipnet->route_cache_id and the
|
|
* sendmsg() call can be asynchronous if they are
|
|
* equal. ipnet->route_cache_id will never have a value of zero.
|
|
*/
|
|
sock->snd_route_cache_id = 0;
|
|
}
|
|
|
|
IP_GLOBAL void ipnet_sock_update_reuse(Ipnet_socket *sock);
|
|
IP_GLOBAL Ip_size_t ipnet_sock_get_bound_port_size(void);
|
|
IP_GLOBAL Ipnet_socket *ipnet_sock_get(Ipnet_socket_lookup_key *key, Ipcom_list **head);
|
|
IP_GLOBAL Ipnet_socket *ipnet_sock_next(Ipnet_socket *sock);
|
|
IP_GLOBAL Ip_bool ipnet_sock_has_waiting_writers(Ipnet_socket *sock);
|
|
IP_GLOBAL Ip_bool ipnet_is_sock_readable(Ipnet_socket *sock, int lowat);
|
|
IP_GLOBAL Ip_bool ipnet_is_sock_writable(Ipnet_socket *sock, int lowat);
|
|
IP_GLOBAL Ip_bool ipnet_is_sock_exceptional(Ipnet_socket *sock, int lowat);
|
|
|
|
IP_PUBLIC void ipnet_sock_data_avail(Ipnet_socket *sock, int so_errno, int how);
|
|
|
|
IP_GLOBAL void ipnet_sock_pkt_drain(void);
|
|
IP_GLOBAL void *ipnet_sock_alloc_private_data(Ipnet_socket *sock, Ip_size_t size);
|
|
|
|
#ifdef IPNET_USE_ROUTER_ALERT
|
|
IP_GLOBAL int ipnet_sock_join_router_alert_chain(Ipnet_socket *sock);
|
|
IP_GLOBAL int ipnet_sock_leave_router_alert_chain(Ipnet_socket *sock);
|
|
#endif
|
|
IP_GLOBAL int ipnet_sock_router_alert_pkt(Ipcom_pkt *pkt);
|
|
|
|
IP_GLOBAL int ipnet_configd_start(void);
|
|
IP_GLOBAL int ipnet_raw_input(Ipcom_pkt *pkt, Ip_bool take_ownership, int proto,
|
|
IP_CONST void *src_addr, Ip_u16 src_port,
|
|
IP_CONST void *dst_addr, Ip_u16 dst_port,
|
|
Ipnet_sock_lookup_f socklookup);
|
|
|
|
IP_GLOBAL int ipnet_sock_bind(Ipnet_socket *sock, IP_CONST struct Ip_sockaddr *name,
|
|
Ip_socklen_t namelen, Ip_bool check_resuse);
|
|
IP_GLOBAL Ip_u16 ipnet_next_ephemeral_port(Ipnet_socket *sock);
|
|
IP_GLOBAL int ipnet_queue_received_packet(Ipcom_pkt *pkt, Ipnet_socket *sock);
|
|
IP_GLOBAL void ipnet_sock_free(Ipnet_socket *sock, Ip_bool clear_sockets_arr);
|
|
IP_GLOBAL int ipnet_do_close(Ipnet_socket *sock);
|
|
IP_GLOBAL int ipnet_do_socketselect(int nfds,
|
|
Ip_fd_set *readfds,
|
|
Ip_fd_set *writefds,
|
|
Ip_fd_set *exceptfds,
|
|
struct Ip_timeval *timeout);
|
|
IP_GLOBAL int ipnet_sock_drop_all_multicast_memberships(Ipnet_socket *sock, Ipnet_netif *netif,
|
|
Ip_bool drop_ip4, Ip_bool drop_ip6);
|
|
IP_GLOBAL int ipnet_increase_hdr_space(Ipcom_pkt **ppkt, Ip_bool is_iphdr_valid);
|
|
|
|
IP_GLOBAL Ipnet_route_entry * ipnet_sock_get_route(Ipnet_socket *sock);
|
|
|
|
IP_GLOBAL int ipnet_ioctl_move_if_rt_to_vr(Ipnet_netif *netif, Ip_u16 vr);
|
|
IP_GLOBAL int ipnet_sock_create_lookup_tables(void);
|
|
IP_GLOBAL int ipnet_sock_set_reachable(Ipnet_socket *sock);
|
|
IP_GLOBAL void ipnet_sock_set_unreachable(Ipnet_socket *sock);
|
|
IP_GLOBAL void ipnet_sock_bind_addr_removed(Ipnet_socket *sock_list);
|
|
IP_GLOBAL void ipnet_sock_change_addr_entry(Ipnet_socket *old_sock_list,
|
|
Ipnet_socket **pnew_sock_list,
|
|
void *addr_entry);
|
|
IP_GLOBAL int ipnet_sock_unconnect(Ipnet_socket *sock);
|
|
IP_GLOBAL int ipnet_sock_bind_to_port(Ipnet_socket *sock,
|
|
IP_CONST struct Ip_sockaddr *name,
|
|
Ip_bool check_reuse);
|
|
IP_GLOBAL void ipnet_sock_unbind(Ipnet_socket *sock);
|
|
IP_GLOBAL int ipnet_pkt_get_maxlen(Ipcom_pkt *pkt);
|
|
|
|
IP_INLINE Ipnet_sock_ops *ipnet_sock_get_ops(Ipnet_socket *sock)
|
|
{
|
|
/*
|
|
* For NAE:s
|
|
* The ipnet_sock_ops array is located in local memory, so the
|
|
* returned pointer must not be stored in any shared memory area
|
|
* (like the socket structure for example). This function must be
|
|
* called each time the socket options in needed.
|
|
*/
|
|
ip_assert(sock->ops_handle >= 0);
|
|
return ipnet_sock_ops[sock->ops_handle];
|
|
}
|
|
IP_GLOBAL int
|
|
ipnet_sock_get_ops_handle(int domain, int type, int protocol,
|
|
Ip_bool *no_domain, Ip_bool *no_type);
|
|
IP_GLOBAL int ipnet_sock_register_ops(Ipnet_sock_ops *ops);
|
|
|
|
#ifdef IPSCTP
|
|
IP_GLOBAL int ipnet_sock_sctp_register(void);
|
|
#endif
|
|
IP_GLOBAL int ipnet_sock_udp_register(void);
|
|
#ifdef IPTCP
|
|
IP_GLOBAL int ipnet_sock_tcp_register(void);
|
|
#endif
|
|
#ifdef IPCOM_USE_INET
|
|
IP_GLOBAL int ipnet_sock_ip4_register(void);
|
|
IP_GLOBAL void ipnet_ip4_reg_transport_layer(Ip_u8 ip_proto,
|
|
Ipnet_transport_layer_rx_func trans_rx);
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
IP_GLOBAL int ipnet_sock_ip6_register(void);
|
|
IP_GLOBAL void ipnet_ip6_reg_transport_layer(Ip_u8 ip_proto,
|
|
Ipnet_transport_layer_rx_func trans_rx);
|
|
#endif
|
|
#ifdef IPNET_USE_ROUTESOCK
|
|
IP_GLOBAL int ipnet_sock_route_register(void);
|
|
#endif
|
|
#ifdef IPNET_USE_NETLINKSOCK
|
|
IP_GLOBAL int ipnet_sock_netlink_register(void);
|
|
#endif
|
|
#ifdef IPCOM_USE_PACKET
|
|
IP_GLOBAL int ipnet_sock_packet_register(void);
|
|
#endif
|
|
#ifdef IPIPSEC2
|
|
IP_GLOBAL void ipnet_ipsec_rx(Ipnet_dst_cache *dst, Ipcom_pkt *pkt, Ip_u8 proto);
|
|
IP_GLOBAL int ipnet_proto_ah_register(void);
|
|
IP_GLOBAL int ipnet_proto_esp_register(void);
|
|
IP_GLOBAL int ipnet_sock_key_register(void);
|
|
#endif
|
|
#ifdef IPNET_USE_SOCKDEV
|
|
IP_GLOBAL int ipnet_sock_sockdev_register(void);
|
|
#endif
|
|
|
|
IP_GLOBAL void ipnet_sock_ip4_get_ops(Ipnet_sock_inet_ops *ops);
|
|
IP_GLOBAL void ipnet_sock_ip6_get_ops(Ipnet_sock_inet_ops *ops);
|
|
|
|
#ifdef IPCOM_FORWARDER_NAE
|
|
IP_GLOBAL void ipnet_nae_unsupported_transport_layer_rx(Ipnet_dst_cache *dst,
|
|
Ipcom_pkt *pkt);
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* socket function callable by IPNET in user context
|
|
*===========================================================================
|
|
*/
|
|
|
|
IP_GLOBAL int ipnet_usr_sock_pkt_recv(Ipnet_socket *sock, struct Ip_msghdr *msg, int flags);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPNET packet socket
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPCOM_USE_PACKET
|
|
IP_GLOBAL Ip_bool ipnet_packet_input(Ipnet_netif *netif, Ipcom_pkt *pkt);
|
|
IP_GLOBAL int ipnet_packet_output(Ipnet_socket *sock, IP_CONST struct Ip_msghdr *msg, Ipcom_pkt *pkt);
|
|
IP_GLOBAL Ip_bool ipnet_packet_getsockopt(int optname, IP_CONST struct Ip_packet_mreq *mreq, Ip_socklen_t *optlen);
|
|
IP_GLOBAL Ip_bool ipnet_packet_setsockopt(Ipnet_socket *sock, int optname, IP_CONST struct Ip_packet_mreq *mreq, Ip_socklen_t optlen);
|
|
#endif /* IPCOM_USE_PACKET */
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Fragmentation & reassembly
|
|
*===========================================================================
|
|
*/
|
|
typedef Ip_bool (*Ipnet_is_part_of_same_pkt_func)(Ipcom_pkt *frag1, Ipcom_pkt *frag2);
|
|
typedef Ip_bool (*Ipnet_more_fragments_func)(Ipcom_pkt *frag);
|
|
typedef void (*Ipnet_update_ip_header_func)(Ipcom_pkt *pkt);
|
|
typedef void (*Ipnet_reassemble_err_func)(Ipcom_pkt *frag_list);
|
|
|
|
IP_GLOBAL Ipcom_pkt *
|
|
ipnet_reassembly(struct Ipnet_peer_info_struct *peer_info,
|
|
Ipcom_pkt *pkt,
|
|
Ipnet_is_part_of_same_pkt_func is_part_of_same_pkt,
|
|
Ipnet_more_fragments_func more_fragments);
|
|
IP_GLOBAL Ipcom_pkt *
|
|
ipnet_create_reassembled_packet(Ipcom_pkt *fragment_list,
|
|
Ipnet_update_ip_header_func update_ip_header,
|
|
Ipnet_reassemble_err_func report_reassemble_err);
|
|
IP_GLOBAL Ipcom_pkt *
|
|
ipnet_fragment_packet(Ipcom_pkt *pkt,
|
|
int ip_hdr_size,
|
|
int other_hdr_size,
|
|
int mtu,
|
|
Ipnet_more_fragments_func more_fragments);
|
|
|
|
IP_GLOBAL void
|
|
ipnet_frag_set_peer_info(Ipcom_pkt *frag, Ipnet_peer_info *peer_info);
|
|
|
|
IP_GLOBAL Ipnet_peer_info *
|
|
ipnet_frag_to_peer_info(Ipcom_pkt *frag);
|
|
|
|
IP_GLOBAL void
|
|
ipnet_frag_release_peer_info(Ipcom_pkt *frag);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ROUTING SOCKET
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IPNET_USE_ROUTESOCK
|
|
IP_GLOBAL void ipnet_routesock_addr_add(struct Ipnet_netif_struct *netif, int domain, void *addr);
|
|
IP_GLOBAL void ipnet_routesock_addr_delete(struct Ipnet_netif_struct *netif, int domain, void *addr);
|
|
IP_GLOBAL void ipnet_routesock_addr_conflict(Ipnet_netif *netif, int domain, void *addr);
|
|
IP_GLOBAL void ipnet_routesock_if_change(struct Ipnet_netif_struct *netif);
|
|
IP_GLOBAL void ipnet_routesock_if_announce(Ipnet_netif *netif, Ip_u16 what);
|
|
IP_GLOBAL void ipnet_routesock_rt_add(Ipnet_route_entry *rt);
|
|
IP_GLOBAL void ipnet_routesock_rt_delete(Ipnet_route_entry *rt);
|
|
IP_GLOBAL void ipnet_routesock_rt_change(Ipnet_route_entry *rt);
|
|
IP_GLOBAL void ipnet_routesock_rt_miss(Ipcom_route *rtab, IP_CONST void *key);
|
|
IP_GLOBAL void ipnet_routesock_rt_redirect(Ipcom_route *rtab, Ip_u32 ifindex,
|
|
IP_CONST void *dst, IP_CONST void *new_gw);
|
|
IP_GLOBAL void ipnet_routesock_neigh_resolve(Ipnet_neigh *neigh);
|
|
#endif /* IPNET_USE_ROUTESOCK */
|
|
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* PACKET POOL FUNCTIONS
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IPNET_USE_PACKET_POOL
|
|
IP_GLOBAL int ipnet_pkt_pool_init(void);
|
|
IP_GLOBAL int ipnet_pkt_pool_hdr_count_hint(void);
|
|
IP_GLOBAL void ipnet_pkt_pool_drain();
|
|
#endif /* IPNET_USE_PACKET_POOL */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* DEBUG FUNCTIONS
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IPNET_DEBUG
|
|
IP_GLOBAL void ipnet_pkt_remove_from_alloc_list(Ipcom_pkt *pkt);
|
|
IP_GLOBAL void ipnet_pkt_add_to_alloc_list(Ipcom_pkt *pkt);
|
|
IP_GLOBAL void ipnet_pkt_check(Ipcom_pkt *pkt);
|
|
#endif /* IPNET_DEBUG */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* POWER ON SELF-TEST
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IPNET_USE_POST
|
|
IP_GLOBAL void ipnet_post_run(void);
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_alloc_snd_bytes
|
|
*===========================================================================
|
|
* Description: Allocate socket send buffer space.
|
|
* Parameters: sock - a socket.
|
|
* total_buf_len - number of bytes of space to allocate in the
|
|
* socket send buffer.
|
|
* Returns: IP_TRUE if successful;
|
|
* IP_FALSE if there is currently not enough space;
|
|
*/
|
|
IP_INLINE Ip_bool
|
|
ipnet_alloc_snd_bytes(Ipnet_socket *sock, int total_buf_len)
|
|
{
|
|
int snd_bytes;
|
|
do
|
|
{
|
|
snd_bytes = ipcom_atomic_get(&sock->snd_bytes);
|
|
if (snd_bytes >= sock->send_max_bytes || snd_bytes + total_buf_len < snd_bytes)
|
|
return 0;
|
|
} while (!ipcom_atomic_ptr_cas((Ip_ptrdiff_t*)&sock->snd_bytes, snd_bytes,
|
|
snd_bytes + total_buf_len));
|
|
return 1;
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|