/*
 *  OsmoGGSN - Gateway GPRS Support Node
 *  Copyright (C) 2002, 2003, 2004 Mondru AB.
 *  Copyright (C) 2017 Harald Welte <laforge@gnumonks.org>
 *
 *  The contents of this file may be used under the terms of the GNU
 *  General Public License Version 2, provided that the above copyright
 *  notice and this permission notice is included in all copies or
 *  substantial portions of the software.
 *
 */

/*
 * pdp.c:
 *
 */

#include <../config.h>

#include <osmocom/core/logging.h>

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <inttypes.h>
#include "pdp.h"
#include "gtp.h"
#include "lookupa.h"
#include "queue.h"

/* ***********************************************************
 * Functions related to PDP storage
 *
 * Lifecycle
 * For a GGSN pdp context life begins with the reception of a
 * create pdp context request. It normally ends with the reception
 * of a delete pdp context request, but will also end with the
 * reception of an error indication message.
 * Provisions should probably be made for terminating pdp contexts
 * based on either idle timeout, or by sending downlink probe
 * messages (ping?) to see if the MS is still responding.
 *
 * For an SGSN pdp context life begins with the application just
 * before sending off a create pdp context request. It normally
 * ends when a delete pdp context response message is received
 * from the GGSN, but should also end when with the reception of
 * an error indication message.
 *
 *
 * HASH Tables
 *
 * Downlink packets received in the GGSN are identified only by their
 * network interface together with their destination IP address (Two
 * network interfaces can use the same private IP address). Each IMSI
 * (mobile station) can have several PDP contexts using the same IP
 * address. In this case the traffic flow template (TFT) is used to
 * determine the correct PDP context for a particular IMSI. Also it
 * should be possible for each PDP context to use several IP adresses
 * For fixed wireless access a mobile station might need a full class
 * C network. Even in the case of several IP adresses the PDP context
 * should be determined on the basis of the network IP address.
 * Thus we need a hash table based on network interface + IP address.
 *
 * Uplink packets are for GTP0 identified by their IMSI and NSAPI, which
 * is collectively called the tunnel identifier. There is also a 16 bit
 * flow label that can be used for identification of uplink packets. This
 * however is quite useless as it limits the number of contexts to 65536.
 * For GTP1 uplink packets are identified by a Tunnel Endpoint Identifier
 * (32 bit), or in some cases by the combination of IMSI and NSAPI.
 * For GTP1 delete context requests there is a need to find the PDP
 * contexts with the same IP address. This however can be done by using
 * the IP hash table.
 * Thus we need a hash table based on TID (IMSI and NSAPI). The TEID will
 * be used for directly addressing the PDP context.

 * pdp_newpdp
 * Gives you a pdp context with no hash references In some way
 * this should have a limited lifetime.
 *
 * pdp_freepdp
 * Frees a context that was previously allocated with
 * pdp_newpdp
 *
 *
 * pdp_getpdpIP
 * An incoming IP packet is uniquely identified by a pointer
 * to a network connection (void *) and an IP address
 * (struct in_addr)
 *
 * pdp_getpdpGTP
 * An incoming GTP packet is uniquely identified by a the
 * TID (imsi + nsapi (8 octets)) in or by the Flow Label
 * (2 octets) in gtp0 or by the Tunnel Endpoint Identifier
 * (4 octets) in gtp1.
 *
 * This leads to an architecture where the receiving GSN
 * chooses a Flow Label or a Tunnel Endpoint Identifier
 * when the connection is setup.
 * Thus no hash table is needed for GTP lookups.
 *
 *************************************************************/

static struct gsn_t *g_gsn;

int pdp_init(struct gsn_t *gsn)
{
	if (!g_gsn) {
		g_gsn = gsn;
	} else {
		LOGP(DLGTP, LOGL_FATAL, "This interface is depreacted and doesn't support multiple GGSN!");
		return -1;
	}

	return 0;
}

int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
	       struct pdp_t *pdp_old)
{
	return gtp_pdp_newpdp(g_gsn, pdp, imsi, nsapi, pdp_old);
}

int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
	       struct pdp_t *pdp_old)
{
	struct pdp_t *pdpa = gsn->pdpa;
	int n;
	for (n = 0; n < PDP_MAX; n++) {	/* TODO: Need to do better than linear search */
		if (pdpa[n].inuse == 0) {
			*pdp = &pdpa[n];
			if (NULL != pdp_old)
				memcpy(*pdp, pdp_old, sizeof(struct pdp_t));
			else
				memset(*pdp, 0, sizeof(struct pdp_t));
			(*pdp)->inuse = 1;
			(*pdp)->gsn = gsn;
			(*pdp)->imsi = imsi;
			(*pdp)->nsapi = nsapi;
			(*pdp)->fllc = (uint16_t) n + 1;
			(*pdp)->fllu = (uint16_t) n + 1;
			(*pdp)->teid_own = (uint32_t) n + 1;
			if (!(*pdp)->secondary)
				(*pdp)->teic_own = (uint32_t) n + 1;
			pdp_tidset(*pdp, pdp_gettid(imsi, nsapi));

			/* Insert reference in primary context */
			if (((*pdp)->teic_own > 0)
			    && ((*pdp)->teic_own <= PDP_MAX)) {
				pdpa[(*pdp)->teic_own -
				     1].secondary_tei[(*pdp)->nsapi & 0x0f] =
				    (*pdp)->teid_own;
			}
			/* Default: Generate G-PDU sequence numbers on Tx */
			(*pdp)->tx_gpdu_seq = true;
			INIT_LLIST_HEAD(&(*pdp)->qmsg_list_req);
			return 0;
		}
	}
	return EOF;		/* No more available */
}

int pdp_freepdp(struct pdp_t *pdp)
{
	struct qmsg_t *qmsg, *qmsg2;
	struct pdp_t *pdpa = pdp->gsn->pdpa;
	int rc;

	/* Remove all enqueued messages belonging to this pdp from req tx transmit
	   queue. queue_freemsg will call llist_del(). */
	llist_for_each_entry_safe(qmsg, qmsg2, &pdp->qmsg_list_req, entry) {
		if ((rc = queue_freemsg(pdp->gsn->queue_req, qmsg)))
			LOGP(DLGTP, LOGL_ERROR,
			     "Failed freeing qmsg from qmsg_list_req during pdp_freepdp()! %d\n", rc);
	}

	pdp_tiddel(pdp);

	/* Remove any references in primary context */
	if ((pdp->secondary) && (pdp->teic_own > 0)
	    && (pdp->teic_own <= PDP_MAX)) {
		pdpa[pdp->teic_own - 1].secondary_tei[pdp->nsapi & 0x0f] = 0;
	}

	memset(pdp, 0, sizeof(struct pdp_t));
	return 0;
}

int pdp_getpdp(struct pdp_t **pdp)
{
	*pdp = &g_gsn->pdpa[0];
	return 0;
}

int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl)
{
	return gtp_pdp_getgtp0(g_gsn, pdp, fl);
}


int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl)
{
	struct pdp_t *pdpa = gsn->pdpa;

	if ((fl > PDP_MAX) || (fl < 1)) {
		return EOF;	/* Not found */
	} else {
		*pdp = &pdpa[fl - 1];
		if ((*pdp)->inuse)
			return 0;
		else
			return EOF;
		/* Context exists. We do no further validity checking. */
	}
}

int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei)
{
	return gtp_pdp_getgtp1(g_gsn, pdp, tei);
}

int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei)
{
	struct pdp_t *pdpa = gsn->pdpa;

	if ((tei > PDP_MAX) || (tei < 1)) {
		return EOF;	/* Not found */
	} else {
		*pdp = &pdpa[tei - 1];
		if ((*pdp)->inuse)
			return 0;
		else
			return EOF;
		/* Context exists. We do no further validity checking. */
	}
}

/* get a PDP based on the *peer* address + TEI-Data.  Used for matching inbound Error Ind */
int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn)
{
	return gtp_pdp_getgtp1_peer_d(g_gsn, pdp, peer, teid_gn);
}

int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn)
{
	struct pdp_t *pdpa = gsn->pdpa;
	unsigned int i;

	/* this is O(n) but we don't have (nor want) another hash... */
	for (i = 0; i < PDP_MAX; i++) {
		struct pdp_t *candidate = &pdpa[i];
		if (candidate->inuse && candidate->teid_gn == teid_gn &&
		    candidate->gsnru.l == sizeof(peer->sin_addr) &&
		    !memcmp(&peer->sin_addr, candidate->gsnru.v, sizeof(peer->sin_addr))) {
			*pdp = &pdpa[i];
			return 0;
		}
	}
	return EOF;
}

int pdp_tidhash(uint64_t tid)
{
	return (lookup(&tid, sizeof(tid), 0) % PDP_MAX);
}

int pdp_tidset(struct pdp_t *pdp, uint64_t tid)
{
	struct pdp_t **hashtid = pdp->gsn->hashtid;
	int hash = pdp_tidhash(tid);
	struct pdp_t *pdp2;
	struct pdp_t *pdp_prev = NULL;
	DEBUGP(DLGTP, "Begin pdp_tidset tid = %"PRIx64"\n", tid);
	pdp->tidnext = NULL;
	pdp->tid = tid;
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext)
		pdp_prev = pdp2;
	if (!pdp_prev)
		hashtid[hash] = pdp;
	else
		pdp_prev->tidnext = pdp;
	DEBUGP(DLGTP, "End pdp_tidset\n");
	return 0;
}

int pdp_tiddel(struct pdp_t *pdp)
{
	struct pdp_t **hashtid = pdp->gsn->hashtid;
	int hash = pdp_tidhash(pdp->tid);
	struct pdp_t *pdp2;
	struct pdp_t *pdp_prev = NULL;
	DEBUGP(DLGTP, "Begin pdp_tiddel tid = %"PRIx64"\n", pdp->tid);
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
		if (pdp2 == pdp) {
			if (!pdp_prev)
				hashtid[hash] = pdp2->tidnext;
			else
				pdp_prev->tidnext = pdp2->tidnext;
			DEBUGP(DLGTP, "End pdp_tiddel: PDP found\n");
			return 0;
		}
		pdp_prev = pdp2;
	}
	DEBUGP(DLGTP, "End pdp_tiddel: PDP not found\n");
	return EOF;		/* End of linked list and not found */
}

int pdp_tidget(struct pdp_t **pdp, uint64_t tid)
{
	return gtp_pdp_tidget(g_gsn, pdp, tid);
}

int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid)
{
	struct pdp_t **hashtid = gsn->hashtid;
	int hash = pdp_tidhash(tid);
	struct pdp_t *pdp2;
	DEBUGP(DLGTP, "Begin pdp_tidget tid = %"PRIx64"\n", tid);
	for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
		if (pdp2->tid == tid) {
			*pdp = pdp2;
			DEBUGP(DLGTP, "Begin pdp_tidget. Found\n");
			return 0;
		}
	}
	DEBUGP(DLGTP, "Begin pdp_tidget. Not found\n");
	return EOF;		/* End of linked list and not found */
}

int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
{
	return gtp_pdp_getimsi(g_gsn, pdp, imsi, nsapi);
}

int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi)
{
	return gtp_pdp_tidget(gsn, pdp, pdp_gettid(imsi, nsapi));
}


/* Various conversion functions */

uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi)
{
	return (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60);
}

void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid)
{
	pdp->imsi = teid & 0x0fffffffffffffffull;
	pdp->nsapi = (teid & 0xf000000000000000ull) >> 60;
}

/* Count amount of secondary PDP contexts linked to this primary PDP context
 * (itself included). Must be called on a primary PDP context. */
unsigned int pdp_count_secondary(const struct pdp_t *pdp)
{
	unsigned int n;
	unsigned int count = 0;
	OSMO_ASSERT(!pdp->secondary);

	for (n = 0; n < PDP_MAXNSAPI; n++)
		if (pdp->secondary_tei[n])
			count++;
	return count;
}
