1508 lines
53 KiB
C
1508 lines
53 KiB
C
/* ipcom_pkt.h - API of IPCOM packets */
|
|
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK API HEADER FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_pkt.h,v $ $Revision: 1.115.10.18 $
|
|
* $Source: /home/interpeak/CVSRoot/ipcom/include/ipcom_pkt.h,v $
|
|
* $Author: svc-cmnet $ $Date: 2018-09-12 23:34:21 $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifndef IPCOM_PKT_H
|
|
#define IPCOM_PKT_H
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
* Definition of IPNET and IPLITE packet structure - Ipcom_pkt.
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This library contains the API for IPCOM packets.
|
|
INCLUDE FILES: ipcom_atomic.h, ipcom_cstyle.h, ipcom_type.h
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipcom_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include <ipcom_atomic.h>
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_type.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Light weight debug
|
|
*===========================================================================
|
|
* Define to enable "minimum performace degrading" debug features. This will
|
|
* automatically be undefined when IP_DEBUG is defined
|
|
*/
|
|
|
|
#ifdef IP_LW_DEBUG
|
|
#define IP_CHK_LWERROR(p) \
|
|
do { \
|
|
ipcom_nae_rmb(); \
|
|
if ((p)->lw_error) *(int *)0x89 = 0x98; \
|
|
} while(0)
|
|
#else
|
|
#define IP_CHK_LWERROR(p)
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Driver layer macros
|
|
*===========================================================================
|
|
* Set pkt->start to a correct minimum value with alignment 'align' on 'data'.
|
|
*/
|
|
#define IPCOM_DRV_SET_PKT_START(pkt, link_hdr_size, align) \
|
|
do { \
|
|
Ip_ptrdiff_t a = (align) - 1; \
|
|
(pkt)->start = (int)(ipcom_conf_max_link_hdr_size - (link_hdr_size)); \
|
|
(pkt)->start += (int)(((align) - ((Ip_ptrdiff_t)&(pkt)->data[(pkt)->start] & a)) & a); \
|
|
} while((0))
|
|
|
|
|
|
/* Maximum number of times this packet can go through the IP-output layer
|
|
in the same context. */
|
|
#define IPCOM_PKT_MAX_RECURSE_LEVEL 4
|
|
|
|
#if defined(IPCOM_FORWARDER_NAE)
|
|
#define IPCOM_PKT_INFO_LEN 100
|
|
#else
|
|
#define IPCOM_PKT_INFO_LEN 400
|
|
#endif
|
|
|
|
/* packet info things */
|
|
#define IPCOM_PKT_INFO_COPY 0x80 /* All types with this bit set
|
|
must be be copied to clones */
|
|
|
|
#define IPCOM_PKT_INFO_OPRIO (1 | IPCOM_PKT_INFO_COPY)
|
|
#define IPCOM_PKT_INFO_DROP_PRECEDENCE (2 | IPCOM_PKT_INFO_COPY)
|
|
#define IPCOM_PKT_INFO_VLAN_TAG (3 | IPCOM_PKT_INFO_COPY)
|
|
|
|
/*
|
|
* Special ipcom_pkt_malloc() fcflags values. These must not use
|
|
* bits used by the IP_FLAG_FC_* macros in ipcom_cstyle.h.
|
|
* Note that the bits (1 << 16) to (1 << 31) are used internally
|
|
* by ipnet_pkt_pool.c and are not available either. We start
|
|
* at (1<<15) and allocate towards less-significant bits until
|
|
* we hit those in ipcom_cstyle.h.
|
|
*/
|
|
|
|
/*
|
|
* Don't allocate a larger buffer if the best fit buffer size for
|
|
* the specified nonzero MTU is not available. Setting this flag
|
|
* in fcflags in ipcom_pkt_malloc(), for a given mtu value the
|
|
* same memory buffer cache will always be used to allocate the buffer.
|
|
*/
|
|
#define IPCOM_FLAG_FC_EXACT 0x8000
|
|
|
|
#ifndef IP_FASTTEXT
|
|
#define IP_FASTTEXT
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
struct Ipcom_pkt_struct; /* dummy forward declaration. */
|
|
struct Ipcom_netif_struct; /* dummy forward declaration. */
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt_trace_buffer
|
|
*===========================================================================
|
|
* A trace is a notification of who owned the packet and where in the
|
|
* code the trace was made from. Can be usefull in debugging to figure
|
|
* out where in the stack this packet has been
|
|
*/
|
|
#if defined(IP_DEBUG) || defined(IP_LW_DEBUG)
|
|
#define IPCOM_PKT_TRACE_BUFFER_LEN 10
|
|
|
|
/*
|
|
*===========================================================================
|
|
* IPCOM_PKT_ID_XXX
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
enum Ipcom_pkt_id {
|
|
IPCOM_PKT_ID_INIT,
|
|
IPCOM_PKT_ID_MALLOC, /* Packet has just been allocated */
|
|
IPCOM_PKT_ID_RX, /* In driver RX */
|
|
IPCOM_PKT_ID_TX, /* In driver TX */
|
|
IPCOM_PKT_ID_FREEQ, /* In free queue */
|
|
IPCOM_PKT_ID_ADDREF, /* Decreasae reference */
|
|
IPCOM_PKT_ID_DELREF, /* Decreasae reference */
|
|
IPCOM_PKT_ID_INPUT, /* Packed is processed by ipcom_pkt_input(). */
|
|
IPCOM_PKT_ID_INQ, /* In input-queue */
|
|
IPCOM_PKT_ID_OUTQ, /* In input output-queue */
|
|
IPCOM_PKT_ID_NETIF_OUTQ, /* In interface output-queue */
|
|
IPCOM_PKT_ID_SOCKRECVQ, /* In socket receive queue */
|
|
IPCOM_PKT_ID_TCP, /* Allocated by TCP. */
|
|
IPCOM_PKT_ID_TCP_INPUT, /* Packet is processed by TCP input */
|
|
IPCOM_PKT_ID_TCP_OUTPUT, /* Packet is processed by TCP output */
|
|
IPCOM_PKT_ID_TCP_SOCKOOORECVQ, /* In TCP out-of-order receive queue */
|
|
IPCOM_PKT_ID_TCP_RETRANSQ, /* In TCP retransmission queue */
|
|
IPCOM_PKT_ID_IP4_INPUT, /* Packet is processed by IPv4 input */
|
|
IPCOM_PKT_ID_IP4_OUTPUT, /* Packet is processed by IPv4 output */
|
|
IPCOM_PKT_ID_IP4_REASSEMBLY, /* Packet is a IPv4 fragment in the reassembly queue */
|
|
IPCOM_PKT_ID_IP6_INPUT, /* Packet is processed by IPv6 input */
|
|
IPCOM_PKT_ID_IP6_OUTPUT, /* Packet is processed by IPv6 output */
|
|
IPCOM_PKT_ID_IP6_REASSEMBLY, /* Packet is a IPv6 fragment in the reassembly queue */
|
|
IPCOM_PKT_ID_REMOVE, /* The packet is beeing removed from its queue */
|
|
IPCOM_PKT_ID_IPSEC_INPUT, /* Packet is processed by ipsec input */
|
|
IPCOM_PKT_ID_IPSEC_OUTPUT, /* New ipsec packet for output */
|
|
IPCOM_PKT_ID_IPSEC_OUTPUT_ORG, /* Packet is processed by ipsec output */
|
|
IPCOM_PKT_ID_IPSEC_PF_KEY_IN, /* PF_KEY input */
|
|
IPCOM_PKT_ID_PPP, /* Allocated by PPP. */
|
|
IPCOM_PKT_ID_PPP_ORGOUT, /* Original output packet (unescaped). */
|
|
IPCOM_PKT_ID_PPP_INPUT, /* Packet is processed by PPP input */
|
|
IPCOM_PKT_ID_PPP_OUTPUT, /* Packet is processed by PPP output */
|
|
IPCOM_PKT_ID_RTSOCK, /* Allocated by routesock. */
|
|
IPCOM_PKT_ID_UDP_INPUT, /* UDP input. */
|
|
IPCOM_PKT_ID_NETIF_DEQUEUE, /* Dequeued from interface queue */
|
|
IPCOM_PKT_ID_SOCKSENDQ, /* Datagram socket send queue */
|
|
IPCOM_PKT_ID_SENT_PIPE, /* Sent into stack pipe */
|
|
IPCOM_PKT_ID_RECV_PIPE, /* Received from stack pipe */
|
|
IPCOM_PKT_ID_FRAG, /* New fragment */
|
|
IPCOM_PKT_ID_PRE_SEND_SIG, /* Pending Secure NDP signature verification/creation */
|
|
IPCOM_PKT_ID_POST_SEND_SIG, /* After Secure NDP signature verification/creation */
|
|
IPCOM_PKT_ID_CACHE, /* Packet is freed and sitting in the packet cache */
|
|
IPCOM_PKT_ID_SCTP_INPUT, /* Packet is processed by SCTP input */
|
|
IPCOM_PKT_ID_ETH_TX, /* Transmitted on Ether */
|
|
IPCOM_PKT_ID_FWD_TX, /* Transmitted by forwarder */
|
|
IPCOM_PKT_ID_TUNNEL_RX, /* Received on tunnel interface */
|
|
IPCOM_PKT_ID_TUNNEL_TX, /* Transmitted on tunnel interface */
|
|
|
|
IPCOM_PKT_ID_LAST
|
|
};
|
|
|
|
#endif
|
|
|
|
#ifdef IP_DEBUG
|
|
|
|
#ifdef IP_LW_DEBUG
|
|
#undef IP_LW_DEBUG
|
|
#endif
|
|
|
|
typedef struct Ipcom_pkt_trace_buffer_struct
|
|
{
|
|
enum Ipcom_pkt_id id;
|
|
Ip_pid_t pid; /* Process ID of the task owning this packet
|
|
when the trace entry was stored */
|
|
IP_CONST char *file; /* The file from where the trace entry was
|
|
made */
|
|
int line; /* The line from where the trace entry was
|
|
made */
|
|
}
|
|
Ipcom_pkt_trace_buffer;
|
|
|
|
|
|
#define IPCOM_PKT_TRACE_FL(pkt, id_arg, file_arg, line_arg) \
|
|
do { \
|
|
Ip_u32 tbval = (pkt)->next_trace++; \
|
|
Ipcom_pkt_trace_buffer *tb; \
|
|
if (tbval >= IPCOM_PKT_TRACE_BUFFER_LEN) \
|
|
tbval = 0; \
|
|
tb = &(pkt)->trace_buffer[tbval]; \
|
|
if ((pkt)->next_trace >= IPCOM_PKT_TRACE_BUFFER_LEN) \
|
|
(pkt)->next_trace = 0; \
|
|
tb->id = id_arg; \
|
|
tb->pid = ipcom_getpid();\
|
|
tb->file = file_arg; \
|
|
tb->line = line_arg; \
|
|
} while (0);
|
|
|
|
#endif
|
|
|
|
#ifdef IP_LW_DEBUG
|
|
|
|
#define IPCOM_PKT_SANITY_TCP(p) do { if ((p)->start < 0) *(int *)0x15 = 0x14; } while(0)
|
|
#define IPCOM_PKT_SANITY_IP(p) do { if ((p)->start < 0) *(int *)0x15 = 0x14; } while(0)
|
|
#define IPCOM_PKT_SANITY(p) do { if ((p)->start < 0) *(int *)0x15 = 0x14; } while(0)
|
|
|
|
|
|
#if defined(IPCOM_FORWARDER_NAE)
|
|
extern int ipcom_forwarder_nae_id(void);
|
|
#else
|
|
#define ipfwd_db_get_nae() (0)
|
|
#endif
|
|
|
|
#define IPCOM_PKT_TRACE_FL(pkt, id_arg, file_arg, line_arg) \
|
|
do { \
|
|
(pkt)->lw_trace = id_arg; \
|
|
(pkt)->lw_nae = ipcom_forwarder_nae_id(); \
|
|
} while(0);
|
|
|
|
#endif /* IP_LW_DEBUG */
|
|
|
|
#if !defined(IP_LW_DEBUG) && !defined(IP_DEBUG)
|
|
#define IPCOM_PKT_TRACE_FL(pkt, id_arg, file, line)
|
|
#define IPCOM_PKT_SANITY_TCP(p)
|
|
#define IPCOM_PKT_SANITY_IP(p)
|
|
#endif
|
|
|
|
#define IPCOM_PKT_TRACE(pkt, id_arg) IPCOM_PKT_TRACE_FL(pkt, id_arg, __FILE__, __LINE__)
|
|
|
|
/* Emulates the old pkt->id member */
|
|
#define IPCOM_GET_PKT_ID(pkt) \
|
|
((pkt)->trace_buffer[(pkt)->next_trace == 0 \
|
|
? IPCOM_PKT_TRACE_BUFFER_LEN - 1 \
|
|
: pkt->next_trace - 1].id)
|
|
|
|
|
|
/* #ifdef IP_LW_DEBUG */
|
|
#if 0
|
|
#define PKT_BUF_CHECK(p) do {if ((Ip_u32)p & 0x7ff){*(int *)3 = 5;}} while(0)
|
|
#define PKT_PKT_CHECK(p) do {if (((Ip_u32)p & 0x7ff) != 0x700){*(int *)4 = 9;}} while(0)
|
|
#else
|
|
#define PKT_BUF_CHECK(p)
|
|
#define PKT_PKT_CHECK(p)
|
|
#endif
|
|
|
|
#ifdef IPCOM_USE_NON_ETHERNET
|
|
#define IPCOM_NONETH_SET_LINKINFO(_pkt, _llsize, _type) \
|
|
(_pkt)->link_cookie = (Ip_ptrdiff_t)((((_llsize) << 16) & 0xFFFF0000) | ((_type) & 0x0000FFFF))
|
|
#define IPCOM_NONETH_GET_LLSIZE(_pkt) \
|
|
((((Ip_u32)((_pkt)->link_cookie)) >> 16) & 0xFFFF)
|
|
#define IPCOM_NONETH_GET_TYPE(_pkt) \
|
|
(((Ip_u32)((_pkt)->link_cookie)) & 0xFFFF)
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt_freefunc
|
|
*===========================================================================
|
|
* Function to free the pkt->data buffer.
|
|
*/
|
|
typedef void (*Ipcom_pkt_freefunc)(void *data, void *cookie);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt_dtor
|
|
*===========================================================================
|
|
* Function that will be run just before the packet is freed.
|
|
*/
|
|
typedef void (*Ipcom_pkt_dtor)(struct Ipcom_pkt_struct *pkt);
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt_opt_t
|
|
*===========================================================================
|
|
*/
|
|
#ifdef IPCOM_USE_PKT_OPS
|
|
/* TCP Segmentation Offload specific functions */
|
|
typedef void (*Ipcom_pkt_set_tso)(struct Ipcom_pkt_struct *self, int mss, int tcp_hdr_len);
|
|
typedef Ip_bool (*Ipcom_pkt_is_tso_active)(struct Ipcom_pkt_struct *self);
|
|
|
|
typedef struct Ipcom_pkt_ops_struct
|
|
{
|
|
#ifdef IPCOM_USE_TSO
|
|
Ipcom_pkt_set_tso set_tso;
|
|
Ipcom_pkt_is_tso_active is_tso_active;
|
|
#endif /* IPCOM_USE_TSO */
|
|
}
|
|
Ipcom_pkt_ops_t;
|
|
#endif /* IPCOM_USE_PKT_OPS */
|
|
|
|
#ifdef IP_PORT_VXWORKS
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt_done_func
|
|
*===========================================================================
|
|
* Function to free a packet from VxWorks code, possibly calling an output
|
|
* done function.
|
|
*/
|
|
#ifdef IP_DEBUG
|
|
typedef void (*Ipcom_pkt_done_func)(struct Ipcom_pkt_struct *pkt,
|
|
char * file, int line);
|
|
#define IPCOM_PKT_DONE_DEFAULT ipcom_pkt_dfree
|
|
#else
|
|
typedef void (*Ipcom_pkt_done_func)(struct Ipcom_pkt_struct *pkt);
|
|
#define IPCOM_PKT_DONE_DEFAULT ipcom_pkt_free
|
|
#endif /* IP_DEBUG */
|
|
#endif /* IP_PORT_VXWORKS */
|
|
|
|
|
|
#if (defined(IPCOM_FORWARDER_NAE)) && defined(IP_LW_DEBUG)
|
|
|
|
extern int ipcom_forwarder_nae_id(void);
|
|
|
|
#define NAE_OWNER_CHECK(p) do \
|
|
{\
|
|
if ((p)->nae_owner != ipcom_forwarder_nae_id())\
|
|
{\
|
|
printf("%s(%d): NAE %d is not owner of packet(%p:%d)\n", __FUNCTION__, __LINE__, ipcom_forwarder_nae_id(), p, (p)->nae_owner);\
|
|
*(int *)9 = 1;\
|
|
}\
|
|
} while(0)
|
|
|
|
IP_EXTERN void ipcom_nae_owner_set(struct Ipcom_pkt_struct *pkt);
|
|
IP_EXTERN void ipcom_nae_owner_clear(struct Ipcom_pkt_struct *pkt);
|
|
|
|
#define NAE_OWNER_CLEAR(p) ipcom_nae_owner_clear(p)
|
|
#define NAE_OWNER_SET(p) ipcom_nae_owner_set(p)
|
|
#else
|
|
#define NAE_OWNER_CHECK(p)
|
|
#define NAE_OWNER_CLEAR(p)
|
|
#define NAE_OWNER_SET(p)
|
|
#endif
|
|
|
|
#if defined(IPCOM_FORWARDER_NAE)
|
|
#define IPCOM_PKT_GET_TAG(pkt) ((pkt)->nae_key)
|
|
#else
|
|
#define IPCOM_PKT_GET_TAG(pkt) (0)
|
|
#endif
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Ipcom_pkt
|
|
*===========================================================================
|
|
*/
|
|
|
|
typedef struct Ipcom_pkt_struct
|
|
{
|
|
/* Public structures */
|
|
int fd; /* Socket descriptor. */
|
|
Ip_u16 vr_index; /* The virtual router index */
|
|
Ip_u16 offset; /* IP fragment offset */
|
|
Ip_u32 ifindex; /* Interface index. */
|
|
Ip_u32 flags; /* Packet flags. */
|
|
|
|
int ipstart; /* Start of IP (v4/v6) header */
|
|
int tlstart; /* Start of transport header */
|
|
int start; /* Start of layer data */
|
|
int end; /* End of layer data */
|
|
int tcp_offset; /* useless since VxWorks6.9.4.11 */
|
|
int tcp_mtu; /* useless since VxWorks6.9.4.11 */
|
|
#ifdef IPMACSEC
|
|
/* The following are ignored if SecY/Controlled Port support is not available */
|
|
Ip_u8 tx_use_uncontrolled_port:1; /* default is to send pkts on the controlled port (CP), set this flag if otherwise desired */
|
|
Ip_u8 tx_use_controlled_port:1; /* This overrides the tx_use_uncontrolled_port field and forces packets over the CP */
|
|
Ip_u8 rx_uncontrolled_port:1; /* If set, indicates that this packet was received on the uncontrolled port */
|
|
Ip_u8 rx_secy_done:1; /* If set, indicates that this packet was already processed by MACsec SecY */
|
|
Ip_u8 rx_authentic:2; /* If set, indicates that this packet was authenticated (by MACsec SecY) upon reception */
|
|
Ip_u8 rx_private:2; /* If set, indicates that this packet was protected (encrypted) in transit (by MACsec SecY) */
|
|
/* */
|
|
#endif
|
|
/* 32 bytes for cache alignment */
|
|
/***** Private structures *****/
|
|
|
|
#if defined (IPCOM_USE_FORWARDER)
|
|
void *nae_ctx; /* NAE context specific
|
|
information. Its meening might be
|
|
different on different
|
|
achitectures.*/
|
|
int nae_key;
|
|
int nae_owner;
|
|
#ifdef IPCOM_USE_P4080_FORWARDER
|
|
void *nae_msg; /* used for storing associated
|
|
Ipcom_fw_pkt_t structure */
|
|
#endif
|
|
#endif
|
|
|
|
int hw_tag;
|
|
|
|
#ifdef IPCOM_STORE_PHYSICAL_IF
|
|
Ip_u32 physical_ifindex; /* The physical rx interface */
|
|
struct Ipcom_netif_struct *physical_netif; /* The physical rx netif */
|
|
#endif
|
|
|
|
Ip_ptrdiff_t link_cookie; /* Link specific cookie. */
|
|
Ip_u32 chk; /* Checksum place holder. */
|
|
Ip_u8 recurs_level; /* Number of times the IP-layer output function has been
|
|
called in the current call-chain */
|
|
Ip_u8 vrid; /* VRRP ID of this packet */
|
|
|
|
Ip_u16 lla_size; /* Size of Source MAC LLA */
|
|
int lla_off; /* Source MAC LLA */
|
|
|
|
Ip_u8 ipsec_no_sa; /* IPSEC no input sa matched */
|
|
Ip_u8 ipsec_skip; /* IPSEC already done on this output packet */
|
|
Ip_u16 ipsec_hlen; /* IPSEC output packet header and trailer space (forwarded packets only) */
|
|
|
|
Ip_u16 ipsec_seq; /* IPSEC sequence tag */
|
|
Ip_u8 ipsec_input; /* IPSEC input */
|
|
Ip_u8 ipsec_domain; /* IPSEC domain */
|
|
|
|
/* All fields after and including maxlen is not copied when a packet is cloned */
|
|
int maxlen; /* Maximum length of data buffer. */
|
|
#if defined(IPCOM_USE_SMP) || defined(IPCOM_FORWARDER_NAE) || defined(IPCOM_FORWARDER_SMP)
|
|
Ipcom_atomic_t atomic_ref_count; /* The reference count for this packet */
|
|
#else
|
|
int ref_count;
|
|
#endif
|
|
/* Data space. Note: 'data' _must_ start at 32-bit alignemnt! */
|
|
Ip_u8 *data;
|
|
#ifdef IP_PORT_VXWORKS
|
|
Ipcom_pkt_done_func done; /* (send) done function */
|
|
void *done_arg; /* extra info for done() function */
|
|
|
|
int net_svc; /* network service type for benefit of
|
|
the MUX */
|
|
#endif
|
|
void *data_freefunc_cookie; /* Free function cookie */
|
|
Ipcom_pkt_freefunc data_freefunc; /* Function to free the pkt->data buffer */
|
|
Ipcom_pkt_dtor dtor;
|
|
|
|
/* 32 bytes for cache alignment, if IPCOM_STORE_PHYSICAL_IF is not defined */
|
|
|
|
struct Ipcom_pkt_struct *next; /* Next packet in a list */
|
|
struct Ipcom_pkt_struct *next_fragment; /* Next fragment in a datagram */
|
|
struct Ipcom_pkt_struct *next_original; /* Pointer to original pkt. */
|
|
struct Ipcom_pkt_struct *next_part; /* Next packet if this
|
|
packet is distributed
|
|
over more than one
|
|
packet (scatter/gather) */
|
|
|
|
#ifdef IPCOM_USE_PKT_OPS
|
|
IP_CONST Ipcom_pkt_ops_t *ops;
|
|
#endif
|
|
|
|
/* Extra information accociated with this packet. Must only be
|
|
accessed through the ipcom_pkt_*_info() functions. */
|
|
unsigned next_extra_data;
|
|
Ip_ptrdiff_t extra_data[IPCOM_PKT_INFO_LEN / sizeof(Ip_ptrdiff_t)];
|
|
|
|
#ifdef IPROHC
|
|
/* Store pkt's destination address for ethernet multicast */
|
|
Ip_bool flag_rohc;
|
|
Ip_u32 dst[4];
|
|
#endif /* IPROHC */
|
|
|
|
Ip_bool fw_checked;
|
|
|
|
/* Force link layer to output pkt with this frametype set */
|
|
Ip_u16 force_frame_type;
|
|
|
|
#ifdef IPCOM_USE_MUX_DRV
|
|
void *neigh;
|
|
#endif
|
|
|
|
#ifdef IP_LW_DEBUG
|
|
int lw_trace;
|
|
int lw_nae;
|
|
int lw_error;
|
|
#endif
|
|
|
|
#ifdef IP_DEBUG
|
|
struct Ipcom_pkt_struct *next_alloc; /* List of allocated
|
|
packets */
|
|
Ip_u32 num_allocated; /* Number of time this
|
|
packet has been
|
|
allocated */
|
|
unsigned next_trace;
|
|
Ipcom_pkt_trace_buffer trace_buffer[IPCOM_PKT_TRACE_BUFFER_LEN];
|
|
|
|
#endif /* IP_DEBUG */
|
|
|
|
/*
|
|
* Break binary compatibility only if the PTP features are enabled in the
|
|
* VXB
|
|
*/
|
|
#ifdef _WRS_CONFIG_COMPONENT_IPPTP
|
|
|
|
/*
|
|
* Queue Priority
|
|
*
|
|
* Specific the queue number or the priority.
|
|
*
|
|
* 31 | 30 16 | 15 0
|
|
* | |- specific the priority
|
|
* | |- specific the Queue number
|
|
* |- 1: Use queue number, 0: using priority
|
|
*
|
|
*/
|
|
|
|
#ifndef PKT_PRIORITY_FLAGS
|
|
#define PKT_PRIORITY_FLAGS
|
|
#define PKT_PRIORITY_FLAGS_QNUM_EN (0x1 << 31) /* Enable to use queue number */
|
|
#define PKT_PRIORITY_FLAGS_QNUM_OFFSET (16) /* queue number offset */
|
|
#define PKT_PRIORITY_FLAGS_QNUM_MASK (0x7FFF0000) /* queue number mask */
|
|
#define PKT_PRIORITY_FLAGS_SR 0x1 /* Stream Reservation */
|
|
#define PKT_PRIORITY_FLAGS_SP 0x2 /* Strict Priority */
|
|
#define PKT_PRIORITY_FLAGS_BE 0x3 /* Best Effort */
|
|
#define PKT_PRIORITY_FLAGS_SR2 0x4 /* Stream Reservation 2 */
|
|
#endif /* PKT_PRIORITY_FLAGS */
|
|
|
|
Ip_u32 queue_priority;
|
|
|
|
#ifndef PKT_TSN_FLAGS
|
|
#define PKT_TSN_FLAGS
|
|
#define PKT_TSN_TIME_STAMP_DISABLE 0x0
|
|
#define PKT_TSN_TIME_STAMP_FETCH_EN 0x1
|
|
#define PKT_TSN_TIME_STAMP_OFFSET_EN 0x2
|
|
#define PKT_TSN_TIME_LAUNCH_EN 0x4
|
|
#endif /* PKT_TSN_FLAGS */
|
|
|
|
Ip_u32 time_flags;
|
|
|
|
/* The time Stamp returned with the packet */
|
|
|
|
struct Ip_timespec timestamp_fetch; /* With sec, nsec */
|
|
|
|
/* the 1588 time stamp offset for Tx pkt */
|
|
|
|
Ip_u8 timestamp_offset;
|
|
|
|
Ip_u32 launch_time; /* used to set the launch time */
|
|
#endif
|
|
}
|
|
Ipcom_pkt;
|
|
|
|
/* packet flags 'pkt->flags'. */
|
|
|
|
/* Generic flags */
|
|
#define IPCOM_PKT_FLAG_ALLOC (1 << 0) /* The packet is allocated */
|
|
#define IPCOM_PKT_FLAG_LOOPED_BACK (1 << 1) /* This (incoming) packet was sent and received on the same interface */
|
|
#define IPCOM_PKT_FLAG_DELAYED (1 << 2) /* IPLITE: This packet was queued for delayed output from inputd/tickd. */
|
|
#define IPCOM_PKT_FLAG_READONLY (1 << 2) /* IPNET: This packet is read only. */
|
|
#define IPCOM_PKT_FLAG_ZBUF (1 << 3) /* ZeroCopy. Used to remember not to perform checksum of UDP payload. */
|
|
|
|
/* Socket layer flags */
|
|
#define IPCOM_PKT_FLAG_NONBLOCKING (1 << 4) /* Packet was sent using a socket in non-blocking mode */
|
|
#define IPCOM_PKT_FLAG_DONTROUTE (1 << 5) /* Send this on the interface that match the network portion of
|
|
the destionation address */
|
|
/* Network layer flags */
|
|
#define IPCOM_PKT_FLAG_IPSEC_OUT (1 << 6) /* Passed through IPSec (output) */
|
|
#define IPCOM_PKT_FLAG_NAT (1 << 7) /* NAT translated packet */
|
|
#define IPCOM_PKT_FLAG_BROADCAST (1 << 8) /* Destination address is a broadcast address */
|
|
#define IPCOM_PKT_FLAG_MULTICAST (1 << 9) /* Destination address is a multicast address */
|
|
#define IPCOM_PKT_FLAG_LOOP_MCAST (1 << 10) /* Multicast packets should be looped back */
|
|
#define IPCOM_PKT_FLAG_FORWARDED (1 << 11) /* Forwarded packet. */
|
|
#define IPCOM_PKT_FLAG_FRAGMENT (1 << 12) /* This packet is an IP fragment */
|
|
#define IPCOM_PKT_FLAG_MORE_FRAG (1 << 13) /* There is more fragments (but 'next_fragment' can still be IP_NULL) */
|
|
#define IPCOM_PKT_FLAG_HAS_IP_HDR (1 << 14) /* This outgoing packet has an IP header */
|
|
#define IPCOM_PKT_FLAG_ZERO_DATA (1 << 15) /* Set if all of the data is 0, or the data's checksum just is 0 when sending */
|
|
#define IPCOM_PKT_FLAG_IPV4 (1 << 16) /* Used for incoming packets, this is an IPv4 packet */
|
|
#define IPCOM_PKT_FLAG_IPV6 (1 << 17) /* Used for incoming packets, this is an IPv6 packet */
|
|
#define IPCOM_PKT_FLAG_TUNNELED (1 << 18) /* Used for incoming packets, this packet has been tunneled */
|
|
#define IPCOM_PKT_FLAG_OUTPUT (1 << 19) /* Set for outgoing packets */
|
|
#define IPCOM_PKT_FLAG_IPSEC_DONE (1 << 20) /* Incoming ESP/AH packet authenticated by IPSEC */
|
|
#define IPCOM_PKT_FLAG_PROGRESS (1 << 21) /* The transport layer is making forward progress, so the
|
|
neighbor used to communicat with the peer is reachable */
|
|
#define IPCOM_PKT_FLAG_HW_CHECKSUM (1 << 22) /* Output: the hardware must calculate the checksum,
|
|
the checksum will be calculated from &pkt->data[pkt->tlstart]
|
|
to &pkt->data[pkt->end] and stored at pkt->data[pkt->tlstart + pkt->chk]
|
|
Input: Transport header checksum has been verified */
|
|
#define IPCOM_PKT_FLAG_TL_CHECKSUM (1 << 23) /* The pkt->chk field contains the checksum of the transport data */
|
|
#define IPCOM_PKT_FLAG_VLAN_TAG (1 << 24) /* The packet contains IPCOM_INFO_VLAN_TAG info which in turn contains
|
|
a vlan tag (host byte order). The tag will be insert on transmitted
|
|
frames. Ingress packets with this flag set is untagged in the packet
|
|
and the tag they had when received is stored in an
|
|
IPCOM_INFO_VLAN_TAG entry.
|
|
*/
|
|
|
|
/* Link layer flags */
|
|
#define IPCOM_PKT_FLAG_LINK_BROADCAST (1 << 25) /* The packet was sent to a link layer broadcast address */
|
|
#define IPCOM_PKT_FLAG_LINK_MULTICAST (1 << 26) /* The packet was sent to a link layer multicast address */
|
|
#define IPCOM_PKT_FLAG_LINK_OTHER (1 << 27) /* The packet was sent to a link layer address not assigned to this host */
|
|
#define IPCOM_PKT_FLAG_LINK1 (1 << 28) /* Private link layer flag #1 */
|
|
#define IPCOM_PKT_FLAG_LINK2 (1 << 29) /* Private link layer flag #2 */
|
|
#define IPCOM_PKT_FLAG_LINK3 (1 << 30) /* Private link layer flag #3 */
|
|
#define IPCOM_PKT_FLAG_LINK4 (1 << 31) /* Private link layer flag #4 */
|
|
|
|
/* packet malloc priorities */
|
|
#define IPCOM_PKT_MPRIO_MIN 0
|
|
#define IPCOM_PKT_MPRIO_MAX 10
|
|
#define IPCOM_PKT_MPRIO_DEFAULT (IPCOM_PKT_MPRIO_MIN + 1)
|
|
#define IPCOM_PKT_MPRIO_STACK IPCOM_PKT_MPRIO_MAX
|
|
#define IPCOM_PKT_MPRIO_DRV IPCOM_PKT_MPRIO_MAX
|
|
|
|
/* packet output priorities */
|
|
#define IPCOM_PKT_GET_OPRIO(pkt) ipcom_pkt_get_int(pkt, IPCOM_PKT_INFO_OPRIO, Ip_u8)
|
|
#define IPCOM_PKT_SET_OPRIO(pkt, op) ipcom_pkt_set_int(pkt, IPCOM_PKT_INFO_OPRIO, op, Ip_u8)
|
|
#define IPCOM_PKT_OPRIO_BEST_EFFORT 0x0 /* Default priority */
|
|
#define IPCOM_PKT_OPRIO_FILLER 0x1 /* Background tasks (ex: e-mail) */
|
|
#define IPCOM_PKT_OPRIO_BULK 0x2 /* Bulk transfer (ex: FTP) */
|
|
#define IPCOM_PKT_OPRIO_INTERACTIVE 0x3 /* Interactive traffic (ex: SSH) */
|
|
#define IPCOM_PKT_OPRIO_INTERACTIVE_BULK 0x4 /* Interactive bulk traffic (ex: video conferences) */
|
|
#define IPCOM_PKT_OPRIO_CONTROL 0x5 /* Control traffic (ex: ) */
|
|
#define IPCOM_PKT_OPRIO_MAX 0xf
|
|
|
|
#define IPCOM_PKT_GET_DROP_PRECEDENCE(pkt) ipcom_pkt_get_int(pkt, IPCOM_PKT_INFO_DROP_PRECEDENCE, Ip_u8)
|
|
#define IPCOM_PKT_SET_DROP_PRECEDENCE(pkt, dp) ipcom_pkt_set_int(pkt, IPCOM_PKT_INFO_DROP_PRECEDENCE, dp, Ip_u8)
|
|
#define IPCOM_PKT_DROP_PRECEDENCE_UNDEF 0x0 /* Used for traffic that is forwarded using "best effort" policy */
|
|
#define IPCOM_PKT_DROP_PRECEDENCE_LOW 0x1 /* Drop only if absolutely neccessary */
|
|
#define IPCOM_PKT_DROP_PRECEDENCE_MEDIUM 0x2 /* Drop to avoid very long latency and very high memory consumption */
|
|
#define IPCOM_PKT_DROP_PRECEDENCE_HIGH 0x3 /* Drop packet in the case of congestion */
|
|
|
|
/* Set/get virtual router ID */
|
|
#define IPCOM_PKT_SET_VRID(pkt, vrid_) ((pkt)->vrid = vrid_)
|
|
#define IPCOM_PKT_GET_VRID(pkt) ((Ip_u8) (pkt)->vrid)
|
|
|
|
/* Packet reference count macros */
|
|
#if defined(IPCOM_USE_SMP) || defined(IPCOM_FORWARDER_NAE) || defined(IPCOM_FORWARDER_SMP)
|
|
# define IPCOM_PKT_INIT_REF_COUNT(pkt) (ipcom_atomic_set(&(pkt)->atomic_ref_count, 1))
|
|
# define IPCOM_PKT_GET_REF_COUNT(pkt) (ipcom_atomic_get(&(pkt)->atomic_ref_count))
|
|
# define IPCOM_PKT_ADD_REF(pkt) IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_ADDREF); \
|
|
ipcom_atomic_inc(&(pkt)->atomic_ref_count)
|
|
#define IPCOM_PKT_DEL_REF(pkt) (ipcom_atomic_sub_and_return(&(pkt)->atomic_ref_count,1))
|
|
# ifdef IP_PORT_LKM
|
|
# define IPCOM_PKT_HAS_MULTIPLE_OWNERS(pkt) (ipcom_atomic_get(&(pkt)->atomic_ref_count) > 1 || ipcom_lkm_skb_get_ref_count(pkt) > 1)
|
|
# else
|
|
# define IPCOM_PKT_HAS_MULTIPLE_OWNERS(pkt) (ipcom_atomic_get(&(pkt)->atomic_ref_count) > 1)
|
|
# endif
|
|
#else /* !IPCOM_USE_SMP && !IPCOM_FORWARDER_NAE */
|
|
# define IPCOM_PKT_INIT_REF_COUNT(pkt) ((pkt)->ref_count = 1)
|
|
# define IPCOM_PKT_GET_REF_COUNT(pkt) ((pkt)->ref_count)
|
|
# define IPCOM_PKT_ADD_REF(pkt) IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_ADDREF); \
|
|
(++(pkt)->ref_count)
|
|
#define IPCOM_PKT_DEL_REF(pkt) (--(pkt)->ref_count)
|
|
# ifdef IP_PORT_LKM
|
|
# define IPCOM_PKT_HAS_MULTIPLE_OWNERS(pkt) ((pkt)->ref_count > 1 || ipcom_lkm_skb_get_ref_count(pkt) > 1)
|
|
# else
|
|
# define IPCOM_PKT_HAS_MULTIPLE_OWNERS(pkt) ((pkt)->ref_count > 1)
|
|
# endif
|
|
#endif /* IPCOM_USE_SMP, IPCOM_FORWARDER_NAE */
|
|
|
|
#define IPCOM_PKT_RESET_CHECKSUM(pkt) \
|
|
do { \
|
|
IP_BIT_CLR((pkt)->flags, IPCOM_PKT_FLAG_HW_CHECKSUM|IPCOM_PKT_FLAG_TL_CHECKSUM); \
|
|
(pkt)->chk = 0; \
|
|
} while (0)
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC void *
|
|
ipcom_pkt_sg_get_data(Ipcom_pkt *pkt, int offset);
|
|
|
|
IP_PUBLIC Ipcom_pkt *
|
|
ipcom_pkt_make_linear(Ipcom_pkt *pkt);
|
|
|
|
IP_PUBLIC Ipcom_pkt *
|
|
ipcom_pkt_trim_head(Ipcom_pkt *pkt, int trimsize);
|
|
|
|
IP_PUBLIC int
|
|
ipcom_pkt_trim_tail(Ipcom_pkt *pkt, int trimsize);
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* ipcom_pktbuf_free - free packet buffer disassociated with Ipcom_pkt packet
|
|
*
|
|
* This routine frees a buffer that was previously allocated along with
|
|
* an Ipcom_pkt structure using a ipcom_pkt_malloc() call with non-zero
|
|
* <size> argument.
|
|
*
|
|
* The <buf> argument to this routine is the <data> member from the previously
|
|
* allocated Ipcom_pkt packet, and the <cookie> argument is the packet's
|
|
* <data_freefunc_cookie> member. After recording the original packet's
|
|
* <data> and <data_freefunc_cookie> members, the packet's <data> member
|
|
* should be cleared to disassociate it from the packet buffer and prevent a
|
|
* double-free of the buffer when the original Ipcom_pkt is freed using
|
|
* ipcom_pkt_free().
|
|
*
|
|
* This function is intended to support limited cases in which it is
|
|
* convenient to allocate both an Ipcom_pkt packet header and a packet buffer
|
|
* in an ipcom_pkt_malloc() call, but to separate the parts for different
|
|
* uses with different lifetimes. This kind of separation can increase
|
|
* cache efficiency in some network drivers that allocate RX packets out of
|
|
* the ipnet packet pool; the disassociated buffer can be put into the device's
|
|
* RX ring to receive a packet off the wire at some time in the future,
|
|
* while the disassociated and still cache-hot Ipcom_pkt can be reassociated
|
|
* with a filled buffer that holds a received packet for immediate delivery to
|
|
* the stack.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <buf>
|
|
* A pointer to the disassociated buffer to free; the <data> member
|
|
* of the formerly associated Ipcom_pkt with which the buffer was allocated.
|
|
* \i <cookie>
|
|
* The <data_freefunc_cookie> member of the formerly associated packet.
|
|
* \ie
|
|
*
|
|
* RETURNS: \&N/A.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_PUBLIC void ipcom_pktbuf_free
|
|
(
|
|
Ip_u8 *buf,
|
|
void * cookie
|
|
);
|
|
|
|
|
|
#ifdef IP_DEBUG
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_pkt_dfree
|
|
*===========================================================================
|
|
* Description: Frees a packet that was allocated with ipcom_pkt_malloc().
|
|
* Parameters: pkt - The packet to free.
|
|
* file - The file the packet was freed in.
|
|
* line - The line the packet was freed at.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC void ipcom_pkt_dfree(Ipcom_pkt *pkt, char *file, int line);
|
|
#define ipcom_pkt_free(pkt) ipcom_pkt_dfree(pkt, __FILE__, __LINE__)
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_pkt_dmalloc
|
|
*===========================================================================
|
|
* Description: Allocates the requested amount of MTU data. MTU data is
|
|
* defined as IP + transport + application (not link header).
|
|
* Parameters: size - The size of the data MTU in bytes.
|
|
* fcflags - function call flags (see ipcom_cstyle.h)
|
|
* file - The file the packet was allocated in.
|
|
* line - The line the packet was allocated at.
|
|
* Returns: A IPCOM packet.
|
|
*
|
|
*/
|
|
IP_PUBLIC Ipcom_pkt *ipcom_pkt_dmalloc(Ip_size_t size, int fcflags, char *file, int line);
|
|
#define ipcom_pkt_malloc(size, fcflags) ipcom_pkt_dmalloc(size, fcflags, __FILE__, __LINE__)
|
|
|
|
#else /* ifndef IP_DEBUG */
|
|
|
|
/******************************************************************************
|
|
*
|
|
* ipcom_pkt_free - free memory used by the 'Ipcom_pkt' structure
|
|
*
|
|
* This routine frees the memory used by the 'Ipcom_pkt' structure. If the
|
|
* packet's data_freefunc() function is non-NULL, it is called to free the
|
|
* data buffer attached to the packet. Otherwise, if the packet has an
|
|
* attached data buffer, the buffer is assumed to have been allocated as part
|
|
* of ipcom_pkt_malloc(), and is freed in the default way.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* A pointer to the packet to free.
|
|
* \ie
|
|
*
|
|
* RETURNS: \&N/A.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_FASTTEXT IP_PUBLIC void ipcom_pkt_free
|
|
(
|
|
Ipcom_pkt *pkt
|
|
);
|
|
|
|
#ifdef IP_LW_DEBUG
|
|
|
|
extern void ipcom_pkt_free_line(Ipcom_pkt *, int);
|
|
|
|
#define ipcom_pkt_free(a) ipcom_pkt_free_line(a, __LINE__)
|
|
#endif
|
|
|
|
/******************************************************************************
|
|
*
|
|
* ipcom_pkt_malloc - allocate memory for 'Ipcom_pkt' structures
|
|
*
|
|
* This routine is used to allocate memory for 'Ipcom_pkt' structures. The
|
|
* <size> parameter specifies the number of octets to allocate for the IP
|
|
* header, transport header and application data. The TCP/IP stack adds space
|
|
* for the link-layer header. This means that the full size of the data buffer
|
|
* will be greater than <size>. If <size> is zero, the call allocates only
|
|
* an Ipcom_pkt structure with no data buffer attached.
|
|
*
|
|
* The total amount of memory allocated by ipcom_pkt_malloc() can never exceed
|
|
* the predefined TCP/IP stack packet buffer pool <maxsize>.
|
|
*
|
|
* The <fcflags> parameter must be set based on blocking mode and the context of
|
|
* the process that calls ipcom_pkt_malloc(). Available flags are:
|
|
* \is
|
|
* \i 'IP_FLAG_FC_BLOCKOK'
|
|
* Ok for function call to block (used when default is non-blocking).
|
|
* \i 'IP_FLAG_FC_NOBLOCK'
|
|
* Function call may not block (used when default is blocking).
|
|
* \ie
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <size>
|
|
* Either zero, in which case no data buffer is allocated; or else the size in
|
|
* bytes of the portion of the packet data buffer reserved for the IP datagram
|
|
* proper, not counting the link header: the MTU.
|
|
* \i <fcflags>
|
|
* Function call flags.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to a newly allocated packet structure, or 'IP_NULL', if no
|
|
* buffer was available.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_FASTTEXT IP_PUBLIC Ipcom_pkt *ipcom_pkt_malloc
|
|
(
|
|
Ip_size_t size,
|
|
int fcflags
|
|
);
|
|
|
|
#endif /* IP_DEBUG */
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_create - create a valid 'ipcom_pkt' structure from user allocated
|
|
* memory
|
|
*
|
|
* This routine creates a valid 'ipcom_pkt' structure from user allocated memory.
|
|
* This routine can be used to avoid doing memory copy of data from a device
|
|
* driver buffer into an 'ipcom_pkt' structure.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Pointer to a buffer which is large enough to hold an 'ipcom_pkt' structure.
|
|
* \i <data>
|
|
* Pointer to the buffer which contains the packet <data>.
|
|
* \i <data_len>
|
|
* The length of the data buffer.
|
|
* \i <freefunc>
|
|
* A routine that is called when the stack is finished using the packet.
|
|
* \i <cookie>
|
|
* User-defined data that is passed as the second argument to <freefunc>.
|
|
* \ie
|
|
*
|
|
* RETURNS: \&N/A.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_FASTTEXT IP_PUBLIC void ipcom_pkt_create
|
|
(
|
|
Ipcom_pkt *pkt,
|
|
void *data,
|
|
Ip_size_t data_len,
|
|
Ipcom_pkt_freefunc freefunc,
|
|
void *cookie
|
|
);
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_is_stack_task - check if the current task is used to input packet
|
|
*
|
|
* This routine is used to check if the current task is used to input packets
|
|
* into the stack
|
|
*
|
|
* ex: The function will return IP_TRUE when running in the context of the
|
|
* tNetTask on VxWorks or ipnetX on Linux
|
|
*
|
|
*
|
|
* Parameters:
|
|
*
|
|
* RETURNS: IP_TRUE if running in a OS stack task
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_PUBLIC Ip_bool ipcom_is_stack_task
|
|
(
|
|
void
|
|
);
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_input - input packets when called from a non-interrupt context
|
|
*
|
|
* This routine is used to input packets when called from a non-interrupt
|
|
* context.
|
|
*
|
|
* 'pkt-\>start' must be the offset of the link-layer header and 'pkt-\>end' must
|
|
* be the offset to the end of the link-layer data.
|
|
*
|
|
* The ipcom_is_stack_task() function must return IP_TRUE when running the the
|
|
* context of the OS task that calls this function.
|
|
*
|
|
* The TCP/IP stack controls the lifetime of the packet when ipcom_pkt_input() is
|
|
* called, even if the call fails.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <netif>
|
|
* Interface pointer.
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: \&N/A.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_FASTTEXT IP_PUBLIC void ipcom_pkt_input
|
|
(
|
|
struct Ipcom_netif_struct *netif,
|
|
Ipcom_pkt *pkt
|
|
);
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_input_queue - adds packets to the TCP/IP stack\'s input queue
|
|
*
|
|
* This routine is used by driver processes that do not want to parse incoming
|
|
* packets in their own context, for example, interrupt processes. The routine
|
|
* adds packets to the TCP/IP stack\'s packet input queue.
|
|
*
|
|
* 'pkt-\>start' must be the offset of the link-layer header and 'pkt-\>end' must
|
|
* be the offset to the end of the link-layer data.
|
|
*
|
|
* The stack controls the lifetime of the packet when this function is called,
|
|
* even if the call fails.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <netif>
|
|
* Interface pointer.
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: '0' if the packet was successfully processed. A negative ERRNO code
|
|
* is returned if an error occurs.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_PUBLIC int ipcom_pkt_input_queue
|
|
(
|
|
struct Ipcom_netif_struct *netif,
|
|
Ipcom_pkt *pkt
|
|
);
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_output_done - Return outgoing packet to the TCP/IP stack
|
|
*
|
|
* This routine must be called for each IPNET packet that has been sent by the
|
|
* driver.
|
|
*
|
|
* The fcflags parameter is set based on blocking mode and the context of the
|
|
* process that calls ipcom_pkt_output_done(). Available flags are:
|
|
* \is
|
|
* \i 'IP_FLAG_FC_BLOCKOK'
|
|
* Ok for function call to block (used when default is non-blocking).
|
|
* \i 'IP_FLAG_FC_NOBLOCK'
|
|
* Function call may not block (used when default is blocking.
|
|
* \i 'IP_FLAG_FC_ISRCONTEXT'
|
|
* The function is called from ISR (interrupt context).
|
|
* \i 'IP_FLAG_FC_STACKCONTEXT'
|
|
* The function is called from the stack context and code-locked.
|
|
* \ie
|
|
*
|
|
* ipcom_pkt_output_done() calls any callback that the application has registered
|
|
* to IPNET through ipnet_setsockopt().
|
|
*
|
|
* IPNET takes care of freeing the memory allocated by the packet, even if the
|
|
* routine returns an error.
|
|
*
|
|
* An important secondary task of ipcom_pkt_output_done() is to wake up processes
|
|
* waiting to output more packets on the interface. Therefore, it is valid to
|
|
* call ipcom_pkt_output_done() with 'pkt ==' 'IP_NULL' just to trigger more
|
|
* output (if' -IP_ERRNO_EWOULDBLOCK' was previously returned by
|
|
* ipnet_drv_output().
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <netif>
|
|
* Interface pointer.
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <fcflags>
|
|
* Function call flags.
|
|
* \ie
|
|
*
|
|
* RETURNS: '0' if the packet was successfully processed. A negative ERRNO code
|
|
* if an error occurs.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_FASTTEXT IP_PUBLIC int ipcom_pkt_output_done
|
|
(
|
|
struct Ipcom_netif_struct *netif,
|
|
Ipcom_pkt *pkt,
|
|
int fcflags
|
|
);
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_to_master_os - Delivers a packet to the controlling OS.
|
|
*
|
|
* This routine will deliver the specified packet to the Operation
|
|
* System acting as master in this AMP system. This function is
|
|
* typically called when the NAE realizes it cannot process the packet
|
|
* since the packet might alter the state of the network stack,
|
|
* something that only allowed in the stack of the control OS.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: \&N/A.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
#if defined(IPCOM_FORWARDER_NAE)
|
|
IP_PUBLIC void ipcom_pkt_to_master_os
|
|
(
|
|
Ipcom_pkt *pkt
|
|
);
|
|
#endif
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_get_length - Returns the length of the packet data area.
|
|
*
|
|
* This routine returns the total length of the data area in a packet.
|
|
* A packet can consist of more than Ipcom_pkt structure. The packet
|
|
* is linked toghether via the 'next_part' pointer.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: The length of the packet data area.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE int ipcom_pkt_get_length(
|
|
IP_CONST Ipcom_pkt *pkt
|
|
)
|
|
{
|
|
if (pkt == IP_NULL)
|
|
return 0;
|
|
|
|
ip_assert(pkt->end - pkt->start >= 0);
|
|
|
|
if (pkt->next_part == IP_NULL)
|
|
return pkt->end - pkt->start;
|
|
|
|
/*
|
|
* Scatter-gather buffer. Length is the sum of all packet in the chain.
|
|
*/
|
|
return (pkt->end - pkt->start) + ipcom_pkt_get_length(pkt->next_part);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_get_partcnt - Returns the number of parts the packet is built of.
|
|
*
|
|
* This routine returns the number of parts (i.e. scatter-gather buffers)
|
|
* that this packet consists of.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: The number of parts this packet consists of.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE int ipcom_pkt_get_partcnt(
|
|
IP_CONST Ipcom_pkt *pkt
|
|
)
|
|
{
|
|
if (pkt->next_part == IP_NULL)
|
|
return 1;
|
|
|
|
return 1 + ipcom_pkt_get_partcnt(pkt->next_part);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_get_data - Return a pointer 'offset' octets into the data area.
|
|
*
|
|
* This routine returns a pointer 'offset' octets into the packet data area.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <offset>
|
|
* Number of octets into the data area the pointer should be.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer 'offset octets into the data area'
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void* ipcom_pkt_get_data(
|
|
IP_CONST Ipcom_pkt *pkt,
|
|
int offset
|
|
)
|
|
{
|
|
ip_assert(pkt->start >= 0);
|
|
ip_assert(pkt->start + offset <= pkt->end);
|
|
return &pkt->data[pkt->start + offset];
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_get_iphdr - Return a pointer to the IP header in this packet.
|
|
*
|
|
* This routine returns a pointer to the IP header stored in the data
|
|
* area of the specified packet. Note that the pointer returned is only
|
|
* guaranteed to be aligned on a 2 byte boundary.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to the IP header.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void* ipcom_pkt_get_iphdr(
|
|
IP_CONST Ipcom_pkt *pkt
|
|
)
|
|
{
|
|
ip_assert(pkt->ipstart >= 0);
|
|
ip_assert(pkt->ipstart < pkt->end);
|
|
return &pkt->data[pkt->ipstart];
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_reserve_data - Reserves space at the end of the data buffer.
|
|
*
|
|
* This routine reserves space at the end of the buffer pointer to by
|
|
* the 'data' member of Ipcom_pkt. It is intended to be used by network
|
|
* layer code that want to allocate space for its payload. This
|
|
* function must only be called for a packet that has not yet used
|
|
* since it assumes that the whole 'data' area is free. It will
|
|
* typically be called directly after ipcom_pkt_malloc().
|
|
* NOTE: The length of the used data area is 0 after this
|
|
* call. ipcom_pkt_append_data() must be used to mark parts/whole of
|
|
* this reserved area as used.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <data_len>
|
|
* Length of the reserved data area.
|
|
* \ie
|
|
*
|
|
* RETURNS: N/A
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void ipcom_pkt_reserve_data(
|
|
Ipcom_pkt *pkt,
|
|
int data_len
|
|
)
|
|
{
|
|
ip_assert(pkt->data != IP_NULL);
|
|
ip_assert(pkt->maxlen > data_len);
|
|
|
|
/* Reserve at least 46 bytes for Ethernet padding*/
|
|
if (data_len < 46)
|
|
data_len = 46;
|
|
/*
|
|
* 4 byte align the start offset.
|
|
*/
|
|
pkt->start = pkt->end = ((pkt->maxlen - data_len) & ~3);
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_push_back - Allocates space at the end of the packet buffer
|
|
* and returns a pointer to that space.
|
|
*
|
|
* This routine increases the length of the data buffer by moving the
|
|
* end of the data area 'data_len' bytes.This can be used by transport
|
|
* layer protocols that used ipcom_pkt_reserve_data() to allocate a
|
|
* large area (one MSS of TCP for example), but could only partly fill
|
|
* that area initially.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <data_len>
|
|
* Length of the data area.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to the newly allocated data area.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void* ipcom_pkt_push_back(
|
|
Ipcom_pkt *pkt,
|
|
int data_len
|
|
)
|
|
{
|
|
void *data;
|
|
ip_assert(pkt->end + data_len <= pkt->maxlen);
|
|
data = &pkt->data[pkt->end];
|
|
pkt->end += data_len;
|
|
return data;
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_push_front - Allocates space at the beginning of the packet buffer
|
|
* and returns a pointer to that space.
|
|
*
|
|
* This routine allocates space at the beginning of the packet data
|
|
* area and returns a pointer to the newly allocater area.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <data_len>
|
|
* Length of the data area.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to the newly allocated data area.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void* ipcom_pkt_push_front(
|
|
Ipcom_pkt *pkt,
|
|
int data_len
|
|
)
|
|
{
|
|
ip_assert(pkt->start >= data_len);
|
|
pkt->start -= data_len;
|
|
return &pkt->data[pkt->start];
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_pop_front - Removes space at beginning of the packet buffer
|
|
*
|
|
* This routine removes space at the beginning of the packet data area and
|
|
* returns a pointer to the beginning of the removed area
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <data_len>
|
|
* Length of the data area.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to the beginning of the removed data.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void* ipcom_pkt_pop_front(
|
|
Ipcom_pkt *pkt,
|
|
int data_len
|
|
)
|
|
{
|
|
void *data;
|
|
ip_assert(pkt->end - pkt->start >= data_len);
|
|
|
|
data = &pkt->data[pkt->start];
|
|
pkt->start += data_len;
|
|
return data;
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ipcom_pkt_pop_back - Removes octets at the end of the buffer.
|
|
*
|
|
* This routine removes octets at the end of the packet data and
|
|
* returns a pointer to the removed space.
|
|
*
|
|
* Parameters:
|
|
* \is
|
|
* \i <pkt>
|
|
* Packet pointer.
|
|
* \i <data_len>
|
|
* Length of the data area.
|
|
* \ie
|
|
*
|
|
* RETURNS: A pointer to the beginning of the removed data.
|
|
*
|
|
* ERRNO:
|
|
*/
|
|
IP_INLINE void *ipcom_pkt_pop_back(
|
|
Ipcom_pkt *pkt,
|
|
int data_len
|
|
)
|
|
{
|
|
ip_assert(pkt->end - pkt->start >= data_len);
|
|
pkt->end -= data_len;
|
|
return &pkt->data[pkt->end];
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Packet information
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
IP_PUBLIC void *ipcom_pkt_alloc_info(Ipcom_pkt *pkt,
|
|
Ip_u8 info_type,
|
|
Ip_size_t info_size);
|
|
IP_PUBLIC void ipcom_pkt_set_info(Ipcom_pkt *pkt,
|
|
Ip_u8 info_type,
|
|
Ip_size_t info_size,
|
|
void *new_info);
|
|
IP_PUBLIC void ipcom_pkt_create_info(Ipcom_pkt *pkt,
|
|
Ip_u8 info_type,
|
|
Ip_size_t info_size,
|
|
void *new_info);
|
|
|
|
IP_PUBLIC void *ipcom_pkt_get_info(IP_CONST Ipcom_pkt *pkt,
|
|
Ip_u8 info_type);
|
|
IP_PUBLIC void *ipcom_pkt_get_info_and_size(IP_CONST Ipcom_pkt *pkt,
|
|
Ip_u8 info_type,
|
|
Ip_size_t *size);
|
|
IP_PUBLIC void *ipcom_pkt_get_info_safe(IP_CONST Ipcom_pkt *pkt,
|
|
Ip_u8 info_type);
|
|
IP_PUBLIC void ipcom_pkt_copy_info(Ipcom_pkt *dst,
|
|
IP_CONST Ipcom_pkt *src);
|
|
|
|
#define ipcom_pkt_set_int(pkt, info_type, i, int_type) \
|
|
do { \
|
|
int_type i_ = (int_type)(i); \
|
|
ipcom_pkt_set_info(pkt, info_type, sizeof(int_type), &i_); \
|
|
} while (0)
|
|
|
|
#define ipcom_pkt_get_int(pkt, info_type, int_type) \
|
|
(*(int_type*)ipcom_pkt_get_info_safe(pkt, info_type))
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* USER/KERNEL copy
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IP_PORT_LKM
|
|
IP_PUBLIC void *ipcom_copy_to_user(void *s1, const void *s2, Ip_size_t n);
|
|
IP_PUBLIC void *ipcom_copy_from_user(void *s1, const void *s2, Ip_size_t n);
|
|
#else
|
|
#define ipcom_copy_to_user(s1,s2,n) ipcom_memcpy(s1,s2,n)
|
|
#define ipcom_copy_from_user(s1,s2,n) ipcom_memcpy(s1,s2,n)
|
|
#endif
|
|
/*
|
|
*===========================================================================
|
|
* SKB reference counter
|
|
*===========================================================================
|
|
*
|
|
*/
|
|
#ifdef IP_PORT_LKM
|
|
IP_PUBLIC int ipcom_lkm_skb_get_ref_count(Ipcom_pkt *pkt);
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 VARIABLES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_port_pkt_hdr_extra_size
|
|
*===========================================================================
|
|
* The amount of extra space reserved for port-specific usage at the end of
|
|
* each Ipcom_pkt structure.
|
|
*/
|
|
IP_EXTERN Ip_size_t ipcom_port_pkt_hdr_extra_size;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_conf_pkt_pool_buffer_alignment
|
|
*===========================================================================
|
|
* The minimal packet data buffer alignment for packets allocated using
|
|
* ipcom_pkt_malloc(), as required by the ipcom port. Only has effect if
|
|
* set before packet pool creation. The actual alignment guarantee will be
|
|
* the maximum of this variable and the alignment imposed by the packet
|
|
* pool implementation. For example, the IPNET packet pool imposes at least
|
|
* cache-line alignment for packet buffers.
|
|
*
|
|
* The value must be a power of two, or zero. Defaults to zero if not
|
|
* modified by the port.
|
|
*/
|
|
IP_EXTERN Ip_size_t ipcom_conf_pkt_pool_buffer_alignment;
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_conf_pkt_pool_buffer_extra_space
|
|
*===========================================================================
|
|
* The minimal additional space in packet buffers beyond the nominal size
|
|
* (MTU) requested in ipcom_pkt_malloc(), as required by the ipcom port.
|
|
* Only has effect if set before packet pool creation. The actual additional
|
|
* space will be the maximum of this variable and the extra space provided
|
|
* by the pool implementation. For example, the IPNET packet pool provides
|
|
* additional space in each packet data buffer of at least the calculated
|
|
* maximum link header space plus a constant (64 bytes at present).
|
|
*
|
|
* This variable defaults to zero if not modifed by the port.
|
|
*/
|
|
IP_EXTERN Ip_size_t ipcom_conf_pkt_pool_buffer_extra_space;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|