mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-upf.git
synced 2025-11-03 05:23:46 +00:00
144 lines
5.7 KiB
C
144 lines
5.7 KiB
C
/* PFCP message encoding and decoding */
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <inttypes.h>
|
|
|
|
#include <osmocom/core/socket.h>
|
|
#include <osmocom/core/msgb.h>
|
|
#include <osmocom/core/fsm.h>
|
|
|
|
#include <osmocom/pfcp/pfcp_proto.h>
|
|
#include <osmocom/pfcp/pfcp_ies_auto.h>
|
|
#include <osmocom/pfcp/pfcp_strs.h>
|
|
|
|
struct msgb;
|
|
struct osmo_t16l16v_ie;
|
|
|
|
#define OSMO_PFCP_MSGB_ALLOC_SIZE 2048
|
|
|
|
#define OSMO_LOG_PFCP_MSG_SRC(M, LEVEL, file, line, FMT, ARGS...) do { \
|
|
struct osmo_fsm_inst *_fi = (M) ? ( (M)->ctx.session_fi ?: (M)->ctx.peer_fi ) : NULL; \
|
|
enum osmo_pfcp_cause *cause = osmo_pfcp_msg_cause(M); \
|
|
if ((M)->h.seid_present) { \
|
|
LOGPFSMSLSRC(_fi, DLPFCP, LEVEL, file, line, \
|
|
"%s%s PFCP seq-%u SEID-0x%"PRIx64" %s%s%s: " FMT, \
|
|
_fi ? "" : osmo_sockaddr_to_str_c(OTC_SELECT, &(M)->remote_addr), \
|
|
(M)->rx ? "-rx->" : "<-tx-", (M)->h.sequence_nr, \
|
|
(M)->h.seid, \
|
|
osmo_pfcp_message_type_str((M)->h.message_type), cause ? ": " : "", \
|
|
cause ? osmo_pfcp_cause_str(*cause) : "", ##ARGS); \
|
|
} else { \
|
|
LOGPFSMSLSRC(_fi, DLPFCP, LEVEL, file, line, \
|
|
"%s%s PFCP seq-%u %s%s%s: " FMT, \
|
|
_fi ? "" : osmo_sockaddr_to_str_c(OTC_SELECT, &(M)->remote_addr), \
|
|
(M)->rx ? "-rx->" : "<-tx-", (M)->h.sequence_nr, \
|
|
osmo_pfcp_message_type_str((M)->h.message_type), cause ? ": " : "", \
|
|
cause ? osmo_pfcp_cause_str(*cause) : "", ##ARGS); \
|
|
} \
|
|
} while(0)
|
|
|
|
#define OSMO_LOG_PFCP_MSG(M, LEVEL, FMT, ARGS...) \
|
|
OSMO_LOG_PFCP_MSG_SRC(M, LEVEL, __FILE__, __LINE__, FMT, ##ARGS)
|
|
|
|
/* Return the next PFCP transmit sequence number based on the given sequence state var. */
|
|
static inline uint32_t osmo_pfcp_next_seq(uint32_t *seq_state)
|
|
{
|
|
(*seq_state)++;
|
|
(*seq_state) &= 0xffffff;
|
|
return *seq_state;
|
|
}
|
|
|
|
struct osmo_pfcp_header_parsed {
|
|
uint8_t version;
|
|
enum osmo_pfcp_message_type message_type;
|
|
uint32_t sequence_nr;
|
|
bool priority_present;
|
|
uint8_t priority;
|
|
bool seid_present;
|
|
uint64_t seid;
|
|
};
|
|
|
|
struct osmo_pfcp_msg {
|
|
/* Peer's remote address. Received from this peer, or should be sent to this peer. */
|
|
struct osmo_sockaddr remote_addr;
|
|
/* True when this message was received from a remote; false when this message is going to be sent. */
|
|
bool rx;
|
|
/* True when this message is a Response message type; false if Request. This is set by
|
|
* osmo_pfcp_msg_decode() for received messages, and by osmo_pfcp_msg_alloc_tx */
|
|
bool is_response;
|
|
|
|
/* Context information about this message, used for logging */
|
|
struct {
|
|
/* Peer FSM instance that this message is received from / sent to. This can be set in the
|
|
* osmo_pfcp_endpoint->set_msg_ctx() implementation, up to the caller. If present, this is used for
|
|
* logging context, and can also be used by the caller to reduce lookup iterations. */
|
|
struct osmo_fsm_inst *peer_fi;
|
|
struct osmo_use_count *peer_use_count;
|
|
const char *peer_use_token;
|
|
|
|
/* Session FSM instance that this message is received from / sent to. This can be set in the
|
|
* osmo_pfcp_endpoint->set_msg_ctx() implementation, up to the caller. If present, this is used for
|
|
* logging context, and can also be used by the caller to reduce lookup iterations. */
|
|
struct osmo_fsm_inst *session_fi;
|
|
struct osmo_use_count *session_use_count;
|
|
const char *session_use_token;
|
|
} ctx;
|
|
|
|
struct osmo_pfcp_header_parsed h;
|
|
|
|
int ofs_cause;
|
|
int ofs_node_id;
|
|
|
|
/* The union of decoded IEs from all supported PFCP message types. The union and its structure is defined in
|
|
* pfcp_msg_tlv.h, which is generated from pfcp_msg_gen.c.
|
|
*/
|
|
union osmo_pfcp_ies ies;
|
|
};
|
|
|
|
bool osmo_pfcp_msgtype_is_response(enum osmo_pfcp_message_type message_type);
|
|
|
|
int osmo_pfcp_ie_f_teid_to_str_buf(char *buf, size_t len, const struct osmo_pfcp_ie_f_teid *ft);
|
|
char *osmo_pfcp_ie_f_teid_to_str_c(void *ctx, const struct osmo_pfcp_ie_f_teid *ft);
|
|
|
|
int osmo_pfcp_msg_encode(struct msgb *msg, struct osmo_pfcp_msg *pfcp_msg);
|
|
|
|
int osmo_pfcp_msg_decode_header(struct osmo_tlv_load *tlv, struct osmo_pfcp_msg *m,
|
|
const struct msgb *msg);
|
|
int osmo_pfcp_msg_decode_tlv(struct osmo_pfcp_msg *m, struct osmo_tlv_load *tlv);
|
|
|
|
struct osmo_pfcp_msg *osmo_pfcp_msg_alloc_rx(void *ctx, const struct osmo_sockaddr *remote_addr);
|
|
struct osmo_pfcp_msg *osmo_pfcp_msg_alloc_tx(void *ctx, const struct osmo_sockaddr *remote_addr,
|
|
const struct osmo_pfcp_ie_node_id *local_node_id,
|
|
const struct osmo_pfcp_msg *in_reply_to,
|
|
enum osmo_pfcp_message_type msg_type);
|
|
|
|
void osmo_pfcp_msg_invalidate_ctx(struct osmo_pfcp_msg *m, struct osmo_fsm_inst *deleted_fi);
|
|
|
|
void osmo_pfcp_msg_free(struct osmo_pfcp_msg *m);
|
|
|
|
int osmo_pfcp_ie_node_id_from_osmo_sockaddr(struct osmo_pfcp_ie_node_id *node_id, const struct osmo_sockaddr *os);
|
|
int osmo_pfcp_ie_node_id_to_osmo_sockaddr(const struct osmo_pfcp_ie_node_id *node_id, struct osmo_sockaddr *os);
|
|
|
|
#define OSMO_PFCP_MSG_MEMB(M, OFS) ((OFS) <= 0 ? NULL : (void*)((uint8_t*)(M) + OFS))
|
|
|
|
static inline enum osmo_pfcp_cause *osmo_pfcp_msg_cause(const struct osmo_pfcp_msg *m)
|
|
{
|
|
return OSMO_PFCP_MSG_MEMB(m, m->ofs_cause);
|
|
}
|
|
|
|
static inline struct osmo_pfcp_ie_node_id *osmo_pfcp_msg_node_id(const struct osmo_pfcp_msg *m)
|
|
{
|
|
return OSMO_PFCP_MSG_MEMB(m, m->ofs_node_id);
|
|
}
|
|
|
|
int osmo_pfcp_ie_f_seid_cmp(const struct osmo_pfcp_ie_f_seid *a, const struct osmo_pfcp_ie_f_seid *b);
|
|
void osmo_pfcp_ie_f_seid_set_addr(struct osmo_pfcp_ie_f_seid *f_seid, const struct osmo_sockaddr *addr);
|
|
|
|
bool osmo_pfcp_bits_get(const uint8_t *bits, unsigned int bitpos);
|
|
void osmo_pfcp_bits_set(uint8_t *bits, unsigned int bitpos, bool val);
|
|
int osmo_pfcp_bits_to_str_buf(char *buf, size_t buflen, const uint8_t *bits, const struct value_string *bit_strs);
|
|
char *osmo_pfcp_bits_to_str_c(void *ctx, const uint8_t *bits, const struct value_string *bit_str);
|
|
|