[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v5 03/11] lib/uknetdev: Netbuf chaining
Introduce functions for creating and operating netbuf chains. With this, network packet data that is scattered in memory can be described. Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> Reviewed-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx> --- lib/uknetdev/exportsyms.uk | 3 ++ lib/uknetdev/include/uk/netbuf.h | 80 ++++++++++++++++++++++++++++++++++++++++ lib/uknetdev/netbuf.c | 53 ++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) diff --git a/lib/uknetdev/exportsyms.uk b/lib/uknetdev/exportsyms.uk index 5473bba..3153a5d 100644 --- a/lib/uknetdev/exportsyms.uk +++ b/lib/uknetdev/exportsyms.uk @@ -2,3 +2,6 @@ uk_netbuf_init_indir uk_netbuf_alloc_indir uk_netbuf_alloc_buf uk_netbuf_prepare_buf +uk_netbuf_disconnect +uk_netbuf_connect +uk_netbuf_append diff --git a/lib/uknetdev/include/uk/netbuf.h b/lib/uknetdev/include/uk/netbuf.h index 551793a..c0cbb4a 100644 --- a/lib/uknetdev/include/uk/netbuf.h +++ b/lib/uknetdev/include/uk/netbuf.h @@ -121,6 +121,17 @@ struct uk_netbuf { struct uk_alloc *_a; /**< @internal Allocator for free'ing */ }; +/* + * Iterator helpers for netbuf chains + */ +/* head -> tail */ +#define UK_NETBUF_CHAIN_FOREACH(var, head) \ + for ((var) = (head); (var) != NULL; (var) = (var)->next) + +/* tail -> head (reverse) */ +#define UK_NETBUF_CHAIN_FOREACH_R(var, tail) \ + for ((var) = (tail); (var) != NULL; (var) = (var)->prev) + /** * Initializes an external allocated netbuf. * This netbuf has no data area assigned. It is intended @@ -282,6 +293,75 @@ struct uk_netbuf *uk_netbuf_prepare_buf(void *mem, size_t size, uint16_t headroom, size_t privlen, uk_netbuf_dtor_t dtor); +/** + * Retrieves the last element of a netbuf chain + * @param m + * uk_netbuf that is part of a chain + * @returns + * Last uk_netbuf of the chain + */ +#define uk_netbuf_chain_last(m) \ + ({ \ + struct uk_netbuf *__ret = NULL; \ + struct uk_netbuf *__iter; \ + UK_NETBUF_CHAIN_FOREACH(__iter, (m)) \ + __ret = __iter; \ + \ + (__ret); \ + }) + +/** + * Retrieves the first element of a netbuf chain + * @param m + * uk_netbuf that is part of a chain + * @returns + * First uk_netbuf of the chain + */ +#define uk_netbuf_chain_first(m) \ + ({ \ + struct uk_netbuf *__ret = NULL; \ + struct uk_netbuf *__iter; \ + UK_NETBUF_CHAIN_FOREACH_R(__iter, (m)) \ + __ret = __iter; \ + \ + (__ret); \ + }) + +/** + * Connects two netbuf chains + * @param headtail + * Last netbuf element of chain that should come first. + * It can also be just a single netbuf. + * @param tail + * Head element of the second netbuf chain. + * It can also be just a single netbuf. + */ +void uk_netbuf_connect(struct uk_netbuf *headtail, + struct uk_netbuf *tail); + +/** + * Connects two netbuf chains + * @param head + * Heading netbuf element of chain that should come first. + * It can also be just a single netbuf. + * @param tail + * Head element of the second netbuf chain. + * It can also be just a single netbuf. + */ +void uk_netbuf_append(struct uk_netbuf *head, + struct uk_netbuf *tail); + +/** + * Disconnects a netbuf from its chain. The chain will remain + * without the removed element. + * @param m + * uk_netbuf to be removed from its chain + * @returns + * - (NULL) Chain consisted only of m + * - Head of the remaining netbuf chain + */ +struct uk_netbuf *uk_netbuf_disconnect(struct uk_netbuf *m); + #ifdef __cplusplus } #endif diff --git a/lib/uknetdev/netbuf.c b/lib/uknetdev/netbuf.c index 72c349b..c0e41cd 100644 --- a/lib/uknetdev/netbuf.c +++ b/lib/uknetdev/netbuf.c @@ -188,3 +188,56 @@ struct uk_netbuf *uk_netbuf_prepare_buf(void *mem, size_t size, dtor); return m; } + +struct uk_netbuf *uk_netbuf_disconnect(struct uk_netbuf *m) +{ + struct uk_netbuf *remhead = NULL; + + UK_ASSERT(m); + + /* We want to return the next element of m as the + * remaining head of the chain. If there is no next element + * there was no chain. + */ + remhead = m->next; + + /* Reconnect the chains before and after m. */ + if (m->prev) + m->prev->next = m->next; + if (m->next) + m->next->prev = m->prev; + + /* Disconnect m. */ + m->prev = NULL; + m->next = NULL; + + return remhead; +} + + +void uk_netbuf_connect(struct uk_netbuf *headtail, + struct uk_netbuf *tail) +{ + UK_ASSERT(headtail); + UK_ASSERT(!headtail->next); + UK_ASSERT(tail); + UK_ASSERT(!tail->prev); + + headtail->next = tail; + tail->prev = headtail; +} + +void uk_netbuf_append(struct uk_netbuf *head, + struct uk_netbuf *tail) +{ + struct uk_netbuf *headtail; + + UK_ASSERT(head); + UK_ASSERT(!head->prev); + UK_ASSERT(tail); + UK_ASSERT(!tail->prev); + + headtail = uk_netbuf_chain_last(head); + headtail->next = tail; + tail->prev = headtail; +} -- 2.7.4 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |