With folowwing implicit rule drb id = x => correspondind lc id = x+2, eps bearer id = x+4 Changed RLC inner structs, no more statically allocated array, now it is dynamic via malloc and collection of RLC entities are stored in a hashtable. Changed misc simple types Started compiling with all warning setted and treated as errors, still working on RLC and around... Add const qualifier wherever suitable (for example param frame, module id, const pointers, etc) Thinking about a type of context parameter in procedure calls in L2 data plane (modules id, frame, srb flag, enb flag, etc)... git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5222 818b1a75-f10b-46b9-bf7c-635c3b92a50f
794 lines
26 KiB
C
Executable File
794 lines
26 KiB
C
Executable File
/*******************************************************************************
|
|
|
|
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
|
|
|
|
*******************************************************************************/
|
|
|
|
#include "local.h"
|
|
#include "ioctl.h"
|
|
#include "proto_extern.h"
|
|
|
|
//#include <linux/in.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/checksum.h>
|
|
#include <asm/uaccess.h>
|
|
|
|
|
|
// Statistic
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_statistic_reply(struct nas_msg_statistic_reply *msgrep,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
msgrep->rx_packets=priv->stats.rx_packets;
|
|
msgrep->tx_packets=priv->stats.tx_packets;
|
|
msgrep->rx_bytes=priv->stats.rx_bytes;
|
|
msgrep->tx_bytes=priv->stats.tx_bytes;
|
|
msgrep->rx_errors=priv->stats.rx_errors;
|
|
msgrep->tx_errors=priv->stats.tx_errors;
|
|
msgrep->rx_dropped=priv->stats.rx_dropped;
|
|
msgrep->tx_dropped=priv->stats.tx_dropped;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_statistic_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_statistic_reply msgrep;
|
|
printk("NAS_IOCTL_STATISTIC: stat requested\n");
|
|
nas_set_msg_statistic_reply(&msgrep,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_STATISTIC: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Connections List
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_cx_list_reply(uint8_t *msgrep,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
nasLocalConnectionRef_t lcr;
|
|
struct nas_msg_cx_list_reply *list;
|
|
msgrep[0]=NAS_CX_MAX;
|
|
list=(struct nas_msg_cx_list_reply *)(msgrep+1);
|
|
for(lcr=0;lcr<NAS_CX_MAX;++lcr)
|
|
{
|
|
cx=nas_COMMON_search_cx(lcr,priv);
|
|
list[lcr].lcr=lcr;
|
|
list[lcr].state=cx->state;
|
|
list[lcr].cellid=cx->cellid;
|
|
list[lcr].iid4=cx->iid4;
|
|
list[lcr].iid6[0]=cx->iid6[0];
|
|
list[lcr].iid6[1]=cx->iid6[1];
|
|
list[lcr].num_rb=cx->num_rb;
|
|
list[lcr].nsclassifier=cx->nsclassifier;
|
|
printk("NAS_SET_MSG_CX_LIST_REPLY: nsc=%u\n",cx->nsclassifier);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_cx_list_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
uint8_t msgrep[NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1];
|
|
printk("NAS_IOCTL_CX_LIST: connection list requested\n");
|
|
nas_set_msg_cx_list_reply(msgrep,priv);
|
|
if (copy_to_user(gifr->msg, msgrep, NAS_CX_MAX*sizeof(struct nas_msg_cx_list_reply)+1))
|
|
{
|
|
printk("NAS_IOCTL_CX_LIST: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
printk("NAS_IOCTL_CX_LIST: end\n");
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Connection Establishment
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_cx_establishment_reply(struct nas_msg_cx_establishment_reply *msgrep,
|
|
struct nas_msg_cx_establishment_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx!=NULL)
|
|
{
|
|
cx->cellid=msgreq->cellid;
|
|
msgrep->status=nas_mesh_DC_send_cx_establish_request(cx,priv);
|
|
}
|
|
else
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_cx_establishment_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_cx_establishment_request msgreq;
|
|
struct nas_msg_cx_establishment_reply msgrep;
|
|
printk("NAS_IOCTL_ESTABLISHMENT: connection establishment requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_cx_establishment_reply(&msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_CX_ESTABLISHMENT: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Connection Release
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_cx_release_reply(struct nas_msg_cx_release_reply *msgrep,
|
|
struct nas_msg_cx_release_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx!=NULL)
|
|
msgrep->status=nas_mesh_DC_send_cx_release_request(cx,priv);
|
|
else
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Request the release of a connection
|
|
int nas_ioCTL_cx_release_request(struct nas_ioctl *gifr,struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_cx_release_request msgreq;
|
|
struct nas_msg_cx_release_reply msgrep;
|
|
|
|
printk("NAS_IOCTL_CX_RELEASE: connection release requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_CX_RELEASE: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_cx_release_reply(&msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_CX_RELEASE: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
printk("NAS_IOCTL_CX_RELEASE: end\n");
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Radio Bearer List
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_rb_list_reply(uint8_t *msgrep,
|
|
struct nas_msg_rb_list_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx!=NULL)
|
|
{
|
|
uint8_t rbi;
|
|
struct rb_entity *rb;
|
|
struct nas_msg_rb_list_reply *list;
|
|
if (cx->num_rb > NAS_LIST_RB_MAX)
|
|
msgrep[0] = NAS_LIST_RB_MAX;
|
|
else
|
|
msgrep[0] = cx->num_rb;
|
|
list=(struct nas_msg_rb_list_reply *)(msgrep+1);
|
|
for (rb=cx->rb, rbi=0; (rb!=NULL)&&(rbi<msgrep[0]); rb=rb->next, ++rbi)
|
|
{
|
|
list[rbi].state=rb->state;
|
|
list[rbi].rab_id=rb->rab_id;
|
|
list[rbi].sapi=rb->sapi;
|
|
list[rbi].qos=rb->qos;
|
|
}
|
|
}
|
|
else
|
|
msgrep[0]=0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_rb_list_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
uint8_t msgrep[NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1];
|
|
struct nas_msg_rb_list_request msgreq;
|
|
printk("NAS_IOCTL_RB_LIST: Radio Bearer list requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_RB_LIST: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_rb_list_reply(msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_RB_MAX*sizeof(struct nas_msg_rb_list_reply)+1))
|
|
{
|
|
printk("NAS_IOCTL_RB_LIST: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
printk("NAS_IOCTL_CX_LIST: end\n");
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Radio Bearer Establishment
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_rb_establishment_reply(struct nas_msg_rb_establishment_reply *msgrep,
|
|
struct nas_msg_rb_establishment_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
// if ((msgreq->rab_id<3)||(msgreq->rab_id>127))
|
|
if ((msgreq->rab_id<1)||(msgreq->rab_id>MAX_RABS)) // navid : increase the number
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTRABI;
|
|
else
|
|
{
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx==NULL)
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
else
|
|
{
|
|
struct rb_entity *rb;
|
|
rb=nas_COMMON_add_rb(cx, msgreq->rab_id, msgreq->qos);
|
|
if (rb!=NULL){
|
|
// rb->cnxid = msgreq->cnxid;
|
|
// msgrep->status=nas_rg_DC_send_rb_establish_request(cx, rb);
|
|
}
|
|
else
|
|
msgrep->status=-NAS_ERROR_NOMEMORY;
|
|
// msgrep->cnxid = msgreq->cnxid;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_rb_establishment_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_rb_establishment_request msgreq;
|
|
struct nas_msg_rb_establishment_reply msgrep;
|
|
printk("NAS_IOCTL_RB_ESTABLISHMENT: Radio bearer establishment requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
|
|
nas_set_msg_rb_establishment_reply(&msgrep, &msgreq,priv);
|
|
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_RB_ESTABLISHMENT: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Radio Bearer Release
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_rb_release_reply(struct nas_msg_rb_release_reply *msgrep,
|
|
struct nas_msg_rb_release_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
if (msgreq->lcr<NAS_CX_MAX)
|
|
{
|
|
struct rb_entity *rb;
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
rb=nas_COMMON_search_rb(cx, msgreq->rab_id);
|
|
if (rb!=NULL) {
|
|
//msgrep->status=nas_rg_DC_send_rb_release_request(cx, rb);
|
|
}
|
|
else
|
|
msgrep->status=-NAS_ERROR_NOTCONNECTED;
|
|
// msgrep->cnxid = msgreq->cnxid;
|
|
}
|
|
else
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_rb_release_request(
|
|
struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_rb_release_request msgreq;
|
|
struct nas_msg_rb_release_reply msgrep;
|
|
printk("NAS_IOCTL_RB_RELEASE: Radio bearer release requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_RB_RELEASE: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_rb_release_reply(&msgrep, &msgreq, priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_RB_RELEASE: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Classifier List
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_class_list_reply(
|
|
uint8_t *msgrep,
|
|
struct nas_msg_class_list_request *msgreq,
|
|
struct nas_priv *priv) {
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
struct classifier_entity *gc;
|
|
struct nas_msg_class_list_reply *list;
|
|
uint8_t cli;
|
|
list=(struct nas_msg_class_list_reply *)(msgrep+1);
|
|
switch(msgreq->dir)
|
|
{
|
|
case NAS_DIRECTION_SEND:
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx==NULL)
|
|
{
|
|
msgrep[0]=0;
|
|
return;
|
|
}
|
|
gc=cx->sclassifier[msgreq->dscp];
|
|
break;
|
|
case NAS_DIRECTION_RECEIVE:
|
|
cx=NULL;
|
|
gc=priv->rclassifier[msgreq->dscp];
|
|
break;
|
|
default:
|
|
cx=NULL;
|
|
msgrep[0]=0;
|
|
return;
|
|
}
|
|
for (cli=0; (gc!=NULL)&&(cli<NAS_LIST_CLASS_MAX); gc=gc->next, ++cli)
|
|
{
|
|
list[cli].classref=gc->classref;
|
|
list[cli].lcr=msgreq->lcr;
|
|
list[cli].dir=msgreq->dir;
|
|
list[cli].dscp=msgreq->dscp;
|
|
list[cli].rab_id=gc->rab_id;
|
|
list[cli].version=gc->version;
|
|
switch(gc->version)
|
|
{
|
|
case 4:
|
|
list[cli].saddr.ipv4 = gc->saddr.ipv4;
|
|
list[cli].daddr.ipv4 = gc->daddr.ipv4;
|
|
break;
|
|
case 6:
|
|
list[cli].saddr.ipv6 = gc->saddr.ipv6;
|
|
list[cli].daddr.ipv6 = gc->daddr.ipv6;
|
|
break;
|
|
}
|
|
list[cli].protocol=gc->protocol;
|
|
list[cli].sport=ntohs(gc->sport);
|
|
list[cli].dport=ntohs(gc->dport);
|
|
list[cli].splen=gc->splen;
|
|
list[cli].dplen=gc->dplen;
|
|
list[cli].fct=nas_TOOL_invfct(gc);
|
|
}
|
|
msgrep[0]=cli;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_class_list_request(
|
|
struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
uint8_t msgrep[NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1];
|
|
struct nas_msg_class_list_request msgreq;
|
|
printk("NAS_IOCTL_CLASS_LIST: classifier list requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_CLASS_LIST: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_class_list_reply(msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, msgrep, NAS_LIST_CLASS_MAX*sizeof(struct nas_msg_class_list_reply)+1))
|
|
{
|
|
printk("NAS_IOCTL_CLASS_LIST: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Request the addition of a classifier rule
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_class_add_reply(
|
|
struct nas_msg_class_add_reply *msgrep,
|
|
struct nas_msg_class_add_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct classifier_entity *gc,*gc2;
|
|
unsigned char *saddr,*daddr;
|
|
unsigned int *saddr32,*daddr32;
|
|
|
|
printk("[NAS][CLASS] nas_set_msg_class_add_reply\n");
|
|
|
|
|
|
if (msgreq->dscp>NAS_DSCP_MAX){
|
|
printk("NAS_SET_MSG_CLASS_ADD_REPLY: Incoherent parameter value\n");
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
|
|
return;
|
|
}
|
|
if (msgreq->dir==NAS_DIRECTION_SEND){
|
|
|
|
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx!=NULL){
|
|
printk("NAS_SET_MSG_CLASS_ADD_REPLY: DSCP/EXP %d, Classref %d, RB %u\n", msgreq->dscp, msgreq->classref,msgreq->rab_id );
|
|
gc=nas_CLASS_add_sclassifier(cx, msgreq->dscp, msgreq->classref);
|
|
|
|
printk("NAS_SET_MSG_CLASS_ADD_REPLY: %p %p\n" , msgreq, gc);
|
|
|
|
if (gc==NULL){
|
|
msgrep->status=-NAS_ERROR_NOMEMORY;
|
|
return;
|
|
}
|
|
}else{
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
return;
|
|
}
|
|
gc->rab_id=msgreq->rab_id;
|
|
|
|
gc->rb=nas_COMMON_search_rb(cx, gc->rab_id);
|
|
printk("NAS_SET_MSG_CLASS_ADD_REPLY: gc_rb %p %u \n", gc->rb, gc->rab_id);
|
|
}else{
|
|
if (msgreq->dir==NAS_DIRECTION_RECEIVE){
|
|
gc=nas_CLASS_add_rclassifier(msgreq->dscp,
|
|
msgreq->classref,
|
|
priv);
|
|
if (gc==NULL){
|
|
msgrep->status=-NAS_ERROR_NOMEMORY;
|
|
return;
|
|
}
|
|
gc->rab_id=msgreq->rab_id;
|
|
|
|
}else{
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
|
|
return;
|
|
}
|
|
for (gc2 = priv->rclassifier[msgreq->dscp]; gc2!=NULL ; gc2 = gc2->next)
|
|
printk("[NAS][CLASS] Add Receive Classifier dscp %d: rab_id %d (%p,next %p)\n",msgreq->dscp,gc2->rab_id,gc2,gc2->next);
|
|
}
|
|
printk("[NAS][CLASS] Getting addresses ...\n");
|
|
|
|
nas_TOOL_fct(gc, msgreq->fct);
|
|
gc->version=msgreq->version;
|
|
switch(gc->version){
|
|
case 4:
|
|
gc->saddr.ipv4=msgreq->saddr.ipv4;
|
|
gc->daddr.ipv4=msgreq->daddr.ipv4;
|
|
|
|
|
|
|
|
// #ifdef NAS_CLASS_DEBUG
|
|
saddr = (unsigned char *)&gc->saddr.ipv4;
|
|
daddr = (unsigned char *)&gc->daddr.ipv4;
|
|
|
|
printk("[NAS][CLASS] Adding IPv4 %d.%d.%d.%d -> %d.%d.%d.%d\n",
|
|
saddr[0],saddr[1],saddr[2],saddr[3],
|
|
daddr[0],daddr[1],daddr[2],daddr[3]);
|
|
|
|
|
|
|
|
//#endif
|
|
gc->splen=msgreq->splen;
|
|
gc->dplen=msgreq->dplen;
|
|
break;
|
|
case 6:
|
|
memcpy(&gc->saddr.ipv6,&msgreq->saddr.ipv6,16);
|
|
memcpy(&gc->daddr.ipv6,&msgreq->daddr.ipv6,16);
|
|
|
|
saddr32 = (unsigned int *)&gc->saddr.ipv6;
|
|
daddr32 = (unsigned int *)&gc->daddr.ipv6;
|
|
|
|
printk("[NAS][CLASS] Adding IPv6 %X:%X:%X:%X -> %X.%X.%X.%X\n",
|
|
saddr32[0],saddr32[1],saddr32[2],saddr32[3],
|
|
daddr32[0],daddr32[1],daddr32[2],daddr32[3]);
|
|
gc->splen=msgreq->splen;
|
|
gc->dplen=msgreq->dplen;
|
|
break;
|
|
case NAS_MPLS_VERSION_CODE:
|
|
|
|
printk("[NAS][CLASS] Adding MPLS label %d with exp %d\n",
|
|
msgreq->daddr.mpls_label,msgreq->dscp);
|
|
gc->daddr.mpls_label = msgreq->daddr.mpls_label;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
gc->saddr.ipv6.s6_addr32[0]=0;
|
|
gc->daddr.ipv6.s6_addr32[1]=0;
|
|
gc->saddr.ipv6.s6_addr32[2]=0;
|
|
gc->daddr.ipv6.s6_addr32[3]=0;
|
|
gc->splen=0;
|
|
gc->dplen=0;
|
|
break;
|
|
default:
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTVERSION;
|
|
kfree(gc);
|
|
return;
|
|
}
|
|
gc->protocol=msgreq->protocol;
|
|
gc->protocol_message_type=msgreq->protocol_message_type;
|
|
gc->sport=htons(msgreq->sport);
|
|
gc->dport=htons(msgreq->dport);
|
|
msgrep->status=0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_class_add_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_class_add_request msgreq;
|
|
struct nas_msg_class_add_reply msgrep;
|
|
|
|
|
|
printk("NAS_IOCTL_CLASS_ADD: Add classifier components requested\n");
|
|
printk("NAS_IOCTL_CLASS_ADD: size of gifr msg %zd\n", sizeof(gifr->msg));
|
|
|
|
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq))){
|
|
printk("NAS_IOCTL_CLASS_ADD: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
|
|
nas_set_msg_class_add_reply(&msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep))){
|
|
printk("NAS_IOCTL_CLASS_ADD: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Request the deletion of a classifier rule
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_class_del_reply(struct nas_msg_class_del_reply *msgrep,
|
|
struct nas_msg_class_del_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
if (msgreq->dscp>NAS_DSCP_DEFAULT)
|
|
{
|
|
printk("NAS_SET_MSG_CLASS_DEL_REPLY: Incoherent parameter value\n");
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTDSCP;
|
|
return;
|
|
}
|
|
if (msgreq->dir==NAS_DIRECTION_SEND)
|
|
{
|
|
struct cx_entity *cx;
|
|
cx=nas_COMMON_search_cx(msgreq->lcr,priv);
|
|
if (cx!=NULL)
|
|
nas_CLASS_del_sclassifier(cx, msgreq->dscp, msgreq->classref);
|
|
else
|
|
{
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTLCR;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (msgreq->dir==NAS_DIRECTION_RECEIVE)
|
|
nas_CLASS_del_rclassifier(msgreq->dscp, msgreq->classref,priv);
|
|
else
|
|
{
|
|
msgrep->status=-NAS_ERROR_NOTCORRECTDIR;
|
|
return;
|
|
}
|
|
}
|
|
msgrep->status=0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_class_del_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_class_del_request msgreq;
|
|
struct nas_msg_class_del_reply msgrep;
|
|
printk("NAS_IOCTL_CLASS_DEL: Del classifier components requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_CLASS_DEL: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_class_del_reply(&msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_CLASS_DEL: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Measurement
|
|
// Messages for Measurement transfer
|
|
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_measure_reply(struct nas_msg_measure_reply *msgrep, struct nas_msg_measure_request *msgreq,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
int lcr=0; // Temp lcr->mt =0
|
|
int i;
|
|
|
|
cx=nas_COMMON_search_cx(lcr,priv);
|
|
if (cx!=NULL)
|
|
{
|
|
msgrep->num_cells = cx->num_measures;
|
|
for (i=0; i<cx->num_measures; i++){
|
|
msgrep-> measures[i].cell_id = cx->meas_cell_id[i];
|
|
msgrep-> measures[i].level = cx->meas_level[i];
|
|
msgrep-> measures[i].provider_id = cx->provider_id[i];
|
|
}
|
|
msgrep->signal_lost_flag = 0;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_measure_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_measure_request msgreq;
|
|
struct nas_msg_measure_reply msgrep;
|
|
printk("NAS_IOCTL_MEASURE: Measurement requested\n");
|
|
if (copy_from_user(&msgreq, gifr->msg, sizeof(msgreq)))
|
|
{
|
|
printk("NAS_IOCTL_MEASURE: copy_from_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
nas_set_msg_measure_reply(&msgrep, &msgreq,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_MEASURE: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// IMEI
|
|
// Messages for IMEI transfer
|
|
//---------------------------------------------------------------------------
|
|
void nas_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct cx_entity *cx;
|
|
int lcr=0; // Temp lcr->mt =0
|
|
int i;
|
|
|
|
cx=nas_COMMON_search_cx(lcr,priv);
|
|
if (cx!=NULL)
|
|
{
|
|
msgrep->l2id[0] = cx->iid6[0];
|
|
msgrep->l2id[1] = cx->iid6[1];
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
int nas_ioCTL_imei_request(struct nas_ioctl *gifr,
|
|
struct nas_priv *priv){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_msg_l2id_reply msgrep;
|
|
printk("NAS_IOCTL_IMEI: IMEI requested\n");
|
|
nas_set_msg_imei_reply(&msgrep,priv);
|
|
if (copy_to_user(gifr->msg, &msgrep, sizeof(msgrep)))
|
|
{
|
|
printk("NAS_IOCTL_IMEI: copy_to_user failure\n");
|
|
return -EFAULT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// IOCTL command
|
|
//---------------------------------------------------------------------------
|
|
int nas_CTL_ioctl(struct net_device *dev,
|
|
struct ifreq *ifr,
|
|
int cmd){
|
|
//---------------------------------------------------------------------------
|
|
struct nas_ioctl *gifr;
|
|
struct nas_priv *priv=netdev_priv(dev);
|
|
|
|
int r;
|
|
|
|
// printk("NAS_CTL_IOCTL: begin ioctl for instance %d\n",find_inst(dev));
|
|
|
|
switch(cmd)
|
|
{
|
|
case NAS_IOCTL_RRM:
|
|
gifr=(struct nas_ioctl *)ifr;
|
|
switch(gifr->type)
|
|
{
|
|
case NAS_MSG_STATISTIC_REQUEST:
|
|
r=nas_ioCTL_statistic_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CX_ESTABLISHMENT_REQUEST:
|
|
r=nas_ioCTL_cx_establishment_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CX_RELEASE_REQUEST:
|
|
r=nas_ioCTL_cx_release_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CX_LIST_REQUEST:
|
|
r=nas_ioCTL_cx_list_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_RB_ESTABLISHMENT_REQUEST:
|
|
r=nas_ioCTL_rb_establishment_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_RB_RELEASE_REQUEST:
|
|
r= nas_ioCTL_rb_release_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_RB_LIST_REQUEST:
|
|
r=nas_ioCTL_rb_list_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CLASS_ADD_REQUEST:
|
|
r=nas_ioCTL_class_add_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CLASS_LIST_REQUEST:
|
|
r=nas_ioCTL_class_list_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_CLASS_DEL_REQUEST:
|
|
r=nas_ioCTL_class_del_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_MEAS_REQUEST:
|
|
r=nas_ioCTL_measure_request(gifr,priv);
|
|
break;
|
|
case NAS_MSG_IMEI_REQUEST:
|
|
r=nas_ioCTL_imei_request(gifr,priv);
|
|
break;
|
|
default:
|
|
// printk("NAS_IOCTL_RRM: unkwon request type, type=%x\n", gifr->type);
|
|
r=-EFAULT;
|
|
}
|
|
break;
|
|
default:
|
|
// printk("NAS_CTL_IOCTL: Unknown ioctl command, cmd=%x\n", cmd);
|
|
r=-EFAULT;
|
|
}
|
|
// printk("NAS_CTL_IOCTL: end\n");
|
|
return r;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void nas_CTL_send(struct sk_buff *skb,
|
|
struct cx_entity *cx,
|
|
struct classifier_entity *gc){
|
|
//---------------------------------------------------------------------------
|
|
printk("NAS_CTL_SEND - void \n");
|
|
}
|
|
|