Commit 50cea9cf authored by Cedric Roux's avatar Cedric Roux

nr pdcp: pass MAC-I and header to upper layers

Needed by some RRC procedures to validate the integrity of a message
before accepting it.
parent 29a8481d
...@@ -44,6 +44,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -44,6 +44,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
int integrity_size; int integrity_size;
int rx_deliv_sn; int rx_deliv_sn;
uint32_t rx_deliv_hfn; uint32_t rx_deliv_hfn;
uint32_t mac = 0;
uint32_t header = 0;
if (size < 1) { if (size < 1) {
LOG_E(PDCP, "bad PDU received (size = %d)\n", size); LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
...@@ -104,6 +106,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -104,6 +106,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn; rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
/* the MAC-I/header/rcvd_count is needed by some RRC procedures, store it */
if (entity->has_integrity || entity->type == NR_PDCP_SRB) {
mac = (uint32_t)buffer[size-4]
| ((uint32_t)buffer[size-3] << 8)
| ((uint32_t)buffer[size-2] << 16)
| ((uint32_t)buffer[size-1] << 24);
/* higher byte of 'header' is its size, next 2 or 3 bytes are the header */
header = (uint32_t)header_size << 24;
if (header_size == 2)
header |= (buffer[0] << 16) | (buffer[1] << 8);
else
header |= (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
}
if (entity->has_ciphering) if (entity->has_ciphering)
entity->cipher(entity->security_context, entity->cipher(entity->security_context,
buffer+header_size, size-header_size, buffer+header_size, size-header_size,
...@@ -134,7 +151,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -134,7 +151,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
sdu = nr_pdcp_new_sdu(rcvd_count, sdu = nr_pdcp_new_sdu(rcvd_count,
(char *)buffer + header_size, (char *)buffer + header_size,
size - header_size - integrity_size); size - header_size - integrity_size,
mac, header);
entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu); entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
entity->rx_size += size-header_size; entity->rx_size += size-header_size;
...@@ -150,7 +168,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -150,7 +168,8 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
while (entity->rx_list != NULL && count == entity->rx_list->count) { while (entity->rx_list != NULL && count == entity->rx_list->count) {
nr_pdcp_sdu_t *cur = entity->rx_list; nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity, entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size); cur->buffer, cur->size,
cur->mac, cur->header, cur->count);
entity->rx_list = cur->next; entity->rx_list = cur->next;
entity->rx_size -= cur->size; entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++; entity->stats.txsdu_pkts++;
...@@ -330,7 +349,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) ...@@ -330,7 +349,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) { while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
nr_pdcp_sdu_t *cur = entity->rx_list; nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity, entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size); cur->buffer, cur->size,
cur->mac, cur->header, cur->count);
entity->rx_list = cur->next; entity->rx_list = cur->next;
entity->rx_size -= cur->size; entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++; entity->stats.txsdu_pkts++;
...@@ -343,7 +363,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) ...@@ -343,7 +363,8 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
while (entity->rx_list != NULL && count == entity->rx_list->count) { while (entity->rx_list != NULL && count == entity->rx_list->count) {
nr_pdcp_sdu_t *cur = entity->rx_list; nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity, entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size); cur->buffer, cur->size,
cur->mac, cur->header, cur->count);
entity->rx_list = cur->next; entity->rx_list = cur->next;
entity->rx_size -= cur->size; entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++; entity->stats.txsdu_pkts++;
...@@ -373,7 +394,8 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity) ...@@ -373,7 +394,8 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity)
while (entity->rx_list != NULL) { while (entity->rx_list != NULL) {
nr_pdcp_sdu_t *cur = entity->rx_list; nr_pdcp_sdu_t *cur = entity->rx_list;
entity->deliver_sdu(entity->deliver_sdu_data, entity, entity->deliver_sdu(entity->deliver_sdu_data, entity,
cur->buffer, cur->size); cur->buffer, cur->size,
cur->mac, cur->header, cur->count);
entity->rx_list = cur->next; entity->rx_list = cur->next;
entity->rx_size -= cur->size; entity->rx_size -= cur->size;
entity->stats.txsdu_pkts++; entity->stats.txsdu_pkts++;
...@@ -480,7 +502,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -480,7 +502,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
bool has_sdap_rx, bool has_sdap_rx,
bool has_sdap_tx, bool has_sdap_tx,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size,
uint32_t mac, uint32_t header, uint32_t count),
void *deliver_sdu_data, void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
char *buf, int size, int sdu_id), char *buf, int size, int sdu_id),
......
...@@ -96,7 +96,8 @@ typedef struct nr_pdcp_entity_t { ...@@ -96,7 +96,8 @@ typedef struct nr_pdcp_entity_t {
/* callbacks provided to the PDCP module */ /* callbacks provided to the PDCP module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size); char *buf, int size,
uint32_t mac, uint32_t header, uint32_t count);
void *deliver_sdu_data; void *deliver_sdu_data;
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
char *buf, int size, int sdu_id); char *buf, int size, int sdu_id);
...@@ -164,7 +165,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ...@@ -164,7 +165,8 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
bool has_sdap_rx, bool has_sdap_rx,
bool has_sdap_tx, bool has_sdap_tx,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size), char *buf, int size,
uint32_t mac, uint32_t header, uint32_t count),
void *deliver_sdu_data, void *deliver_sdu_data,
void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id,
char *buf, int size, int sdu_id), char *buf, int size, int sdu_id),
......
...@@ -658,7 +658,8 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) ...@@ -658,7 +658,8 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id)
} }
static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size) char *buf, int size,
uint32_t mac, uint32_t header, uint32_t count)
{ {
nr_pdcp_ue_t *ue = _ue; nr_pdcp_ue_t *ue = _ue;
int rb_id; int rb_id;
...@@ -741,7 +742,8 @@ static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id ...@@ -741,7 +742,8 @@ static void deliver_pdu_drb_gnb(void *deliver_pdu_data, ue_id_t ue_id, int rb_id
} }
static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity, static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity,
char *buf, int size) char *buf, int size,
uint32_t mac, uint32_t header, uint32_t count)
{ {
nr_pdcp_ue_t *ue = _ue; nr_pdcp_ue_t *ue = _ue;
int srb_id; int srb_id;
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size) nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size,
uint32_t mac, uint32_t header)
{ {
nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t)); nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
if (ret == NULL) if (ret == NULL)
...@@ -35,6 +36,8 @@ nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size) ...@@ -35,6 +36,8 @@ nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
exit(1); exit(1);
memcpy(ret->buffer, buffer, size); memcpy(ret->buffer, buffer, size);
ret->size = size; ret->size = size;
ret->mac = mac;
ret->header = header;
return ret; return ret;
} }
......
...@@ -28,10 +28,20 @@ typedef struct nr_pdcp_sdu_t { ...@@ -28,10 +28,20 @@ typedef struct nr_pdcp_sdu_t {
uint32_t count; uint32_t count;
char *buffer; char *buffer;
int size; int size;
uint32_t mac;
/* 'header' is decomposed into two parts: higher byte is the size of the
* header (2 or 3 bytes), then the next two or three bytes are the header
* so the size is: (header >> 24) & 0xff
* and first byte of header is: (header >> 16) & 0xff
* second byte of header is: (header >> 8) & 0xff
* and if there is a third, it is: header & 0xff
*/
uint32_t header;
struct nr_pdcp_sdu_t *next; struct nr_pdcp_sdu_t *next;
} nr_pdcp_sdu_t; } nr_pdcp_sdu_t;
nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size); nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size,
uint32_t mac, uint32_t header);
nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu); nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count); int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu); void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
......
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