861 lines
27 KiB
C
861 lines
27 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
#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
|
|
|
|
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, int inst, struct nas_priv *gpriv)
|
|
{
|
|
//---------------------------------------------------------------------------
|
|
printk("NAS_CTL_SEND - void \n");
|
|
}
|
|
|