Commit 1246d482 authored by Lionel Gauthier's avatar Lionel Gauthier

IP Driver for UE using LTE-EPC

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4913 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 56a03c39
This diff is collapsed.
# UE IP Driver makefile
#
NAS_UPDIR := $(shell /bin/pwd)
KERNEL_NAME=$(shell echo `uname -r`)
KERNEL_MAIN_TYPE=$(shell echo `uname -r | cut -d. -f-2 | tr "." "_"`)
export KERNEL_MAIN_TYPE
KERNEL_MAIN_VERSION=$(shell echo `uname -r | cut -d. -f-1`)
ifeq ($(IS_LINUX), 1)
SUBVERSION=$(shell echo `grep '^SUBLEVEL =' /usr/src/linux/Makefile | sed -e 's, ,,g' | sed -e 's/SUBLEVEL=//'`)
else
ifeq ($(IS_KERNEL_OPENAIRINTERFACE), 1)
SUBVERSION=$(shell echo `grep '^SUBLEVEL =' /usr/src/linux-$(KERNEL_NAME)/Makefile | sed -e 's, ,,g' | sed -e 's/SUBLEVEL=//'`)
else
SUBVERSION=$(shell echo `grep '^SUBLEVEL =' /usr/src/linux-headers-$(KERNEL_NAME)/Makefile | sed -e 's, ,,g' | sed -e 's/SUBLEVEL=//'`)
endif
endif
IS_KERNEL_SUBVERSION_GREATER_THAN_20=$(shell if [ $(SUBVERSION) -ge 20 ] ; then echo true ; fi)
KERNEL_ARCH=$(shell echo `uname -m`)
#SET_REGPARM=$(shell if [ $(KERNEL_ARCH) = 'i686' -a $(SUBVERSION) -ge 20 ]; then echo true ; fi)
SET_X64=$(shell if [ $(KERNEL_ARCH) = 'x86_64' -a $(SUBVERSION) -ge 20 ]; then echo true ; fi)
IS_KERNEL_SUBVERSION_GREATER_THAN_22=$(shell if [ $(SUBVERSION) -ge 22 ] ; then echo true ; fi)
IS_KERNEL_SUBVERSION_GREATER_THAN_29=$(shell if [ $(SUBVERSION) -ge 29 ] ; then echo true ; fi)
IS_KERNEL_SUBVERSION_GREATER_THAN_30=$(shell if [ $(SUBVERSION) -ge 30 ] ; then echo true ; fi)
IS_KERNEL_SUBVERSION_GREATER_THAN_32=$(shell if [ $(SUBVERSION) -ge 32 ] ; then echo true ; fi)
# Add global rule for V3 kernels
ifeq ($(KERNEL_MAIN_VERSION),3)
IS_KERNEL_SUBVERSION_GREATER_THAN_22 = "true"
IS_KERNEL_SUBVERSION_GREATER_THAN_29 = "true"
IS_KERNEL_SUBVERSION_GREATER_THAN_30 = "true"
IS_KERNEL_SUBVERSION_GREATER_THAN_32 = "true"
IS_KERNEL_MAIN_VERSION_IS_3 = "true"
endif
GT2622= $(if $(IS_KERNEL_SUBVERSION_GREATER_THAN_22),-DKERNEL_VERSION_GREATER_THAN_2622=1)
GT2629= $(if $(IS_KERNEL_SUBVERSION_GREATER_THAN_29),-DKERNEL_VERSION_GREATER_THAN_2629=1)
GT32= $(if $(IS_KERNEL_SUBVERSION_GREATER_THAN_32),-DKERNEL_VERSION_GREATER_THAN_32=1)
V3= $(if $(IS_KERNEL_MAIN_VERSION_IS_3),-DKERNEL_MAIN_VERSION_IS_3=1)
####################################################
# D E B U G F L A G S
####################################################
####################################################
# EXTRA COMPILER FLAGS
####################################################
EXTRA_CFLAGS = -fno-common $(if $(IS_KERNEL_SUBVERSION_GREATER_THAN_20),-mregparm=3 -fno-stack-protector -mpreferred-stack-boundary=4) $(if $(SET_X64),-DARCH_64,) $(if $(SET_X64),-mcmodel=kernel,) $(if $(SET_X64),-m64,) $(GT2622) $(GT2629) $(V3) $(GT32)
ifdef OAI_NW_DRIVER_USE_NETLINK
EXTRA_CFLAGS += -DOAI_NW_DRIVER_USE_NETLINK
else
EXTRA_CFLAGS += $(shell rtai-config --module-cflags) -DRTAI -D__IN_RTAI__ -Wall
endif
####################################################
# LOADABLE MODULE GOALS
####################################################
obj-m += ue_ip.o
ue_ip-objs += device.o
ue_ip-objs += common.o
ifdef OAI_NW_DRIVER_USE_NETLINK
ue_ip-objs += netlink.o
endif
####################################################
# REVOIR LE CLEAN
####################################################
print:
@echo linux kernel ge 22: $(IS_KERNEL_SUBVERSION_GREATER_THAN_22)
@echo kernel name : $(KERNEL_NAME)
@echo subversion : $(SUBVERSION)
@echo flag gt2622: $(GT2622)
@echo linux kernel ge 29: $(IS_KERNEL_SUBVERSION_GREATER_THAN_29)
@echo flag gt2629: $(GT2629)
@echo linux kernel ge 30: $(IS_KERNEL_SUBVERSION_GREATER_THAN_30)
@echo flag KERNEL_MAIN_VERSION $(KERNEL_MAIN_VERSION)
clean:
rm -f *.ko
rm -f .*.ko.cmd
rm -f .*.o.cmd
rm -f *.o
rm -f *.mod.c
find . -name *.ko -delete
find . -name .*.o -delete
find . -name *.o -delete
find . -name *.mod.c -delete
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface 2
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
#ifndef _UE_IP_CST
#define _UE_IP_CST
#define UE_IP_MAX_LENGTH 180
// General Constants
#define UE_IP_MTU 1500
#define UE_IP_TX_QUEUE_LEN 100
#define UE_IP_ADDR_LEN 8
#define UE_IP_INET6_ADDRSTRLEN 46
#define UE_IP_INET_ADDRSTRLEN 16
#define UE_IP_DEFAULT_RAB_ID 5
#define UE_IP_RESET_RX_FLAGS 0
#define UE_IP_RETRY_LIMIT_DEFAULT 5
#define UE_IP_MESSAGE_MAXLEN 5004
#define UE_IP_TIMER_ESTABLISHMENT_DEFAULT 12
#define UE_IP_TIMER_RELEASE_DEFAULT 2
#define UE_IP_TIMER_IDLE UINT_MAX
#define UE_IP_TIMER_TICK HZ
#define UE_IP_PDCPH_SIZE sizeof(struct pdcp_data_req_header_t)
#define UE_IP_IPV4_SIZE 20
#define UE_IP_IPV6_SIZE 40
#define UE_IP_NB_INSTANCES_MAX 8
#endif
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface 2
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/***************************************************************************
local.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : michelle.wetterwald@eurecom.fr(no longer valid)
yan.moret@eurecom.fr(no longer valid)
knopp@eurecom.fr
gauthier@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef UE_IP_LOCAL_H
#define UE_IP_LOCAL_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <linux/unistd.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "constant.h"
#include "sap.h"
struct ue_ip_priv {
int irq;
int rx_flags;
struct timer_list timer;
spinlock_t lock;
struct net_device_stats stats;
u8 retry_limit;
u32 timer_establishment;
u32 timer_release;
struct sock *nl_sk;
u8 nlmsg[UE_IP_PRIMITIVE_MAX_LENGTH+sizeof(struct nlmsghdr)];
u8 xbuffer[UE_IP_PRIMITIVE_MAX_LENGTH]; // transmition buffer
u8 rbuffer[UE_IP_PRIMITIVE_MAX_LENGTH]; // reception buffer
};
struct ipversion {
#if defined(__LITTLE_ENDIAN_BITFIELD)
u8 reserved:4,
version:4;
#else
u8 version:4,
reserved:4;
#endif
};
typedef struct pdcp_data_req_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_req_header_t;
typedef struct pdcp_data_ind_header_t {
unsigned int rb_id;
unsigned int data_size;
int inst;
} pdcp_data_ind_header_t;
extern struct net_device *ue_ip_dev[UE_IP_NB_INSTANCES_MAX];
#endif
/*******************************************************************************
Eurecom OpenAirInterface 2
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file netlink.c
* \brief establish a netlink
* \author Raymond knopp, and Navid Nikaein, Lionel Gauthier
* \company Eurecom
* \email: knopp@eurecom.fr, and navid.nikaein@eurecom.fr, lionel.gauthier@eurecom.fr
*/
//#include <linux/config.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include "local.h"
#include "proto_extern.h"
//#define NETLINK_DEBUG 1
#define NAS_NETLINK_ID 31
#define NL_DEST_PID 1
static struct sock *nas_nl_sk = NULL;
static int exit_netlink_thread=0;
static int nas_netlink_rx_thread(void *);
static DEFINE_MUTEX(nasmesh_mutex);
static inline void nasmesh_lock(void)
{
mutex_lock(&nasmesh_mutex);
}
static inline void nasmesh_unlock(void)
{
mutex_unlock(&nasmesh_mutex);
}
#ifdef KERNEL_VERSION_GREATER_THAN_2629
// This can also be implemented using thread to get the data from PDCP without blocking.
static void nas_nl_data_ready (struct sk_buff *skb)
{
// wake_up_interruptible(skb->sk->sk_sleep);
//nasmesh_lock();
//netlink_rcv_skb(skb, &my_rcv_msg);// my_rcv_msg is the call back func>
//nasmesh_unlock();
struct nlmsghdr *nlh = NULL;
if (skb) {
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
ue_ip_common_wireless2ip(nlh);
//kfree_skb(skb); // not required,
}
}
#else
static struct task_struct *netlink_rx_thread;
// this thread is used to avoid blocking other system calls from entering the kernel
static int nas_netlink_rx_thread(void *data) {
int err;
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh = NULL;
printk("[UE_IP_DRV][NETLINK] Starting RX Thread \n");
while (!kthread_should_stop()) {
if (nas_nl_sk) {
skb = skb_recv_datagram(nas_nl_sk, 0, 0, &err);
if (skb) {
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] Received socket from PDCP\n");
#endif //NETLINK_DEBUG
nlh = (struct nlmsghdr *)skb->data;
nas_COMMON_QOS_receive(nlh);
skb_free_datagram(nas_nl_sk,skb);
}
}
else {
if (exit_netlink_thread == 1) {
printk("[UE_IP_DRV][NETLINK] exit_netlink_thread\n");
break;
}
}
} // while
printk("[UE_IP_DRV][NETLINK] Exiting RX thread\n");
return(0);
}
static void nas_nl_data_ready (struct sock *sk, int len)
{
wake_up_interruptible(sk->sk_sleep);
}
#endif
int ue_ip_netlink_init(void)
{
printk("[UE_IP_DRV][NETLINK] Running init ...\n");
nas_nl_sk = netlink_kernel_create(
#ifdef KERNEL_VERSION_GREATER_THAN_2622
&init_net,
#endif
NAS_NETLINK_ID,
0,
nas_nl_data_ready,
#ifdef KERNEL_VERSION_GREATER_THAN_2622
&nasmesh_mutex, // NULL
#endif
THIS_MODULE);
if (nas_nl_sk == NULL) {
printk("[UE_IP_DRV][NETLINK] netlink_kernel_create failed \n");
return(-1);
}
#ifdef KERNEL_VERSION_GREATER_THAN_2629
#else
// Create receive thread
netlink_rx_thread = kthread_run(nas_netlink_rx_thread, NULL, "NAS_NETLINK_RX_THREAD");
#endif
return(0);
}
void ue_ip_netlink_release(void) {
exit_netlink_thread=1;
printk("[UE_IP_DRV][NETLINK] Releasing netlink socket\n");
if(nas_nl_sk){
#ifdef KERNEL_VERSION_GREATER_THAN_2629
netlink_kernel_release(nas_nl_sk); //or skb->sk
#else
sock_release(nas_nl_sk->sk_socket);
#endif
}
// printk("[UE_IP_DRV][NETLINK] Removing netlink_rx_thread\n");
//kthread_stop(netlink_rx_thread);
}
int ue_ip_netlink_send(unsigned char *data,unsigned int len) {
struct sk_buff *nl_skb = alloc_skb(NLMSG_SPACE(len),GFP_ATOMIC);
struct nlmsghdr *nlh = (struct nlmsghdr *)nl_skb->data;
int status;
// printk("[UE_IP_DRV][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
skb_put(nl_skb, NLMSG_SPACE(len));
memcpy(NLMSG_DATA(nlh),data,len);
nlh->nlmsg_len = NLMSG_SPACE(len);
nlh->nlmsg_pid = 0; /* from kernel */
NETLINK_CB(nl_skb).pid = 0;
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] In nas_netlink_send, nl_skb %p, nl_sk %x, nlh %p, nlh->nlmsg_len %d\n",nl_skb,nas_nl_sk,nlh,nlh->nlmsg_len);
#endif //DEBUG_NETLINK
if (nas_nl_sk) {
// nasmesh_lock();
status = netlink_unicast(nas_nl_sk, nl_skb, NL_DEST_PID, MSG_DONTWAIT);
// mutex_unlock(&nasmesh_mutex);
if (status < 0) {
printk("[UE_IP_DRV][NETLINK] SEND status is %d\n",status);
return(0);
}
else {
#ifdef NETLINK_DEBUG
printk("[UE_IP_DRV][NETLINK] SEND status is %d\n",status);
#endif
return len;
}
}
else {
printk("[UE_IP_DRV][SEND] socket is NULL\n");
return(0);
}
}
/*******************************************************************************
Eurecom OpenAirInterface 2
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/***************************************************************************
proto_extern.h - description
-------------------
copyright : (C) 2002 by Eurecom
email : michelle.wetterwald@eurecom.fr(no longer valid)
yan.moret@eurecom.fr(no longer valid)
knopp@eurecom.fr
gauthier@eurecom.fr
***************************************************************************
***************************************************************************/
#ifndef _UE_IP_PROTO_H
#define _UE_IP_PROTO_H
#include <linux/if_arp.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/ip.h>
#include <linux/sysctl.h>
#include <linux/timer.h>
#include <asm/param.h>
//#include <sys/sysctl.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/icmpv6.h>
#include <linux/in.h>
#include <net/ndisc.h>
#include "local.h"
// device.c
/** @defgroup _ue_ip_impl_ OAI Network Device for RRC Lite
* @ingroup _ref_implementation_
* @{
\fn int ue_ip_find_inst(struct net_device *dev)
\brief This function determines the instance id for a particular device pointer.
@param dev Pointer to net_device structure
*/
int ue_ip_find_inst(struct net_device *dev);
// common.c
/**
\fn void ue_ip_common_class_wireless2ip(unsigned short dlen, void* pdcp_sdu,int inst,struct classifier_entity *rclass,OaiNwDrvRadioBearerId_t rb_id)
\brief Receive classified LTE packet, build skbuff struct with it and deliver it to the OS network layer.
@param dlen Length of SDU in bytes
@param pdcp_sdu Pointer to received SDU
@param inst Instance number
@param rb_id Radio Bearer Id
*/
void ue_ip_common_class_wireless2ip(unsigned short dlen,
void *pdcp_sdu,
int inst,
OaiNwDrvRadioBearerId_t rb_id);
/**
\fn void ue_ip_common_ip2wireless(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Request the transfer of data (QoS SAP)
@param skb pointer to socket buffer
@param inst device instance
*/
void ue_ip_common_ip2wireless(struct sk_buff *skb, int inst);
/**
\fn void ue_ip_common_ip2wireless_drop(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst)
\brief Drop the IP packet comming from the OS network layer.
@param skb pointer to socket buffer
@param inst device instance
*/
void ue_ip_common_ip2wireless_drop(struct sk_buff *skb, int inst);
#ifndef OAI_NW_DRIVER_USE_NETLINK
/**
\fn void ue_ip_common_wireless2ip()
\brief Retrieve PDU from PDCP through RT-fifos for delivery to the IP stack.
*/
void ue_ip_common_wireless2ip(void);
#else
/**
\fn void ue_ip_common_wireless2ip(struct nlmsghdr *nlh)
\brief Retrieve PDU from PDCP through netlink sockets for delivery to the IP stack.
*/
void ue_ip_common_wireless2ip(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
#ifdef OAI_NW_DRIVER_USE_NETLINK
/**
\fn int ue_ip_netlink_send(unsigned char *data,unsigned int len)
\brief Request the transfer of data by PDCP via netlink socket
@param data pointer to SDU
@param len length of SDU in bytes
@returns Numeber of bytes transfered by netlink socket
*/
int ue_ip_netlink_send(unsigned char *data,unsigned int len);
/**
\fn void ue_ip_COMMON_QOS_receive(struct nlmsghdr *nlh)
\brief Request a PDU from PDCP
@param nlh pointer to netlink message header
*/
void ue_ip_COMMON_QOS_receive(struct nlmsghdr *nlh);
#endif //OAI_NW_DRIVER_USE_NETLINK
// netlink.c
void ue_ip_netlink_release(void);
int ue_ip_netlink_init(void);
/** @} */
#endif
#ifndef UE_IP_SAP_H
#define UE_IP_SAP_H
typedef unsigned short OaiNwDrvRadioBearerId_t;
#define UE_IP_PRIMITIVE_MAX_LENGTH 180 // maximum length of a NAS primitive
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment