aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h')
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h
new file mode 100644
index 0000000..34992da
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h
@@ -0,0 +1,226 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux Offload definitions.
+ * This file is only meant to be included via pvtcp_off.h.
+ */
+
+#ifndef _PVTCP_OFF_LINUX_H_
+#define _PVTCP_OFF_LINUX_H_
+
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/skbuff.h>
+#include <linux/random.h>
+#include <linux/fs.h>
+#include <linux/cred.h>
+
+
+typedef struct PvtcpSock {
+ struct sock *sk;
+ PVTCP_SOCK_COMMON_FIELDS;
+ PVTCP_OFF_SOCK_COMMON_FIELDS;
+ void (*destruct)(struct sock *sk);
+ void (*stateChange)(struct sock *sk);
+ void (*dataReady)(struct sock *sk, int bytes);
+ void (*writeSpace)(struct sock *sk);
+ void (*errorReport)(struct sock *sk);
+} PvtcpSock;
+
+
+typedef enum PvtcpSockNamespace {
+ PVTCP_SOCK_NAMESPACE_INITIAL,
+ PVTCP_SOCK_NAMESPACE_CHANNEL
+} PvtcpSockNamespace;
+
+
+/* Number of large datagram allocations. */
+extern unsigned long long pvtcpOffDgramAllocations;
+
+/* Inet4 loopback addresses. */
+extern unsigned int pvtcpLoopbackOffAddr;
+
+/* Get the 'struct sock' from a PvtcpSock. */
+#define SkFromPvsk(pvsk) ((pvsk)->sk)
+
+/* Get the PvtcpSock from a 'struct sock'. */
+#define PvskFromSk(sk) ((PvtcpSock *)(sk)->sk_user_data)
+
+int
+PvtcpTestAndBindLoopbackInet4(PvtcpSock *pvsk,
+ unsigned int *addr,
+ unsigned short port);
+int
+PvtcpTestAndBindLoopbackInet6(PvtcpSock *pvsk,
+ unsigned long long *addr0,
+ unsigned long long *addr1,
+ unsigned short port);
+
+void PvtcpResetLoopbackInet4(PvtcpSock *pvsk, unsigned int *addr);
+void PvtcpResetLoopbackInet6(PvtcpSock *pvsk, struct in6_addr *in6);
+
+void PvtcpFlowAIO(PvtcpSock *pvsk, int eof);
+void PvtcpOutputAIO(PvtcpSock *pvsk);
+int PvtcpInputAIO(PvtcpSock *pvsk, void *perCpuBuf);
+
+
+/**
+ * @brief Switches a socket to the channel, or the initial name space.
+ * @param pvsk socket to switch.
+ * @param ns which namespace to switch to.
+ */
+
+static inline void
+PvtcpSwitchSock(PvtcpSock *pvsk,
+ PvtcpSockNamespace ns)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ struct sock *sk;
+ struct net *prevNet;
+
+ if (!pvsk) {
+ return;
+ }
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* If this is a phony, create fail reporting pvsk, just return. */
+
+ return;
+ }
+
+ prevNet = sock_net(sk);
+ switch (ns) {
+ case PVTCP_SOCK_NAMESPACE_INITIAL:
+ sock_net_set(sk, get_net(&init_net));
+ break;
+ case PVTCP_SOCK_NAMESPACE_CHANNEL:
+ sock_net_set(sk, get_net(pvsk->state->namespace));
+ break;
+ }
+ put_net(prevNet);
+#endif
+}
+
+
+/**
+ * @brief Tests whether a socket has an explicit namespace.
+ * @param pvsk socket to test.
+ * @return 1 if the socket has a namespace, 0 otherwise.
+ */
+
+static inline int
+PvtcpHasSockNamespace(PvtcpSock *pvsk)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ struct sock *sk;
+ int rc = 0;
+
+ if (!pvsk) {
+ return rc;
+ }
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* If this is a phony, create fail reporting pvsk, just return 0. */
+
+ return rc;
+ }
+
+ rc = (sock_net(sk) != &init_net);
+ return rc;
+#else
+ return 0;
+#endif
+}
+
+
+/**
+ * @brief Retains the pvsock's underlying socket.
+ * @param pvsk socket to retain.
+ */
+
+static inline void
+PvtcpHoldSock(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ if (likely(sk)) {
+ sock_hold(sk);
+ }
+}
+
+
+/**
+ * @brief Releases a hold on the pvsock's underlying socket. If the underlying
+ * socket is NULL, this is an error socket and we deallocate it.
+ * @param pvsk socket to release hold on.
+ */
+
+static inline void
+PvtcpPutSock(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ if (likely(sk)) {
+ sock_put(sk);
+ } else {
+ /*
+ * This is an error socket, which does _not_ have an underlying socket.
+ * We simply need to free it.
+ */
+
+ CommOS_Kfree(pvsk);
+ }
+}
+
+
+/**
+ * @brief Schedules an offload socket for AIO.
+ * @param pvsk socket to schedule.
+ * @sideeffect the socket will be processed by AIO threads.
+ */
+
+static inline void
+PvtcpSchedSock(PvtcpSock *pvsk)
+{
+ /*
+ * We must hold the socket before we enqueue it for AIO, such that it may
+ * not be released while in the workqueue. If CommSvc_ScheduleAIOWork()
+ * returned non-zero, it means the socket had already been enqueued. In
+ * that case, we release the hold. Otherwise, the hold is released by the
+ * AIO function (PvtcpProcessAIO()).
+ * Note that error pv sockets may only originate from synchronized RPCs,
+ * or to be more precise, from PvtcpCreateOp(), and not from IO processing;
+ * this means that they cannot be attempted to be enqueued more than once.
+ */
+
+ PvtcpHoldSock(pvsk);
+ if (CommSvc_ScheduleAIOWork(&pvsk->work)) {
+ PvtcpPutSock(pvsk);
+ }
+}
+
+#endif // _PVTCP_OFF_LINUX_H_