arehbein has uploaded this change for review.

View Change

ipa: Add segmentation callback

Also: Add helper functions used in later commits

Related: OS#5753
Change-Id: I87ef4c7023126b783dd79e7ed47be31e1b76f975
---
M include/osmocom/netif/ipa.h
M src/ipa.c
2 files changed, 101 insertions(+), 0 deletions(-)

git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/52/33652/1
diff --git a/include/osmocom/netif/ipa.h b/include/osmocom/netif/ipa.h
index 0d1085f..12358ba 100644
--- a/include/osmocom/netif/ipa.h
+++ b/include/osmocom/netif/ipa.h
@@ -19,6 +19,8 @@
} __attribute__ ((packed));

struct msgb *osmo_ipa_msg_alloc(int headroom);
+struct msgb *osmo_ipa_ext_msg_alloc(int headroom);
+
void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto);

int osmo_ipa_process_msg(struct msgb *msg);
diff --git a/src/ipa.c b/src/ipa.c
index 197a47f..33801af 100644
--- a/src/ipa.c
+++ b/src/ipa.c
@@ -33,6 +33,7 @@

#include <osmocom/netif/ipa.h>
#include <osmocom/netif/ipa_unit.h>
+#include <osmocom/netif/stream.h>

#define IPA_ALLOC_SIZE 1200

@@ -97,6 +98,11 @@
return msg;
}

+struct msgb *osmo_ipa_ext_msg_alloc(int headroom)
+{
+ return osmo_ipa_msg_alloc(sizeof(struct ipa_head_ext) + headroom);
+}
+
void osmo_ipa_msg_push_header(struct msgb *msg, uint8_t proto)
{
struct ipa_head *hh;
@@ -366,3 +372,84 @@

return 0;
}
+
+#define MSG_CB_IPA_PROTO_OFFSET 0
+/* Used in case of IPAC_PROTO_OSMO */
+#define MSG_CB_IPA_PROTO_EXT_IS_SET_OFFSET 1
+#define MSG_CB_IPA_PROTO_EXT_OFFSET 2
+
+/* Check and remove headers (in case of p == IPAC_PROTO_OSMO, also the IPA extension header).
+ * Returns a negative number on error, otherwise zero */
+static inline int ipa_check_pull_headers(struct msgb *msg)
+{
+ int ret;
+ msg->l1h = msg->data;
+ struct ipa_head *ih = (struct ipa_head *)msg->data;
+ memset(msg->cb, 0, sizeof(msg->cb));
+ msg->cb[MSG_CB_IPA_PROTO_OFFSET] = ih->proto;
+ if ((ret = osmo_ipa_process_msg(msg)) < 0) {
+ LOGP(DLINP, LOGL_ERROR, "Error processing IPA message\n");
+ return -EIO;
+ }
+ msgb_pull(msg, sizeof(struct ipa_head));
+ msg->l2h = msg->data;
+ msg->cb[MSG_CB_IPA_PROTO_EXT_IS_SET_OFFSET] = true;
+ msg->cb[MSG_CB_IPA_PROTO_EXT_OFFSET] = msg->data[0];
+ if (ih->proto != IPAC_PROTO_OSMO)
+ return 0;
+ msgb_pull(msg, sizeof(struct ipa_head_ext));
+ return 0;
+}
+
+/*! Segmentation callback used by libosmo-netif streaming backend
+ * See definition of `struct osmo_io_ops` for callback semantics
+ * \param[out] msg Original `struct msgb` received via osmo_io
+ * \returns The total packet length indicated by the first header,
+ * otherwise
+ * -EAGAIN, if the header has not been read yet,
+ * -ENOBUFS, if the header declares a payload too large
+ */
+int osmo_ipa_segmentation_cb(struct msgb *msg)
+{
+ const struct ipaccess_head *hh = (const struct ipaccess_head *) msg->data;
+ size_t payload_len, total_len;
+ size_t available = msgb_length(msg) + msgb_tailroom(msg);
+ if (msgb_length(msg) < sizeof(*hh)) {
+ /* Haven't even read the entire header */
+ return -EAGAIN;
+ }
+ payload_len = osmo_ntohs(hh->len);
+ total_len = sizeof(*hh) + payload_len;
+ if (OSMO_UNLIKELY(available < total_len)) {
+ LOGP(DLINP, LOGL_ERROR, "Not enough space left in message buffer. "
+ "Have %zu octets, but need %zu\n",
+ available, total_len);
+ return -ENOBUFS;
+ }
+ return total_len;
+}
+
+/* Below: Helper functions for addition of send_ipa functionality in later commit */
+static inline enum ipaccess_proto msg_get_ipa_proto(struct msgb *msg)
+{
+ return msg->cb[MSG_CB_IPA_PROTO_OFFSET];
+}
+
+/* Returns the protocol extension (enum ipaccess_proto) or -ENOPROTOOPT if
+ * we don't have IPAC_PROTO_OSMO specified in the IPA header */
+static inline int msg_get_ipa_proto_ext(struct msgb *msg)
+{
+ if (!msg->cb[MSG_CB_IPA_PROTO_EXT_IS_SET_OFFSET])
+ return -ENOPROTOOPT;
+ return msg->cb[MSG_CB_IPA_PROTO_EXT_OFFSET];
+}
+
+/* Push IPA headers; if we have IPAC_PROTO_OSMO this also takes care of the
+ * extension header */
+static inline void ipa_push_headers(enum ipaccess_proto p, enum ipaccess_proto_ext pe,
+ struct msgb *msg)
+{
+ if (p == IPAC_PROTO_OSMO)
+ ipa_prepend_header_ext(msg, pe);
+ osmo_ipa_msg_push_header(msg, p);
+}

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

Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I87ef4c7023126b783dd79e7ed47be31e1b76f975
Gerrit-Change-Number: 33652
Gerrit-PatchSet: 1
Gerrit-Owner: arehbein <arehbein@sysmocom.de>
Gerrit-MessageType: newchange