Pass multi socket descriptor in SCTP + add SCTP multi init req/resp mechanism

parent 1729b3dc
......@@ -418,6 +418,7 @@ int logInit (void)
register_log_component("S1AP","",S1AP);
register_log_component("X2AP","",X2AP);
register_log_component("SCTP","",SCTP);
......
......@@ -20,12 +20,13 @@
*/
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ , MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ_MULTI, MESSAGE_PRIORITY_MED, sctp_new_association_req_t , sctp_new_association_req_multi)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_REQ_MULTI, MESSAGE_PRIORITY_MED, sctp_new_association_req_multi_t , sctp_new_association_req_multi)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_RESP, MESSAGE_PRIORITY_MED, sctp_new_association_resp_t , sctp_new_association_resp)
MESSAGE_DEF(SCTP_NEW_ASSOCIATION_IND , MESSAGE_PRIORITY_MED, sctp_new_association_ind_t , sctp_new_association_ind)
MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t, sctp_listener_register_upper_layer)
MESSAGE_DEF(SCTP_REGISTER_UPPER_LAYER, MESSAGE_PRIORITY_MED, sctp_listener_register_upper_layer_t , sctp_listener_register_upper_layer)
MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t , sctp_data_req)
MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t , sctp_data_ind)
MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init)
MESSAGE_DEF(SCTP_INIT_MSG_MULTI, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init_multi)
MESSAGE_DEF(SCTP_INIT_MSG_MULTI_REQ, MESSAGE_PRIORITY_MED, sctp_init_t , sctp_init_multi)
MESSAGE_DEF(SCTP_INIT_MSG_MULTI_CNF, MESSAGE_PRIORITY_MED, sctp_init_msg_multi_cnf_t , sctp_init_msg_multi_cnf)
MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t , sctp_close_association)
......@@ -29,7 +29,8 @@
#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind
#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req
#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctp_init
#define SCTP_INIT_MSG_MULTI(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_multi
#define SCTP_INIT_MSG_MULTI_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_multi
#define SCTP_INIT_MSG_MULTI_CNF(mSGpTR) (mSGpTR)->ittiMsg.sctp_init_msg_multi_cnf
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
enum sctp_state_e {
......@@ -58,6 +59,32 @@ typedef struct sctp_new_association_req_s {
net_ip_address_t remote_address;
} sctp_new_association_req_t;
typedef struct sctp_new_association_req_multi_s {
/* Upper layer connexion identifier */
uint16_t ulp_cnx_id;
/* The port to connect to */
uint16_t port;
/* Payload Protocol Identifier to use */
uint32_t ppid;
/* Number of streams used for this association */
uint16_t in_streams;
uint16_t out_streams;
/* Local address to bind to */
net_ip_address_t local_address;
/* Remote address to connect to */
net_ip_address_t remote_address;
/* Multi-socket descriptor */
int multi_sd;
} sctp_new_association_req_multi_t;
typedef struct sctp_init_msg_multi_cnf_s {
int multi_sd;
} sctp_init_msg_multi_cnf_t;
typedef struct sctp_new_association_ind_s {
/* Assoc id of the new association */
int32_t assoc_id;
......
......@@ -60,11 +60,8 @@ void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t enb_port_for_X2C);
static
void x2ap_eNB_handle_sctp_association_resp(instance_t instance,
sctp_new_association_resp_t *sctp_new_association_resp);
uint32_t enb_port_for_X2C,
int multi_sd);
/*
static
......@@ -209,7 +206,7 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p,
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_X2AP, SCTP_INIT_MSG_MULTI);
message = itti_alloc_new_message (TASK_X2AP, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = enb_port_for_X2C;
......@@ -240,11 +237,12 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t enb_port_for_X2C)
uint32_t enb_port_for_X2C,
int multi_sd)
{
MessageDef *message = NULL;
sctp_new_association_req_t *sctp_new_association_req = NULL;
sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
x2ap_eNB_data_t *x2ap_enb_data = NULL;
DevAssert(instance_p != NULL);
......@@ -260,6 +258,8 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p,
sctp_new_association_req->in_streams = in_streams;
sctp_new_association_req->out_streams = out_streams;
sctp_new_association_req->multi_sd = multi_sd;
memcpy(&sctp_new_association_req->remote_address,
target_eNB_ip_address,
sizeof(*target_eNB_ip_address));
......@@ -293,9 +293,7 @@ static
void x2ap_eNB_handle_register_eNB(instance_t instance,
x2ap_register_enb_req_t *x2ap_register_eNB)
{
x2ap_eNB_instance_t *new_instance;
uint8_t index;
DevAssert(x2ap_register_eNB != NULL);
......@@ -309,7 +307,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
DevCheck(new_instance->tac == x2ap_register_eNB->tac, new_instance->tac, x2ap_register_eNB->tac, 0);
DevCheck(new_instance->mcc == x2ap_register_eNB->mcc, new_instance->mcc, x2ap_register_eNB->mcc, 0);
DevCheck(new_instance->mnc == x2ap_register_eNB->mnc, new_instance->mnc, x2ap_register_eNB->mnc, 0);
X2AP_WARN("eNB[%d] already registered\n", instance);
}
else {
new_instance = calloc(1, sizeof(x2ap_eNB_instance_t));
......@@ -327,6 +325,18 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
new_instance->mnc = x2ap_register_eNB->mnc;
new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length;
DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS,
X2AP_MAX_NB_ENB_IP_ADDRESS, x2ap_register_eNB->nb_x2, 0);
memcpy(new_instance->target_enb_x2_ip_address,
x2ap_register_eNB->target_enb_x2_ip_address,
x2ap_register_eNB->nb_x2 * sizeof(net_ip_address_t));
new_instance->nb_x2 = x2ap_register_eNB->nb_x2;
new_instance->enb_x2_ip_address = x2ap_register_eNB->enb_x2_ip_address;
new_instance->sctp_in_streams = x2ap_register_eNB->sctp_in_streams;
new_instance->sctp_out_streams = x2ap_register_eNB->sctp_out_streams;
new_instance->enb_port_for_X2C = x2ap_register_eNB->enb_port_for_X2C;
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
x2ap_eNB_insert_new_instance(new_instance);
......@@ -342,24 +352,41 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
X2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n",
instance, x2ap_register_eNB->eNB_id);
}
}
DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS,
X2AP_MAX_NB_ENB_IP_ADDRESS, x2ap_register_eNB->nb_x2, 0);
static
void x2ap_eNB_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m)
{
x2ap_eNB_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = x2ap_eNB_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
DevAssert(instance->multi_sd >= 0);
/* Trying to connect to the provided list of eNB ip address */
for (index = 0; index < x2ap_register_eNB->nb_x2; index++) {
for (index = 0; index < instance->nb_x2; index++) {
X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
instance, x2ap_register_eNB->eNB_id);
x2ap_eNB_register_eNB(new_instance,
&x2ap_register_eNB->target_enb_x2_ip_address[index],
&x2ap_register_eNB->enb_x2_ip_address,
x2ap_register_eNB->sctp_in_streams,
x2ap_register_eNB->sctp_out_streams,
x2ap_register_eNB->enb_port_for_X2C);
instance_id, instance->eNB_id);
x2ap_eNB_register_eNB(instance,
&instance->target_enb_x2_ip_address[index],
&instance->enb_x2_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->enb_port_for_X2C,
instance->multi_sd);
}
}
void *x2ap_task(void *arg)
......@@ -386,6 +413,11 @@ void *x2ap_task(void *arg)
&X2AP_REGISTER_ENB_REQ(received_msg));
break;
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
......
......@@ -151,7 +151,13 @@ typedef struct x2ap_eNB_instance_s {
uint16_t mnc;
uint8_t mnc_digit_length;
net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
uint8_t nb_x2;
net_ip_address_t enb_x2_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t enb_port_for_X2C;
int multi_sd;
} x2ap_eNB_instance_t;
typedef struct {
......
......@@ -24,6 +24,20 @@
#include "sctp_common.h"
#include "sctp_eNB_itti_messaging.h"
int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd)
{
MessageDef *message_p;
sctp_init_msg_multi_cnf_t *sctp_init_msg_multi_cnf_p;
message_p = itti_alloc_new_message(TASK_SCTP, SCTP_INIT_MSG_MULTI_CNF);
sctp_init_msg_multi_cnf_p = &message_p->ittiMsg.sctp_init_msg_multi_cnf;
sctp_init_msg_multi_cnf_p->multi_sd = multi_sd;
return itti_send_msg_to_task(task_id, instance, message_p);
}
int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream)
{
......
......@@ -22,6 +22,8 @@
#ifndef SCTP_ITTI_MESSAGING_H_
#define SCTP_ITTI_MESSAGING_H_
int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd);
int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer,
uint32_t buffer_length, uint16_t stream);
......
......@@ -220,10 +220,10 @@ void
sctp_handle_new_association_req_multi(
const instance_t instance,
const task_id_t requestor,
const sctp_new_association_req_t * const sctp_new_association_req_p,
int sd)
const sctp_new_association_req_multi_t * const sctp_new_association_req_p)
{
int ns;
int sd;
int32_t assoc_id = 0;
......@@ -235,6 +235,8 @@ sctp_handle_new_association_req_multi(
*/
DevAssert(sctp_new_association_req_p != NULL);
sd = sctp_new_association_req_p->multi_sd;
/* Create new socket with IPv6 affinity */
//#warning "SCTP may Force IPv4 only, here"
......@@ -265,8 +267,9 @@ sctp_handle_new_association_req_multi(
SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n",
(int)strlen(sctp_new_association_req_p->remote_address.ipv6_address),
sctp_new_association_req_p->remote_address.ipv6_address);
close(sd);
return;
//close(sd);
//return;
exit(1);
}
SCTP_DEBUG("Converted ipv6 address %*s to network type\n",
......@@ -284,8 +287,9 @@ sctp_handle_new_association_req_multi(
SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n",
(int)strlen(sctp_new_association_req_p->remote_address.ipv4_address),
sctp_new_association_req_p->remote_address.ipv4_address);
close(sd);
return;
//close(sd);
//return;
exit(1);
}
SCTP_DEBUG("Converted ipv4 address %*s to network type\n",
......@@ -307,7 +311,7 @@ sctp_handle_new_association_req_multi(
SCTP_STATE_UNREACHABLE, 0, 0);
/* Add the socket to list of fd monitored by ITTI */
//itti_unsubscribe_event_fd(TASK_SCTP, sd);
close(sd);
//close(sd);
return;
} else {
SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n",
......@@ -1043,7 +1047,6 @@ void *sctp_eNB_task(void *arg)
struct epoll_event *events;
MessageDef *received_msg = NULL;
int result;
int multi_sd = -1;
SCTP_DEBUG("Starting SCTP layer\n");
......@@ -1072,8 +1075,10 @@ void *sctp_eNB_task(void *arg)
}
break;
case SCTP_INIT_MSG_MULTI: {
SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI\n");
case SCTP_INIT_MSG_MULTI_REQ: {
int multi_sd;
SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n");
multi_sd = sctp_create_new_listener(
ITTI_MESSAGE_GET_INSTANCE(received_msg),
......@@ -1084,6 +1089,10 @@ void *sctp_eNB_task(void *arg)
/* SCTP socket creation or bind failed... */
SCTP_ERROR("Failed to create new SCTP listener\n");
}
sctp_itti_send_init_msg_multi_cnf(
ITTI_MSG_ORIGIN_ID(received_msg),
ITTI_MESSAGE_GET_INSTANCE(received_msg),
multi_sd);
}
break;
......@@ -1097,8 +1106,7 @@ void *sctp_eNB_task(void *arg)
case SCTP_NEW_ASSOCIATION_REQ_MULTI: {
sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg),
ITTI_MSG_ORIGIN_ID(received_msg),
&received_msg->ittiMsg.sctp_new_association_req_multi,
multi_sd);
&received_msg->ittiMsg.sctp_new_association_req_multi);
}
break;
......
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