blob: 4c1d9044a23af4d9856269c94c416bb573d6f781 [file] [log] [blame]
/*
* Copyright (c) 2010 Mindspeed Technologies, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
#ifndef _MODULE_SOCKET_H_
#define _MODULE_SOCKET_H_
#include "types.h"
#include "fe.h"
#include "mtd.h"
#include "channels.h"
#include "layer2.h"
#if !defined(COMCERTO_2000) || defined(COMCERTO_2000_CONTROL)
extern struct slist_head sock4_cache[];
extern struct slist_head sock6_cache[];
extern struct slist_head sockid_cache[];
#else
extern PVOID sock4_cache[];
extern PVOID sock6_cache[];
extern PVOID sockid_cache[];
#endif
#if defined(COMCERTO_2000)
#define SOCK_VALID (1 << 0)
#define SOCK_USED (1 << 1)
#define SOCK_UPDATING (1 << 2)
#endif
extern channel_t socket_output_channel[];
#define SOCKET_TYPE_L2TP 3 // Socket to LAN or WAN for L2TP
#define SOCKET_TYPE_MSP 2 // Socket to MSP
#define SOCKET_TYPE_ACP 1 // Socket to ACP
#define SOCKET_TYPE_FPP 0 // Socket to LAN or WAN
#define SOCKET_STATS_SIZE 128 // max socket statistics (in bytes)
#define SOCK_OWNER_NONE 0
#define SOCK_OWNER_RTP_RELAY 1
#define SOCK_OWNER_NATPT 2
#define SOCK_OWNER_NATT 3
#define SOCK_OWNER_L2TP 4
#define SOCKET_CREATE 0
#define SOCKET_BIND 1
#define SOCKET_UNBIND 2
#define SOCKET_UPDATE 3
#if !defined(COMCERTO_2000)
// IPv4 data path socket entry
typedef struct _tSockEntry{
struct slist_entry list;
struct slist_entry list_id;
struct _tSockEntry *nextid;
U8 SocketFamily;
U8 SocketType; // 1 -> to ACP / 0 -> to LAN or WAN (based on pRtEntry)
PVOID owner;
PRouteEntry pRtEntry;
U16 queue;
U16 dscp;
U32 SocketStats[SOCKET_STATS_SIZE/4];
U32 route_id;
U8 initial_takeover_done;
U32 next;
U16 SocketID;
U16 owner_type;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
BOOL qos_enable;
U8 rtpqos_slot;
//end of common header
U32 Saddr_v4;
U32 Daddr_v4;
U16 hash;
U16 hash_by_id;
}SockEntry, *PSockEntry;
// IPv6 data path socket entry
typedef struct _tSock6Entry{
struct slist_entry list;
struct slist_entry list_id;
struct _tSockEntry *nextid;
U8 SocketFamily;
U8 SocketType; /** 1 -> to ACP / 0 -> to LAN or WAN (based on pRtEntry) */
PVOID owner;
PRouteEntry pRtEntry;
U16 queue;
U16 dscp;
U32 SocketStats[SOCKET_STATS_SIZE/4];
U32 route_id;
U8 initial_takeover_done;
U32 next;
U16 SocketID;
U16 owner_type;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
BOOL qos_enable;
U8 rtpqos_slot;
//end of common header
U32 Saddr_v6[4];
U32 Daddr_v6[4];
U16 hash;
U16 hash_by_id;
}Sock6Entry, *PSock6Entry;
#elif defined(COMCERTO_2000_CONTROL)
// IPv4/v6 control path HW socket entry (componed of the infos needed by both classifier and util-pe)
typedef struct _thw_sock {
/* UTIL and CLASS */
U32 flags;
U32 dma_addr;
U32 next;
U32 nextid;
U16 SocketID;
U8 SocketFamily;
U8 SocketType;
PVOID owner;
U16 owner_type;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
U16 queue;
U16 dscp;
union {
struct {
U32 Saddr_v4;
U32 Daddr_v4;
};
struct {
U32 Saddr_v6[4];
U32 Daddr_v6[4];
};
};
struct hw_route route;
U16 secure;
U16 SA_nr_rx;
U16 SA_handle_rx[SA_MAX_OP];
U16 SA_nr_tx;
U16 SA_handle_tx[SA_MAX_OP];
/* UTIL only */
U32 route_id;
U32 SocketStats[SOCKET_STATS_SIZE/4];
U16 hash;
U16 hash_by_id;
U8 initial_takeover_done;
BOOL qos_enable;
U8 rtpqos_slot;
/* HOST only , these fields are only used by host software, so keep them at the end of the structure */
struct dlist_head list;
struct dlist_head list_id;
struct _tSockEntry *sw_sock; /*pointer to the software socket entry */
unsigned long removal_time;
}hw_sock;
// IPv4/v6 control path SW socket entry
typedef struct _tSockEntry{
struct slist_entry list;
struct slist_entry list_id;
U16 hash;
U16 hash_by_id;
U32 nextid;
U16 SocketID;
U8 SocketFamily;
U8 SocketType; /** 1 -> to ACP / 0 -> to LAN or WAN (based on pRtEntry) */
PVOID owner;
U16 owner_type;
PRouteEntry pRtEntry;
U16 queue;
U16 dscp;
U32 SocketStats[SOCKET_STATS_SIZE/4];
U32 route_id;
U8 initial_takeover_done;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
union {
struct {
U32 Saddr_v4;
U32 Daddr_v4;
};
struct {
U32 Saddr_v6[4];
U32 Daddr_v6[4];
};
};
U16 secure;
U16 SA_nr_rx;
U16 SA_handle_rx[SA_MAX_OP];
U16 SA_nr_tx;
U16 SA_handle_tx[SA_MAX_OP];
struct _thw_sock *hw_sock; /** pointer to the hardware socket entry */
}SockEntry, *PSockEntry;
typedef SockEntry Sock6Entry;
typedef PSockEntry PSock6Entry;
#else
#if defined (COMCERTO_2000_CLASS)
// IPv4/v6 data path socket entry for classifier
typedef struct _tSockEntry{
U32 flags;
U32 dma_addr;
U32 next;
U32 nextid;
U16 SocketID;
U8 SocketFamily;
U8 SocketType;
PVOID owner;
U16 owner_type;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
U16 queue;
U16 dscp;
union {
struct {
U32 Saddr_v4;
U32 Daddr_v4;
};
struct {
U32 Saddr_v6[4];
U32 Daddr_v6[4];
};
};
RouteEntry route;
U16 secure;
U16 SA_nr_rx;
U16 SA_handle_rx[SA_MAX_OP];
U16 SA_nr_tx;
U16 SA_handle_tx[SA_MAX_OP];
}SockEntry, *PSockEntry;
typedef SockEntry Sock6Entry;
typedef PSockEntry PSock6Entry;
#else
// IPv4/v6 data path socket entry for util-pe
typedef struct _tSockEntry{
U32 flags;
U32 dma_addr;
U32 next;
U32 nextid;
U16 SocketID;
U8 SocketFamily;
U8 SocketType;
PVOID owner;
U16 owner_type;
U16 Sport;
U16 Dport;
U8 proto;
U8 connected;
U16 queue;
U16 dscp;
union {
struct {
U32 Saddr_v4;
U32 Daddr_v4;
};
struct {
U32 Saddr_v6[4];
U32 Daddr_v6[4];
};
};
RouteEntry route;
U16 secure;
U16 SA_nr_rx;
U16 SA_handle_rx[SA_MAX_OP];
U16 SA_nr_tx;
U16 SA_handle_tx[SA_MAX_OP];
U32 route_id;
U32 SocketStats[SOCKET_STATS_SIZE/4];
U16 hash;
U16 hash_by_id;
U8 initial_takeover_done;
BOOL qos_enable;
U8 rtpqos_slot;
}SockEntry, *PSockEntry;
typedef SockEntry Sock6Entry;
typedef PSockEntry PSock6Entry;
#endif
#endif
static __inline U32 HASH_SOCKID(U16 id)
{
return (id & (NUM_SOCK_ENTRIES - 1));
}
static __inline U32 HASH_SOCK(U32 Daddr, U32 Dport, U16 Proto)
{
U32 sum;
Daddr = ntohl(Daddr);
Dport = ntohs(Dport);
sum = ((Daddr << 7) | (Daddr >> 25));
sum += ((Dport << 11) | (Dport >> 21));
sum += (sum >> 16) + Proto;
return (sum ^ (sum >> 8)) & (NUM_SOCK_ENTRIES - 1);
}
static __inline U32 HASH_SOCK6(U32 Daddr, U32 Dport, U16 Proto)
{
U32 sum;
Daddr = ntohl(Daddr);
Dport = ntohs(Dport);
sum = ((Daddr << 7) | (Daddr >> 25));
sum += ((Dport << 11) | (Dport >> 21));
sum += (sum >> 16) + Proto;
return (sum ^ (sum >> 8)) & (NUM_SOCK_ENTRIES - 1);
}
int SOCKET_expt_match(PMetadata mtd);
PRouteEntry SOCKET4_get_route(PSockEntry pSocket);
PRouteEntry SOCKET6_get_route(PSock6Entry pSocket);
BOOL SOCKET4_check_route(PSockEntry pSocket)__attribute__ ((noinline));
int SOCKET4_send_rtp_packet(PMetadata mtd, PSockEntry pSocket, BOOL ipv4_update, U32 payload_diff)__attribute__ ((noinline));
BOOL SOCKET6_check_route(PSock6Entry pSocket) __attribute__ ((noinline));
int SOCKET6_send_rtp_packet(PMetadata mtd, PSock6Entry pSocket, BOOL ipv6_update, U32 payload_diff) __attribute__ ((noinline));
PSockEntry SOCKET_find_entry_by_id(U16 socketID)__attribute__ ((noinline));
PSockEntry SOCKET4_find_entry(U32 saddr, U16 sport, U32 daddr, U16 dport, U16 proto)__attribute__ ((noinline));
PSock6Entry SOCKET6_find_entry(U32 *saddr, U16 sport, U32 *daddr, U16 dport, U16 proto) __attribute__ ((noinline));
#if defined (COMCERTO_2000_CONTROL)
PSock6Entry socket6_alloc(void);
int socket6_add(PSock6Entry pSocket);
void socket6_remove(PSock6Entry pSocket, U32 hash, U32 hash_by_id);
PSockEntry socket4_alloc(void);
int socket4_add(PSockEntry pSocket);
void socket4_remove(PSockEntry pSocket, U32 hash, U32 hash_by_id);
void socket6_free(PSock6Entry pSocket);
void socket4_free(PSockEntry pSocket);
#endif
void socket4_update(PSockEntry pSocket, u8 event);
void socket6_update(PSock6Entry pSocket, u8 event);
BOOL socket_init(void);
void socket_exit(void);
#if defined(COMCERTO_2000_CLASS)
/* PBUF route entry memory chunk is used to allocated a socket entry */
#define SOCKET_BUFFER()\
((PVOID)(CLASS_ROUTE0_BASE_ADDR))
#elif defined(COMCERTO_2000_UTIL)
#include "util_dmem_storage.h"
#endif
#endif