neels submitted this change.

View Change

Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified
move libosmo-pfcp to libosmo-pfcp.git

The first user of this is osmo-hnbgw, to implement GTP mapping via a
UPF.

Related: SYS#5895
Change-Id: I1464cdd846b00707b0abba9126aa5bb784b7caf1
---
M configure.ac
M include/osmocom/Makefile.am
D include/osmocom/pfcp/Makefile.am
D include/osmocom/pfcp/pfcp_endpoint.h
D include/osmocom/pfcp/pfcp_ies_custom.h
D include/osmocom/pfcp/pfcp_msg.h
D include/osmocom/pfcp/pfcp_proto.h
D include/osmocom/pfcp/pfcp_strs.h
M src/Makefile.am
D src/libosmo-pfcp/Makefile.am
D src/libosmo-pfcp/gen__pfcp_ies_auto.c
D src/libosmo-pfcp/pfcp_endpoint.c
D src/libosmo-pfcp/pfcp_ies_custom.c
D src/libosmo-pfcp/pfcp_msg.c
D src/libosmo-pfcp/pfcp_strs.c
M tests/Makefile.am
D tests/libosmo-pfcp/Makefile.am
D tests/libosmo-pfcp/pfcp_test.c
D tests/libosmo-pfcp/pfcp_test.ok
M tests/testsuite.at
20 files changed, 1 insertion(+), 4,755 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9ee5011..fe41cc9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,7 @@
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)
PKG_CHECK_MODULES(LIBOSMOGTLV, libosmo-gtlv >= 0.1.0)
+PKG_CHECK_MODULES(LIBOSMOPFCP, libosmo-pfcp >= 0.1.0)

dnl checks for header files
AC_HEADER_STDC
@@ -198,14 +199,11 @@
AC_OUTPUT(
include/Makefile
include/osmocom/Makefile
- include/osmocom/pfcp/Makefile
include/osmocom/upf/Makefile
src/Makefile
- src/libosmo-pfcp/Makefile
src/osmo-upf/Makefile
tests/Makefile
tests/atlocal
- tests/libosmo-pfcp/Makefile
doc/Makefile
doc/examples/Makefile
doc/manuals/Makefile
diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am
index 5a1276e..3f929f1 100644
--- a/include/osmocom/Makefile.am
+++ b/include/osmocom/Makefile.am
@@ -1,4 +1,3 @@
SUBDIRS = \
- pfcp \
upf \
$(NULL)
diff --git a/include/osmocom/pfcp/Makefile.am b/include/osmocom/pfcp/Makefile.am
deleted file mode 100644
index a9bdeab..0000000
--- a/include/osmocom/pfcp/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-pfcp_HEADERS = \
- pfcp_endpoint.h \
- pfcp_ies_custom.h \
- pfcp_ies_auto.h \
- pfcp_msg.h \
- pfcp_proto.h \
- pfcp_strs.h \
- $(NULL)
-
-pfcpdir = $(includedir)/osmocom/pfcp
-
-BUILT_SOURCES = \
- pfcp_ies_auto.h \
- $(NULL)
-
-CLEANFILES = \
- pfcp_ies_auto.h \
- $(NULL)
-
-pfcp_ies_auto.h: $(top_srcdir)/src/libosmo-pfcp/gen__pfcp_ies_auto.c
- $(MAKE) -C $(top_builddir)/src/libosmo-pfcp gen__pfcp_ies_auto
- $(top_builddir)/src/libosmo-pfcp/gen__pfcp_ies_auto h > $(builddir)/pfcp_ies_auto.h
diff --git a/include/osmocom/pfcp/pfcp_endpoint.h b/include/osmocom/pfcp/pfcp_endpoint.h
deleted file mode 100644
index acc878e..0000000
--- a/include/osmocom/pfcp/pfcp_endpoint.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include <osmocom/core/socket.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/tdef.h>
-
-#include <osmocom/pfcp/pfcp_msg.h>
-
-struct osmo_pfcp_endpoint;
-struct osmo_fsm_inst;
-
-#define OSMO_PFCP_TIMER_HEARTBEAT_REQ -19
-#define OSMO_PFCP_TIMER_HEARTBEAT_RESP -20
-#define OSMO_PFCP_TIMER_GRACEFUL_REL -21
-#define OSMO_PFCP_TIMER_T1 -22
-#define OSMO_PFCP_TIMER_N1 -23
-#define OSMO_PFCP_TIMER_KEEP_RESP -24
-#define OSMO_PFCP_TIMER_ASSOC_RETRY -26
-
-extern struct osmo_tdef osmo_pfcp_tdefs[];
-
-/* Ownership of m remains with the caller / m will be deallocated by the caller.
- * \param ep The PFCP endpoint that received and decoded the message.
- * \param m The message that was received.
- * \param req If m is a PFCP Response to an earlier Request, req is that request message. Otherwise req is NULL.
- */
-typedef void (*osmo_pfcp_endpoint_cb)(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m,
- struct osmo_pfcp_msg *req);
-
-/* Send/receive PFCP messages to/from remote PFCP endpoints. */
-struct osmo_pfcp_endpoint {
- struct {
- /* Local address */
- struct osmo_sockaddr local_addr;
- /* Local PFCP Node ID, as sent in outgoing messages' Node ID IE */
- struct osmo_pfcp_ie_node_id local_node_id;
-
- /* Timer definitions to use, if any. See t1_ms, keep_resp_ms. Use osmo_pfcp_tdefs by default. It is
- * convenient to add osmo_pfcp_tdefs as one of your program's osmo_tdef_group entries and call
- * osmo_tdef_vty_init() to expose PFCP timers on the VTY. */
- const struct osmo_tdef *tdefs;
- } cfg;
-
- /* PFCP socket */
- struct osmo_fd pfcp_fd;
-
- /* The time at which this endpoint last restarted, as seconds since unix epoch. */
- uint32_t recovery_time_stamp;
-
- /* State for determining the next sequence number for transmitting a request message */
- uint32_t seq_nr_state;
-
- /* This function is called just after decoding and before handling the message.
- * This function may set ctx.peer_fi and ctx.session_fi, used for logging context during message decoding.
- * The caller may also use these fi pointers to reduce lookup iterations in rx_msg().
- */
- osmo_pfcp_endpoint_cb set_msg_ctx;
-
- /* Callback to receive single incoming PFCP messages from a remote peer, already decoded. */
- osmo_pfcp_endpoint_cb rx_msg;
-
- /* application-private data */
- void *priv;
-
- /* All transmitted PFCP Request messages, list of osmo_pfcp_queue_entry.
- * For a transmitted Request message, wait for a matching Response from a remote peer; if none arrives,
- * retransmit (see n1 and t1_ms). */
- struct llist_head sent_requests;
- /* All transmitted PFCP Response messages, list of osmo_pfcp_queue_entry.
- * For a transmitted Response message, keep it in the queue for a fixed amount of time. If the peer retransmits
- * the original Request, do not dispatch the Request, but respond with the queued message directly. */
- struct llist_head sent_responses;
-};
-
-struct osmo_pfcp_endpoint *osmo_pfcp_endpoint_create(void *ctx, void *priv);
-int osmo_pfcp_endpoint_bind(struct osmo_pfcp_endpoint *ep);
-void osmo_pfcp_endpoint_close(struct osmo_pfcp_endpoint *ep);
-void osmo_pfcp_endpoint_free(struct osmo_pfcp_endpoint **ep);
-
-int osmo_pfcp_endpoint_tx(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m);
-int osmo_pfcp_endpoint_tx_data(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m);
-int osmo_pfcp_endpoint_tx_heartbeat_req(struct osmo_pfcp_endpoint *ep, const struct osmo_sockaddr *remote_addr);
-
-void osmo_pfcp_endpoint_invalidate_ctx(struct osmo_pfcp_endpoint *ep, struct osmo_fsm_inst *deleted_fi);
diff --git a/include/osmocom/pfcp/pfcp_ies_custom.h b/include/osmocom/pfcp/pfcp_ies_custom.h
deleted file mode 100644
index 08e62d1..0000000
--- a/include/osmocom/pfcp/pfcp_ies_custom.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* Definitions for decoded PFCP IEs, to be used by the auto-generated pfcp_ies_auto.c. */
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include <osmocom/core/socket.h>
-
-#include <osmocom/pfcp/pfcp_proto.h>
-
-/* Common pattern used in various PFCP IEs. */
-struct osmo_pfcp_ip_addrs {
- bool v4_present;
- struct osmo_sockaddr v4;
- bool v6_present;
- struct osmo_sockaddr v6;
-};
-
-int osmo_pfcp_ip_addrs_set(struct osmo_pfcp_ip_addrs *dst, const struct osmo_sockaddr *addr);
-
-/* 3GPP TS 29.244 8.2.38, IETF RFC 1035 3.1 */
-struct osmo_pfcp_ie_node_id {
- enum osmo_pfcp_node_id_type type;
- union {
- struct osmo_sockaddr ip;
- /* Fully qualified domain name in "dot" notation ("host.example.com") */
- char fqdn[254];
- };
-};
-
-int osmo_pfcp_ie_node_id_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_ie_node_id *node_id);
-char *osmo_pfcp_ie_node_id_to_str_c(void *ctx, const struct osmo_pfcp_ie_node_id *node_id);
-
-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);
-
-/* 3GPP TS 29.244 8.2.25
- * Usage:
- * struct osmo_pfcp_ie_up_function_features x;
- * osmo_pfcp_bits_set(x.bits, OSMO_PFCP_UP_FEAT_BUNDL, true);
- * if (osmo_pfcp_bits_get(x.bits, OSMO_PFCP_UP_FEAT_BUNDL))
- * foo();
- * printf("%s\n", osmo_pfcp_bits_to_str_c(x.bits, osmo_pfcp_up_feature_strs));
- */
-struct osmo_pfcp_ie_up_function_features {
- uint8_t bits[6];
-};
-
-/* 3GPP TS 29.244 8.2.58
- * struct osmo_pfcp_ie_cp_function_features x;
- * osmo_pfcp_bits_set(x.bits, OSMO_PFCP_CP_FEAT_BUNDL, true);
- * if (osmo_pfcp_bits_get(x.bits, OSMO_PFCP_CP_FEAT_BUNDL))
- * foo();
- * printf("%s\n", osmo_pfcp_bits_to_str_c(x.bits, osmo_pfcp_cp_feature_strs));
- */
-struct osmo_pfcp_ie_cp_function_features {
- uint8_t bits[1];
-};
-
-/* 3GPP TS 29.244 8.2.37 */
-struct osmo_pfcp_ie_f_seid {
- uint64_t seid;
- struct osmo_pfcp_ip_addrs ip_addr;
-};
-
-void osmo_pfcp_ie_f_seid_set(struct osmo_pfcp_ie_f_seid *f_seid, uint64_t seid,
- const struct osmo_sockaddr *remote_addr);
-
-/* 3GPP TS 29.244 8.3.2 */
-struct osmo_pfcp_ie_f_teid {
- bool choose_flag;
- union {
- struct {
- uint32_t teid;
- struct osmo_pfcp_ip_addrs ip_addr;
- } fixed;
- struct {
- bool ipv4_addr;
- bool ipv6_addr;
- bool choose_id_present;
- uint8_t choose_id;
- } choose;
- };
-};
-
-/* 3GPP TS 29.244 8.2.62 */
-struct osmo_pfcp_ie_ue_ip_address {
- bool chv6;
- bool chv4;
- bool ip_is_destination;
- struct osmo_pfcp_ip_addrs ip_addr;
- bool ipv6_prefix_delegation_bits_present;
- uint8_t ipv6_prefix_delegation_bits;
- bool ipv6_prefix_length_present;
- uint8_t ipv6_prefix_length;
-};
-
-/* 3GPP TS 29.244 8.2.26.
- * Usage:
- * struct osmo_pfcp_ie_apply_action x;
- * osmo_pfcp_bits_set(x.bits, OSMO_PFCP_APPLY_ACTION_FORW, true);
- * if (osmo_pfcp_bits_get(x.bits, OSMO_PFCP_APPLY_ACTION_FORW))
- * foo();
- * printf("%s\n", osmo_pfcp_bits_to_str_c(x.bits, osmo_pfcp_apply_action_strs));
- */
-struct osmo_pfcp_ie_apply_action {
- uint8_t bits[2];
-};
-
-struct osmo_pfcp_ie_network_inst {
- /* A domain name may have up to 253 characters; plus nul. */
- char str[253+1];
-};
-
-struct osmo_pfcp_ie_activate_predefined_rules {
- char str[256];
-};
-
-/* 3GPP TS 29.244 8.2.56 */
-struct osmo_pfcp_ie_outer_header_creation {
- /* desc_bits Usage:
- * osmo_pfcp_bits_set(x.desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4, true);
- * if (osmo_pfcp_bits_get(x.desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4))
- * foo();
- * printf("%s\n", osmo_pfcp_bits_to_str_c(x.desc_bits, osmo_pfcp_outer_header_creation_strs));
- */
- uint8_t desc_bits[2];
- bool teid_present;
- uint32_t teid;
- struct osmo_pfcp_ip_addrs ip_addr;
- bool port_number_present;
- uint16_t port_number;
- bool c_tag_present;
- uint32_t c_tag;
- bool s_tag_present;
- uint32_t s_tag;
-};
-
-/* 3GPP TS 29.244 8.2.64. */
-struct osmo_pfcp_ie_outer_header_removal {
- enum osmo_pfcp_outer_header_removal_desc desc;
- bool gtp_u_extension_header_del_present;
- uint8_t gtp_u_extension_header_del_bits[1];
-};
diff --git a/include/osmocom/pfcp/pfcp_msg.h b/include/osmocom/pfcp/pfcp_msg.h
deleted file mode 100644
index 2833408..0000000
--- a/include/osmocom/pfcp/pfcp_msg.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* PFCP message encoding and decoding */
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#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;
-struct osmo_pfcp_msg;
-
-#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)
-
-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;
-};
-
-/* For PFCP requests, notify when a PFCP response has arrived, or when the PFCP response timed out.
- * When rx_resp == NULL, receiving a response timed out or the response could not be decoded.
- * On error, errmsg may convey a human readable error message.
- * Return 1 to also pass rx_resp to osmo_pfcp_endpoint->rx_msg(), return 0 to mark rx_resp handled and not pass it to
- * rx_msg() (to save lookup iterations). Return negative on error, rx_resp is dropped.
- * Find in req the original osmo_pfcp_msg instance; in req->ctx.priv, arbitrary user data may be passed.
- * For example:
- *
- * static int on_foo_resp(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg)
- * {
- * struct something *obj = req->ctx.priv;
- * if (!rx_resp) {
- * handle_error();
- * return 0;
- * }
- * handle_response(obj, rx_resp);
- * return 0;
- * }
- *
- * int do_request(struct something *obj)
- * {
- * struct osmo_pfcp_msg *req;
- * req = osmo_pfcp_msg_alloc_tx(pfcp_ep, &upf_addr, &pfcp_ep->cfg.local_node_id, NULL, OSMO_PFCP_MSGT_FOO);
- * req->h.seid_present = true;
- * req->h.seid = remote_seid;
- * req->ies.foo... = ...;
- * req->ctx.on_resp = on_foo_resp;
- * req->ctx.priv = obj;
- * return osmo_pfcp_endpoint_tx(pfcp_ep, req);
- * }
- */
-typedef int (*osmo_pfcp_resp_cb)(struct osmo_pfcp_msg *req, struct osmo_pfcp_msg *rx_resp, const char *errmsg);
-
-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;
-
- 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_ies_auto.h, which is generated by gen__pfcp_ies_auto.c.
- */
- union osmo_pfcp_ies ies;
-
- /* 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;
-
- osmo_pfcp_resp_cb resp_cb;
- void *priv;
- } ctx;
-
- /* When a message gets encoded, the encoded packet is cached here for possible retransmissions. */
- struct msgb *encoded;
-};
-
-/* Given a &osmo_pfcp_msg->ies pointer, return the &osmo_pfcp_msg.
- * In the TLV API, only the 'ies' union is passed around as argument. This macro is useful in error callbacks to obtain
- * the related osmo_pfcp_msg and thus the logging context pointers (ctx.peer_fi and ctx.session_fi). */
-#define OSMO_PFCP_MSG_FOR_IES(IES_P) ((struct osmo_pfcp_msg *)((char *)IES_P - offsetof(struct osmo_pfcp_msg, 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, const struct osmo_pfcp_msg *pfcp_msg);
-
-int osmo_pfcp_msg_decode_header(struct osmo_gtlv_load *tlv, struct osmo_pfcp_msg *m,
- const struct msgb *msg);
-int osmo_pfcp_msg_decode_tlv(struct osmo_pfcp_msg *m, struct osmo_gtlv_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);
-
-uint32_t osmo_pfcp_next_seq_nr(uint32_t *next_seq_nr_state);
-uint64_t osmo_pfcp_next_seid(uint64_t *next_seid_state);
-
-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_msg_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_msg *m);
-char *osmo_pfcp_msg_to_str_c(void *ctx, const struct osmo_pfcp_msg *m);
diff --git a/include/osmocom/pfcp/pfcp_proto.h b/include/osmocom/pfcp/pfcp_proto.h
deleted file mode 100644
index d387b1b..0000000
--- a/include/osmocom/pfcp/pfcp_proto.h
+++ /dev/null
@@ -1,528 +0,0 @@
-/* 3GPP TS 29.244: Packet Forwarding Control Protocol */
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#define OSMO_PFCP_PORT 8805
-
-/* Section 7.3 / Table 7.3-1 */
-enum osmo_pfcp_message_type {
- OSMO_PFCP_MSGT_NONE = 0,
-
- /* Node related messages */
- OSMO_PFCP_MSGT_HEARTBEAT_REQ = 1,
- OSMO_PFCP_MSGT_HEARTBEAT_RESP = 2,
- OSMO_PFCP_MSGT_PFD_MGMT_REQ = 3,
- OSMO_PFCP_MSGT_PFD_MGMT_RESP = 4,
- OSMO_PFCP_MSGT_ASSOC_SETUP_REQ = 5,
- OSMO_PFCP_MSGT_ASSOC_SETUP_RESP = 6,
- OSMO_PFCP_MSGT_ASSOC_UPDATE_REQ = 7,
- OSMO_PFCP_MSGT_ASSOC_UPDATE_RESP = 8,
- OSMO_PFCP_MSGT_ASSOC_RELEASE_REQ = 9,
- OSMO_PFCP_MSGT_ASSOC_RELEASE_RESP = 10,
- OSMO_PFCP_MSGT_VERSION_NOT_SUPP_RESP = 11,
- OSMO_PFCP_MSGT_NODE_REPORT_REQ = 12,
- OSMO_PFCP_MSGT_NODE_REPORT_RESP = 13,
- OSMO_PFCP_MSGT_SESSION_SET_DEL_REQ = 14,
- OSMO_PFCP_MSGT_SESSION_SET_DEL_RESP = 15,
-
- /* Session related messages */
- OSMO_PFCP_MSGT_SESSION_EST_REQ = 50,
- OSMO_PFCP_MSGT_SESSION_EST_RESP = 51,
- OSMO_PFCP_MSGT_SESSION_MOD_REQ = 52,
- OSMO_PFCP_MSGT_SESSION_MOD_RESP = 53,
- OSMO_PFCP_MSGT_SESSION_DEL_REQ = 54,
- OSMO_PFCP_MSGT_SESSION_DEL_RESP = 55,
- OSMO_PFCP_MSGT_SESSION_REP_REQ = 56,
- OSMO_PFCP_MSGT_SESSION_REP_RESP = 57,
-};
-
-/* Section 8.1.2 / Table 8.1.2-1 */
-enum osmo_pfcp_iei {
- OSMO_PFCP_INVALID_IEI = 0,
- OSMO_PFCP_IEI_CREATE_PDR = 1,
- OSMO_PFCP_IEI_PDI = 2,
- OSMO_PFCP_IEI_CREATE_FAR = 3,
- OSMO_PFCP_IEI_FORW_PARAMS = 4,
- OSMO_PFCP_IEI_DUPL_PARAMS = 5,
- OSMO_PFCP_IEI_CREATE_URR = 6,
- OSMO_PFCP_IEI_CREATE_QER = 7,
- OSMO_PFCP_IEI_CREATED_PDR = 8,
- OSMO_PFCP_IEI_UPD_PDR = 9,
- OSMO_PFCP_IEI_UPD_FAR = 10,
- OSMO_PFCP_IEI_UPD_FORW_PARAMS = 11,
- OSMO_PFCP_IEI_UPD_BAR_SESS_REP_RESP = 12,
- OSMO_PFCP_IEI_UPD_URR = 13,
- OSMO_PFCP_IEI_UPD_QER = 14,
- OSMO_PFCP_IEI_REMOVE_PDR = 15,
- OSMO_PFCP_IEI_REMOVE_FAR = 16,
- OSMO_PFCP_IEI_REMOVE_URR = 17,
- OSMO_PFCP_IEI_REMOVE_QER = 18,
- OSMO_PFCP_IEI_CAUSE = 19,
- OSMO_PFCP_IEI_SOURCE_IFACE = 20,
- OSMO_PFCP_IEI_F_TEID = 21,
- OSMO_PFCP_IEI_NETWORK_INST = 22,
- OSMO_PFCP_IEI_SDF_FILTER = 23,
- OSMO_PFCP_IEI_APPLICATION_ID = 24,
- OSMO_PFCP_IEI_GATE_STATUS = 25,
- OSMO_PFCP_IEI_MBR = 26,
- OSMO_PFCP_IEI_GBR = 27,
- OSMO_PFCP_IEI_QER_CORRELATION_ID = 28,
- OSMO_PFCP_IEI_PRECEDENCE = 29,
- OSMO_PFCP_IEI_TRANSPORT_LEVEL_MARKING = 30,
- OSMO_PFCP_IEI_VOLUME_THRESH = 31,
- OSMO_PFCP_IEI_TIME_THRESH = 32,
- OSMO_PFCP_IEI_MONITORING_TIME = 33,
- OSMO_PFCP_IEI_SUBSEQUENT_VOLUME_THRESH = 34,
- OSMO_PFCP_IEI_SUBSEQUENT_TIME_THRESH = 35,
- OSMO_PFCP_IEI_INACT_DETECTION_TIME = 36,
- OSMO_PFCP_IEI_REPORTING_TRIGGERS = 37,
- OSMO_PFCP_IEI_REDIRECT_INFO = 38,
- OSMO_PFCP_IEI_REP_TYPE = 39,
- OSMO_PFCP_IEI_OFFENDING_IE = 40,
- OSMO_PFCP_IEI_FORW_POLICY = 41,
- OSMO_PFCP_IEI_DESTINATION_IFACE = 42,
- OSMO_PFCP_IEI_UP_FUNCTION_FEATURES = 43,
- OSMO_PFCP_IEI_APPLY_ACTION = 44,
- OSMO_PFCP_IEI_DL_DATA_SERVICE_INFO = 45,
- OSMO_PFCP_IEI_DL_DATA_NOTIFICATION_DELAY = 46,
- OSMO_PFCP_IEI_DL_BUFF_DURATION = 47,
- OSMO_PFCP_IEI_DL_BUFF_SUGGESTED_PACKET_COUNT = 48,
- OSMO_PFCP_IEI_PFCPSMREQ_FLAGS = 49,
- OSMO_PFCP_IEI_PFCPSRRSP_FLAGS = 50,
- OSMO_PFCP_IEI_LOAD_CTRL_INFO = 51,
- OSMO_PFCP_IEI_SEQUENCE_NUMBER = 52,
- OSMO_PFCP_IEI_METRIC = 53,
- OSMO_PFCP_IEI_OVERLOAD_CTRL_INFO = 54,
- OSMO_PFCP_IEI_TIMER = 55,
- OSMO_PFCP_IEI_PDR_ID = 56,
- OSMO_PFCP_IEI_F_SEID = 57,
- OSMO_PFCP_IEI_APPLICATION_IDS_PFDS = 58,
- OSMO_PFCP_IEI_PFD_CONTEXT = 59,
- OSMO_PFCP_IEI_NODE_ID = 60,
- OSMO_PFCP_IEI_PFD_CONTENTS = 61,
- OSMO_PFCP_IEI_MEAS_METHOD = 62,
- OSMO_PFCP_IEI_USAGE_REP_TRIGGER = 63,
- OSMO_PFCP_IEI_MEAS_PERIOD = 64,
- OSMO_PFCP_IEI_FQ_CSID = 65,
- OSMO_PFCP_IEI_VOLUME_MEAS = 66,
- OSMO_PFCP_IEI_DURATION_MEAS = 67,
- OSMO_PFCP_IEI_APPLICATION_DETECTION_INFO = 68,
- OSMO_PFCP_IEI_TIME_OF_FIRST_PACKET = 69,
- OSMO_PFCP_IEI_TIME_OF_LAST_PACKET = 70,
- OSMO_PFCP_IEI_QUOTA_HOLDING_TIME = 71,
- OSMO_PFCP_IEI_DROPPED_DL_TRAFFIC_THRESH = 72,
- OSMO_PFCP_IEI_VOLUME_QUOTA = 73,
- OSMO_PFCP_IEI_TIME_QUOTA = 74,
- OSMO_PFCP_IEI_START_TIME = 75,
- OSMO_PFCP_IEI_END_TIME = 76,
- OSMO_PFCP_IEI_QUERY_URR = 77,
- OSMO_PFCP_IEI_USAGE_REP_SESS_MOD_RESP = 78,
- OSMO_PFCP_IEI_USAGE_REP_SESS_DEL_RESP = 79,
- OSMO_PFCP_IEI_USAGE_REP_SESS_REP_REQ = 80,
- OSMO_PFCP_IEI_URR_ID = 81,
- OSMO_PFCP_IEI_LINKED_URR_ID = 82,
- OSMO_PFCP_IEI_DL_DATA_REP = 83,
- OSMO_PFCP_IEI_OUTER_HEADER_CREATION = 84,
- OSMO_PFCP_IEI_CREATE_BAR = 85,
- OSMO_PFCP_IEI_UPD_BAR_SESS_MOD_REQ = 86,
- OSMO_PFCP_IEI_REMOVE_BAR = 87,
- OSMO_PFCP_IEI_BAR_ID = 88,
- OSMO_PFCP_IEI_CP_FUNCTION_FEATURES = 89,
- OSMO_PFCP_IEI_USAGE_INFO = 90,
- OSMO_PFCP_IEI_APPLICATION_INST_ID = 91,
- OSMO_PFCP_IEI_FLOW_INFO = 92,
- OSMO_PFCP_IEI_UE_IP_ADDRESS = 93,
- OSMO_PFCP_IEI_PACKET_RATE = 94,
- OSMO_PFCP_IEI_OUTER_HEADER_REMOVAL = 95,
- OSMO_PFCP_IEI_RECOVERY_TIME_STAMP = 96,
- OSMO_PFCP_IEI_DL_FLOW_LEVEL_MARKING = 97,
- OSMO_PFCP_IEI_HEADER_ENRICHMENT = 98,
- OSMO_PFCP_IEI_ERROR_IND_REP = 99,
- OSMO_PFCP_IEI_MEAS_INFO = 100,
- OSMO_PFCP_IEI_NODE_REP_TYPE = 101,
- OSMO_PFCP_IEI_USER_PLANE_PATH_FAILURE_REP = 102,
- OSMO_PFCP_IEI_REMOTE_GTP_U_PEER = 103,
- OSMO_PFCP_IEI_UR_SEQN = 104,
- OSMO_PFCP_IEI_UPD_DUPL_PARAMS = 105,
- OSMO_PFCP_IEI_ACTIVATE_PREDEFINED_RULES = 106,
- OSMO_PFCP_IEI_DEACTIVATE_PREDEFINED_RULES = 107,
- OSMO_PFCP_IEI_FAR_ID = 108,
- OSMO_PFCP_IEI_QER_ID = 109,
- OSMO_PFCP_IEI_OCI_FLAGS = 110,
- OSMO_PFCP_IEI_PFCP_ASSOC_RELEASE_REQ = 111,
- OSMO_PFCP_IEI_GRACEFUL_RELEASE_PERIOD = 112,
- OSMO_PFCP_IEI_PDN_TYPE = 113,
- OSMO_PFCP_IEI_FAILED_RULE_ID = 114,
- OSMO_PFCP_IEI_TIME_QUOTA_MECHANISM = 115,
- OSMO_PFCP_IEI_RESERVED = 116,
- OSMO_PFCP_IEI_USER_PLANE_INACT_TIMER = 117,
- OSMO_PFCP_IEI_AGGREGATED_URRS = 118,
- OSMO_PFCP_IEI_MULTIPLIER = 119,
- OSMO_PFCP_IEI_AGGREGATED_URR_ID = 120,
- OSMO_PFCP_IEI_SUBSEQUENT_VOLUME_QUOTA = 121,
- OSMO_PFCP_IEI_SUBSEQUENT_TIME_QUOTA = 122,
- OSMO_PFCP_IEI_RQI = 123,
- OSMO_PFCP_IEI_QFI = 124,
- OSMO_PFCP_IEI_QUERY_URR_REFERENCE = 125,
- OSMO_PFCP_IEI_ADDITIONAL_USAGE_REPS_INFO = 126,
- OSMO_PFCP_IEI_CREATE_TRAFFIC_ENDPOINT = 127,
- OSMO_PFCP_IEI_CREATED_TRAFFIC_ENDPOINT = 128,
- OSMO_PFCP_IEI_UPD_TRAFFIC_ENDPOINT = 129,
- OSMO_PFCP_IEI_REMOVE_TRAFFIC_ENDPOINT = 130,
- OSMO_PFCP_IEI_TRAFFIC_ENDPOINT_ID = 131,
- OSMO_PFCP_IEI_ETHERNET_PACKET_FILTER = 132,
- OSMO_PFCP_IEI_MAC_ADDRESS = 133,
- OSMO_PFCP_IEI_C_TAG = 134,
- OSMO_PFCP_IEI_S_TAG = 135,
- OSMO_PFCP_IEI_ETHERTYPE = 136,
- OSMO_PFCP_IEI_PROXYING = 137,
- OSMO_PFCP_IEI_ETHERNET_FILTER_ID = 138,
- OSMO_PFCP_IEI_ETHERNET_FILTER_PROPERTIES = 139,
- OSMO_PFCP_IEI_SUGGESTED_BUFF_PACKETS_COUNT = 140,
- OSMO_PFCP_IEI_USER_ID = 141,
- OSMO_PFCP_IEI_ETHERNET_PDU_SESS_INFO = 142,
- OSMO_PFCP_IEI_ETHERNET_TRAFFIC_INFO = 143,
- OSMO_PFCP_IEI_MAC_ADDRS_DETECTED = 144,
- OSMO_PFCP_IEI_MAC_ADDRS_REMOVED = 145,
- OSMO_PFCP_IEI_ETHERNET_INACT_TIMER = 146,
- OSMO_PFCP_IEI_ADDITIONAL_MONITORING_TIME = 147,
- OSMO_PFCP_IEI_EVENT_QUOTA = 148,
- OSMO_PFCP_IEI_EVENT_THRESH = 149,
- OSMO_PFCP_IEI_SUBSEQUENT_EVENT_QUOTA = 150,
- OSMO_PFCP_IEI_SUBSEQUENT_EVENT_THRESH = 151,
- OSMO_PFCP_IEI_TRACE_INFO = 152,
- OSMO_PFCP_IEI_FRAMED_ROUTE = 153,
- OSMO_PFCP_IEI_FRAMED_ROUTING = 154,
- OSMO_PFCP_IEI_FRAMED_IPV6_ROUTE = 155,
- OSMO_PFCP_IEI_TIME_STAMP = 156,
- OSMO_PFCP_IEI_AVERAGING_WINDOW = 157,
- OSMO_PFCP_IEI_PAGING_POLICY_INDICATOR = 158,
- OSMO_PFCP_IEI_APN_DNN = 159,
- OSMO_PFCP_IEI_3GPP_IFACE_TYPE = 160,
- OSMO_PFCP_IEI_PFCPSRREQ_FLAGS = 161,
- OSMO_PFCP_IEI_PFCPAUREQ_FLAGS = 162,
- OSMO_PFCP_IEI_ACTIVATION_TIME = 163,
- OSMO_PFCP_IEI_DEACTIVATION_TIME = 164,
- OSMO_PFCP_IEI_CREATE_MAR = 165,
- OSMO_PFCP_IEI_3GPP_ACCESS_FORW_ACTION_INFO = 166,
- OSMO_PFCP_IEI_NON_3GPP_ACCESS_FORW_ACTION_INFO = 167,
- OSMO_PFCP_IEI_REMOVE_MAR = 168,
- OSMO_PFCP_IEI_UPD_MAR = 169,
- OSMO_PFCP_IEI_MAR_ID = 170,
- OSMO_PFCP_IEI_STEERING_FUNCTIONALITY = 171,
- OSMO_PFCP_IEI_STEERING_MODE = 172,
- OSMO_PFCP_IEI_WEIGHT = 173,
- OSMO_PFCP_IEI_PRIORITY = 174,
- OSMO_PFCP_IEI_UPD_3GPP_ACCESS_FORW_ACTION_INFO = 175,
- OSMO_PFCP_IEI_UPD_NON_3GPP_ACCESS_FORW_ACTION_INFO = 176,
- OSMO_PFCP_IEI_UE_IP_ADDRESS_POOL_IDENTITY = 177,
- OSMO_PFCP_IEI_ALTERNATIVE_SMF_IP_ADDRESS = 178,
- OSMO_PFCP_IEI_PACKET_REPLICATION_AND_DETECTION_CARRY_ON_INFO = 179,
- OSMO_PFCP_IEI_SMF_SET_ID = 180,
- OSMO_PFCP_IEI_QUOTA_VALIDITY_TIME = 181,
- OSMO_PFCP_IEI_NUMBER_OF_REPS = 182,
- OSMO_PFCP_IEI_PFCP_SESS_RETENTION_INFO_IN_ASSOC_SETUP_REQ = 183,
- OSMO_PFCP_IEI_PFCPASRSP_FLAGS = 184,
- OSMO_PFCP_IEI_CP_ENTITY_IP_ADDRESS = 185,
- OSMO_PFCP_IEI_PFCPSEREQ_FLAGS = 186,
- OSMO_PFCP_IEI_USER_PLANE_PATH_RECOVERY_REP = 187,
- OSMO_PFCP_IEI_IP_MULTICAST_ADDR_INFO_IN_SESS_EST_REQ = 188,
- OSMO_PFCP_IEI_JOIN_IP_MULTICAST_INFO_IE_IN_USAGE_REP = 189,
- OSMO_PFCP_IEI_LEAVE_IP_MULTICAST_INFO_IE_IN_USAGE_REP = 190,
- OSMO_PFCP_IEI_IP_MULTICAST_ADDRESS = 191,
- OSMO_PFCP_IEI_SOURCE_IP_ADDRESS = 192,
- OSMO_PFCP_IEI_PACKET_RATE_STATUS = 193,
- OSMO_PFCP_IEI_CREATE_BRIDGE_INFO_FOR_TSC = 194,
- OSMO_PFCP_IEI_CREATED_BRIDGE_INFO_FOR_TSC = 195,
- OSMO_PFCP_IEI_DS_TT_PORT_NUMBER = 196,
- OSMO_PFCP_IEI_NW_TT_PORT_NUMBER = 197,
- OSMO_PFCP_IEI_TSN_BRIDGE_ID = 198,
- OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_MOD_REQ = 199,
- OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_MOD_RESP = 200,
- OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_REP_REQ = 201,
- OSMO_PFCP_IEI_PORT_MGMT_INFO_CONTAINER = 202,
- OSMO_PFCP_IEI_CLOCK_DRIFT_CTRL_INFO = 203,
- OSMO_PFCP_IEI_REQUESTED_CLOCK_DRIFT_INFO = 204,
- OSMO_PFCP_IEI_CLOCK_DRIFT_REP = 205,
- OSMO_PFCP_IEI_TSN_TIME_DOMAIN_NUMBER = 206,
- OSMO_PFCP_IEI_TIME_OFFSET_THRESH = 207,
- OSMO_PFCP_IEI_CUMULATIVE_RATERATIO_THRESH = 208,
- OSMO_PFCP_IEI_TIME_OFFSET_MEAS = 209,
- OSMO_PFCP_IEI_CUMULATIVE_RATERATIO_MEAS = 210,
- OSMO_PFCP_IEI_REMOVE_SRR = 211,
- OSMO_PFCP_IEI_CREATE_SRR = 212,
- OSMO_PFCP_IEI_UPD_SRR = 213,
- OSMO_PFCP_IEI_SESS_REP = 214,
- OSMO_PFCP_IEI_SRR_ID = 215,
- OSMO_PFCP_IEI_ACCESS_AVAIL_CTRL_INFO = 216,
- OSMO_PFCP_IEI_REQUESTED_ACCESS_AVAIL_INFO = 217,
- OSMO_PFCP_IEI_ACCESS_AVAIL_REP = 218,
- OSMO_PFCP_IEI_ACCESS_AVAIL_INFO = 219,
- OSMO_PFCP_IEI_PROVIDE_ATSSS_CTRL_INFO = 220,
- OSMO_PFCP_IEI_ATSSS_CTRL_PARAMS = 221,
- OSMO_PFCP_IEI_MPTCP_CTRL_INFO = 222,
- OSMO_PFCP_IEI_ATSSS_LL_CTRL_INFO = 223,
- OSMO_PFCP_IEI_PMF_CTRL_INFO = 224,
- OSMO_PFCP_IEI_MPTCP_PARAMS = 225,
- OSMO_PFCP_IEI_ATSSS_LL_PARAMS = 226,
- OSMO_PFCP_IEI_PMF_PARAMS = 227,
- OSMO_PFCP_IEI_MPTCP_ADDRESS_INFO = 228,
- OSMO_PFCP_IEI_UE_LINK_SPECIFIC_IP_ADDRESS = 229,
- OSMO_PFCP_IEI_PMF_ADDRESS_INFO = 230,
- OSMO_PFCP_IEI_ATSSS_LL_INFO = 231,
- OSMO_PFCP_IEI_DATA_NETWORK_ACCESS_IDENTIFIER = 232,
- OSMO_PFCP_IEI_UE_IP_ADDRESS_POOL_INFO = 233,
- OSMO_PFCP_IEI_AVERAGE_PACKET_DELAY = 234,
- OSMO_PFCP_IEI_MIN_PACKET_DELAY = 235,
- OSMO_PFCP_IEI_MAX_PACKET_DELAY = 236,
- OSMO_PFCP_IEI_QOS_REP_TRIGGER = 237,
- OSMO_PFCP_IEI_GTP_U_PATH_QOS_CTRL_INFO = 238,
- OSMO_PFCP_IEI_GTP_U_PATH_QOS_REP_NODE_REP_REQ = 239,
- OSMO_PFCP_IEI_QOS_INFO_IN_GTP_U_PATH_QOS_REP = 240,
- OSMO_PFCP_IEI_GTP_U_PATH_IFACE_TYPE = 241,
- OSMO_PFCP_IEI_QOS_MONITORING_PER_QOS_FLOW_CTRL_INFO = 242,
- OSMO_PFCP_IEI_REQUESTED_QOS_MONITORING = 243,
- OSMO_PFCP_IEI_REPORTING_FREQUENCY = 244,
- OSMO_PFCP_IEI_PACKET_DELAY_THRESHOLDS = 245,
- OSMO_PFCP_IEI_MIN_WAIT_TIME = 246,
- OSMO_PFCP_IEI_QOS_MONITORING_REP = 247,
- OSMO_PFCP_IEI_QOS_MONITORING_MEAS = 248,
- OSMO_PFCP_IEI_MT_EDT_CTRL_INFO = 249,
- OSMO_PFCP_IEI_DL_DATA_PACKETS_SIZE = 250,
- OSMO_PFCP_IEI_QER_CTRL_INDICATIONS = 251,
- OSMO_PFCP_IEI_PACKET_RATE_STATUS_REP = 252,
- OSMO_PFCP_IEI_NF_INST_ID = 253,
- OSMO_PFCP_IEI_ETHERNET_CONTEXT_INFO = 254,
- OSMO_PFCP_IEI_REDUNDANT_TRANSMISSION_PARAMS = 255,
- OSMO_PFCP_IEI_UPDATED_PDR = 256,
- OSMO_PFCP_IEI_S_NSSAI = 257,
- OSMO_PFCP_IEI_IP_VERSION = 258,
- OSMO_PFCP_IEI_PFCPASREQ_FLAGS = 259,
- OSMO_PFCP_IEI_DATA_STATUS = 260,
- OSMO_PFCP_IEI_PROVIDE_RDS_CONF_INFO = 261,
- OSMO_PFCP_IEI_RDS_CONF_INFO = 262,
- OSMO_PFCP_IEI_QUERY_PACKET_RATE_STATUS_IE_IN_SESS_MOD_REQ = 263,
- OSMO_PFCP_IEI_PACKET_RATE_STATUS_REP_IE_IN_SESS_MOD_RESP = 264,
- OSMO_PFCP_IEI_MPTCP_APPLICABLE_IND = 265,
- OSMO_PFCP_IEI_BRIDGE_MGMT_INFO_CONTAINER = 266,
- OSMO_PFCP_IEI_UE_IP_ADDRESS_USAGE_INFO = 267,
- OSMO_PFCP_IEI_NUMBER_OF_UE_IP_ADDRS = 268,
- OSMO_PFCP_IEI_VALIDITY_TIMER = 269,
- OSMO_PFCP_IEI_REDUNDANT_TRANSMISSION_FORW_PARAMS = 270,
- OSMO_PFCP_IEI_TRANSPORT_DELAY_REPORTING = 271,
-};
-
-/* Section 8.2.1 / Table 8.2.1-1 */
-enum osmo_pfcp_cause {
- OSMO_PFCP_CAUSE_RESERVED = 0,
- OSMO_PFCP_CAUSE_REQUEST_ACCEPTED = 1,
- OSMO_PFCP_CAUSE_MORE_USAGE_REPORT_TO_SEND = 2,
- OSMO_PFCP_CAUSE_REQUEST_REJECTED = 64,
- OSMO_PFCP_CAUSE_SESSION_CTX_NOT_FOUND = 65,
- OSMO_PFCP_CAUSE_MANDATORY_IE_MISSING = 66,
- OSMO_PFCP_CAUSE_CONDITIONAL_IE_MISSING = 67,
- OSMO_PFCP_CAUSE_INVALID_LENGTH = 68,
- OSMO_PFCP_CAUSE_MANDATORY_IE_INCORRECT = 69,
- OSMO_PFCP_CAUSE_INVALID_FORW_POLICY = 70,
- OSMO_PFCP_CAUSE_INVALID_F_TEID_ALLOC_OPTION = 71,
- OSMO_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOC = 72,
- OSMO_PFCP_CAUSE_RULE_CREATION_MOD_FAILURE = 73,
- OSMO_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION = 74,
- OSMO_PFCP_CAUSE_NO_RESOURCES_AVAILABLE = 75,
- OSMO_PFCP_CAUSE_SERVICE_NOT_SUPPORTED = 76,
- OSMO_PFCP_CAUSE_SYSTEM_FAILURE = 77,
- OSMO_PFCP_CAUSE_REDIRECTION_REQUESTED = 78,
- OSMO_PFCP_CAUSE_ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED = 79,
-};
-
-/* Section 8.2.38 */
-enum osmo_pfcp_node_id_type {
- OSMO_PFCP_NODE_ID_T_IPV4 = 0,
- OSMO_PFCP_NODE_ID_T_IPV6 = 1,
- OSMO_PFCP_NODE_ID_T_FQDN = 2,
-};
-
-enum osmo_pfcp_3gpp_iface_type {
- OSMO_PFCP_3GPP_IFACE_TYPE_S1_U = 0,
- OSMO_PFCP_3GPP_IFACE_TYPE_S5_S8_U = 1,
- OSMO_PFCP_3GPP_IFACE_TYPE_S4_U = 2,
- OSMO_PFCP_3GPP_IFACE_TYPE_S11_U = 3,
- OSMO_PFCP_3GPP_IFACE_TYPE_S12_U = 4,
- OSMO_PFCP_3GPP_IFACE_TYPE_GN_GP_U = 5,
- OSMO_PFCP_3GPP_IFACE_TYPE_S2A_U = 6,
- OSMO_PFCP_3GPP_IFACE_TYPE_S2B_U = 7,
- OSMO_PFCP_3GPP_IFACE_TYPE_ENODEB_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING = 8,
- OSMO_PFCP_3GPP_IFACE_TYPE_ENODEB_GTP_U_INTERFACE_FOR_UL_DATA_FORWARDING = 9,
- OSMO_PFCP_3GPP_IFACE_TYPE_SGW_UPF_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING = 10,
- OSMO_PFCP_3GPP_IFACE_TYPE_N3_3GPP_ACCESS = 11,
- OSMO_PFCP_3GPP_IFACE_TYPE_N3_TRUSTED_NON_3GPP_ACCESS = 12,
- OSMO_PFCP_3GPP_IFACE_TYPE_N3_UNTRUSTED_NON_3GPP_ACCESS = 13,
- OSMO_PFCP_3GPP_IFACE_TYPE_N3_FOR_DATA_FORWARDING = 14,
- OSMO_PFCP_3GPP_IFACE_TYPE_N9 = 15,
- OSMO_PFCP_3GPP_IFACE_TYPE_SGI = 16,
- OSMO_PFCP_3GPP_IFACE_TYPE_N6 = 17,
- OSMO_PFCP_3GPP_IFACE_TYPE_N19 = 18,
- OSMO_PFCP_3GPP_IFACE_TYPE_S8_U = 19,
- OSMO_PFCP_3GPP_IFACE_TYPE_GP_U = 20,
-};
-
-enum osmo_pfcp_source_iface {
- OSMO_PFCP_SOURCE_IFACE_ACCESS = 0,
- OSMO_PFCP_SOURCE_IFACE_CORE = 1,
- OSMO_PFCP_SOURCE_IFACE_SGI_LAN_N6_LAN = 2,
- OSMO_PFCP_SOURCE_IFACE_CP_FUNCTION = 3,
- OSMO_PFCP_SOURCE_IFACE_5G_VN_INTERNAL = 4,
-};
-
-enum osmo_pfcp_dest_iface {
- OSMO_PFCP_DEST_IFACE_ACCESS = 0,
- OSMO_PFCP_DEST_IFACE_CORE = 1,
- OSMO_PFCP_DEST_IFACE_SGI_LAN_N6_LAN = 2,
- OSMO_PFCP_DEST_IFACE_CP_FUNCTION = 3,
- OSMO_PFCP_DEST_IFACE_LI_FUNCTION = 4,
- OSMO_PFCP_DEST_IFACE_5G_VN_INTERNAL = 5,
-};
-
-/* The enum values correspond to the bit index in the supported features bitmask in the PFCP UP Function Features IE.
- * 0 means first octet and first bit, "Octet 5 Bit 1" as in spec;
- * 7 means first octet last bit, "Octet 5 Bit 8";
- * 8 means second octet first bit, "Octet 6 Bit 1";
- * and so on.
- * Intended for use with osmo_pfcp_bits_get(), osmo_pfcp_bits_set(), osmo_pfcp_bits_to_str_c().
- */
-enum osmo_pfcp_up_feature {
- OSMO_PFCP_UP_FEAT_BUCP = 0,
- OSMO_PFCP_UP_FEAT_DDND,
- OSMO_PFCP_UP_FEAT_DLBD,
- OSMO_PFCP_UP_FEAT_TRST,
- OSMO_PFCP_UP_FEAT_FTUP,
- OSMO_PFCP_UP_FEAT_PFDM,
- OSMO_PFCP_UP_FEAT_HEEU,
- OSMO_PFCP_UP_FEAT_TREU,
- OSMO_PFCP_UP_FEAT_EMPU,
- OSMO_PFCP_UP_FEAT_PDIU,
- OSMO_PFCP_UP_FEAT_UDBC,
- OSMO_PFCP_UP_FEAT_QUOAC,
- OSMO_PFCP_UP_FEAT_TRACE,
- OSMO_PFCP_UP_FEAT_FRRT,
- OSMO_PFCP_UP_FEAT_PFDE,
- OSMO_PFCP_UP_FEAT_EPFAR,
- OSMO_PFCP_UP_FEAT_DPDRA,
- OSMO_PFCP_UP_FEAT_ADPDP,
- OSMO_PFCP_UP_FEAT_UEIP,
- OSMO_PFCP_UP_FEAT_SSET,
- OSMO_PFCP_UP_FEAT_MNOP,
- OSMO_PFCP_UP_FEAT_MTE,
- OSMO_PFCP_UP_FEAT_BUNDL,
- OSMO_PFCP_UP_FEAT_GCOM,
- OSMO_PFCP_UP_FEAT_MPAS,
- OSMO_PFCP_UP_FEAT_RTTL,
- OSMO_PFCP_UP_FEAT_VTIME,
- OSMO_PFCP_UP_FEAT_NORP,
- OSMO_PFCP_UP_FEAT_IP6PL,
- OSMO_PFCP_UP_FEAT_TSCU,
- OSMO_PFCP_UP_FEAT_MPTCP,
- OSMO_PFCP_UP_FEAT_ATSSSLL,
- OSMO_PFCP_UP_FEAT_QFQM,
- OSMO_PFCP_UP_FEAT_GPQM,
- OSMO_PFCP_UP_FEAT_MTEDT,
- OSMO_PFCP_UP_FEAT_CIOT,
- OSMO_PFCP_UP_FEAT_ETHAR,
- OSMO_PFCP_UP_FEAT_DDDS,
- OSMO_PFCP_UP_FEAT_RDS,
- OSMO_PFCP_UP_FEAT_RTTWP,
-};
-
-/* The enum values correspond to the bit index in the supported features bitmask in the PFCP CP Function Features IE.
- * 0 means first octet and first bit, "Octet 5 Bit 1" as in spec;
- * 7 means first octet last bit, "Octet 5 Bit 8";
- * 8 means second octet first bit, "Octet 6 Bit 1";
- * and so on.
- * Intended for use with osmo_pfcp_bits_get(), osmo_pfcp_bits_set(), osmo_pfcp_bits_to_str_c().
- */
-enum osmo_pfcp_cp_feature {
- OSMO_PFCP_CP_FEAT_LOAD = 0,
- OSMO_PFCP_CP_FEAT_OVRL,
- OSMO_PFCP_CP_FEAT_EPFAR,
- OSMO_PFCP_CP_FEAT_SSET,
- OSMO_PFCP_CP_FEAT_BUNDL,
- OSMO_PFCP_CP_FEAT_MPAS,
- OSMO_PFCP_CP_FEAT_ARDR,
- OSMO_PFCP_CP_FEAT_UIAUR,
-};
-
-/* The enum values correspond to the bit index in the PFCP Apply Action IE.
- * 0 means first octet and first bit, "Octet 5 Bit 1" as in spec;
- * 7 means first octet last bit, "Octet 5 Bit 8";
- * 8 means second octet first bit, "Octet 6 Bit 1";
- * and so on.
- * Intended for use with osmo_pfcp_bits_get(), osmo_pfcp_bits_set(), osmo_pfcp_bits_to_str_c().
- */
-enum osmo_pfcp_apply_action {
- OSMO_PFCP_APPLY_ACTION_DROP = 0,
- OSMO_PFCP_APPLY_ACTION_FORW,
- OSMO_PFCP_APPLY_ACTION_BUFF,
- OSMO_PFCP_APPLY_ACTION_NOCP,
- OSMO_PFCP_APPLY_ACTION_DUPL,
- OSMO_PFCP_APPLY_ACTION_IPMA,
- OSMO_PFCP_APPLY_ACTION_IPMD,
- OSMO_PFCP_APPLY_ACTION_DFRT,
- OSMO_PFCP_APPLY_ACTION_EDRT,
- OSMO_PFCP_APPLY_ACTION_BDPN,
- OSMO_PFCP_APPLY_ACTION_DDPN,
-};
-
-/* The enum values correspond to the bit index in the description bitmask in the PFCP Outer Header Creation IE.
- * 0 means first octet and first bit, "Octet 5 Bit 1" as in spec;
- * 7 means first octet last bit, "Octet 5 Bit 8";
- * 8 means second octet first bit, "Octet 6 Bit 1";
- * and so on.
- * Intended for use with osmo_pfcp_bits_get(), osmo_pfcp_bits_set(), osmo_pfcp_bits_to_str_c().
- */
-enum osmo_pfcp_outer_header_creation {
- OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4 = 0,
- OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV6,
- OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV4,
- OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV6,
- OSMO_PFCP_OUTER_HEADER_CREATION_IPV4,
- OSMO_PFCP_OUTER_HEADER_CREATION_IPV6,
- OSMO_PFCP_OUTER_HEADER_CREATION_C_TAG,
- OSMO_PFCP_OUTER_HEADER_CREATION_S_TAG,
- OSMO_PFCP_OUTER_HEADER_CREATION_N19_INDICATION,
- OSMO_PFCP_OUTER_HEADER_CREATION_N6_INDICATION,
-};
-
-/* 3GPP TS 29.244 8.2.64 */
-enum osmo_pfcp_outer_header_removal_desc {
- OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV4 = 0,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV6 = 1,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_UDP_IPV4 = 2,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_UDP_IPV6 = 3,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_IPV4 = 4,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_IPV6 = 5,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IP = 6,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_VLAN_S_TAG = 7,
- OSMO_PFCP_OUTER_HEADER_REMOVAL_S_TAG_AND_C_TAG = 8,
-};
diff --git a/include/osmocom/pfcp/pfcp_strs.h b/include/osmocom/pfcp/pfcp_strs.h
deleted file mode 100644
index d0b106a..0000000
--- a/include/osmocom/pfcp/pfcp_strs.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include <osmocom/core/utils.h>
-
-#include <osmocom/pfcp/pfcp_proto.h>
-
-extern const struct value_string osmo_pfcp_message_type_strs[];
-static inline const char *osmo_pfcp_message_type_str(enum osmo_pfcp_message_type val)
-{
- return get_value_string(osmo_pfcp_message_type_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_iei_strs[];
-static inline const char *osmo_pfcp_iei_str(enum osmo_pfcp_iei val)
-{
- return get_value_string(osmo_pfcp_iei_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_cause_strs[];
-static inline const char *osmo_pfcp_cause_str(enum osmo_pfcp_cause val)
-{
- return get_value_string(osmo_pfcp_cause_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_up_feature_strs[];
-static inline const char *osmo_pfcp_up_feature_str(enum osmo_pfcp_up_feature val)
-{
- return get_value_string(osmo_pfcp_up_feature_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_cp_feature_strs[];
-static inline const char *osmo_pfcp_cp_feature_str(enum osmo_pfcp_cp_feature val)
-{
- return get_value_string(osmo_pfcp_cp_feature_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_apply_action_strs[];
-static inline const char *osmo_pfcp_apply_action_str(enum osmo_pfcp_apply_action val)
-{
- return get_value_string(osmo_pfcp_apply_action_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_outer_header_creation_strs[];
-static inline const char *osmo_pfcp_outer_header_creation_str(enum osmo_pfcp_outer_header_creation val)
-{
- return get_value_string(osmo_pfcp_outer_header_creation_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_outer_header_removal_desc_strs[];
-static inline const char *osmo_pfcp_outer_header_removal_desc_str(enum osmo_pfcp_outer_header_removal_desc val)
-{
- return get_value_string(osmo_pfcp_outer_header_removal_desc_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_source_iface_strs[];
-static inline const char *osmo_pfcp_source_iface_str(enum osmo_pfcp_source_iface val)
-{
- return get_value_string(osmo_pfcp_source_iface_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_dest_iface_strs[];
-static inline const char *osmo_pfcp_dest_iface_str(enum osmo_pfcp_dest_iface val)
-{
- return get_value_string(osmo_pfcp_dest_iface_strs, val);
-}
-
-extern const struct value_string osmo_pfcp_3gpp_iface_type_strs[];
-static inline const char *osmo_pfcp_3gpp_iface_type_str(enum osmo_pfcp_3gpp_iface_type val)
-{
- return get_value_string(osmo_pfcp_3gpp_iface_type_strs, val);
-}
diff --git a/src/Makefile.am b/src/Makefile.am
index 78c8adb..a8ba763 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,3 @@
SUBDIRS = \
- libosmo-pfcp \
osmo-upf \
$(NULL)
diff --git a/src/libosmo-pfcp/Makefile.am b/src/libosmo-pfcp/Makefile.am
deleted file mode 100644
index eb8c78f..0000000
--- a/src/libosmo-pfcp/Makefile.am
+++ /dev/null
@@ -1,55 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir)/include \
- -I$(top_builddir) \
- -I$(builddir) \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGTLV_CFLAGS) \
- $(LIBOSMOVTY_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- $(NULL)
-
-AM_LDFLAGS = \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGTLV_LIBS) \
- $(LIBOSMOVTY_LIBS) \
- $(COVERAGE_LDFLAGS) \
- $(NULL)
-
-noinst_LIBRARIES = \
- libosmo-pfcp.a \
- $(NULL)
-
-libosmo_pfcp_a_SOURCES = \
- pfcp_endpoint.c \
- pfcp_ies_custom.c \
- pfcp_msg.c \
- pfcp_strs.c \
- \
- pfcp_ies_auto.c \
- $(NULL)
-
-BUILT_SOURCES = \
- pfcp_ies_auto.c \
- $(NULL)
-
-CLEANFILES = \
- pfcp_ies_auto.c \
- $(NULL)
-
-pfcp_ies_auto.c: $(srcdir)/gen__pfcp_ies_auto.c
- $(MAKE) gen__pfcp_ies_auto
- $(builddir)/gen__pfcp_ies_auto c > $(builddir)/pfcp_ies_auto.c
-
-noinst_PROGRAMS = \
- gen__pfcp_ies_auto \
- $(NULL)
-
-gen__pfcp_ies_auto_SOURCES = \
- gen__pfcp_ies_auto.c \
- $(NULL)
diff --git a/src/libosmo-pfcp/gen__pfcp_ies_auto.c b/src/libosmo-pfcp/gen__pfcp_ies_auto.c
deleted file mode 100644
index 0dfb43c..0000000
--- a/src/libosmo-pfcp/gen__pfcp_ies_auto.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/* Tool to generate C source code of structs and IE arrays for de- and encoding PFCP messages. */
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gtlv/gtlv_gen.h>
-
-#define O OSMO_GTLV_GEN_O
-#define M OSMO_GTLV_GEN_M
-#define O_MULTI OSMO_GTLV_GEN_O_MULTI
-#define M_MULTI OSMO_GTLV_GEN_M_MULTI
-#define ALL_FROM_NAME osmo_gtlv_gen_ie_auto
-
-#define Ms(MEMB_NAME) M(MEMB_NAME, #MEMB_NAME)
-#define Os(MEMB_NAME) O(MEMB_NAME, #MEMB_NAME)
-#define O_MULTIs(N, MEMB_NAME) O_MULTI(N, MEMB_NAME, #MEMB_NAME)
-#define M_MULTIs(N, M, MEMB_NAME) M_MULTI(N, M, MEMB_NAME, #MEMB_NAME)
-
-static const struct osmo_gtlv_gen_ie recovery_time_stamp = {
- "uint32_t",
- .dec_enc = "32be",
- .spec_ref = "7.4.2",
-};
-
-static const struct osmo_gtlv_gen_ie cause = {
- "enum osmo_pfcp_cause",
- .spec_ref = "8.2.1",
-};
-
-static const struct osmo_gtlv_gen_ie offending_ie = {
- .decoded_type = "enum osmo_pfcp_iei",
- .spec_ref = "8.2.22",
-};
-
-static const struct osmo_gtlv_gen_ie f_seid = {
- .tag_name = "f_seid",
- .spec_ref = "8.2.37",
-};
-
-static const struct osmo_gtlv_gen_ie pdr_id = {
- .decoded_type = "uint16_t",
- .dec_enc = "16be",
- .spec_ref = "8.2.36",
-};
-
-static const struct osmo_gtlv_gen_ie precedence = {
- .decoded_type = "uint32_t",
- .dec_enc = "32be",
- .spec_ref = "8.2.11",
-};
-
-static const struct osmo_gtlv_gen_ie source_iface = {
- .decoded_type = "enum osmo_pfcp_source_iface",
- .spec_ref = "8.2.2",
-};
-
-static const struct osmo_gtlv_gen_ie f_teid = {
- .tag_name = "f_teid",
- .spec_ref = "8.2.3",
-};
-
-static const struct osmo_gtlv_gen_ie traffic_endpoint_id = {
- .tag_name = "traffic_endpoint_id",
- .decoded_type = "uint8_t",
- .dec_enc = "8",
- .spec_ref = "8.2.92",
-};
-
-static const struct osmo_gtlv_gen_ie iface_type = {
- .decoded_type = "enum osmo_pfcp_3gpp_iface_type",
- .tag_name = "3gpp_iface_type",
- .spec_ref = "8.2.118",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_pdi[] = {
- Ms(source_iface),
- O(f_teid, "local_f_teid"),
- O(ALL_FROM_NAME, "ue_ip_address"),
- Os(traffic_endpoint_id),
- O(iface_type, "source_iface_type"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie pdi = {
- .nested_ies = ies_in_pdi,
- .spec_ref = "7.5.2.2-2",
-};
-
-static const struct osmo_gtlv_gen_ie far_id = {
- .decoded_type = "uint32_t",
- .dec_enc = "32be",
- .spec_ref = "8.2.74",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_create_pdr[] = {
- Ms(pdr_id),
- Ms(precedence),
- Ms(pdi),
- O(ALL_FROM_NAME, "outer_header_removal"),
- Os(far_id),
- O(ALL_FROM_NAME, "activate_predefined_rules"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie create_pdr = {
- .nested_ies = ies_in_create_pdr,
- .spec_ref = "7.5.2.2",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_created_pdr[] = {
- Ms(pdr_id),
- O(f_teid, "local_f_teid"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie created_pdr = {
- .nested_ies = ies_in_created_pdr,
- .spec_ref = "7.5.3.2",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_upd_pdr[] = {
- Ms(pdr_id),
- O(ALL_FROM_NAME, "outer_header_removal"),
- Os(pdi),
- Os(far_id),
- O(ALL_FROM_NAME, "activate_predefined_rules"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie upd_pdr = {
- .nested_ies = ies_in_upd_pdr,
- .spec_ref = "7.5.4.2",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_updated_pdr[] = {
- Ms(pdr_id),
- O(f_teid, "local_f_teid"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie updated_pdr = {
- .nested_ies = ies_in_updated_pdr,
- .spec_ref = "7.5.9.3",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_remove_pdr[] = {
- Ms(pdr_id),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie remove_pdr = {
- .nested_ies = ies_in_remove_pdr,
- .spec_ref = "7.5.4.6",
-};
-
-static const struct osmo_gtlv_gen_ie destination_iface = {
- .decoded_type = "enum osmo_pfcp_dest_iface",
- .dec_enc = "dest_iface",
- .spec_ref = "8.2.24",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_forw_params[] = {
- Ms(destination_iface),
- O(ALL_FROM_NAME, "network_inst"),
- O(ALL_FROM_NAME, "outer_header_creation"),
- O(traffic_endpoint_id, "linked_te_id"),
- O(iface_type, "destination_iface_type"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie forw_params = {
- .nested_ies = ies_in_forw_params,
- .spec_ref = "7.5.2.3-2",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_upd_forw_params[] = {
- Os(destination_iface),
- O(ALL_FROM_NAME, "network_inst"),
- O(ALL_FROM_NAME, "outer_header_creation"),
- O(traffic_endpoint_id, "linked_te_id"),
- O(iface_type, "destination_iface_type"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie upd_forw_params = {
- .nested_ies = ies_in_upd_forw_params,
- .spec_ref = "7.5.4.3-2",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_create_far[] = {
- Ms(far_id),
- M(ALL_FROM_NAME, "apply_action"),
- Os(forw_params),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie create_far = {
- .nested_ies = ies_in_create_far,
- .spec_ref = "7.5.2.3",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_remove_far[] = {
- Ms(far_id),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie remove_far = {
- .nested_ies = ies_in_remove_far,
- .spec_ref = "7.5.4.6",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_upd_far[] = {
- Ms(far_id),
- O(ALL_FROM_NAME, "apply_action"),
- Os(upd_forw_params),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie upd_far = {
- .nested_ies = ies_in_upd_far,
- .spec_ref = "7.5.4.3",
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_heartbeat_req[] = {
- Ms(recovery_time_stamp),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_heartbeat_resp[] = {
- Ms(recovery_time_stamp),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_assoc_setup_req[] = {
- M(ALL_FROM_NAME, "node_id"),
- Ms(recovery_time_stamp),
- O(ALL_FROM_NAME, "up_function_features"),
- O(ALL_FROM_NAME, "cp_function_features"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_assoc_setup_resp[] = {
- M(ALL_FROM_NAME, "node_id"),
- Ms(cause),
- Ms(recovery_time_stamp),
- O(ALL_FROM_NAME, "up_function_features"),
- O(ALL_FROM_NAME, "cp_function_features"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_assoc_release_req[] = {
- M(ALL_FROM_NAME, "node_id"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_assoc_release_resp[] = {
- M(ALL_FROM_NAME, "node_id"),
- Ms(cause),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_est_req[] = {
- M(ALL_FROM_NAME, "node_id"),
- O(f_seid, "cp_f_seid"),
- M_MULTIs(32, 1, create_pdr),
- M_MULTI(32, 1, create_far, "create_far"),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_est_resp[] = {
- M(ALL_FROM_NAME, "node_id"),
- Ms(cause),
- Os(offending_ie),
- O(f_seid, "up_f_seid"),
- O_MULTIs(32, created_pdr),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_mod_req[] = {
- O(f_seid, "cp_f_seid"),
- O_MULTIs(32, remove_pdr),
- O_MULTIs(32, remove_far),
- O_MULTIs(32, create_pdr),
- O_MULTIs(32, create_far),
- O_MULTIs(32, upd_pdr),
- O_MULTIs(32, upd_far),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_mod_resp[] = {
- Ms(cause),
- Os(offending_ie),
- O_MULTIs(32, created_pdr),
- O_MULTIs(32, updated_pdr),
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_del_req[] = {
- /* no IEs */
- {}
-};
-
-static const struct osmo_gtlv_gen_ie_o ies_in_msg_session_del_resp[] = {
- Ms(cause),
- {}
-};
-
-#define MSG(NAME) { #NAME, ies_in_msg_##NAME }
-static const struct osmo_gtlv_gen_msg pfcp_msg_defs[] = {
- MSG(heartbeat_req),
- MSG(heartbeat_resp),
- MSG(assoc_setup_req),
- MSG(assoc_setup_resp),
- MSG(assoc_release_req),
- MSG(assoc_release_resp),
- MSG(session_est_req),
- MSG(session_est_resp),
- MSG(session_mod_req),
- MSG(session_mod_resp),
- MSG(session_del_req),
- MSG(session_del_resp),
- {}
-};
-
-int main(int argc, const char **argv)
-{
- struct osmo_gtlv_gen_cfg cfg = {
- .proto_name = "osmo_pfcp",
- .spec_ref_prefix = "3GPP TS 29.244 ",
- .message_type_enum = "enum osmo_pfcp_message_type",
- .message_type_prefix = "OSMO_PFCP_MSGT_",
- .tag_enum = "enum osmo_pfcp_iei",
- .tag_prefix = "OSMO_PFCP_IEI_",
- .decoded_type_prefix = "struct osmo_pfcp_ie_",
- .h_header = "#include <osmocom/pfcp/pfcp_ies_custom.h>",
- .c_header = "#include <osmocom/pfcp/pfcp_ies_auto.h>",
- .msg_defs = pfcp_msg_defs,
- .add_enc_to_str = true,
- };
- return osmo_gtlv_gen_main(&cfg, argc, argv);
-}
diff --git a/src/libosmo-pfcp/pfcp_endpoint.c b/src/libosmo-pfcp/pfcp_endpoint.c
deleted file mode 100644
index 83b7c1a..0000000
--- a/src/libosmo-pfcp/pfcp_endpoint.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/tdef.h>
-
-#include <osmocom/pfcp/pfcp_endpoint.h>
-#include <osmocom/pfcp/pfcp_msg.h>
-
-/*! Entry of pfcp_endpoint message queue of PFCP messages, for re-transsions. */
-struct osmo_pfcp_queue_entry {
- /* entry in per-peer list of messages waiting for a response */
- struct llist_head entry;
- /* back-pointer */
- struct osmo_pfcp_endpoint *ep;
- /* message we have transmitted */
- struct osmo_pfcp_msg *m;
- /* T1 timer: How long to wait for response before retransmitting */
- struct osmo_timer_list t1;
- /* N1: number of pending re-transmissions */
- unsigned int n1_remaining;
-};
-
-/* Find a matching osmo_pfcp_queue_entry for given rx_hdr.
- * A returned osmo_pfcp_queue_entry is guaranteed to be a Response if rx is a Request, and vice versa. */
-static struct osmo_pfcp_queue_entry *
-osmo_pfcp_queue_find(struct llist_head *queue, const struct osmo_pfcp_msg *rx)
-{
- struct osmo_pfcp_queue_entry *qe;
- /* It's important to match only a Request to a Response and vice versa, because the remote peer makes its own
- * sequence_nr. There could be a collision of sequence_nr. But as long as all Requests look for a Response and
- * vice versa, the sequence_nr scopes don't overlap. */
- llist_for_each_entry(qe, queue, entry) {
- if (qe->m->is_response != rx->is_response
- && qe->m->h.sequence_nr == rx->h.sequence_nr)
- return qe;
- }
- return NULL;
-}
-
-/* clean up and deallocate the given osmo_pfcp_queue_entry */
-static void osmo_pfcp_queue_del(struct osmo_pfcp_queue_entry *qe)
-{
- /* see also the talloc destructor: osmo_pfcp_queue_destructor() */
- talloc_free(qe);
-}
-
-static int osmo_pfcp_queue_destructor(struct osmo_pfcp_queue_entry *qe)
-{
- osmo_timer_del(&qe->t1);
- llist_del(&qe->entry);
- return 0;
-}
-
-struct osmo_tdef osmo_pfcp_tdefs[] = {
- { .T = OSMO_PFCP_MSGT_HEARTBEAT_REQ, .default_val = 15, .unit = OSMO_TDEF_S,
- .desc = "PFCP Heartbeat Request period, how long to wait between issuing requests"
- },
- { .T = OSMO_PFCP_MSGT_HEARTBEAT_RESP, .default_val = 15, .unit = OSMO_TDEF_S,
- .desc = "PFCP Heartbeat Response timeout, the time after which to regard a non-responding peer as disconnected"
- },
- { .T = OSMO_PFCP_TIMER_GRACEFUL_REL, .default_val = 15, .unit = OSMO_TDEF_S,
- .desc = "PFCP peer graceful shutdown timeout, how long to keep the peer's state after a peer requested"
- " graceful shutdown"
- },
- { .T = OSMO_PFCP_TIMER_T1, .default_val = 3000, .unit = OSMO_TDEF_MS,
- .desc = "PFCP request timeout, how long after a missing response to retransmit a PFCP request"
- },
- { .T = OSMO_PFCP_TIMER_N1, .default_val = 3, .unit = OSMO_TDEF_CUSTOM,
- .desc = "Number of PFCP request retransmission attempts"
- },
- { .T = OSMO_PFCP_TIMER_KEEP_RESP, .default_val = 10000, .unit = OSMO_TDEF_MS,
- .desc = "PFCP response timeout, how long to keep a response, in case its same request is retransmitted by the peer"
- },
- { .T = OSMO_PFCP_TIMER_ASSOC_RETRY, .default_val = 15, .unit = OSMO_TDEF_S,
- .desc = "Idle time between attempts of PFCP Association Setup (CPF)"
- },
- {}
-};
-
-struct osmo_pfcp_endpoint *osmo_pfcp_endpoint_create(void *ctx, void *priv)
-{
- struct osmo_pfcp_endpoint *ep = talloc_zero(ctx, struct osmo_pfcp_endpoint);
- uint32_t unix_time;
- if (!ep)
- return NULL;
-
- INIT_LLIST_HEAD(&ep->sent_requests);
- INIT_LLIST_HEAD(&ep->sent_responses);
-
- ep->cfg.tdefs = osmo_pfcp_tdefs;
- ep->priv = priv;
- ep->pfcp_fd.fd = -1;
-
- /* time() returns seconds since 1970 (UNIX epoch), but the recovery_time_stamp is coded in the NTP format, which is
- * seconds since 1900, the NTP era 0. 2208988800L is the offset between UNIX epoch and NTP era 0.
- * TODO: what happens when we enter NTP era 1? Is it sufficient to integer-wrap? */
- unix_time = time(NULL);
- ep->recovery_time_stamp = unix_time + 2208988800L;
- LOGP(DLPFCP, LOGL_NOTICE, "PFCP endpoint: recovery timestamp = 0x%08x (%u seconds since UNIX epoch,"
- " which is %u seconds since NTP era 0; IETF RFC 5905)\n",
- ep->recovery_time_stamp, unix_time, ep->recovery_time_stamp);
-
- return ep;
-}
-
-static unsigned int ep_n1(struct osmo_pfcp_endpoint *ep)
-{
- return osmo_tdef_get(ep->cfg.tdefs, OSMO_PFCP_TIMER_N1, OSMO_TDEF_CUSTOM, -1);
-}
-
-static unsigned int ep_t1(struct osmo_pfcp_endpoint *ep)
-{
- return osmo_tdef_get(ep->cfg.tdefs, OSMO_PFCP_TIMER_T1, OSMO_TDEF_MS, -1);
-}
-
-static unsigned int ep_keep_resp(struct osmo_pfcp_endpoint *ep)
-{
- return osmo_tdef_get(ep->cfg.tdefs, OSMO_PFCP_TIMER_KEEP_RESP, OSMO_TDEF_MS, -1);
-}
-
-static int osmo_pfcp_endpoint_tx_data_no_logging(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m);
-
-/* Return true to keep the message in the queue, false for dropping from the queue. */
-static bool pfcp_queue_retrans(struct osmo_pfcp_queue_entry *qe)
-{
- struct osmo_pfcp_endpoint *endpoint = qe->ep;
- unsigned int t1_ms = ep_t1(endpoint);
- struct osmo_pfcp_msg *m = qe->m;
- int rc;
-
- /* re-transmit */
- if (qe->n1_remaining)
- qe->n1_remaining--;
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO, "re-sending (%u attempts remaining)\n", qe->n1_remaining);
-
- rc = osmo_pfcp_endpoint_tx_data_no_logging(endpoint, m);
- /* If encoding failed, it cannot ever succeed. Drop the queue entry. */
- if (rc)
- return false;
- /* if no more attempts remaining, drop from queue */
- if (!qe->n1_remaining)
- return false;
- /* re-schedule timer, keep in queue */
- osmo_timer_schedule(&qe->t1, t1_ms/1000, t1_ms%1000);
- return true;
-}
-
-/* T1 for a given queue entry has expired */
-static void pfcp_queue_timer_cb(void *data)
-{
- struct osmo_pfcp_queue_entry *qe = data;
- bool keep;
-
- if (qe->m->is_response) {
- /* The response has waited in the queue for any retransmissions of its initiating request. Now that time
- * has passed and the response can be dropped from the queue. */
- keep = false;
- } else {
- /* The request is still here, which means it has not received a response from the remote side.
- * Retransmit the request. */
- keep = pfcp_queue_retrans(qe);
- }
-
- if (keep)
- return;
- /* Drop the queue entry. No more retransmissions. */
- if (!qe->m->is_response && qe->m->ctx.resp_cb)
- qe->m->ctx.resp_cb(qe->m, NULL, "PFCP retransmissions elapsed, no response received");
- osmo_pfcp_queue_del(qe);
-}
-
-/* Directly encode and transmit the message, without storing in the retrans_queue. */
-static int osmo_pfcp_endpoint_tx_data_no_logging(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m)
-{
- int rc;
-
- if (!m->encoded) {
- /* Allocate msgb as child of the message m, so that when m gets deallocated at the end of
- * retransmission queueing, the msgb gets deallocated with it. */
- m->encoded = msgb_alloc_c(m, OSMO_PFCP_MSGB_ALLOC_SIZE, "PFCP-tx");
- OSMO_ASSERT(m->encoded);
- rc = osmo_pfcp_msg_encode(m->encoded, m);
- if (rc) {
- msgb_free(m->encoded);
- m->encoded = NULL;
- return rc;
- }
- }
-
- rc = sendto(ep->pfcp_fd.fd, msgb_data(m->encoded), msgb_length(m->encoded), 0,
- (struct sockaddr *)&m->remote_addr, sizeof(m->remote_addr));
- if (rc != msgb_length(m->encoded)) {
- OSMO_LOG_PFCP_MSG(m, LOGL_ERROR, "sendto() failed: rc = %d != length %u\n",
- rc, msgb_length(m->encoded));
- return -EIO;
- }
- return 0;
-}
-
-int osmo_pfcp_endpoint_tx_data(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m)
-{
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO, "sending\n");
- return osmo_pfcp_endpoint_tx_data_no_logging(ep, m);
-}
-
-int osmo_pfcp_endpoint_tx_heartbeat_req(struct osmo_pfcp_endpoint *ep, const struct osmo_sockaddr *remote_addr)
-{
- struct osmo_pfcp_msg *tx = osmo_pfcp_msg_alloc_tx(OTC_SELECT, remote_addr, NULL, NULL,
- OSMO_PFCP_MSGT_HEARTBEAT_REQ);
- tx->ies.heartbeat_req.recovery_time_stamp = ep->recovery_time_stamp;
- tx->h.sequence_nr = osmo_pfcp_next_seq_nr(&ep->seq_nr_state);
- return osmo_pfcp_endpoint_tx_data(ep, tx);
-}
-
-/* add a given msgb to the queue of per-peer messages waiting for a response */
-static int osmo_pfcp_endpoint_retrans_queue_add(struct osmo_pfcp_endpoint *endpoint, struct osmo_pfcp_msg *m)
-{
- struct osmo_pfcp_queue_entry *qe;
- unsigned int n1 = ep_n1(endpoint);
- unsigned int t1_ms = ep_t1(endpoint);
- unsigned int keep_resp_ms = ep_keep_resp(endpoint);
- unsigned int timeout = m->is_response ? keep_resp_ms : t1_ms;
-
- LOGP(DLPFCP, LOGL_DEBUG, "retransmit unanswered Requests %u x %ums; keep sent Responses for %ums\n",
- n1, t1_ms, keep_resp_ms);
- /* If there are no retransmissions or no timeout, it makes no sense to add to the queue. */
- if (!n1 || !t1_ms) {
- if (!m->is_response && m->ctx.resp_cb)
- m->ctx.resp_cb(m, NULL, "PFCP timeout is zero, cannot wait for a response");
- return 0;
- }
-
- qe = talloc(endpoint, struct osmo_pfcp_queue_entry);
- OSMO_ASSERT(qe);
- *qe = (struct osmo_pfcp_queue_entry){
- .ep = endpoint,
- .m = m,
- .n1_remaining = m->is_response ? 0 : n1,
- };
- talloc_steal(qe, m);
-
- /* Slight optimization: Add sent requests to the start of the list: we will usually receive a response shortly
- * after sending a request, removing that entry from the queue quickly.
- * Add sent responses to the end of the list: they will rarely be retransmitted at all. */
- if (m->is_response)
- llist_add_tail(&qe->entry, &endpoint->sent_responses);
- else
- llist_add_tail(&qe->entry, &endpoint->sent_requests);
- talloc_set_destructor(qe, osmo_pfcp_queue_destructor);
-
- osmo_timer_setup(&qe->t1, pfcp_queue_timer_cb, qe);
- osmo_timer_schedule(&qe->t1, timeout/1000, timeout%1000);
- return 0;
-}
-
-/* Transmit a PFCP message.
- * Store the message in the local message queue for possible retransmissions.
- * On success, return zero, and pass ownership of m to ep. ep deallocates m when all retransmissions are done / a reply
- * has been received.
- * On error, return nonzero, and immediately deallocate m. */
-int osmo_pfcp_endpoint_tx(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m)
-{
- struct osmo_pfcp_ie_node_id *node_id;
- int rc;
- if (!m->is_response)
- m->h.sequence_nr = osmo_pfcp_next_seq_nr(&ep->seq_nr_state);
- node_id = osmo_pfcp_msg_node_id(m);
- if (node_id)
- *node_id = ep->cfg.local_node_id;
-
- rc = osmo_pfcp_endpoint_tx_data(ep, m);
- if (rc) {
- if (!m->is_response && m->ctx.resp_cb)
- m->ctx.resp_cb(m, NULL, "Failed to transmit request");
- osmo_pfcp_msg_free(m);
- return rc;
- }
- osmo_pfcp_endpoint_retrans_queue_add(ep, m);
- return 0;
-}
-
-static void osmo_pfcp_endpoint_handle_rx(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m)
-{
- bool dispatch_rx = true;
- struct osmo_pfcp_queue_entry *prev_msg;
- struct osmo_pfcp_msg *req;
-
- if (m->h.message_type == OSMO_PFCP_MSGT_HEARTBEAT_REQ) {
- /* Directly answer with a Heartbeat Response. */
- struct osmo_pfcp_msg *resp = osmo_pfcp_msg_alloc_tx(OTC_SELECT, NULL, NULL, m, OSMO_PFCP_MSGT_HEARTBEAT_RESP);
- resp->ies.heartbeat_resp.recovery_time_stamp = ep->recovery_time_stamp;
- osmo_pfcp_endpoint_tx_data(ep, resp);
- /* Still also dispatch the Rx event to the peer. */
- }
-
- /* If this is receiving a response, search for matching sent request that is now completed.
- * If this is receiving a request, search for a matching sent response that can be retransmitted.
- * A match is found by sequence_nr. */
- prev_msg = osmo_pfcp_queue_find(m->is_response ? &ep->sent_requests : &ep->sent_responses, m);
-
- if (prev_msg && !m->is_response) {
- /* m is a request, and we have already sent a response to this same request earlier. Retransmit the same
- * response, and don't dispatch the msg rx. Keep our response queued in case the request is
- * retransmitted yet another time. */
-
- /* Populate message context to point at peer and session, if applicable.
- * With that context applied, log message rx. */
- if (ep->set_msg_ctx)
- ep->set_msg_ctx(ep, m, NULL);
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO, "received retransmission of earlier request\n");
-
- /* Also log on the earlier PFCP msg that it is resent */
- OSMO_LOG_PFCP_MSG(prev_msg->m, LOGL_INFO, "re-sending cached response\n");
- osmo_pfcp_endpoint_tx_data_no_logging(ep, prev_msg->m);
- return;
- }
-
- req = NULL;
- if (prev_msg && m->is_response) {
- /* m is a response to the earlier request prev_msg->m. The request is now ACKed and can be dropped from
- * the retransmission queue: see 'if (req)' below. */
- req = prev_msg->m;
- }
-
- /* Populate message context to point at peer and session, if applicable.
- * With that context applied, log message rx. */
- if (ep->set_msg_ctx)
- ep->set_msg_ctx(ep, m, req);
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO, "received\n");
-
- if (req && req->ctx.resp_cb) {
- int rc = req->ctx.resp_cb(req, m, NULL);
- /* Only dispatch the response to rx_msg() when resp_cb() asks for it with rc == 1 (or when there is no
- * resp_cb()). */
- if (rc != 1) {
- dispatch_rx = false;
- OSMO_LOG_PFCP_MSG(m, LOGL_DEBUG,
- "response handled by m->resp_cb(), not dispatching to rx_msg()\n");
- }
- }
-
- if (dispatch_rx)
- ep->rx_msg(ep, m, req);
- if (req)
- osmo_pfcp_queue_del(prev_msg);
-}
-
-/* call-back for PFCP socket file descriptor */
-static int osmo_pfcp_fd_cb(struct osmo_fd *ofd, unsigned int what)
-{
- int rc;
- struct osmo_pfcp_endpoint *ep = ofd->data;
-
- if (what & OSMO_FD_READ) {
- struct osmo_sockaddr remote;
- socklen_t remote_len = sizeof(remote);
- struct msgb *msg = msgb_alloc_c(OTC_SELECT, OSMO_PFCP_MSGB_ALLOC_SIZE, "PFCP-rx");
- if (!msg)
- return -ENOMEM;
-
- msg->l3h = msg->tail;
- rc = recvfrom(ofd->fd, msg->tail, msgb_tailroom(msg), 0, (struct sockaddr *)&remote, &remote_len);
- if (rc <= 0)
- return -EIO;
- msgb_put(msg, rc);
-
- OSMO_ASSERT(ep->rx_msg);
-
- /* This may be a bundle of PFCP messages. Parse and receive each message received, by shifting l4h
- * through the message bundle. */
- msg->l4h = msg->l3h;
- while (msgb_l4len(msg)) {
- struct osmo_gtlv_load tlv;
- struct osmo_pfcp_msg *m = osmo_pfcp_msg_alloc_rx(OTC_SELECT, &remote);
- m->encoded = msg;
-
- rc = osmo_pfcp_msg_decode_header(&tlv, m, msg);
- if (rc < 0)
- break;
- msg->l4h += rc;
-
- rc = osmo_pfcp_msg_decode_tlv(m, &tlv);
- /* If errors occurred, they have already been logged on DLPFCP. */
- if (rc == 0)
- osmo_pfcp_endpoint_handle_rx(ep, m);
- osmo_pfcp_msg_free(m);
- }
- msgb_free(msg);
- }
- return 0;
-}
-
-/*! bind a PFCP endpoint to its configured address (ep->cfg.local_addr).
- * \return 0 on success, negative on error. */
-int osmo_pfcp_endpoint_bind(struct osmo_pfcp_endpoint *ep)
-{
- int rc;
- /* close the existing socket, if any */
- osmo_pfcp_endpoint_close(ep);
-
- if (!ep->rx_msg) {
- LOGP(DLPFCP, LOGL_ERROR, "missing rx_msg cb at osmo_pfcp_endpoint\n");
- return -EINVAL;
- }
-
- /* create the new socket, binding to configured local address */
- ep->pfcp_fd.cb = osmo_pfcp_fd_cb;
- ep->pfcp_fd.data = ep;
- rc = osmo_sock_init_osa_ofd(&ep->pfcp_fd, SOCK_DGRAM, IPPROTO_UDP, &ep->cfg.local_addr, NULL, OSMO_SOCK_F_BIND);
- if (rc < 0)
- return rc;
- return 0;
-}
-
-void osmo_pfcp_endpoint_close(struct osmo_pfcp_endpoint *ep)
-{
- struct osmo_pfcp_queue_entry *qe;
- while ((qe = llist_first_entry_or_null(&ep->sent_requests, struct osmo_pfcp_queue_entry, entry)))
- osmo_pfcp_queue_del(qe);
- while ((qe = llist_first_entry_or_null(&ep->sent_responses, struct osmo_pfcp_queue_entry, entry)))
- osmo_pfcp_queue_del(qe);
-
- if (ep->pfcp_fd.fd != -1) {
- osmo_fd_unregister(&ep->pfcp_fd);
- close(ep->pfcp_fd.fd);
- ep->pfcp_fd.fd = -1;
- }
-}
-
-void osmo_pfcp_endpoint_free(struct osmo_pfcp_endpoint **ep)
-{
- if (!*ep)
- return;
- osmo_pfcp_endpoint_close(*ep);
- talloc_free(*ep);
- *ep = NULL;
-}
-
-/* Call osmo_pfcp_msg_invalidate_ctx(deleted_fi) on all queued osmo_pfcp_msg instances in the retrans_queue. */
-void osmo_pfcp_endpoint_invalidate_ctx(struct osmo_pfcp_endpoint *ep, struct osmo_fsm_inst *deleted_fi)
-{
- struct osmo_pfcp_queue_entry *qe;
- llist_for_each_entry(qe, &ep->sent_requests, entry)
- osmo_pfcp_msg_invalidate_ctx(qe->m, deleted_fi);
- llist_for_each_entry(qe, &ep->sent_responses, entry)
- osmo_pfcp_msg_invalidate_ctx(qe->m, deleted_fi);
-}
diff --git a/src/libosmo-pfcp/pfcp_ies_custom.c b/src/libosmo-pfcp/pfcp_ies_custom.c
deleted file mode 100644
index 3b3769a..0000000
--- a/src/libosmo-pfcp/pfcp_ies_custom.c
+++ /dev/null
@@ -1,999 +0,0 @@
-/* Decoded PFCP IEs, to be used by the auto-generated pfcp_ies_auto.c. */
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-#include <inttypes.h>
-
-#include <osmocom/core/socket.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/msgb.h>
-
-#include <osmocom/gtlv/gtlv.h>
-
-#include <osmocom/pfcp/pfcp_ies_custom.h>
-#include <osmocom/pfcp/pfcp_strs.h>
-#include <osmocom/pfcp/pfcp_msg.h>
-
-/* Assumes presence of local variable osmo_pfcp_msg *m. m->log_ctx may be NULL. */
-#define RETURN_ERROR(RC, FMT, ARGS...) \
- do {\
- OSMO_ASSERT(decoded_struct); \
- OSMO_LOG_PFCP_MSG(OSMO_PFCP_MSG_FOR_IES(decoded_struct), LOGL_ERROR, FMT " (%d: %s)\n", ##ARGS, RC, \
- strerror((RC) > 0 ? (RC) : -(RC))); \
- return RC; \
- } while (0)
-
-/* Assumes presence of local variable osmo_gtlv_load *tlv. Usage:
- * ENSURE_LENGTH_IS_EXACTLY(2);
- */
-#define ENSURE_LENGTH_IS_EXACTLY(VAL) \
- do { \
- if (!(tlv->len == VAL)) \
- RETURN_ERROR(-EINVAL, "IE has length = %zu, expected length == " #VAL, tlv->len); \
- } while (0)
-
-/* Assumes presence of local variable osmo_gtlv_load *tlv. Usage:
- * ENSURE_LENGTH_IS_AT_LEAST(1);
- */
-#define ENSURE_LENGTH_IS_AT_LEAST(VAL) \
- do { \
- if (!(tlv->len >= VAL)) \
- RETURN_ERROR(-EINVAL, "IE has length = %zu, expected length >= " #VAL, tlv->len); \
- } while (0)
-
-/* Assumes presence of local variable osmo_gtlv_load *tlv. Usage:
- * const uint8_t *pos = tlv->val;
- * ENSURE_REMAINING_LENGTH_IS_AT_LEAST("first part", pos, 23);
- * <parse first part>
- * pos += 23;
- * ENSURE_REMAINING_LENGTH_IS_AT_LEAST("very long part", pos, 235);
- * <parse very long part>
- * pos += 235;
- */
-#define ENSURE_REMAINING_LENGTH_IS_AT_LEAST(NAME, POS, MIN_VAL) \
- do { \
- if (!((tlv->len - ((POS) - tlv->val)) >= MIN_VAL)) \
- RETURN_ERROR(-EINVAL, \
- "at value octet %d: %zu octets remaining, but " #NAME " requires length >= " #MIN_VAL, \
- (int)((POS) - tlv->val), \
- tlv->len - ((POS) - tlv->val)); \
- } while (0)
-
-void osmo_pfcp_ie_f_seid_set(struct osmo_pfcp_ie_f_seid *f_seid, uint64_t seid, const struct osmo_sockaddr *remote_addr)
-{
- *f_seid = (struct osmo_pfcp_ie_f_seid) {
- .seid = seid,
- };
- osmo_pfcp_ip_addrs_set(&f_seid->ip_addr, remote_addr);
-}
-
-int osmo_pfcp_dec_cause(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- enum osmo_pfcp_cause *cause = decode_to;
- ENSURE_LENGTH_IS_EXACTLY(1);
- *cause = *tlv->val;
- return 0;
-}
-
-int osmo_pfcp_enc_cause(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const enum osmo_pfcp_cause *cause = encode_from;
- msgb_put_u8(tlv->dst, *cause);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_cause(char *buf, size_t buflen, const void *encode_from)
-{
- const enum osmo_pfcp_cause *cause = encode_from;
- return snprintf(buf, buflen, "%s", osmo_pfcp_cause_str(*cause));
-}
-
-int osmo_pfcp_dec_offending_ie(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- enum osmo_pfcp_iei *offending_ie = decode_to;
- ENSURE_LENGTH_IS_EXACTLY(2);
- *offending_ie = osmo_load16be(tlv->val);
- return 0;
-}
-
-int osmo_pfcp_enc_offending_ie(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const enum osmo_pfcp_iei *offending_ie = encode_from;
- msgb_put_u16(tlv->dst, *offending_ie);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_offending_ie(char *buf, size_t buflen, const void *encode_from)
-{
- const enum osmo_pfcp_iei *offending_ie = encode_from;
- return snprintf(buf, buflen, "%s", osmo_pfcp_iei_str(*offending_ie));
-}
-
-int osmo_pfcp_dec_8(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- uint8_t *u8 = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- *u8 = tlv->val[0];
- return 0;
-}
-
-int osmo_pfcp_enc_8(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const uint8_t *u8 = encode_from;
- msgb_put_u8(tlv->dst, *u8);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_8(char *buf, size_t buflen, const void *encode_from)
-{
- const uint8_t *u8 = encode_from;
- return snprintf(buf, buflen, "%u", *u8);
-}
-
-int osmo_pfcp_dec_16be(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- uint16_t *u16 = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(2);
- *u16 = osmo_load16be(tlv->val);
- return 0;
-}
-
-int osmo_pfcp_enc_16be(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const uint16_t *u16 = encode_from;
- msgb_put_u16(tlv->dst, *u16);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_16be(char *buf, size_t buflen, const void *encode_from)
-{
- const uint16_t *u16 = encode_from;
- return snprintf(buf, buflen, "%u", *u16);
-}
-
-int osmo_pfcp_dec_32be(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- uint32_t *u32 = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(4);
- *u32 = osmo_load32be(tlv->val);
- return 0;
-}
-
-int osmo_pfcp_enc_32be(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const uint32_t *u32 = encode_from;
- msgb_put_u32(tlv->dst, *u32);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_32be(char *buf, size_t buflen, const void *encode_from)
-{
- const uint32_t *u32 = encode_from;
- return snprintf(buf, buflen, "%u", *u32);
-}
-
-int osmo_pfcp_dec_3gpp_iface_type(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- enum osmo_pfcp_3gpp_iface_type *_3gpp_iface_type = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- *_3gpp_iface_type = tlv->val[0] & 0x3f;
- return 0;
-}
-
-int osmo_pfcp_enc_3gpp_iface_type(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const enum osmo_pfcp_3gpp_iface_type *_3gpp_iface_type = encode_from;
- msgb_put_u8(tlv->dst, (uint8_t)(*_3gpp_iface_type) & 0x3f);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_3gpp_iface_type(char *buf, size_t buflen, const void *encode_from)
-{
- const enum osmo_pfcp_3gpp_iface_type *_3gpp_iface_type = encode_from;
- return snprintf(buf, buflen, "%s", osmo_pfcp_3gpp_iface_type_str(*_3gpp_iface_type));
-}
-
-int osmo_pfcp_dec_source_iface(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- enum osmo_pfcp_source_iface *source_iface = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- *source_iface = tlv->val[0] & 0xf;
- return 0;
-}
-
-int osmo_pfcp_enc_source_iface(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const enum osmo_pfcp_source_iface *source_iface = encode_from;
- msgb_put_u8(tlv->dst, (uint8_t)(*source_iface) & 0xf);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_source_iface(char *buf, size_t buflen, const void *encode_from)
-{
- const enum osmo_pfcp_source_iface *source_iface = encode_from;
- return snprintf(buf, buflen, "%s", osmo_pfcp_source_iface_str(*source_iface));
-}
-
-int osmo_pfcp_dec_dest_iface(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- enum osmo_pfcp_dest_iface *dest_interface = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- *dest_interface = tlv->val[0] & 0xf;
- return 0;
-}
-
-int osmo_pfcp_enc_dest_iface(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const enum osmo_pfcp_dest_iface *dest_interface = encode_from;
- msgb_put_u8(tlv->dst, (uint8_t)(*dest_interface) & 0xf);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_dest_iface(char *buf, size_t buflen, const void *encode_from)
-{
- const enum osmo_pfcp_dest_iface *dest_iface = encode_from;
- return snprintf(buf, buflen, "%s", osmo_pfcp_dest_iface_str(*dest_iface));
-}
-
-int osmo_pfcp_dec_node_id(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_node_id *node_id = decode_to;
- const void *ip;
- unsigned int ip_len;
- unsigned int want_len;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- node_id->type = *(uint8_t *)tlv->val;
- ip = &tlv->val[1];
- ip_len = tlv->len - 1;
-
- switch (node_id->type) {
- case OSMO_PFCP_NODE_ID_T_IPV4:
- want_len = sizeof(node_id->ip.u.sin.sin_addr);
- if (ip_len != want_len)
- RETURN_ERROR(-EINVAL, "Node ID: wrong IPv4 address value length %u, expected %u",
- ip_len, want_len);
- osmo_sockaddr_from_octets(&node_id->ip, ip, ip_len);
- break;
- case OSMO_PFCP_NODE_ID_T_IPV6:
- want_len = sizeof(node_id->ip.u.sin6.sin6_addr);
- if (ip_len != want_len)
- RETURN_ERROR(-EINVAL, "Node ID: wrong IPv6 address value length %u, expected %u",
- ip_len, want_len);
- osmo_sockaddr_from_octets(&node_id->ip, ip, ip_len);
- break;
- case OSMO_PFCP_NODE_ID_T_FQDN:
- /* Copy and add a trailing nul */
- OSMO_STRLCPY_ARRAY(node_id->fqdn, ip);
- break;
- default:
- RETURN_ERROR(-EINVAL, "Invalid Node ID Type: %d", node_id->type);
- }
- return 0;
-}
-
-int osmo_pfcp_enc_node_id(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- unsigned int l;
- const struct osmo_pfcp_ie_node_id *node_id = encode_from;
- msgb_put_u8(tlv->dst, node_id->type);
- switch (node_id->type) {
- case OSMO_PFCP_NODE_ID_T_IPV4:
- l = sizeof(node_id->ip.u.sin.sin_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &node_id->ip);
- break;
- case OSMO_PFCP_NODE_ID_T_IPV6:
- l = sizeof(node_id->ip.u.sin6.sin6_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &node_id->ip);
- break;
- case OSMO_PFCP_NODE_ID_T_FQDN:
- l = strnlen(node_id->fqdn, sizeof(node_id->fqdn));
- /* Copy without trailing nul */
- memcpy((char *)msgb_put(tlv->dst, l), node_id->fqdn, l);
- break;
- default:
- RETURN_ERROR(-EINVAL, "Invalid Node ID Type: %d", node_id->type);
- }
- return 0;
-}
-
-int osmo_pfcp_ie_node_id_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_ie_node_id *node_id)
-{
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
-
- switch (node_id->type) {
- case OSMO_PFCP_NODE_ID_T_IPV4:
- OSMO_STRBUF_PRINTF(sb, "v4:");
- break;
- case OSMO_PFCP_NODE_ID_T_IPV6:
- OSMO_STRBUF_PRINTF(sb, "v6:");
- break;
- case OSMO_PFCP_NODE_ID_T_FQDN:
- OSMO_STRBUF_PRINTF(sb, "fqdn:");
- OSMO_STRBUF_APPEND(sb, osmo_quote_str_buf3,
- node_id->fqdn, strnlen(node_id->fqdn, sizeof(node_id->fqdn)));
- return sb.chars_needed;
- default:
- OSMO_STRBUF_PRINTF(sb, "unknown-node-id-type-%u", node_id->type);
- return sb.chars_needed;
- }
-
- OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &node_id->ip);
- return sb.chars_needed;
-}
-
-char *osmo_pfcp_ie_node_id_to_str_c(void *ctx, const struct osmo_pfcp_ie_node_id *node_id)
-{
- OSMO_NAME_C_IMPL(ctx, 64, "ERROR", osmo_pfcp_ie_node_id_to_str_buf, node_id)
-}
-
-int osmo_pfcp_enc_to_str_node_id(char *buf, size_t buflen, const void *encode_from)
-{
- return osmo_pfcp_ie_node_id_to_str_buf(buf, buflen, encode_from);
-}
-
-bool osmo_pfcp_bits_get(const uint8_t *bits, unsigned int bitpos)
-{
- unsigned int bytenum = bitpos / 8;
- unsigned int bitmask = 1 << (bitpos % 8);
-
- return (bool)(bits[bytenum] & bitmask);
-}
-
-void osmo_pfcp_bits_set(uint8_t *bits, unsigned int bitpos, bool val)
-{
- unsigned int bytenum = bitpos / 8;
- unsigned int bitmask = 1 << (bitpos % 8);
-
- if (val)
- bits[bytenum] |= bitmask;
- else
- bits[bytenum] &= ~bitmask;
-}
-
-int osmo_pfcp_bits_to_str_buf(char *buf, size_t buflen, const uint8_t *bits, const struct value_string *bit_strs)
-{
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- OSMO_STRBUF_PRINTF(sb, "(");
- for (; bit_strs->str; bit_strs++) {
- if (osmo_pfcp_bits_get(bits, bit_strs->value)) {
- OSMO_STRBUF_PRINTF(sb, " %s", bit_strs->str);
- }
- }
- OSMO_STRBUF_PRINTF(sb, " )");
- return sb.chars_needed;
-}
-
-char *osmo_pfcp_bits_to_str_c(void *ctx, const uint8_t *bits, const struct value_string *bit_str)
-{
- OSMO_NAME_C_IMPL(ctx, 64, "ERROR", osmo_pfcp_bits_to_str_buf, bits, bit_str)
-}
-
-int osmo_pfcp_dec_up_function_features(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_up_function_features *up_function_features = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(6);
- memcpy(up_function_features->bits, tlv->val, 6);
- return 0;
-}
-
-int osmo_pfcp_enc_up_function_features(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_up_function_features *up_function_features = encode_from;
- memcpy(msgb_put(tlv->dst, 6), up_function_features->bits, 6);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_up_function_features(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_up_function_features *up_function_features = encode_from;
- return osmo_pfcp_bits_to_str_buf(buf, buflen, up_function_features->bits, osmo_pfcp_up_feature_strs);
-}
-
-int osmo_pfcp_dec_cp_function_features(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_cp_function_features *cp_function_features = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(sizeof(cp_function_features->bits));
- memcpy(cp_function_features->bits, tlv->val, sizeof(cp_function_features->bits));
- return 0;
-}
-
-int osmo_pfcp_enc_cp_function_features(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_cp_function_features *cp_function_features = encode_from;
- memcpy(msgb_put(tlv->dst, sizeof(cp_function_features->bits)),
- cp_function_features->bits, sizeof(cp_function_features->bits));
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_cp_function_features(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_cp_function_features *cp_function_features = encode_from;
- return osmo_pfcp_bits_to_str_buf(buf, buflen, cp_function_features->bits, osmo_pfcp_cp_feature_strs);
-}
-
-int osmo_pfcp_dec_f_seid(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_f_seid *f_seid = decode_to;
- uint8_t flags;
- uint8_t pos;
- unsigned int l;
- /* flags and 8 octet seid */
- ENSURE_LENGTH_IS_AT_LEAST(9);
- flags = tlv->val[0];
- f_seid->ip_addr.v6_present = flags & 1;
- f_seid->ip_addr.v4_present = flags & 2;
- f_seid->seid = osmo_load64be(&tlv->val[1]);
- pos = 9;
- if (f_seid->ip_addr.v4_present) {
- l = sizeof(f_seid->ip_addr.v4.u.sin.sin_addr);
- if (pos + l > tlv->len)
- RETURN_ERROR(-EINVAL, "F-SEID IE is too short for the IPv4 address: %zu", tlv->len);
- osmo_sockaddr_from_octets(&f_seid->ip_addr.v4, &tlv->val[pos], l);
- pos += l;
- }
- if (f_seid->ip_addr.v6_present) {
- l = sizeof(f_seid->ip_addr.v4.u.sin6.sin6_addr);
- if (pos + l > tlv->len)
- RETURN_ERROR(-EINVAL, "F-SEID IE is too short for the IPv6 address: %zu", tlv->len);
- osmo_sockaddr_from_octets(&f_seid->ip_addr.v6, &tlv->val[pos], l);
- pos += l;
- }
- return 0;
-}
-
-int osmo_pfcp_enc_f_seid(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_f_seid *f_seid = encode_from;
- unsigned int l;
- uint8_t flags = (f_seid->ip_addr.v6_present ? 1 : 0) + (f_seid->ip_addr.v4_present ? 2 : 0);
- /* flags and 8 octet seid */
- msgb_put_u8(tlv->dst, flags);
- osmo_store64be(f_seid->seid, msgb_put(tlv->dst, 8));
-
- if (f_seid->ip_addr.v4_present) {
- if (f_seid->ip_addr.v4.u.sin.sin_family != AF_INET)
- RETURN_ERROR(-EINVAL,
- "f_seid IE indicates IPv4 address, but there is no ipv4_addr");
- l = sizeof(f_seid->ip_addr.v4.u.sin.sin_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &f_seid->ip_addr.v4);
- }
- if (f_seid->ip_addr.v6_present) {
- if (f_seid->ip_addr.v6.u.sin6.sin6_family != AF_INET6)
- RETURN_ERROR(-EINVAL,
- "f_seid IE indicates IPv6 address, but there is no ipv6_addr");
- l = sizeof(f_seid->ip_addr.v6.u.sin6.sin6_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &f_seid->ip_addr.v6);
- }
- return 0;
-}
-
-static int ip_addrs_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_ip_addrs *addrs)
-{
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- if (addrs->v4_present) {
- OSMO_STRBUF_PRINTF(sb, ",v4:");
- OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &addrs->v4);
- }
- if (addrs->v6_present) {
- OSMO_STRBUF_PRINTF(sb, ",v6:");
- OSMO_STRBUF_APPEND(sb, osmo_sockaddr_to_str_buf2, &addrs->v6);
- }
- return sb.chars_needed;
-}
-
-int osmo_pfcp_enc_to_str_f_seid(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_f_seid *f_seid = encode_from;
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- OSMO_STRBUF_PRINTF(sb, "0x%"PRIx64, f_seid->seid);
- OSMO_STRBUF_APPEND(sb, ip_addrs_to_str_buf, &f_seid->ip_addr);
- return sb.chars_needed;
-}
-
-int osmo_pfcp_dec_f_teid(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_f_teid *f_teid = decode_to;
- uint8_t flags;
- const uint8_t *pos;
-
- *f_teid = (struct osmo_pfcp_ie_f_teid){};
-
- pos = tlv->val;
-
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("flags", pos, 1);
- flags = *pos;
- pos++;
- f_teid->choose_flag = flags & 4;
-
- if (!f_teid->choose_flag) {
- /* A fixed TEID and address are provided */
- f_teid->fixed.ip_addr.v4_present = flags & 1;
- f_teid->fixed.ip_addr.v6_present = flags & 2;
-
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("TEID", pos, 4);
- f_teid->fixed.teid = osmo_load32be(pos);
- pos += 4;
-
- if (f_teid->fixed.ip_addr.v4_present) {
- osmo_static_assert(sizeof(f_teid->fixed.ip_addr.v4.u.sin.sin_addr) == 4, sin_addr_size_is_4);
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv4 address", pos, 4);
- osmo_sockaddr_from_octets(&f_teid->fixed.ip_addr.v4, pos, 4);
- pos += 4;
- }
- if (f_teid->fixed.ip_addr.v6_present) {
- osmo_static_assert(sizeof(f_teid->fixed.ip_addr.v6.u.sin6.sin6_addr) == 16, sin6_addr_size_is_16);
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv6 address", pos, 16);
- osmo_sockaddr_from_octets(&f_teid->fixed.ip_addr.v6, pos, 16);
- pos += 16;
- }
- } else {
- /* CH flag is 1, choose an F-TEID. */
- f_teid->choose.ipv4_addr = flags & 1;
- f_teid->choose.ipv6_addr = flags & 2;
- f_teid->choose.choose_id_present = flags & 8;
-
- if (f_teid->choose.choose_id_present) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("CHOOSE ID", pos, 1);
- f_teid->choose.choose_id = *pos;
- pos++;
- }
- }
- return 0;
-}
-
-int osmo_pfcp_enc_f_teid(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_f_teid *f_teid = encode_from;
- uint8_t flags;
-
- flags = (f_teid->choose_flag ? 4 : 0);
-
- if (!f_teid->choose_flag) {
- /* A fixed TEID and address are provided */
- flags |= (f_teid->fixed.ip_addr.v4_present ? 1 : 0)
- + (f_teid->fixed.ip_addr.v6_present ? 2 : 0);
-
- msgb_put_u8(tlv->dst, flags);
- msgb_put_u32(tlv->dst, f_teid->fixed.teid);
-
- if (f_teid->fixed.ip_addr.v4_present) {
- if (f_teid->fixed.ip_addr.v4.u.sin.sin_family != AF_INET)
- RETURN_ERROR(-EINVAL,
- "f_teid IE indicates IPv4 address, but there is no ipv4_addr"
- " (sin_family = %d != AF_INET)", f_teid->fixed.ip_addr.v4.u.sin.sin_family);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, 4), 4, &f_teid->fixed.ip_addr.v4);
- }
- if (f_teid->fixed.ip_addr.v6_present) {
- if (f_teid->fixed.ip_addr.v6.u.sin6.sin6_family != AF_INET6)
- RETURN_ERROR(-EINVAL,
- "f_teid IE indicates IPv6 address, but there is no ipv6_addr"
- " (sin6_family = %d != AF_INET6)", f_teid->fixed.ip_addr.v6.u.sin6.sin6_family);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, 16), 16, &f_teid->fixed.ip_addr.v6);
- }
- } else {
- flags |= (f_teid->choose.ipv4_addr ? 1 : 0)
- + (f_teid->choose.ipv6_addr ? 2 : 0)
- + (f_teid->choose.choose_id_present ? 8 : 0);
- msgb_put_u8(tlv->dst, flags);
- if (f_teid->choose.choose_id_present)
- msgb_put_u8(tlv->dst, f_teid->choose.choose_id);
- }
- return 0;
-}
-
-int osmo_pfcp_ie_f_teid_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_ie_f_teid *ft)
-{
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- if (ft->choose_flag) {
- OSMO_STRBUF_PRINTF(sb, "CHOOSE");
- if (ft->choose.ipv4_addr)
- OSMO_STRBUF_PRINTF(sb, "-v4");
- if (ft->choose.ipv6_addr)
- OSMO_STRBUF_PRINTF(sb, "-v6");
- if (ft->choose.choose_id_present)
- OSMO_STRBUF_PRINTF(sb, "-id%u", ft->choose.choose_id);
- } else {
- OSMO_STRBUF_PRINTF(sb, "TEID-0x%x", ft->fixed.teid);
- OSMO_STRBUF_APPEND(sb, ip_addrs_to_str_buf, &ft->fixed.ip_addr);
- }
- return sb.chars_needed;
-}
-
-char *osmo_pfcp_ie_f_teid_to_str_c(void *ctx, const struct osmo_pfcp_ie_f_teid *ft)
-{
- OSMO_NAME_C_IMPL(ctx, 64, "ERROR", osmo_pfcp_ie_f_teid_to_str_buf, ft)
-}
-
-int osmo_pfcp_enc_to_str_f_teid(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_f_teid *f_teid = encode_from;
- return osmo_pfcp_ie_f_teid_to_str_buf(buf, buflen, f_teid);
-}
-
-int osmo_pfcp_dec_apply_action(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_apply_action *apply_action = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- *apply_action = (struct osmo_pfcp_ie_apply_action){};
- memcpy(apply_action->bits, tlv->val, OSMO_MIN(tlv->len, sizeof(apply_action->bits)));
- return 0;
-}
-
-int osmo_pfcp_enc_apply_action(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_apply_action *apply_action = encode_from;
- memcpy(msgb_put(tlv->dst, sizeof(apply_action->bits)),
- apply_action->bits, sizeof(apply_action->bits));
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_apply_action(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_apply_action *apply_action = encode_from;
- return osmo_pfcp_bits_to_str_buf(buf, buflen, apply_action->bits, osmo_pfcp_apply_action_strs);
-}
-
-int osmo_pfcp_dec_network_inst(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_network_inst *network_inst = decode_to;
- osmo_strlcpy(network_inst->str, (const char *)tlv->val, OSMO_MIN(sizeof(network_inst->str), tlv->len+1));
- return 0;
-}
-
-int osmo_pfcp_enc_network_inst(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_network_inst *network_inst = encode_from;
- unsigned int l = strlen(network_inst->str);
- if (l)
- memcpy(msgb_put(tlv->dst, l), network_inst->str, l);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_network_inst(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_network_inst *network_inst = encode_from;
- return osmo_quote_str_buf3(buf, buflen, network_inst->str,
- strnlen(network_inst->str, sizeof(network_inst->str)));
-}
-
-int osmo_pfcp_dec_outer_header_creation(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_outer_header_creation *ohc = decode_to;
- const uint8_t *pos;
- bool gtp_u_udp_ipv4;
- bool gtp_u_udp_ipv6;
- bool udp_ipv4;
- bool udp_ipv6;
- bool ipv4;
- bool ipv6;
- bool c_tag;
- bool s_tag;
-
- *ohc = (struct osmo_pfcp_ie_outer_header_creation){};
-
- ENSURE_LENGTH_IS_AT_LEAST(2);
-
- memcpy(ohc->desc_bits, tlv->val, 2);
-
- gtp_u_udp_ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4);
- udp_ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV4);
- ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_IPV4);
- gtp_u_udp_ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV6);
- udp_ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV6);
- ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_IPV6);
- c_tag = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_C_TAG);
- s_tag = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_S_TAG);
-
- pos = tlv->val + 2;
- if (gtp_u_udp_ipv4 || gtp_u_udp_ipv6) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("TEID", pos, 4);
- ohc->teid_present = true;
- ohc->teid = osmo_load32be(pos);
- pos += 4;
- }
- if (gtp_u_udp_ipv4 || udp_ipv4 || ipv4) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv4 address", pos, 4);
- ohc->ip_addr.v4_present = true;
- osmo_sockaddr_from_octets(&ohc->ip_addr.v4, pos, 4);
- pos += 4;
- }
- if (gtp_u_udp_ipv6 || udp_ipv6 || ipv6) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv6 address", pos, 16);
- ohc->ip_addr.v6_present = true;
- osmo_sockaddr_from_octets(&ohc->ip_addr.v6, pos, 16);
- pos += 16;
- }
- if (udp_ipv4 || udp_ipv6) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("UDP port number", pos, 2);
- ohc->port_number_present = true;
- ohc->port_number = osmo_load16be(pos);
- pos += 2;
- }
- if (c_tag) {
- ohc->c_tag_present = true;
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("C-TAG", pos, 3);
- ohc->c_tag_present = true;
- ohc->c_tag = osmo_load32be_ext_2(pos, 3);
- pos += 3;
- }
- if (s_tag) {
- ohc->s_tag_present = true;
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("S-TAG", pos, 3);
- ohc->s_tag_present = true;
- ohc->s_tag = osmo_load32be_ext_2(pos, 3);
- pos += 3;
- }
-
- return 0;
-}
-
-int osmo_pfcp_enc_outer_header_creation(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_outer_header_creation *ohc = encode_from;
- bool gtp_u_udp_ipv4;
- bool gtp_u_udp_ipv6;
- bool udp_ipv4;
- bool udp_ipv6;
- bool ipv4;
- bool ipv6;
- bool c_tag;
- bool s_tag;
-
- memcpy(msgb_put(tlv->dst, sizeof(ohc->desc_bits)), ohc->desc_bits, sizeof(ohc->desc_bits));
-
- gtp_u_udp_ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4);
- udp_ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV4);
- ipv4 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_IPV4);
- gtp_u_udp_ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV6);
- udp_ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV6);
- ipv6 = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_IPV6);
- c_tag = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_C_TAG);
- s_tag = osmo_pfcp_bits_get(ohc->desc_bits, OSMO_PFCP_OUTER_HEADER_CREATION_S_TAG);
-
- if ((gtp_u_udp_ipv4 || gtp_u_udp_ipv6) != (ohc->teid_present))
- RETURN_ERROR(-EINVAL, "teid_present = %s does not match the description bits 0x%02x\n",
- ohc->teid_present ? "true" : "false",
- ohc->desc_bits[0]);
- if (ohc->teid_present)
- msgb_put_u32(tlv->dst, ohc->teid);
-
- if ((gtp_u_udp_ipv4 || udp_ipv4 || ipv4) != ohc->ip_addr.v4_present)
- RETURN_ERROR(-EINVAL, "ipv4_addr_present = %s does not match the description bits 0x%02x\n",
- ohc->ip_addr.v4_present ? "true" : "false",
- ohc->desc_bits[0]);
- if (ohc->ip_addr.v4_present)
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, 4), 4, &ohc->ip_addr.v4);
-
- if ((gtp_u_udp_ipv6 || udp_ipv6 || ipv6) != ohc->ip_addr.v6_present)
- RETURN_ERROR(-EINVAL, "ipv6_addr_present = %s does not match the description bits 0x%02x\n",
- ohc->ip_addr.v6_present ? "true" : "false",
- ohc->desc_bits[0]);
- if (ohc->ip_addr.v6_present)
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, 16), 16, &ohc->ip_addr.v6);
-
- if ((udp_ipv4 || udp_ipv6) != ohc->port_number_present)
- RETURN_ERROR(-EINVAL, "port_number_present = %s does not match the description bits 0x%02x\n",
- ohc->port_number_present ? "true" : "false",
- ohc->desc_bits[0]);
- if (ohc->port_number_present)
- msgb_put_u16(tlv->dst, ohc->port_number);
-
- if (c_tag != ohc->c_tag_present)
- RETURN_ERROR(-EINVAL, "c_tag_present = %s does not match the description bits 0x%02x%02x\n",
- ohc->c_tag_present ? "true" : "false",
- ohc->desc_bits[1], ohc->desc_bits[0]);
- if (ohc->c_tag_present)
- osmo_store32be_ext(ohc->c_tag, msgb_put(tlv->dst, 3), 3);
-
- if (s_tag != ohc->s_tag_present)
- RETURN_ERROR(-EINVAL, "s_tag_present = %s does not match the description bits 0x%02x%02x\n",
- ohc->s_tag_present ? "true" : "false",
- ohc->desc_bits[1], ohc->desc_bits[0]);
- if (ohc->s_tag_present)
- osmo_store32be_ext(ohc->s_tag, msgb_put(tlv->dst, 3), 3);
-
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_outer_header_creation(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_outer_header_creation *ohc = encode_from;
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- OSMO_STRBUF_APPEND(sb, osmo_pfcp_bits_to_str_buf, ohc->desc_bits, osmo_pfcp_outer_header_creation_strs);
- if (ohc->teid_present)
- OSMO_STRBUF_PRINTF(sb, ",TEID:0x%x", ohc->teid);
- OSMO_STRBUF_APPEND(sb, ip_addrs_to_str_buf, &ohc->ip_addr);
- if (ohc->port_number_present)
- OSMO_STRBUF_PRINTF(sb, ",port:%u", ohc->port_number);
- if (ohc->c_tag_present)
- OSMO_STRBUF_PRINTF(sb, ",c-tag:%u", ohc->c_tag);
- if (ohc->s_tag_present)
- OSMO_STRBUF_PRINTF(sb, ",s-tag:%u", ohc->s_tag);
- return sb.chars_needed;
-}
-
-int osmo_pfcp_dec_activate_predefined_rules(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_activate_predefined_rules *activate_predefined_rules = decode_to;
- osmo_strlcpy(activate_predefined_rules->str, (const char *)tlv->val, OSMO_MIN(sizeof(activate_predefined_rules->str), tlv->len+1));
- return 0;
-}
-
-int osmo_pfcp_enc_activate_predefined_rules(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_activate_predefined_rules *activate_predefined_rules = encode_from;
- unsigned int l = strlen(activate_predefined_rules->str);
- if (l)
- memcpy(msgb_put(tlv->dst, l), activate_predefined_rules->str, l);
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_activate_predefined_rules(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_activate_predefined_rules *activate_predefined_rules = encode_from;
- return osmo_quote_str_buf3(buf, buflen, activate_predefined_rules->str,
- strnlen(activate_predefined_rules->str, sizeof(activate_predefined_rules->str)));
-}
-
-int osmo_pfcp_dec_outer_header_removal(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_outer_header_removal *outer_header_removal = decode_to;
- ENSURE_LENGTH_IS_AT_LEAST(1);
- outer_header_removal->desc = tlv->val[0];
-
- if (tlv->len > 1) {
- outer_header_removal->gtp_u_extension_header_del_present = true;
- memcpy(outer_header_removal->gtp_u_extension_header_del_bits, &tlv->val[1],
- sizeof(outer_header_removal->gtp_u_extension_header_del_bits));
- }
- return 0;
-}
-
-int osmo_pfcp_enc_outer_header_removal(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_outer_header_removal *outer_header_removal = encode_from;
- msgb_put_u8(tlv->dst, outer_header_removal->desc);
- if (outer_header_removal->gtp_u_extension_header_del_present) {
- memcpy(msgb_put(tlv->dst, sizeof(outer_header_removal->gtp_u_extension_header_del_bits)),
- outer_header_removal->gtp_u_extension_header_del_bits,
- sizeof(outer_header_removal->gtp_u_extension_header_del_bits));
- }
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_outer_header_removal(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_outer_header_removal *outer_header_removal = encode_from;
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- OSMO_STRBUF_PRINTF(sb, "%s", osmo_pfcp_outer_header_removal_desc_str(outer_header_removal->desc));
- if (outer_header_removal->gtp_u_extension_header_del_present)
- OSMO_STRBUF_PRINTF(sb, ",ext-hdr-del:0x%x", outer_header_removal->gtp_u_extension_header_del_bits[0]);
- return sb.chars_needed;
-}
-
-int osmo_pfcp_dec_ue_ip_address(void *decoded_struct, void *decode_to, const struct osmo_gtlv_load *tlv)
-{
- struct osmo_pfcp_ie_ue_ip_address *ue_ip_address = decode_to;
- const uint8_t *pos;
- uint8_t flags;
-
- pos = tlv->val;
-
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("flags", pos, 1);
- flags = *pos;
- pos++;
-
- ue_ip_address->ipv6_prefix_length_present = flags & (1 << 6);
- ue_ip_address->chv6 = flags & (1 << 5);
- ue_ip_address->chv4 = flags & (1 << 4);
- ue_ip_address->ipv6_prefix_delegation_bits_present = flags & (1 << 3);
- ue_ip_address->ip_is_destination = flags & (1 << 2);
- ue_ip_address->ip_addr.v4_present = flags & (1 << 1);
- ue_ip_address->ip_addr.v6_present = flags & (1 << 0);
-
- if (ue_ip_address->ip_addr.v4_present) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv4 address", pos, 4);
- osmo_sockaddr_from_octets(&ue_ip_address->ip_addr.v4, pos, 4);
- pos += 4;
- }
- if (ue_ip_address->ip_addr.v6_present) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv6 address", pos, 16);
- osmo_sockaddr_from_octets(&ue_ip_address->ip_addr.v6, pos, 16);
- pos += 16;
- }
-
- if (ue_ip_address->ipv6_prefix_delegation_bits_present) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv6 prefix delegation bits", pos, 1);
- ue_ip_address->ipv6_prefix_delegation_bits = *pos;
- pos++;
- }
- if (ue_ip_address->ipv6_prefix_length_present) {
- ENSURE_REMAINING_LENGTH_IS_AT_LEAST("IPv6 prefix length", pos, 1);
- ue_ip_address->ipv6_prefix_length = *pos;
- pos++;
- }
-
- return 0;
-}
-
-int osmo_pfcp_enc_ue_ip_address(struct osmo_gtlv_put *tlv, const void *decoded_struct, const void *encode_from)
-{
- const struct osmo_pfcp_ie_ue_ip_address *ue_ip_address = encode_from;
- unsigned int l;
- uint8_t flags;
-
- flags = 0
- | (ue_ip_address->ipv6_prefix_length_present ? (1 << 6) : 0)
- | (ue_ip_address->chv6 ? (1 << 5) : 0)
- | (ue_ip_address->chv4 ? (1 << 4) : 0)
- | (ue_ip_address->ipv6_prefix_delegation_bits_present ? (1 << 3) : 0)
- | (ue_ip_address->ip_is_destination ? (1 << 2) : 0)
- | (ue_ip_address->ip_addr.v4_present ? (1 << 1) : 0)
- | (ue_ip_address->ip_addr.v6_present ? (1 << 0) : 0)
- ;
-
- msgb_put_u8(tlv->dst, flags);
-
- if (ue_ip_address->ip_addr.v4_present) {
- if (ue_ip_address->ip_addr.v4.u.sin.sin_family != AF_INET)
- RETURN_ERROR(-EINVAL,
- "ue_ip_address IE indicates IPv4 address, but there is no ipv4_addr");
- l = sizeof(ue_ip_address->ip_addr.v4.u.sin.sin_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &ue_ip_address->ip_addr.v4);
- }
- if (ue_ip_address->ip_addr.v6_present) {
- if (ue_ip_address->ip_addr.v6.u.sin6.sin6_family != AF_INET6)
- RETURN_ERROR(-EINVAL,
- "ue_ip_address IE indicates IPv6 address, but there is no ipv6_addr");
- l = sizeof(ue_ip_address->ip_addr.v6.u.sin6.sin6_addr);
- osmo_sockaddr_to_octets(msgb_put(tlv->dst, l), l, &ue_ip_address->ip_addr.v6);
- }
-
- if (ue_ip_address->ipv6_prefix_delegation_bits_present)
- msgb_put_u8(tlv->dst, ue_ip_address->ipv6_prefix_delegation_bits);
-
- if (ue_ip_address->ipv6_prefix_length_present)
- msgb_put_u8(tlv->dst, ue_ip_address->ipv6_prefix_length);
-
- return 0;
-}
-
-int osmo_pfcp_enc_to_str_ue_ip_address(char *buf, size_t buflen, const void *encode_from)
-{
- const struct osmo_pfcp_ie_ue_ip_address *uia = encode_from;
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- if (uia->chv4)
- OSMO_STRBUF_PRINTF(sb, "chv4");
- if (uia->chv6)
- OSMO_STRBUF_PRINTF(sb, "%schv4", sb.pos ? "," : "");
- if (uia->ip_is_destination)
- OSMO_STRBUF_PRINTF(sb, "%sdst", sb.pos ? "," : "");
- OSMO_STRBUF_APPEND(sb, ip_addrs_to_str_buf, &uia->ip_addr);
- if (uia->ipv6_prefix_delegation_bits_present)
- OSMO_STRBUF_PRINTF(sb, ",ipv6-prefix-deleg:%x", uia->ipv6_prefix_delegation_bits);
- if (uia->ipv6_prefix_length_present)
- OSMO_STRBUF_PRINTF(sb, ",ipv6-prefix-len:%u", uia->ipv6_prefix_length);
- return sb.chars_needed;
-}
diff --git a/src/libosmo-pfcp/pfcp_msg.c b/src/libosmo-pfcp/pfcp_msg.c
deleted file mode 100644
index 9d65efc..0000000
--- a/src/libosmo-pfcp/pfcp_msg.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-#include <string.h>
-
-#include <osmocom/core/endian.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/fsm.h>
-#include <osmocom/core/use_count.h>
-#include <osmocom/core/bitvec.h>
-
-#include <osmocom/pfcp/pfcp_msg.h>
-#include <osmocom/gtlv/gtlv_dec_enc.h>
-
-/* Assumes presence of local variable osmo_pfcp_msg *m. m->log_ctx may be NULL. */
-#define RETURN_ERROR(RC, FMT, ARGS...) \
- do {\
- OSMO_ASSERT(m); \
- OSMO_LOG_PFCP_MSG(m, LOGL_ERROR, FMT " (%d: %s)\n", ##ARGS, RC, strerror((RC) > 0 ? (RC) : -(RC))); \
- return RC; \
- } while (0)
-
-bool osmo_pfcp_msgtype_is_response(enum osmo_pfcp_message_type message_type)
-{
- switch (message_type) {
- case OSMO_PFCP_MSGT_HEARTBEAT_RESP:
- case OSMO_PFCP_MSGT_PFD_MGMT_RESP:
- case OSMO_PFCP_MSGT_ASSOC_SETUP_RESP:
- case OSMO_PFCP_MSGT_ASSOC_UPDATE_RESP:
- case OSMO_PFCP_MSGT_ASSOC_RELEASE_RESP:
- case OSMO_PFCP_MSGT_VERSION_NOT_SUPP_RESP:
- case OSMO_PFCP_MSGT_NODE_REPORT_RESP:
- case OSMO_PFCP_MSGT_SESSION_SET_DEL_RESP:
- case OSMO_PFCP_MSGT_SESSION_EST_RESP:
- case OSMO_PFCP_MSGT_SESSION_MOD_RESP:
- case OSMO_PFCP_MSGT_SESSION_DEL_RESP:
- case OSMO_PFCP_MSGT_SESSION_REP_RESP:
- return true;
- default:
- return false;
- }
-}
-
-struct osmo_pfcp_header_common {
-#if OSMO_IS_LITTLE_ENDIAN
- uint8_t seid_present:1,
- message_priority_present:1,
- follow_on:1,
- spare:2,
- version:3;
- uint8_t message_type;
- uint16_t message_length;
-#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
- uint8_t version:3, spare:2, follow_on:1, message_priority_present:1, seid_present:1;
- uint8_t message_type;
- uint16_t message_length;
-#endif
-} __attribute__ ((packed));
-
-struct osmo_pfcp_header_no_seid {
- struct osmo_pfcp_header_common c;
- uint8_t sequence_nr[3];
- uint8_t spare;
-} __attribute__ ((packed));
-
-struct osmo_pfcp_header_seid {
-#if OSMO_IS_LITTLE_ENDIAN
- struct osmo_pfcp_header_common c;
- uint64_t session_endpoint_identifier;
- uint8_t sequence_nr[3];
- uint8_t message_priority:4,
- spare:4;
-#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
- struct osmo_pfcp_header_common c;
- uint64_t session_endpoint_identifier;
- uint8_t sequence_nr[3];
- uint8_t spare:4, message_priority:4;
-#endif
-} __attribute__ ((packed));
-
-int osmo_pfcp_ie_node_id_from_osmo_sockaddr(struct osmo_pfcp_ie_node_id *node_id, const struct osmo_sockaddr *os)
-{
- switch (os->u.sa.sa_family) {
- case AF_INET:
- node_id->type = OSMO_PFCP_NODE_ID_T_IPV4;
- break;
- case AF_INET6:
- node_id->type = OSMO_PFCP_NODE_ID_T_IPV6;
- break;
- default:
- return -ENOTSUP;
- }
- node_id->ip = *os;
- return 0;
-}
-
-int osmo_pfcp_ie_node_id_to_osmo_sockaddr(const struct osmo_pfcp_ie_node_id *node_id, struct osmo_sockaddr *os)
-{
- switch (node_id->type) {
- case OSMO_PFCP_NODE_ID_T_IPV4:
- if (os->u.sa.sa_family != AF_INET)
- return -EINVAL;
- break;
- case OSMO_PFCP_NODE_ID_T_IPV6:
- if (os->u.sa.sa_family != AF_INET6)
- return -EINVAL;
- break;
- default:
- return -ENOTSUP;
- }
- *os = node_id->ip;
- return 0;
-}
-
-static int pfcp_header_set_message_length(struct osmo_pfcp_header_common *c, unsigned int header_and_payload_len)
-{
- if (header_and_payload_len < sizeof(struct osmo_pfcp_header_common))
- return -EINVAL;
- if (header_and_payload_len - sizeof(struct osmo_pfcp_header_common) > UINT16_MAX)
- return -EMSGSIZE;
- osmo_store16be(header_and_payload_len - sizeof(struct osmo_pfcp_header_common),
- &c->message_length);
- return 0;
-}
-
-static unsigned int pfcp_header_get_message_length(const struct osmo_pfcp_header_common *c)
-{
- unsigned int len = osmo_load16be(&c->message_length);
- return len + sizeof(struct osmo_pfcp_header_common);
-}
-
-/*! Encode and append the given PFCP header to a msgb.
- * \param[out] msg message buffer to which to push the header.
- * \param[in] to-be-encoded representation of PFCP header. */
-static int enc_pfcp_header(struct msgb *msg, const struct osmo_pfcp_msg *m)
-{
- const struct osmo_pfcp_header_parsed *parsed = &m->h;
- struct osmo_pfcp_header_seid *h_seid;
- struct osmo_pfcp_header_no_seid *h_no_seid;
- struct osmo_pfcp_header_common *c;
- int rc;
-
- if (!parsed->seid_present) {
- h_no_seid = (struct osmo_pfcp_header_no_seid *)msgb_put(msg, sizeof(struct osmo_pfcp_header_no_seid));
- c = &h_no_seid->c;
- } else {
- h_seid = (struct osmo_pfcp_header_seid *)msgb_put(msg, sizeof(struct osmo_pfcp_header_seid));
- c = &h_seid->c;
- }
-
- *c = (struct osmo_pfcp_header_common){
- .version = parsed->version,
- .message_priority_present = (parsed->priority_present ? 1 : 0),
- .seid_present = (parsed->seid_present ? 1 : 0),
- .message_type = parsed->message_type,
- };
-
- /* Put a preliminary length reflecting only the header, until it is updated later in osmo_pfcp_msg_encode(). */
- rc = pfcp_header_set_message_length(c, parsed->seid_present ? sizeof(struct osmo_pfcp_header_seid)
- : sizeof(struct osmo_pfcp_header_no_seid));
- if (rc)
- RETURN_ERROR(rc, "Problem with PFCP message length");
-
- if (!parsed->seid_present) {
- osmo_store32be_ext(parsed->sequence_nr, h_no_seid->sequence_nr, 3);
- if (parsed->priority_present)
- RETURN_ERROR(-EINVAL, "Message Priority can only be present when the SEID is also present");
- } else {
- osmo_store64be(parsed->seid, &h_seid->session_endpoint_identifier);
- osmo_store32be_ext(parsed->sequence_nr, h_seid->sequence_nr, 3);
- if (parsed->priority_present)
- h_seid->message_priority = parsed->priority;
- }
-
- return 0;
-}
-
-static void osmo_pfcp_msg_set_memb_ofs(struct osmo_pfcp_msg *m)
-{
- const struct osmo_gtlv_coding *mc = osmo_pfcp_get_msg_coding(m->h.message_type);
- m->ofs_cause = 0;
- m->ofs_node_id = 0;
- if (!mc)
- return;
- for (; !osmo_gtlv_coding_end(mc) && (m->ofs_cause == 0 || m->ofs_node_id == 0); mc++) {
- if (mc->ti.tag == OSMO_PFCP_IEI_CAUSE)
- m->ofs_cause = offsetof(struct osmo_pfcp_msg, ies) + mc->memb_ofs;
- if (mc->ti.tag == OSMO_PFCP_IEI_NODE_ID)
- m->ofs_node_id = offsetof(struct osmo_pfcp_msg, ies) + mc->memb_ofs;
- }
-};
-
-/*! Decode a single PFCP message's header.
- *
- * If msg->l4h is non-NULL, decode at msgb_l4(msg). If l4h is NULL, decode at msgb_l3(msg).
- * In case of bundled PFCP messages, decode only one message and return the offset to the next message in the buffer.
- * Hence, to decode a message bundle, increment msg->l4h until all messages are decoded:
- *
- * msg->l4h = msg->l3h;
- * while (msgb_l4len(msg)) {
- * struct osmo_pfcp_msg m;
- * struct osmo_gtlv_load tlv;
- * int rc;
- * rc = osmo_pfcp_msg_decode_header(&tlv, &m, msg);
- * if (rc < 0)
- * error();
- * msg->l4h += rc;
- *
- * if (osmo_pfcp_msg_decode_tlv(&m, &tlv))
- * error();
- * handle(&m);
- * }
- *
- * \param[out] tlv Return TLV start pointer and length in tlv->src.*.
- * \param[inout] m Place the decoded data in m->h; use m->ctx.* as logging context.
- * \param[in] msg PFCP data to parse, possibly containing a PFCP message bundle.
- * \return total single PFCP message length (<= data_len) on success, negative on error.
- */
-int osmo_pfcp_msg_decode_header(struct osmo_gtlv_load *tlv, struct osmo_pfcp_msg *m,
- const struct msgb *msg)
-{
- struct osmo_pfcp_header_parsed *parsed = &m->h;
- const uint8_t *pfcp_msg_data;
- unsigned int pfcp_msg_data_len;
- unsigned int header_len;
- unsigned int message_length;
- const struct osmo_pfcp_header_common *c;
-
- if (msg->l4h) {
- pfcp_msg_data = msgb_l4(msg);
- pfcp_msg_data_len = msgb_l4len(msg);
- } else {
- pfcp_msg_data = msgb_l3(msg);
- pfcp_msg_data_len = msgb_l3len(msg);
- }
-
- if (!pfcp_msg_data || !pfcp_msg_data_len)
- RETURN_ERROR(-EINVAL, "No Layer 3 data in this message buffer");
-
- if (pfcp_msg_data_len < sizeof(struct osmo_pfcp_header_common))
- RETURN_ERROR(-EINVAL, "Message too short for PFCP header: %u", pfcp_msg_data_len);
-
- c = (void *)pfcp_msg_data;
-
- header_len = (c->seid_present ? sizeof(struct osmo_pfcp_header_seid) : sizeof(struct osmo_pfcp_header_no_seid));
- if (pfcp_msg_data_len < header_len)
- RETURN_ERROR(-EINVAL, "Message too short for PFCP header: %u", pfcp_msg_data_len);
-
- *parsed = (struct osmo_pfcp_header_parsed){
- .version = c->version,
- .priority_present = (bool)c->message_priority_present,
- .seid_present = (bool)c->seid_present,
- .message_type = c->message_type,
- };
-
- m->is_response = osmo_pfcp_msgtype_is_response(parsed->message_type);
- osmo_pfcp_msg_set_memb_ofs(m);
-
- message_length = pfcp_header_get_message_length(c);
- if (message_length > pfcp_msg_data_len)
- RETURN_ERROR(-EMSGSIZE,
- "The header's indicated total message length %u is larger than the received data %u",
- message_length, pfcp_msg_data_len);
-
- /* T16L16V payload data and len */
- *tlv = (struct osmo_gtlv_load){
- .cfg = &osmo_t16l16v_cfg,
- .src = {
- .data = pfcp_msg_data + header_len,
- .len = message_length - header_len,
- },
- };
-
- if (c->follow_on) {
- /* Another PFCP message should follow */
- if (pfcp_msg_data_len - message_length < sizeof(struct osmo_pfcp_header_common))
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO,
- "PFCP message indicates more messages should follow in the bundle,"
- " but remaining size %u is too short", pfcp_msg_data_len - message_length);
- } else {
- /* No more PFCP message should follow in the bundle */
- if (pfcp_msg_data_len > message_length)
- OSMO_LOG_PFCP_MSG(m, LOGL_INFO, "Surplus data after PFCP message: %u",
- pfcp_msg_data_len - message_length);
- }
-
- if (!parsed->seid_present) {
- const struct osmo_pfcp_header_no_seid *h_no_seid = (void *)pfcp_msg_data;
- parsed->sequence_nr = osmo_load32be_ext_2(h_no_seid->sequence_nr, 3);
- if (parsed->priority_present)
- RETURN_ERROR(-EINVAL, "Message Priority can only be present when the SEID is also present");
- } else {
- const struct osmo_pfcp_header_seid *h_seid = (void *)pfcp_msg_data;
- parsed->seid = osmo_load64be(&h_seid->session_endpoint_identifier);
- parsed->sequence_nr = osmo_load32be_ext_2(h_seid->sequence_nr, 3);
- if (parsed->priority_present)
- parsed->priority = h_seid->message_priority;
- }
-
- return message_length;
-}
-
-void osmo_pfcp_msg_err_cb(void *data, void *decoded_struct, const char *file, int line, const char *fmt, ...)
-{
- va_list ap;
- if (log_check_level(DLPFCP, LOGL_ERROR)) {
- char *errmsg;
-
- va_start(ap, fmt);
- errmsg = talloc_vasprintf(OTC_SELECT, fmt, ap);
- va_end(ap);
- OSMO_LOG_PFCP_MSG_SRC((struct osmo_pfcp_msg *)data, LOGL_ERROR, file, line, "%s", errmsg);
- }
-}
-
-int osmo_pfcp_msg_decode_tlv(struct osmo_pfcp_msg *m, struct osmo_gtlv_load *tlv)
-{
- return osmo_pfcp_ies_decode(&m->ies, tlv, false, m->h.message_type, osmo_pfcp_msg_err_cb, m, osmo_pfcp_iei_strs);
-}
-
-static int osmo_pfcp_msg_encode_tlv(struct msgb *msg, const struct osmo_pfcp_msg *m)
-{
- struct osmo_gtlv_put tlv = {
- .cfg = &osmo_t16l16v_cfg,
- .dst = msg,
- };
- return osmo_pfcp_ies_encode(&tlv, &m->ies, m->h.message_type, osmo_pfcp_msg_err_cb, (void *)m, osmo_pfcp_iei_strs);
-}
-
-/* Append the encoded PFCP message to the message buffer.
- *
- * If msg->l3h is NULL, point it at the start of the encoded message.
- * Always point msg->l4h at the start of the newly encoded message.
- * Hence, in a message bundle, msg->l3h always points at the first PFCP message, while msg->l4h always points at the
- * last PFCP message.
- *
- * When adding a PFCP message to a bundle, set the Follow On (FO) flag of the previously last message to 1, and of the
- * newly encoded, now last message as 0.
- *
- * To log errors to a specific osmo_fsm_inst, point m->log_ctx to that instance before calling this function. Otherwise
- * set log_ctx = NULL.
- *
- * \return 0 on success, negative on error. */
-int osmo_pfcp_msg_encode(struct msgb *msg, const struct osmo_pfcp_msg *m)
-{
- struct osmo_pfcp_header_common *c;
- int rc;
-
- /* Forming a bundle? If yes, set the Follow On flag of the currently last message to 1 */
- if (msg->l4h && msgb_l4len(msg)) {
- c = msgb_l4(msg);
- c->follow_on = 1;
- }
- /* Make sure l3h points at the first PFCP message in a message bundle */
- if (!msg->l3h)
- msg->l3h = msg->tail;
- /* Make sure l4h points at the last PFCP message in a message bundle */
- msg->l4h = msg->tail;
- c = (void *)msg->tail;
-
- rc = enc_pfcp_header(msg, m);
- if (rc)
- return rc;
-
- rc = osmo_pfcp_msg_encode_tlv(msg, m);
- if (rc)
- return rc;
-
- /* Update the header's message_length */
- rc = pfcp_header_set_message_length(c, msgb_l4len(msg));
- if (rc)
- RETURN_ERROR(rc, "Problem with PFCP message length");
- return 0;
-}
-
-static int osmo_pfcp_msg_destructor(struct osmo_pfcp_msg *m);
-
-static struct osmo_pfcp_msg *_osmo_pfcp_msg_alloc(void *ctx, const struct osmo_sockaddr *remote_addr)
-{
- struct osmo_pfcp_msg *m = talloc(ctx, struct osmo_pfcp_msg);
- *m = (struct osmo_pfcp_msg){
- .remote_addr = *remote_addr,
- .h = {
- .version = 1,
- },
- };
- talloc_set_destructor(m, osmo_pfcp_msg_destructor);
- return m;
-}
-
-struct osmo_pfcp_msg *osmo_pfcp_msg_alloc_rx(void *ctx, const struct osmo_sockaddr *remote_addr)
-{
- struct osmo_pfcp_msg *rx = _osmo_pfcp_msg_alloc(ctx, remote_addr);
- rx->rx = true;
- return rx;
-}
-
-struct osmo_pfcp_msg *osmo_pfcp_msg_alloc_tx(void *ctx, const struct osmo_sockaddr *remote_addr,
- const struct osmo_pfcp_ie_node_id *node_id,
- const struct osmo_pfcp_msg *in_reply_to,
- enum osmo_pfcp_message_type msg_type)
-{
- struct osmo_pfcp_msg *tx;
- if (!remote_addr && in_reply_to)
- remote_addr = &in_reply_to->remote_addr;
- OSMO_ASSERT(remote_addr);
- tx = _osmo_pfcp_msg_alloc(ctx, remote_addr);
- tx->is_response = osmo_pfcp_msgtype_is_response(msg_type);
- tx->h.message_type = msg_type;
- if (in_reply_to)
- tx->h.sequence_nr = in_reply_to->h.sequence_nr;
- osmo_pfcp_msg_set_memb_ofs(tx);
-
- /* Write the local node id data to the correct tx->ies.* member. */
- if (node_id) {
- struct osmo_pfcp_ie_node_id *tx_node_id = osmo_pfcp_msg_node_id(tx);
- if (tx_node_id)
- *tx_node_id = *node_id;
- }
- return tx;
-}
-
-static int osmo_pfcp_msg_destructor(struct osmo_pfcp_msg *m)
-{
- OSMO_LOG_PFCP_MSG(m, LOGL_DEBUG, "discarding\n");
- if (m->ctx.session_use_count)
- osmo_use_count_get_put(m->ctx.session_use_count, m->ctx.session_use_token, -1);
- m->ctx.session_fi = NULL;
- m->ctx.session_use_count = NULL;
- m->ctx.session_use_token = NULL;
-
- if (m->ctx.peer_use_count)
- osmo_use_count_get_put(m->ctx.peer_use_count, m->ctx.peer_use_token, -1);
- m->ctx.peer_fi = NULL;
- m->ctx.peer_use_count = NULL;
- m->ctx.peer_use_token = NULL;
- return 0;
-}
-
-void osmo_pfcp_msg_free(struct osmo_pfcp_msg *m)
-{
- if (!m)
- return;
- talloc_free(m);
-}
-
-uint32_t osmo_pfcp_next_seq_nr(uint32_t *next_seq_nr_state)
-{
- (*next_seq_nr_state)++;
- (*next_seq_nr_state) &= 0xffffff;
- /* Avoid seq == 0, so that it doesn't look like the value is missing. */
- if (!(*next_seq_nr_state))
- (*next_seq_nr_state)++;
- return *next_seq_nr_state;
-}
-
-uint64_t osmo_pfcp_next_seid(uint64_t *next_seid_state)
-{
- (*next_seid_state)++;
- /* Avoid SEID == 0, which is sent in Session Establishment Request before a remote SEID is known. */
- if (!*next_seid_state)
- (*next_seid_state)++;
- return *next_seid_state;
-}
-
-int osmo_pfcp_ip_addrs_set(struct osmo_pfcp_ip_addrs *dst, const struct osmo_sockaddr *addr)
-{
- switch (addr->u.sas.ss_family) {
- case AF_INET:
- dst->v4_present = true;
- dst->v4 = *addr;
- return 0;
- case AF_INET6:
- dst->v6_present = true;
- dst->v6 = *addr;
- return 0;
- default:
- return -ENOTSUP;
- }
-}
-
-/* If a osmo_fsm_inst placed in m->ctx deallocates before the osmo_pfcp_msg, call this function, to make sure to avoid
- * use after free. Alternatively use m->ctx.*_use_count to make sure the FSM inst does not deallocate before the
- * osmo_pfcp_msg is discarded from the resend queue. */
-void osmo_pfcp_msg_invalidate_ctx(struct osmo_pfcp_msg *m, struct osmo_fsm_inst *deleted_fi)
-{
- if (m->ctx.session_fi == deleted_fi) {
- m->ctx.session_fi = NULL;
- m->ctx.session_use_count = NULL;
- m->ctx.session_use_token = NULL;
- }
- if (m->ctx.peer_fi == deleted_fi) {
- m->ctx.peer_fi = NULL;
- m->ctx.peer_use_count = NULL;
- m->ctx.peer_use_token = NULL;
- }
-}
-
-int osmo_pfcp_msg_to_str_buf(char *buf, size_t buflen, const struct osmo_pfcp_msg *m)
-{
- struct osmo_strbuf sb = { .buf = buf, .len = buflen };
- OSMO_STRBUF_PRINTF(sb, "PFCPv%u %s hdr={seq=%u", m->h.version, osmo_pfcp_message_type_str(m->h.message_type),
- m->h.sequence_nr);
- if (m->h.priority_present)
- OSMO_STRBUF_PRINTF(sb, " prio=%u", m->h.priority);
- if (m->h.seid_present)
- OSMO_STRBUF_PRINTF(sb, " SEID=0x%"PRIx64, m->h.seid);
- OSMO_STRBUF_PRINTF(sb, "} ies={");
- OSMO_STRBUF_APPEND(sb, osmo_pfcp_ies_encode_to_str, &m->ies, m->h.message_type, osmo_pfcp_iei_strs);
- OSMO_STRBUF_PRINTF(sb, " }");
- return sb.chars_needed;
-}
-
-char *osmo_pfcp_msg_to_str_c(void *ctx, const struct osmo_pfcp_msg *m)
-{
- OSMO_NAME_C_IMPL(ctx, 256, "ERROR", osmo_pfcp_msg_to_str_buf, m)
-}
diff --git a/src/libosmo-pfcp/pfcp_strs.c b/src/libosmo-pfcp/pfcp_strs.c
deleted file mode 100644
index bd53aa0..0000000
--- a/src/libosmo-pfcp/pfcp_strs.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <osmocom/pfcp/pfcp_strs.h>
-
-const struct value_string osmo_pfcp_message_type_strs[] = {
- { OSMO_PFCP_MSGT_HEARTBEAT_REQ, "HEARTBEAT_REQ" },
- { OSMO_PFCP_MSGT_HEARTBEAT_RESP, "HEARTBEAT_RESP" },
- { OSMO_PFCP_MSGT_PFD_MGMT_REQ, "PFD_MGMT_REQ" },
- { OSMO_PFCP_MSGT_PFD_MGMT_RESP, "PFD_MGMT_RESP" },
- { OSMO_PFCP_MSGT_ASSOC_SETUP_REQ, "ASSOC_SETUP_REQ" },
- { OSMO_PFCP_MSGT_ASSOC_SETUP_RESP, "ASSOC_SETUP_RESP" },
- { OSMO_PFCP_MSGT_ASSOC_UPDATE_REQ, "ASSOC_UPDATE_REQ" },
- { OSMO_PFCP_MSGT_ASSOC_UPDATE_RESP, "ASSOC_UPDATE_RESP" },
- { OSMO_PFCP_MSGT_ASSOC_RELEASE_REQ, "ASSOC_RELEASE_REQ" },
- { OSMO_PFCP_MSGT_ASSOC_RELEASE_RESP, "ASSOC_RELEASE_RESP" },
- { OSMO_PFCP_MSGT_VERSION_NOT_SUPP_RESP, "VERSION_NOT_SUPP_RESP" },
- { OSMO_PFCP_MSGT_NODE_REPORT_REQ, "NODE_REPORT_REQ" },
- { OSMO_PFCP_MSGT_NODE_REPORT_RESP, "NODE_REPORT_RESP" },
- { OSMO_PFCP_MSGT_SESSION_SET_DEL_REQ, "SESSION_SET_DEL_REQ" },
- { OSMO_PFCP_MSGT_SESSION_SET_DEL_RESP, "SESSION_SET_DEL_RESP" },
- { OSMO_PFCP_MSGT_SESSION_EST_REQ, "SESSION_EST_REQ" },
- { OSMO_PFCP_MSGT_SESSION_EST_RESP, "SESSION_EST_RESP" },
- { OSMO_PFCP_MSGT_SESSION_MOD_REQ, "SESSION_MOD_REQ" },
- { OSMO_PFCP_MSGT_SESSION_MOD_RESP, "SESSION_MOD_RESP" },
- { OSMO_PFCP_MSGT_SESSION_DEL_REQ, "SESSION_DEL_REQ" },
- { OSMO_PFCP_MSGT_SESSION_DEL_RESP, "SESSION_DEL_RESP" },
- { OSMO_PFCP_MSGT_SESSION_REP_REQ, "SESSION_REP_REQ" },
- { OSMO_PFCP_MSGT_SESSION_REP_RESP, "SESSION_REP_RESP" },
- { 0 }
-};
-
-const struct value_string osmo_pfcp_iei_strs[] = {
- { OSMO_PFCP_IEI_CREATE_PDR, "Create PDR" },
- { OSMO_PFCP_IEI_PDI, "PDI" },
- { OSMO_PFCP_IEI_CREATE_FAR, "Create FAR" },
- { OSMO_PFCP_IEI_FORW_PARAMS, "Forwarding Parameters" },
- { OSMO_PFCP_IEI_DUPL_PARAMS, "Duplicating Parameters" },
- { OSMO_PFCP_IEI_CREATE_URR, "Create URR" },
- { OSMO_PFCP_IEI_CREATE_QER, "Create QER" },
- { OSMO_PFCP_IEI_CREATED_PDR, "Created PDR" },
- { OSMO_PFCP_IEI_UPD_PDR, "Update PDR" },
- { OSMO_PFCP_IEI_UPD_FAR, "Update FAR" },
- { OSMO_PFCP_IEI_UPD_FORW_PARAMS, "Update Forwarding Parameters" },
- { OSMO_PFCP_IEI_UPD_BAR_SESS_REP_RESP, "Update BAR (PFCP Session Report Response)" },
- { OSMO_PFCP_IEI_UPD_URR, "Update URR" },
- { OSMO_PFCP_IEI_UPD_QER, "Update QER" },
- { OSMO_PFCP_IEI_REMOVE_PDR, "Remove PDR" },
- { OSMO_PFCP_IEI_REMOVE_FAR, "Remove FAR" },
- { OSMO_PFCP_IEI_REMOVE_URR, "Remove URR" },
- { OSMO_PFCP_IEI_REMOVE_QER, "Remove QER" },
- { OSMO_PFCP_IEI_CAUSE, "Cause" },
- { OSMO_PFCP_IEI_SOURCE_IFACE, "Source Interface" },
- { OSMO_PFCP_IEI_F_TEID, "F-TEID" },
- { OSMO_PFCP_IEI_NETWORK_INST, "Network Instance" },
- { OSMO_PFCP_IEI_SDF_FILTER, "SDF Filter" },
- { OSMO_PFCP_IEI_APPLICATION_ID, "Application ID" },
- { OSMO_PFCP_IEI_GATE_STATUS, "Gate Status" },
- { OSMO_PFCP_IEI_MBR, "MBR" },
- { OSMO_PFCP_IEI_GBR, "GBR" },
- { OSMO_PFCP_IEI_QER_CORRELATION_ID, "QER Correlation ID" },
- { OSMO_PFCP_IEI_PRECEDENCE, "Precedence" },
- { OSMO_PFCP_IEI_TRANSPORT_LEVEL_MARKING, "Transport Level Marking" },
- { OSMO_PFCP_IEI_VOLUME_THRESH, "Volume Threshold" },
- { OSMO_PFCP_IEI_TIME_THRESH, "Time Threshold" },
- { OSMO_PFCP_IEI_MONITORING_TIME, "Monitoring Time" },
- { OSMO_PFCP_IEI_SUBSEQUENT_VOLUME_THRESH, "Subsequent Volume Threshold" },
- { OSMO_PFCP_IEI_SUBSEQUENT_TIME_THRESH, "Subsequent Time Threshold" },
- { OSMO_PFCP_IEI_INACT_DETECTION_TIME, "Inactivity Detection Time" },
- { OSMO_PFCP_IEI_REPORTING_TRIGGERS, "Reporting Triggers" },
- { OSMO_PFCP_IEI_REDIRECT_INFO, "Redirect Information" },
- { OSMO_PFCP_IEI_REP_TYPE, "Report Type" },
- { OSMO_PFCP_IEI_OFFENDING_IE, "Offending IE" },
- { OSMO_PFCP_IEI_FORW_POLICY, "Forwarding Policy" },
- { OSMO_PFCP_IEI_DESTINATION_IFACE, "Destination Interface" },
- { OSMO_PFCP_IEI_UP_FUNCTION_FEATURES, "UP Function Features" },
- { OSMO_PFCP_IEI_APPLY_ACTION, "Apply Action" },
- { OSMO_PFCP_IEI_DL_DATA_SERVICE_INFO, "Downlink Data Service Information" },
- { OSMO_PFCP_IEI_DL_DATA_NOTIFICATION_DELAY, "Downlink Data Notification Delay" },
- { OSMO_PFCP_IEI_DL_BUFF_DURATION, "DL Buffering Duration" },
- { OSMO_PFCP_IEI_DL_BUFF_SUGGESTED_PACKET_COUNT, "DL Buffering Suggested Packet Count" },
- { OSMO_PFCP_IEI_PFCPSMREQ_FLAGS, "PFCPSMReq-Flags" },
- { OSMO_PFCP_IEI_PFCPSRRSP_FLAGS, "PFCPSRRsp-Flags" },
- { OSMO_PFCP_IEI_LOAD_CTRL_INFO, "Load Control Information" },
- { OSMO_PFCP_IEI_SEQUENCE_NUMBER, "Sequence Number" },
- { OSMO_PFCP_IEI_METRIC, "Metric" },
- { OSMO_PFCP_IEI_OVERLOAD_CTRL_INFO, "Overload Control Information" },
- { OSMO_PFCP_IEI_TIMER, "Timer" },
- { OSMO_PFCP_IEI_PDR_ID, "PDR ID" },
- { OSMO_PFCP_IEI_F_SEID, "F-SEID" },
- { OSMO_PFCP_IEI_APPLICATION_IDS_PFDS, "Application ID's PFDs" },
- { OSMO_PFCP_IEI_PFD_CONTEXT, "PFD context" },
- { OSMO_PFCP_IEI_NODE_ID, "Node ID" },
- { OSMO_PFCP_IEI_PFD_CONTENTS, "PFD contents" },
- { OSMO_PFCP_IEI_MEAS_METHOD, "Measurement Method" },
- { OSMO_PFCP_IEI_USAGE_REP_TRIGGER, "Usage Report Trigger" },
- { OSMO_PFCP_IEI_MEAS_PERIOD, "Measurement Period" },
- { OSMO_PFCP_IEI_FQ_CSID, "FQ-CSID" },
- { OSMO_PFCP_IEI_VOLUME_MEAS, "Volume Measurement" },
- { OSMO_PFCP_IEI_DURATION_MEAS, "Duration Measurement" },
- { OSMO_PFCP_IEI_APPLICATION_DETECTION_INFO, "Application Detection Information" },
- { OSMO_PFCP_IEI_TIME_OF_FIRST_PACKET, "Time of First Packet" },
- { OSMO_PFCP_IEI_TIME_OF_LAST_PACKET, "Time of Last Packet" },
- { OSMO_PFCP_IEI_QUOTA_HOLDING_TIME, "Quota Holding Time" },
- { OSMO_PFCP_IEI_DROPPED_DL_TRAFFIC_THRESH, "Dropped DL Traffic Threshold" },
- { OSMO_PFCP_IEI_VOLUME_QUOTA, "Volume Quota" },
- { OSMO_PFCP_IEI_TIME_QUOTA, "Time Quota" },
- { OSMO_PFCP_IEI_START_TIME, "Start Time" },
- { OSMO_PFCP_IEI_END_TIME, "End Time" },
- { OSMO_PFCP_IEI_QUERY_URR, "Query URR" },
- { OSMO_PFCP_IEI_USAGE_REP_SESS_MOD_RESP, "Usage Report (Session Modification Response)" },
- { OSMO_PFCP_IEI_USAGE_REP_SESS_DEL_RESP, "Usage Report (Session Deletion Response)" },
- { OSMO_PFCP_IEI_USAGE_REP_SESS_REP_REQ, "Usage Report (Session Report Request)" },
- { OSMO_PFCP_IEI_URR_ID, "URR ID" },
- { OSMO_PFCP_IEI_LINKED_URR_ID, "Linked URR ID" },
- { OSMO_PFCP_IEI_DL_DATA_REP, "Downlink Data Report" },
- { OSMO_PFCP_IEI_OUTER_HEADER_CREATION, "Outer Header Creation" },
- { OSMO_PFCP_IEI_CREATE_BAR, "Create BAR" },
- { OSMO_PFCP_IEI_UPD_BAR_SESS_MOD_REQ, "Update BAR (Session Modification Request)" },
- { OSMO_PFCP_IEI_REMOVE_BAR, "Remove BAR" },
- { OSMO_PFCP_IEI_BAR_ID, "BAR ID" },
- { OSMO_PFCP_IEI_CP_FUNCTION_FEATURES, "CP Function Features" },
- { OSMO_PFCP_IEI_USAGE_INFO, "Usage Information" },
- { OSMO_PFCP_IEI_APPLICATION_INST_ID, "Application Instance ID" },
- { OSMO_PFCP_IEI_FLOW_INFO, "Flow Information" },
- { OSMO_PFCP_IEI_UE_IP_ADDRESS, "UE IP Address" },
- { OSMO_PFCP_IEI_PACKET_RATE, "Packet Rate" },
- { OSMO_PFCP_IEI_OUTER_HEADER_REMOVAL, "Outer Header Removal" },
- { OSMO_PFCP_IEI_RECOVERY_TIME_STAMP, "Recovery Time Stamp" },
- { OSMO_PFCP_IEI_DL_FLOW_LEVEL_MARKING, "DL Flow Level Marking" },
- { OSMO_PFCP_IEI_HEADER_ENRICHMENT, "Header Enrichment" },
- { OSMO_PFCP_IEI_ERROR_IND_REP, "Error Indication Report" },
- { OSMO_PFCP_IEI_MEAS_INFO, "Measurement Information" },
- { OSMO_PFCP_IEI_NODE_REP_TYPE, "Node Report Type" },
- { OSMO_PFCP_IEI_USER_PLANE_PATH_FAILURE_REP, "User Plane Path Failure Report" },
- { OSMO_PFCP_IEI_REMOTE_GTP_U_PEER, "Remote GTP-U Peer" },
- { OSMO_PFCP_IEI_UR_SEQN, "UR-SEQN" },
- { OSMO_PFCP_IEI_UPD_DUPL_PARAMS, "Update Duplicating Parameters" },
- { OSMO_PFCP_IEI_ACTIVATE_PREDEFINED_RULES, "Activate Predefined Rules" },
- { OSMO_PFCP_IEI_DEACTIVATE_PREDEFINED_RULES, "Deactivate Predefined Rules" },
- { OSMO_PFCP_IEI_FAR_ID, "FAR ID" },
- { OSMO_PFCP_IEI_QER_ID, "QER ID" },
- { OSMO_PFCP_IEI_OCI_FLAGS, "OCI Flags" },
- { OSMO_PFCP_IEI_PFCP_ASSOC_RELEASE_REQ, "PFCP Association Release Request" },
- { OSMO_PFCP_IEI_GRACEFUL_RELEASE_PERIOD, "Graceful Release Period" },
- { OSMO_PFCP_IEI_PDN_TYPE, "PDN Type" },
- { OSMO_PFCP_IEI_FAILED_RULE_ID, "Failed Rule ID" },
- { OSMO_PFCP_IEI_TIME_QUOTA_MECHANISM, "Time Quota Mechanism" },
- { OSMO_PFCP_IEI_RESERVED, "Reserved" },
- { OSMO_PFCP_IEI_USER_PLANE_INACT_TIMER, "User Plane Inactivity Timer" },
- { OSMO_PFCP_IEI_AGGREGATED_URRS, "Aggregated URRs" },
- { OSMO_PFCP_IEI_MULTIPLIER, "Multiplier" },
- { OSMO_PFCP_IEI_AGGREGATED_URR_ID, "Aggregated URR ID" },
- { OSMO_PFCP_IEI_SUBSEQUENT_VOLUME_QUOTA, "Subsequent Volume Quota" },
- { OSMO_PFCP_IEI_SUBSEQUENT_TIME_QUOTA, "Subsequent Time Quota" },
- { OSMO_PFCP_IEI_RQI, "RQI" },
- { OSMO_PFCP_IEI_QFI, "QFI" },
- { OSMO_PFCP_IEI_QUERY_URR_REFERENCE, "Query URR Reference" },
- { OSMO_PFCP_IEI_ADDITIONAL_USAGE_REPS_INFO, "Additional Usage Reports Information" },
- { OSMO_PFCP_IEI_CREATE_TRAFFIC_ENDPOINT, "Create Traffic Endpoint" },
- { OSMO_PFCP_IEI_CREATED_TRAFFIC_ENDPOINT, "Created Traffic Endpoint" },
- { OSMO_PFCP_IEI_UPD_TRAFFIC_ENDPOINT, "Update Traffic Endpoint" },
- { OSMO_PFCP_IEI_REMOVE_TRAFFIC_ENDPOINT, "Remove Traffic Endpoint" },
- { OSMO_PFCP_IEI_TRAFFIC_ENDPOINT_ID, "Traffic Endpoint ID" },
- { OSMO_PFCP_IEI_ETHERNET_PACKET_FILTER, "Ethernet Packet Filter" },
- { OSMO_PFCP_IEI_MAC_ADDRESS, "MAC address" },
- { OSMO_PFCP_IEI_C_TAG, "C-TAG" },
- { OSMO_PFCP_IEI_S_TAG, "S-TAG" },
- { OSMO_PFCP_IEI_ETHERTYPE, "Ethertype" },
- { OSMO_PFCP_IEI_PROXYING, "Proxying" },
- { OSMO_PFCP_IEI_ETHERNET_FILTER_ID, "Ethernet Filter ID" },
- { OSMO_PFCP_IEI_ETHERNET_FILTER_PROPERTIES, "Ethernet Filter Properties" },
- { OSMO_PFCP_IEI_SUGGESTED_BUFF_PACKETS_COUNT, "Suggested Buffering Packets Count" },
- { OSMO_PFCP_IEI_USER_ID, "User ID" },
- { OSMO_PFCP_IEI_ETHERNET_PDU_SESS_INFO, "Ethernet PDU Session Information" },
- { OSMO_PFCP_IEI_ETHERNET_TRAFFIC_INFO, "Ethernet Traffic Information" },
- { OSMO_PFCP_IEI_MAC_ADDRS_DETECTED, "MAC Addresses Detected" },
- { OSMO_PFCP_IEI_MAC_ADDRS_REMOVED, "MAC Addresses Removed" },
- { OSMO_PFCP_IEI_ETHERNET_INACT_TIMER, "Ethernet Inactivity Timer" },
- { OSMO_PFCP_IEI_ADDITIONAL_MONITORING_TIME, "Additional Monitoring Time" },
- { OSMO_PFCP_IEI_EVENT_QUOTA, "Event Quota" },
- { OSMO_PFCP_IEI_EVENT_THRESH, "Event Threshold" },
- { OSMO_PFCP_IEI_SUBSEQUENT_EVENT_QUOTA, "Subsequent Event Quota" },
- { OSMO_PFCP_IEI_SUBSEQUENT_EVENT_THRESH, "Subsequent Event Threshold" },
- { OSMO_PFCP_IEI_TRACE_INFO, "Trace Information" },
- { OSMO_PFCP_IEI_FRAMED_ROUTE, "Framed-Route" },
- { OSMO_PFCP_IEI_FRAMED_ROUTING, "Framed-Routing" },
- { OSMO_PFCP_IEI_FRAMED_IPV6_ROUTE, "Framed-IPv6-Route" },
- { OSMO_PFCP_IEI_TIME_STAMP, "Time Stamp" },
- { OSMO_PFCP_IEI_AVERAGING_WINDOW, "Averaging Window" },
- { OSMO_PFCP_IEI_PAGING_POLICY_INDICATOR, "Paging Policy Indicator" },
- { OSMO_PFCP_IEI_APN_DNN, "APN/DNN" },
- { OSMO_PFCP_IEI_3GPP_IFACE_TYPE, "3GPP Interface Type" },
- { OSMO_PFCP_IEI_PFCPSRREQ_FLAGS, "PFCPSRReq-Flags" },
- { OSMO_PFCP_IEI_PFCPAUREQ_FLAGS, "PFCPAUReq-Flags" },
- { OSMO_PFCP_IEI_ACTIVATION_TIME, "Activation Time" },
- { OSMO_PFCP_IEI_DEACTIVATION_TIME, "Deactivation Time" },
- { OSMO_PFCP_IEI_CREATE_MAR, "Create MAR" },
- { OSMO_PFCP_IEI_3GPP_ACCESS_FORW_ACTION_INFO, "3GPP Access Forwarding Action Information" },
- { OSMO_PFCP_IEI_NON_3GPP_ACCESS_FORW_ACTION_INFO, "Non-3GPP Access Forwarding Action Information" },
- { OSMO_PFCP_IEI_REMOVE_MAR, "Remove MAR" },
- { OSMO_PFCP_IEI_UPD_MAR, "Update MAR" },
- { OSMO_PFCP_IEI_MAR_ID, "MAR ID" },
- { OSMO_PFCP_IEI_STEERING_FUNCTIONALITY, "Steering Functionality" },
- { OSMO_PFCP_IEI_STEERING_MODE, "Steering Mode" },
- { OSMO_PFCP_IEI_WEIGHT, "Weight" },
- { OSMO_PFCP_IEI_PRIORITY, "Priority" },
- { OSMO_PFCP_IEI_UPD_3GPP_ACCESS_FORW_ACTION_INFO, "Update 3GPP Access Forwarding Action Information" },
- { OSMO_PFCP_IEI_UPD_NON_3GPP_ACCESS_FORW_ACTION_INFO, "Update Non 3GPP Access Forwarding Action Information" },
- { OSMO_PFCP_IEI_UE_IP_ADDRESS_POOL_IDENTITY, "UE IP address Pool Identity" },
- { OSMO_PFCP_IEI_ALTERNATIVE_SMF_IP_ADDRESS, "Alternative SMF IP Address" },
- { OSMO_PFCP_IEI_PACKET_REPLICATION_AND_DETECTION_CARRY_ON_INFO, "Packet Replication and Detection Carry-On Information" },
- { OSMO_PFCP_IEI_SMF_SET_ID, "SMF Set ID" },
- { OSMO_PFCP_IEI_QUOTA_VALIDITY_TIME, "Quota Validity Time" },
- { OSMO_PFCP_IEI_NUMBER_OF_REPS, "Number of Reports" },
- { OSMO_PFCP_IEI_PFCP_SESS_RETENTION_INFO_IN_ASSOC_SETUP_REQ, "PFCP Session Retention Information (within PFCP Association Setup Request)" },
- { OSMO_PFCP_IEI_PFCPASRSP_FLAGS, "PFCPASRsp-Flags" },
- { OSMO_PFCP_IEI_CP_ENTITY_IP_ADDRESS, "CP PFCP Entity IP Address" },
- { OSMO_PFCP_IEI_PFCPSEREQ_FLAGS, "PFCPSEReq-Flags" },
- { OSMO_PFCP_IEI_USER_PLANE_PATH_RECOVERY_REP, "User Plane Path Recovery Report" },
- { OSMO_PFCP_IEI_IP_MULTICAST_ADDR_INFO_IN_SESS_EST_REQ, "IP Multicast Addressing Info within PFCP Session Establishment Request" },
- { OSMO_PFCP_IEI_JOIN_IP_MULTICAST_INFO_IE_IN_USAGE_REP, "Join IP Multicast Information IE within Usage Report" },
- { OSMO_PFCP_IEI_LEAVE_IP_MULTICAST_INFO_IE_IN_USAGE_REP, "Leave IP Multicast Information IE within Usage Report" },
- { OSMO_PFCP_IEI_IP_MULTICAST_ADDRESS, "IP Multicast Address" },
- { OSMO_PFCP_IEI_SOURCE_IP_ADDRESS, "Source IP Address" },
- { OSMO_PFCP_IEI_PACKET_RATE_STATUS, "Packet Rate Status" },
- { OSMO_PFCP_IEI_CREATE_BRIDGE_INFO_FOR_TSC, "Create Bridge Info for TSC" },
- { OSMO_PFCP_IEI_CREATED_BRIDGE_INFO_FOR_TSC, "Created Bridge Info for TSC" },
- { OSMO_PFCP_IEI_DS_TT_PORT_NUMBER, "DS-TT Port Number" },
- { OSMO_PFCP_IEI_NW_TT_PORT_NUMBER, "NW-TT Port Number" },
- { OSMO_PFCP_IEI_TSN_BRIDGE_ID, "TSN Bridge ID" },
- { OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_MOD_REQ, "TSC Management Information IE within PFCP Session Modification Request" },
- { OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_MOD_RESP, "TSC Management Information IE within PFCP Session Modification Response" },
- { OSMO_PFCP_IEI_TSC_MGMT_INFO_IE_IN_SESS_REP_REQ, "TSC Management Information IE within PFCP Session Report Request" },
- { OSMO_PFCP_IEI_PORT_MGMT_INFO_CONTAINER, "Port Management Information Container" },
- { OSMO_PFCP_IEI_CLOCK_DRIFT_CTRL_INFO, "Clock Drift Control Information" },
- { OSMO_PFCP_IEI_REQUESTED_CLOCK_DRIFT_INFO, "Requested Clock Drift Information" },
- { OSMO_PFCP_IEI_CLOCK_DRIFT_REP, "Clock Drift Report" },
- { OSMO_PFCP_IEI_TSN_TIME_DOMAIN_NUMBER, "TSN Time Domain Number" },
- { OSMO_PFCP_IEI_TIME_OFFSET_THRESH, "Time Offset Threshold" },
- { OSMO_PFCP_IEI_CUMULATIVE_RATERATIO_THRESH, "Cumulative rateRatio Threshold" },
- { OSMO_PFCP_IEI_TIME_OFFSET_MEAS, "Time Offset Measurement" },
- { OSMO_PFCP_IEI_CUMULATIVE_RATERATIO_MEAS, "Cumulative rateRatio Measurement" },
- { OSMO_PFCP_IEI_REMOVE_SRR, "Remove SRR" },
- { OSMO_PFCP_IEI_CREATE_SRR, "Create SRR" },
- { OSMO_PFCP_IEI_UPD_SRR, "Update SRR" },
- { OSMO_PFCP_IEI_SESS_REP, "Session Report" },
- { OSMO_PFCP_IEI_SRR_ID, "SRR ID" },
- { OSMO_PFCP_IEI_ACCESS_AVAIL_CTRL_INFO, "Access Availability Control Information" },
- { OSMO_PFCP_IEI_REQUESTED_ACCESS_AVAIL_INFO, "Requested Access Availability Information" },
- { OSMO_PFCP_IEI_ACCESS_AVAIL_REP, "Access Availability Report" },
- { OSMO_PFCP_IEI_ACCESS_AVAIL_INFO, "Access Availability Information" },
- { OSMO_PFCP_IEI_PROVIDE_ATSSS_CTRL_INFO, "Provide ATSSS Control Information" },
- { OSMO_PFCP_IEI_ATSSS_CTRL_PARAMS, "ATSSS Control Parameters" },
- { OSMO_PFCP_IEI_MPTCP_CTRL_INFO, "MPTCP Control Information" },
- { OSMO_PFCP_IEI_ATSSS_LL_CTRL_INFO, "ATSSS-LL Control Information" },
- { OSMO_PFCP_IEI_PMF_CTRL_INFO, "PMF Control Information" },
- { OSMO_PFCP_IEI_MPTCP_PARAMS, "MPTCP Parameters" },
- { OSMO_PFCP_IEI_ATSSS_LL_PARAMS, "ATSSS-LL Parameters" },
- { OSMO_PFCP_IEI_PMF_PARAMS, "PMF Parameters" },
- { OSMO_PFCP_IEI_MPTCP_ADDRESS_INFO, "MPTCP Address Information" },
- { OSMO_PFCP_IEI_UE_LINK_SPECIFIC_IP_ADDRESS, "UE Link-Specific IP Address" },
- { OSMO_PFCP_IEI_PMF_ADDRESS_INFO, "PMF Address Information" },
- { OSMO_PFCP_IEI_ATSSS_LL_INFO, "ATSSS-LL Information" },
- { OSMO_PFCP_IEI_DATA_NETWORK_ACCESS_IDENTIFIER, "Data Network Access Identifier" },
- { OSMO_PFCP_IEI_UE_IP_ADDRESS_POOL_INFO, "UE IP address Pool Information" },
- { OSMO_PFCP_IEI_AVERAGE_PACKET_DELAY, "Average Packet Delay" },
- { OSMO_PFCP_IEI_MIN_PACKET_DELAY, "Minimum Packet Delay" },
- { OSMO_PFCP_IEI_MAX_PACKET_DELAY, "Maximum Packet Delay" },
- { OSMO_PFCP_IEI_QOS_REP_TRIGGER, "QoS Report Trigger" },
- { OSMO_PFCP_IEI_GTP_U_PATH_QOS_CTRL_INFO, "GTP-U Path QoS Control Information" },
- { OSMO_PFCP_IEI_GTP_U_PATH_QOS_REP_NODE_REP_REQ, "GTP-U Path QoS Report (PFCP Node Report Request)" },
- { OSMO_PFCP_IEI_QOS_INFO_IN_GTP_U_PATH_QOS_REP, "QoS Information in GTP-U Path QoS Report" },
- { OSMO_PFCP_IEI_GTP_U_PATH_IFACE_TYPE, "GTP-U Path Interface Type" },
- { OSMO_PFCP_IEI_QOS_MONITORING_PER_QOS_FLOW_CTRL_INFO, "QoS Monitoring per QoS flow Control Information" },
- { OSMO_PFCP_IEI_REQUESTED_QOS_MONITORING, "Requested QoS Monitoring" },
- { OSMO_PFCP_IEI_REPORTING_FREQUENCY, "Reporting Frequency" },
- { OSMO_PFCP_IEI_PACKET_DELAY_THRESHOLDS, "Packet Delay Thresholds" },
- { OSMO_PFCP_IEI_MIN_WAIT_TIME, "Minimum Wait Time" },
- { OSMO_PFCP_IEI_QOS_MONITORING_REP, "QoS Monitoring Report" },
- { OSMO_PFCP_IEI_QOS_MONITORING_MEAS, "QoS Monitoring Measurement" },
- { OSMO_PFCP_IEI_MT_EDT_CTRL_INFO, "MT-EDT Control Information" },
- { OSMO_PFCP_IEI_DL_DATA_PACKETS_SIZE, "DL Data Packets Size" },
- { OSMO_PFCP_IEI_QER_CTRL_INDICATIONS, "QER Control Indications" },
- { OSMO_PFCP_IEI_PACKET_RATE_STATUS_REP, "Packet Rate Status Report" },
- { OSMO_PFCP_IEI_NF_INST_ID, "NF Instance ID" },
- { OSMO_PFCP_IEI_ETHERNET_CONTEXT_INFO, "Ethernet Context Information" },
- { OSMO_PFCP_IEI_REDUNDANT_TRANSMISSION_PARAMS, "Redundant Transmission Parameters" },
- { OSMO_PFCP_IEI_UPDATED_PDR, "Updated PDR" },
- { OSMO_PFCP_IEI_S_NSSAI, "S-NSSAI" },
- { OSMO_PFCP_IEI_IP_VERSION, "IP version" },
- { OSMO_PFCP_IEI_PFCPASREQ_FLAGS, "PFCPASReq-Flags" },
- { OSMO_PFCP_IEI_DATA_STATUS, "Data Status" },
- { OSMO_PFCP_IEI_PROVIDE_RDS_CONF_INFO, "Provide RDS configuration information" },
- { OSMO_PFCP_IEI_RDS_CONF_INFO, "RDS configuration information" },
- { OSMO_PFCP_IEI_QUERY_PACKET_RATE_STATUS_IE_IN_SESS_MOD_REQ, "Query Packet Rate Status IE within PFCP Session Modification Request" },
- { OSMO_PFCP_IEI_PACKET_RATE_STATUS_REP_IE_IN_SESS_MOD_RESP, "Packet Rate Status Report IE within PFCP Session Modification Response" },
- { OSMO_PFCP_IEI_MPTCP_APPLICABLE_IND, "MPTCP Applicable Indication" },
- { OSMO_PFCP_IEI_BRIDGE_MGMT_INFO_CONTAINER, "Bridge Management Information Container" },
- { OSMO_PFCP_IEI_UE_IP_ADDRESS_USAGE_INFO, "UE IP Address Usage Information" },
- { OSMO_PFCP_IEI_NUMBER_OF_UE_IP_ADDRS, "Number of UE IP Addresses" },
- { OSMO_PFCP_IEI_VALIDITY_TIMER, "Validity Timer" },
- { OSMO_PFCP_IEI_REDUNDANT_TRANSMISSION_FORW_PARAMS, "Redundant Transmission Forwarding Parameters" },
- { OSMO_PFCP_IEI_TRANSPORT_DELAY_REPORTING, "Transport Delay Reporting" },
- { 0 }
-};
-
-const struct value_string osmo_pfcp_cause_strs[] = {
- { OSMO_PFCP_CAUSE_RESERVED, "0" },
- { OSMO_PFCP_CAUSE_REQUEST_ACCEPTED, "Request accepted (success)" },
- { OSMO_PFCP_CAUSE_MORE_USAGE_REPORT_TO_SEND, "More Usage Report to send" },
- { OSMO_PFCP_CAUSE_REQUEST_REJECTED, "Request rejected (reason not specified)" },
- { OSMO_PFCP_CAUSE_SESSION_CTX_NOT_FOUND, "Session context not found" },
- { OSMO_PFCP_CAUSE_MANDATORY_IE_MISSING, "Mandatory IE missing" },
- { OSMO_PFCP_CAUSE_CONDITIONAL_IE_MISSING, "Conditional IE missing" },
- { OSMO_PFCP_CAUSE_INVALID_LENGTH, "Invalid length" },
- { OSMO_PFCP_CAUSE_MANDATORY_IE_INCORRECT, "Mandatory IE incorrect" },
- { OSMO_PFCP_CAUSE_INVALID_FORW_POLICY, "Invalid Forwarding Policy" },
- { OSMO_PFCP_CAUSE_INVALID_F_TEID_ALLOC_OPTION, "Invalid F-TEID allocation option" },
- { OSMO_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOC, "No established PFCP Association" },
- { OSMO_PFCP_CAUSE_RULE_CREATION_MOD_FAILURE, "Rule creation/modification Failure" },
- { OSMO_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION, "PFCP entity in congestion" },
- { OSMO_PFCP_CAUSE_NO_RESOURCES_AVAILABLE, "No resources available" },
- { OSMO_PFCP_CAUSE_SERVICE_NOT_SUPPORTED, "Service not supported" },
- { OSMO_PFCP_CAUSE_SYSTEM_FAILURE, "System failure" },
- { OSMO_PFCP_CAUSE_REDIRECTION_REQUESTED, "Redirection Requested" },
- { OSMO_PFCP_CAUSE_ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED, "All dynamic addresses are occupied" },
- { 0 }
-};
-
-const struct value_string osmo_pfcp_up_feature_strs[] = {
- { OSMO_PFCP_UP_FEAT_BUCP, "BUCP" },
- { OSMO_PFCP_UP_FEAT_DDND, "DDND" },
- { OSMO_PFCP_UP_FEAT_DLBD, "DLBD" },
- { OSMO_PFCP_UP_FEAT_TRST, "TRST" },
- { OSMO_PFCP_UP_FEAT_FTUP, "FTUP" },
- { OSMO_PFCP_UP_FEAT_PFDM, "PFDM" },
- { OSMO_PFCP_UP_FEAT_HEEU, "HEEU" },
- { OSMO_PFCP_UP_FEAT_TREU, "TREU" },
- { OSMO_PFCP_UP_FEAT_EMPU, "EMPU" },
- { OSMO_PFCP_UP_FEAT_PDIU, "PDIU" },
- { OSMO_PFCP_UP_FEAT_UDBC, "UDBC" },
- { OSMO_PFCP_UP_FEAT_QUOAC, "QUOAC" },
- { OSMO_PFCP_UP_FEAT_TRACE, "TRACE" },
- { OSMO_PFCP_UP_FEAT_FRRT, "FRRT" },
- { OSMO_PFCP_UP_FEAT_PFDE, "PFDE" },
- { OSMO_PFCP_UP_FEAT_EPFAR, "EPFAR" },
- { OSMO_PFCP_UP_FEAT_DPDRA, "DPDRA" },
- { OSMO_PFCP_UP_FEAT_ADPDP, "ADPDP" },
- { OSMO_PFCP_UP_FEAT_UEIP, "UEIP" },
- { OSMO_PFCP_UP_FEAT_SSET, "SSET" },
- { OSMO_PFCP_UP_FEAT_MNOP, "MNOP" },
- { OSMO_PFCP_UP_FEAT_MTE, "MTE" },
- { OSMO_PFCP_UP_FEAT_BUNDL, "BUNDL" },
- { OSMO_PFCP_UP_FEAT_GCOM, "GCOM" },
- { OSMO_PFCP_UP_FEAT_MPAS, "MPAS" },
- { OSMO_PFCP_UP_FEAT_RTTL, "RTTL" },
- { OSMO_PFCP_UP_FEAT_VTIME, "VTIME" },
- { OSMO_PFCP_UP_FEAT_NORP, "NORP" },
- { OSMO_PFCP_UP_FEAT_IP6PL, "IP6PL" },
- { OSMO_PFCP_UP_FEAT_TSCU, "TSCU" },
- { OSMO_PFCP_UP_FEAT_MPTCP, "MPTCP" },
- { OSMO_PFCP_UP_FEAT_ATSSSLL, "ATSSSLL" },
- { OSMO_PFCP_UP_FEAT_QFQM, "QFQM" },
- { OSMO_PFCP_UP_FEAT_GPQM, "GPQM" },
- { OSMO_PFCP_UP_FEAT_MTEDT, "MTEDT" },
- { OSMO_PFCP_UP_FEAT_CIOT, "CIOT" },
- { OSMO_PFCP_UP_FEAT_ETHAR, "ETHAR" },
- { OSMO_PFCP_UP_FEAT_DDDS, "DDDS" },
- { OSMO_PFCP_UP_FEAT_RDS, "RDS" },
- { OSMO_PFCP_UP_FEAT_RTTWP, "RTTWP" },
- {}
-};
-
-
-const struct value_string osmo_pfcp_cp_feature_strs[] = {
- { OSMO_PFCP_CP_FEAT_LOAD, "LOAD" },
- { OSMO_PFCP_CP_FEAT_OVRL, "OVRL" },
- { OSMO_PFCP_CP_FEAT_EPFAR, "EPFAR" },
- { OSMO_PFCP_CP_FEAT_SSET, "SSET" },
- { OSMO_PFCP_CP_FEAT_BUNDL, "BUNDL" },
- { OSMO_PFCP_CP_FEAT_MPAS, "MPAS" },
- { OSMO_PFCP_CP_FEAT_ARDR, "ARDR" },
- { OSMO_PFCP_CP_FEAT_UIAUR, "UIAUR" },
- {}
-};
-
-const struct value_string osmo_pfcp_apply_action_strs[] = {
- { OSMO_PFCP_APPLY_ACTION_DROP, "DROP" },
- { OSMO_PFCP_APPLY_ACTION_FORW, "FORW" },
- { OSMO_PFCP_APPLY_ACTION_BUFF, "BUFF" },
- { OSMO_PFCP_APPLY_ACTION_NOCP, "NOCP" },
- { OSMO_PFCP_APPLY_ACTION_DUPL, "DUPL" },
- { OSMO_PFCP_APPLY_ACTION_IPMA, "IPMA" },
- { OSMO_PFCP_APPLY_ACTION_IPMD, "IPMD" },
- { OSMO_PFCP_APPLY_ACTION_DFRT, "DFRT" },
- { OSMO_PFCP_APPLY_ACTION_EDRT, "EDRT" },
- { OSMO_PFCP_APPLY_ACTION_BDPN, "BDPN" },
- { OSMO_PFCP_APPLY_ACTION_DDPN, "DDPN" },
- {}
-};
-
-const struct value_string osmo_pfcp_outer_header_creation_strs[] = {
- { OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV4, "GTP_U_UDP_IPV4" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_GTP_U_UDP_IPV6, "GTP_U_UDP_IPV6" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV4, "UDP_IPV4" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_UDP_IPV6, "UDP_IPV6" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_IPV4, "IPV4" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_IPV6, "IPV6" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_C_TAG, "C_TAG" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_S_TAG, "S_TAG" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_N19_INDICATION, "N19_INDICATION" },
- { OSMO_PFCP_OUTER_HEADER_CREATION_N6_INDICATION, "N6_INDICATION" },
- {}
-};
-
-const struct value_string osmo_pfcp_outer_header_removal_desc_strs[] = {
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV4, "GTP_U_UDP_IPV4" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV6, "GTP_U_UDP_IPV6" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_UDP_IPV4, "UDP_IPV4" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_UDP_IPV6, "UDP_IPV6" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_IPV4, "IPV4" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_IPV6, "IPV6" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IP, "GTP_U_UDP_IP" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_VLAN_S_TAG, "VLAN_S_TAG" },
- { OSMO_PFCP_OUTER_HEADER_REMOVAL_S_TAG_AND_C_TAG, "S_TAG_AND_C_TAG" },
- {}
-};
-
-const struct value_string osmo_pfcp_source_iface_strs[] = {
- { OSMO_PFCP_SOURCE_IFACE_ACCESS, "Access" },
- { OSMO_PFCP_SOURCE_IFACE_CORE, "Core" },
- { OSMO_PFCP_SOURCE_IFACE_SGI_LAN_N6_LAN, "SGi-LAN/N6-LAN" },
- { OSMO_PFCP_SOURCE_IFACE_CP_FUNCTION, "CP-function" },
- { OSMO_PFCP_SOURCE_IFACE_5G_VN_INTERNAL, "5G-VN-Internal" },
- {}
-};
-
-const struct value_string osmo_pfcp_dest_iface_strs[] = {
- { OSMO_PFCP_DEST_IFACE_ACCESS, "Access" },
- { OSMO_PFCP_DEST_IFACE_CORE, "Core" },
- { OSMO_PFCP_DEST_IFACE_SGI_LAN_N6_LAN, "SGi-LAN/N6-LAN" },
- { OSMO_PFCP_DEST_IFACE_CP_FUNCTION, "CP-function" },
- { OSMO_PFCP_DEST_IFACE_LI_FUNCTION, "LI-function" },
- { OSMO_PFCP_DEST_IFACE_5G_VN_INTERNAL, "5G-VN-Internal" },
- {}
-};
-
-const struct value_string osmo_pfcp_3gpp_iface_type_strs[] = {
- { OSMO_PFCP_3GPP_IFACE_TYPE_S1_U, "S1_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S5_S8_U, "S5_S8_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S4_U, "S4_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S11_U, "S11_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S12_U, "S12_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_GN_GP_U, "GN_GP_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S2A_U, "S2A_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S2B_U, "S2B_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_ENODEB_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING, "ENODEB_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_ENODEB_GTP_U_INTERFACE_FOR_UL_DATA_FORWARDING, "ENODEB_GTP_U_INTERFACE_FOR_UL_DATA_FORWARDING" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_SGW_UPF_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING, "SGW_UPF_GTP_U_INTERFACE_FOR_DL_DATA_FORWARDING" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N3_3GPP_ACCESS, "N3_3GPP_ACCESS" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N3_TRUSTED_NON_3GPP_ACCESS, "N3_TRUSTED_NON_3GPP_ACCESS" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N3_UNTRUSTED_NON_3GPP_ACCESS, "N3_UNTRUSTED_NON_3GPP_ACCESS" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N3_FOR_DATA_FORWARDING, "N3_FOR_DATA_FORWARDING" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N9, "N9" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_SGI, "SGI" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N6, "N6" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_N19, "N19" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_S8_U, "S8_U" },
- { OSMO_PFCP_3GPP_IFACE_TYPE_GP_U, "GP_U" },
- {}
-};
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fad7e6c..66510f0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,3 @@
-SUBDIRS = \
- libosmo-pfcp \
- $(NULL)
-
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
:;{ \
diff --git a/tests/libosmo-pfcp/Makefile.am b/tests/libosmo-pfcp/Makefile.am
deleted file mode 100644
index eba3aa4..0000000
--- a/tests/libosmo-pfcp/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
-AM_CPPFLAGS = \
- $(all_includes) \
- -I$(top_srcdir)/include \
- -I$(top_builddir)/include \
- $(NULL)
-
-AM_CFLAGS = \
- -Wall \
- $(LIBOSMOCORE_CFLAGS) \
- $(LIBOSMOGTLV_CFLAGS) \
- $(NULL)
-
-noinst_PROGRAMS = \
- pfcp_test \
- $(NULL)
-
-EXTRA_DIST = \
- pfcp_test.ok \
- $(NULL)
-
-pfcp_test_SOURCES = \
- pfcp_test.c \
- $(NULL)
-
-pfcp_test_LDADD = \
- $(top_builddir)/src/libosmo-pfcp/libosmo-pfcp.a \
- $(LIBOSMOCORE_LIBS) \
- $(LIBOSMOGTLV_LIBS) \
- $(NULL)
-
-.PHONY: update_exp
-update_exp:
- $(builddir)/pfcp_test >$(srcdir)/pfcp_test.ok
diff --git a/tests/libosmo-pfcp/pfcp_test.c b/tests/libosmo-pfcp/pfcp_test.c
deleted file mode 100644
index 189622e..0000000
--- a/tests/libosmo-pfcp/pfcp_test.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * (C) 2021-2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
- * All Rights Reserved.
- *
- * Author: Neels Janosch Hofmeyr <nhofmeyr@sysmocom.de>
- *
- * SPDX-License-Identifier: GPL-2.0+
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdio.h>
-#include <errno.h>
-
-#include <osmocom/core/application.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/msgb.h>
-
-#include <osmocom/pfcp/pfcp_msg.h>
-
-void *ctx;
-
-/* struct osmo_sockaddr */
-#define v4_ue { \
- .u.sin = { \
- .sin_family = AF_INET, \
- .sin_addr = { 0x1700a8c0 }, \
- } \
-}
-
-/* struct osmo_sockaddr */
-#define v4_gtp { \
- .u.sin = { \
- .sin_family = AF_INET, \
- .sin_addr = { 0x0708090a }, \
- } \
-}
-
-/* struct osmo_pfcp_ie_f_teid */
-#define f_teid_access_local { \
- .choose_flag = true, \
- .choose = { \
- .ipv4_addr = true, \
- }, \
-}
-
-/* struct osmo_pfcp_ie_f_teid */
-#define f_teid_created { \
- .fixed = { \
- .teid = 1234, \
- .ip_addr = { \
- .v4_present = true, \
- .v4 = v4_gtp, \
- }, \
- }, \
-}
-
-/* struct osmo_pfcp_ie_outer_header_creation */
-#define ohc_access { \
- .desc_bits = { 0x01 }, \
- .teid_present = true, \
- .teid = 0xabcdef, \
- .ip_addr = { \
- .v4_present = true, \
- .v4 = v4_gtp, \
- }, \
-}
-
-/* struct osmo_pfcp_ie_apply_action */
-#define aa_forw { \
- .bits = { 0x02 }, \
-}
-
-/* struct osmo_pfcp_ie_f_seid */
-#define f_seid { \
- .seid = 0x1234567890abcdef, \
- .ip_addr = { \
- .v4_present = true, \
- .v4 = v4_gtp, \
- }, \
-}
-
-struct osmo_pfcp_msg tests[] = {
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_HEARTBEAT_REQ,
- .sequence_nr = 1,
- },
- .ies.heartbeat_req = {
- .recovery_time_stamp = 1234,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_HEARTBEAT_RESP,
- .sequence_nr = 2,
- },
- .ies.heartbeat_resp = {
- .recovery_time_stamp = 5678,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_ASSOC_SETUP_REQ,
- .sequence_nr = 3,
- },
- .ies.assoc_setup_req = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_IPV4,
- .ip.u.sin = {
- .sin_family = AF_INET,
- .sin_addr = { 0x01020304 },
- },
- },
- .recovery_time_stamp = 0x2b2b2b2b,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_ASSOC_SETUP_RESP,
- .sequence_nr = 4,
- },
- .ies.assoc_setup_resp = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_FQDN,
- .fqdn = "example.com",
- },
- .cause = OSMO_PFCP_CAUSE_REQUEST_ACCEPTED,
- .recovery_time_stamp = 0x2b2b2b2b,
- .up_function_features_present = true,
- .up_function_features.bits = { 1, 2 },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_ASSOC_RELEASE_REQ,
- .sequence_nr = 5,
- },
- .ies.assoc_release_req = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_IPV6,
- .ip.u.sin6 = {
- .sin6_family = AF_INET6,
- .sin6_addr = {{{ 1, 2, 3, 4 }}},
- },
- },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_ASSOC_RELEASE_RESP,
- .sequence_nr = 6,
- },
- .ies.assoc_release_resp = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_IPV4,
- .ip.u.sin = {
- .sin_family = AF_INET,
- .sin_addr = { 0x01020304 },
- },
- },
- .cause = OSMO_PFCP_CAUSE_REQUEST_REJECTED,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_EST_REQ,
- .sequence_nr = 7,
- .seid_present = true,
- .seid = 0,
- },
- .ies.session_est_req = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_IPV4,
- .ip.u.sin = {
- .sin_family = AF_INET,
- .sin_addr = { 0x0100007f },
- },
- },
- .cp_f_seid_present = true,
- .cp_f_seid = f_seid,
- .create_pdr_count = 2,
- .create_pdr = {
- {
- .pdr_id = 1,
- .precedence = 255,
- .pdi = {
- .source_iface = OSMO_PFCP_SOURCE_IFACE_CORE,
- .ue_ip_address_present = true,
- .ue_ip_address = {
- .ip_is_destination = true,
- .ip_addr = {
- .v4_present = true,
- .v4 = v4_ue,
- },
- },
- },
- .far_id_present = true,
- .far_id = 1,
- },
- {
- .pdr_id = 2,
- .precedence = 255,
- .pdi = {
- .source_iface = OSMO_PFCP_SOURCE_IFACE_ACCESS,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_access_local,
- },
- .outer_header_removal_present = true,
- .outer_header_removal = {
- .desc = OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV4,
- },
- .far_id_present = true,
- .far_id = 2,
- },
- },
- .create_far_count = 2,
- .create_far = {
- {
- .far_id = 1,
- .forw_params_present = true,
- .forw_params = {
- .destination_iface = OSMO_PFCP_DEST_IFACE_ACCESS,
- .outer_header_creation_present = true,
- .outer_header_creation = ohc_access,
- },
- .apply_action = aa_forw,
- },
- {
- .far_id = 2,
- .forw_params_present = true,
- .forw_params = {
- .destination_iface = OSMO_PFCP_DEST_IFACE_CORE,
- },
- .apply_action = aa_forw,
- },
- },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_EST_RESP,
- .sequence_nr = 8,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- .ies.session_est_resp = {
- .node_id = {
- .type = OSMO_PFCP_NODE_ID_T_IPV4,
- .ip.u.sin = {
- .sin_family = AF_INET,
- .sin_addr = { 0x0200007f },
- },
- },
- .cause = OSMO_PFCP_CAUSE_REQUEST_ACCEPTED,
- .up_f_seid_present = true,
- .up_f_seid = f_seid,
- .created_pdr_count = 2,
- .created_pdr = {
- {
- .pdr_id = 1,
- },
- {
- .pdr_id = 2,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_created,
- },
- },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_MOD_REQ,
- .sequence_nr = 9,
- .seid_present = true,
- .seid = 0,
- },
- .ies.session_mod_req = {
- .remove_pdr_count = 1,
- .remove_pdr = {
- {
- .pdr_id = 1,
- },
- },
- .remove_far_count = 1,
- .remove_far = {
- {
- .far_id = 1,
- },
- },
- .create_pdr_count = 1,
- .create_pdr = {
- {
- .pdr_id = 3,
- .precedence = 255,
- .pdi = {
- .source_iface = OSMO_PFCP_SOURCE_IFACE_ACCESS,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_access_local,
- },
- .outer_header_removal_present = true,
- .outer_header_removal = {
- .desc = OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV4,
- },
- .far_id_present = true,
- .far_id = 3,
- },
- },
- .create_far_count = 1,
- .create_far = {
- {
- .far_id = 3,
- .forw_params_present = true,
- .forw_params = {
- .destination_iface = OSMO_PFCP_DEST_IFACE_ACCESS,
- .outer_header_creation_present = true,
- .outer_header_creation = ohc_access,
- },
- .apply_action = aa_forw,
- },
- },
- .upd_pdr_count = 1,
- .upd_pdr = {
- {
- .pdr_id = 1,
- .pdi = {
- .source_iface = OSMO_PFCP_SOURCE_IFACE_ACCESS,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_access_local,
- },
- .outer_header_removal_present = true,
- .outer_header_removal = {
- .desc = OSMO_PFCP_OUTER_HEADER_REMOVAL_GTP_U_UDP_IPV4,
- },
- .far_id_present = true,
- .far_id = 1,
- },
- },
- .upd_far_count = 1,
- .upd_far = {
- {
- .far_id = 1,
- .upd_forw_params_present = true,
- .upd_forw_params = {
- .destination_iface = OSMO_PFCP_DEST_IFACE_CORE,
- .network_inst_present = true,
- .network_inst = {
- .str = "internet",
- },
- },
- .apply_action = aa_forw,
- },
- },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_MOD_RESP,
- .sequence_nr = 10,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- .ies.session_mod_resp = {
- .cause = OSMO_PFCP_CAUSE_REQUEST_ACCEPTED,
- .created_pdr_count = 1,
- .created_pdr = {
- {
- .pdr_id = 3,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_created,
- },
- },
- .updated_pdr_count = 1,
- .updated_pdr = {
- {
- .pdr_id = 1,
- .local_f_teid_present = true,
- .local_f_teid = f_teid_created,
- },
- },
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_MOD_RESP,
- .sequence_nr = 11,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- .ies.session_mod_resp = {
- .cause = OSMO_PFCP_CAUSE_MANDATORY_IE_MISSING,
- .offending_ie_present = true,
- .offending_ie = OSMO_PFCP_IEI_APPLY_ACTION,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_DEL_REQ,
- .sequence_nr = 12,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_DEL_RESP,
- .sequence_nr = 13,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- .ies.session_del_resp = {
- .cause = OSMO_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOC,
- },
- },
- {
- .h = {
- .version = 1,
- .message_type = OSMO_PFCP_MSGT_SESSION_DEL_RESP,
- .sequence_nr = 13,
- .seid_present = true,
- .seid = 0x0123456789abcdef,
- },
- .ies.session_del_resp = {
- .cause = OSMO_PFCP_CAUSE_REQUEST_ACCEPTED,
- },
- },
-};
-
-void test_enc_dec()
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(tests); i++) {
- void *loop_ctx = talloc_named_const(ctx, 0, "loop");
- int rc;
- const struct osmo_pfcp_msg *orig = &tests[i];
- struct osmo_pfcp_msg parsed = {};
- struct msgb *msg;
- struct osmo_gtlv_load tlv;
-
- printf("\n=== start %s[%d]\n", __func__, i);
- printf("encoding: %s\n", osmo_pfcp_message_type_str(orig->h.message_type));
- printf("%s\n", osmo_pfcp_msg_to_str_c(loop_ctx, orig));
- msg = msgb_alloc(1024, __func__);
- rc = osmo_pfcp_msg_encode(msg, orig);
- printf("osmo_pfcp_msg_encode() rc = %d\n", rc);
- printf("%s.\n", osmo_hexdump(msg->data, msg->len));
-
- rc = osmo_pfcp_msg_decode_header(&tlv, &parsed, msg);
- printf("osmo_pfcp_msg_decode_header() rc = %d\n", rc);
- if (rc != msgb_length(msg)) {
- printf("ERROR: expected rc = %d\n", msgb_length(msg));
- exit(1);
- } else {
- printf("rc == msgb_length()\n");
- }
-
- rc = osmo_pfcp_msg_decode_tlv(&parsed, &tlv);
- printf("osmo_pfcp_msg_decode_tlv() rc = %d\n", rc);
-
- if (strcmp(osmo_pfcp_msg_to_str_c(loop_ctx, orig),
- osmo_pfcp_msg_to_str_c(loop_ctx, &parsed))) {
- printf(" ERROR: parsed != orig\n");
- printf(" orig: %s\n",
- osmo_pfcp_msg_to_str_c(loop_ctx, orig));
- printf(" parsed: %s\n",
- osmo_pfcp_msg_to_str_c(loop_ctx, &parsed));
- exit(1);
- } else {
- printf("parsed == orig\n");
- }
-
- msgb_free(msg);
- printf("=== end %s[%d]\n", __func__, i);
- talloc_free(loop_ctx);
- }
-}
-
-int main()
-{
- ctx = talloc_named_const(NULL, 0, "pfcp_test");
- msgb_talloc_ctx_init(ctx, 0);
-
- test_enc_dec();
-
- talloc_free(ctx);
- return 0;
-}
diff --git a/tests/libosmo-pfcp/pfcp_test.ok b/tests/libosmo-pfcp/pfcp_test.ok
deleted file mode 100644
index 2b8cc1a..0000000
--- a/tests/libosmo-pfcp/pfcp_test.ok
+++ /dev/null
@@ -1,154 +0,0 @@
-
-=== start test_enc_dec[0]
-encoding: HEARTBEAT_REQ
-PFCPv1 HEARTBEAT_REQ hdr={seq=1} ies={ 'Recovery Time Stamp'=1234 }
-osmo_pfcp_msg_encode() rc = 0
-20 01 00 0c 00 00 01 00 00 60 00 04 00 00 04 d2 .
-osmo_pfcp_msg_decode_header() rc = 16
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[0]
-
-=== start test_enc_dec[1]
-encoding: HEARTBEAT_RESP
-PFCPv1 HEARTBEAT_RESP hdr={seq=2} ies={ 'Recovery Time Stamp'=5678 }
-osmo_pfcp_msg_encode() rc = 0
-20 02 00 0c 00 00 02 00 00 60 00 04 00 00 16 2e .
-osmo_pfcp_msg_decode_header() rc = 16
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[1]
-
-=== start test_enc_dec[2]
-encoding: ASSOC_SETUP_REQ
-PFCPv1 ASSOC_SETUP_REQ hdr={seq=3} ies={ 'Node ID'=v4:4.3.2.1 'Recovery Time Stamp'=724249387 }
-osmo_pfcp_msg_encode() rc = 0
-20 05 00 15 00 00 03 00 00 3c 00 05 00 04 03 02 01 00 60 00 04 2b 2b 2b 2b .
-osmo_pfcp_msg_decode_header() rc = 25
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[2]
-
-=== start test_enc_dec[3]
-encoding: ASSOC_SETUP_RESP
-PFCPv1 ASSOC_SETUP_RESP hdr={seq=4} ies={ 'Node ID'=fqdn:"example.com" 'Cause'=Request accepted (success) 'Recovery Time Stamp'=724249387 'UP Function Features'=( BUCP PDIU ) }
-osmo_pfcp_msg_encode() rc = 0
-20 06 00 2b 00 00 04 00 00 3c 00 0c 02 65 78 61 6d 70 6c 65 2e 63 6f 6d 00 13 00 01 01 00 60 00 04 2b 2b 2b 2b 00 2b 00 06 01 02 00 00 00 00 .
-osmo_pfcp_msg_decode_header() rc = 47
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[3]
-
-=== start test_enc_dec[4]
-encoding: ASSOC_RELEASE_REQ
-PFCPv1 ASSOC_RELEASE_REQ hdr={seq=5} ies={ 'Node ID'=v6:[102:304::] }
-osmo_pfcp_msg_encode() rc = 0
-20 09 00 19 00 00 05 00 00 3c 00 11 01 01 02 03 04 00 00 00 00 00 00 00 00 00 00 00 00 .
-osmo_pfcp_msg_decode_header() rc = 29
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[4]
-
-=== start test_enc_dec[5]
-encoding: ASSOC_RELEASE_RESP
-PFCPv1 ASSOC_RELEASE_RESP hdr={seq=6} ies={ 'Node ID'=v4:4.3.2.1 'Cause'=Request rejected (reason not specified) }
-osmo_pfcp_msg_encode() rc = 0
-20 0a 00 12 00 00 06 00 00 3c 00 05 00 04 03 02 01 00 13 00 01 40 .
-osmo_pfcp_msg_decode_header() rc = 22
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[5]
-
-=== start test_enc_dec[6]
-encoding: SESSION_EST_REQ
-PFCPv1 SESSION_EST_REQ hdr={seq=7 SEID=0x0} ies={ 'Node ID'=v4:127.0.0.1 'F-SEID'=0x1234567890abcdef,v4:10.9.8.7 'Create PDR'={ { 'PDR ID'=1 'Precedence'=255 'PDI'={ 'Source Interface'=Core 'UE IP Address'=,dst,v4:192.168.0.23 } 'FAR ID'=1 }, { 'PDR ID'=2 'Precedence'=255 'PDI'={ 'Source Interface'=Access 'F-TEID'=CHOOSE-v4 } 'Outer Header Removal'=GTP_U_UDP_IPV4 'FAR ID'=2 } } 'Create FAR'={ { 'FAR ID'=1 'Apply Action'=( FORW ) 'Forwarding Parameters'={ 'Destination Interface'=Access 'Outer Header Creation'=( GTP_U_UDP_IPV4 ),TEID:0xabcdef,v4:10.9.8.7 } }, { 'FAR ID'=2 'Apply Action'=( FORW ) 'Forwarding Parameters'={ 'Destination Interface'=Core } } } }
-osmo_pfcp_msg_encode() rc = 0
-21 32 00 c3 00 00 00 00 00 00 00 00 00 00 07 00 00 3c 00 05 00 7f 00 00 01 00 39 00 0d 02 12 34 56 78 90 ab cd ef 0a 09 08 07 00 01 00 28 00 38 00 02 00 01 00 1d 00 04 00 00 00 ff 00 02 00 0e 00 14 00 01 01 00 5d 00 05 06 c0 a8 00 17 00 6c 00 04 00 00 00 01 00 01 00 29 00 38 00 02 00 02 00 1d 00 04 00 00 00 ff 00 02 00 0a 00 14 00 01 00 00 15 00 01 05 00 5f 00 01 00 00 6c 00 04 00 00 00 02 00 03 00 25 00 6c 00 04 00 00 00 01 00 2c 00 02 02 00 00 04 00 13 00 2a 00 01 00 00 54 00 0a 01 00 00 ab cd ef 0a 09 08 07 00 03 00 17 00 6c 00 04 00 00 00 02 00 2c 00 02 02 00 00 04 00 05 00 2a 00 01 01 .
-osmo_pfcp_msg_decode_header() rc = 199
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[6]
-
-=== start test_enc_dec[7]
-encoding: SESSION_EST_RESP
-PFCPv1 SESSION_EST_RESP hdr={seq=8 SEID=0x123456789abcdef} ies={ 'Node ID'=v4:127.0.0.2 'Cause'=Request accepted (success) 'F-SEID'=0x1234567890abcdef,v4:10.9.8.7 'Created PDR'={ { 'PDR ID'=1 }, { 'PDR ID'=2 'F-TEID'=TEID-0x4d2,v4:10.9.8.7 } } }
-osmo_pfcp_msg_encode() rc = 0
-21 33 00 4c 01 23 45 67 89 ab cd ef 00 00 08 00 00 3c 00 05 00 7f 00 00 02 00 13 00 01 01 00 39 00 0d 02 12 34 56 78 90 ab cd ef 0a 09 08 07 00 08 00 06 00 38 00 02 00 01 00 08 00 13 00 38 00 02 00 02 00 15 00 09 01 00 00 04 d2 0a 09 08 07 .
-osmo_pfcp_msg_decode_header() rc = 80
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[7]
-
-=== start test_enc_dec[8]
-encoding: SESSION_MOD_REQ
-PFCPv1 SESSION_MOD_REQ hdr={seq=9 SEID=0x0} ies={ 'Remove PDR'={ { 'PDR ID'=1 } } 'Remove FAR'={ { 'FAR ID'=1 } } 'Create PDR'={ { 'PDR ID'=3 'Precedence'=255 'PDI'={ 'Source Interface'=Access 'F-TEID'=CHOOSE-v4 } 'Outer Header Removal'=GTP_U_UDP_IPV4 'FAR ID'=3 } } 'Create FAR'={ { 'FAR ID'=3 'Apply Action'=( FORW ) 'Forwarding Parameters'={ 'Destination Interface'=Access 'Outer Header Creation'=( GTP_U_UDP_IPV4 ),TEID:0xabcdef,v4:10.9.8.7 } } } 'Update PDR'={ { 'PDR ID'=1 'Outer Header Removal'=GTP_U_UDP_IPV4 'FAR ID'=1 } } 'Update FAR'={ { 'FAR ID'=1 'Update Forwarding Parameters'={ 'Network Instance'="internet" } } } }
-osmo_pfcp_msg_encode() rc = 0
-21 34 00 ab 00 00 00 00 00 00 00 00 00 00 09 00 00 0f 00 06 00 38 00 02 00 01 00 10 00 08 00 6c 00 04 00 00 00 01 00 01 00 29 00 38 00 02 00 03 00 1d 00 04 00 00 00 ff 00 02 00 0a 00 14 00 01 00 00 15 00 01 05 00 5f 00 01 00 00 6c 00 04 00 00 00 03 00 03 00 25 00 6c 00 04 00 00 00 03 00 2c 00 02 02 00 00 04 00 13 00 2a 00 01 00 00 54 00 0a 01 00 00 ab cd ef 0a 09 08 07 00 09 00 13 00 38 00 02 00 01 00 5f 00 01 00 00 6c 00 04 00 00 00 01 00 0a 00 18 00 6c 00 04 00 00 00 01 00 0b 00 0c 00 16 00 08 69 6e 74 65 72 6e 65 74 .
-osmo_pfcp_msg_decode_header() rc = 175
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[8]
-
-=== start test_enc_dec[9]
-encoding: SESSION_MOD_RESP
-PFCPv1 SESSION_MOD_RESP hdr={seq=10 SEID=0x123456789abcdef} ies={ 'Cause'=Request accepted (success) 'Created PDR'={ { 'PDR ID'=3 'F-TEID'=TEID-0x4d2,v4:10.9.8.7 } } 'Updated PDR'={ { 'PDR ID'=1 'F-TEID'=TEID-0x4d2,v4:10.9.8.7 } } }
-osmo_pfcp_msg_encode() rc = 0
-21 35 00 3f 01 23 45 67 89 ab cd ef 00 00 0a 00 00 13 00 01 01 00 08 00 13 00 38 00 02 00 03 00 15 00 09 01 00 00 04 d2 0a 09 08 07 01 00 00 13 00 38 00 02 00 01 00 15 00 09 01 00 00 04 d2 0a 09 08 07 .
-osmo_pfcp_msg_decode_header() rc = 67
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[9]
-
-=== start test_enc_dec[10]
-encoding: SESSION_MOD_RESP
-PFCPv1 SESSION_MOD_RESP hdr={seq=11 SEID=0x123456789abcdef} ies={ 'Cause'=Mandatory IE missing 'Offending IE'=Apply Action }
-osmo_pfcp_msg_encode() rc = 0
-21 35 00 17 01 23 45 67 89 ab cd ef 00 00 0b 00 00 13 00 01 42 00 28 00 02 00 2c .
-osmo_pfcp_msg_decode_header() rc = 27
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[10]
-
-=== start test_enc_dec[11]
-encoding: SESSION_DEL_REQ
-PFCPv1 SESSION_DEL_REQ hdr={seq=12 SEID=0x123456789abcdef} ies={ }
-osmo_pfcp_msg_encode() rc = 0
-21 36 00 0c 01 23 45 67 89 ab cd ef 00 00 0c 00 .
-osmo_pfcp_msg_decode_header() rc = 16
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[11]
-
-=== start test_enc_dec[12]
-encoding: SESSION_DEL_RESP
-PFCPv1 SESSION_DEL_RESP hdr={seq=13 SEID=0x123456789abcdef} ies={ 'Cause'=No established PFCP Association }
-osmo_pfcp_msg_encode() rc = 0
-21 37 00 11 01 23 45 67 89 ab cd ef 00 00 0d 00 00 13 00 01 48 .
-osmo_pfcp_msg_decode_header() rc = 21
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[12]
-
-=== start test_enc_dec[13]
-encoding: SESSION_DEL_RESP
-PFCPv1 SESSION_DEL_RESP hdr={seq=13 SEID=0x123456789abcdef} ies={ 'Cause'=Request accepted (success) }
-osmo_pfcp_msg_encode() rc = 0
-21 37 00 11 01 23 45 67 89 ab cd ef 00 00 0d 00 00 13 00 01 01 .
-osmo_pfcp_msg_decode_header() rc = 21
-rc == msgb_length()
-osmo_pfcp_msg_decode_tlv() rc = 0
-parsed == orig
-=== end test_enc_dec[13]
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 352fba9..09a77c3 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -1,8 +1,2 @@
AT_INIT
AT_BANNER([Regression tests.])
-
-AT_SETUP([pfcp])
-AT_KEYWORDS([pfcp])
-cat $abs_srcdir/libosmo-pfcp/pfcp_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/libosmo-pfcp/pfcp_test], [], [expout], [ignore])
-AT_CLEANUP

null

To view, visit change 28306. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmo-upf
Gerrit-Branch: master
Gerrit-Change-Id: I1464cdd846b00707b0abba9126aa5bb784b7caf1
Gerrit-Change-Number: 28306
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged