arehbein has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmo-netif/+/33652 )


Change subject: ipa: Add segmentation callback
......................................................................

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 https://gerrit.osmocom.org/c/libosmo-netif/+/33652
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Change-Id: I87ef4c7023126b783dd79e7ed47be31e1b76f975
Gerrit-Change-Number: 33652
Gerrit-PatchSet: 1
Gerrit-Owner: arehbein <[email protected]>
Gerrit-MessageType: newchange

Reply via email to