From bdbec30a849807fb5e6841a38cfe0d168e5962b9 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Thu, 21 Dec 2023 12:06:05 +0100 Subject: seitan: Add netlink, sendto()/sendmsg(), iovec handling, demo with routes A bit rough at the moment, but it does the trick. Bonus: setsockopt() (with magic values only, not used in any demo yet). Signed-off-by: Stefano Brivio --- cooker/call.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) (limited to 'cooker/call.c') diff --git a/cooker/call.c b/cooker/call.c index bb53829..dd37fe9 100644 --- a/cooker/call.c +++ b/cooker/call.c @@ -72,7 +72,7 @@ static union value parse_metadata(struct gluten_ctx *g, struct field *f, if (tag_offset.type == OFFSET_NULL) die(" tag not found"); - if ((*base_offset)->type == OFFSET_NULL) { + if ((*base_offset)->type == OFFSET_NULL || (f->flags & WBUF)) { **base_offset = tag_offset; } else if (f->flags & MASK || add) { emit_bitwise(g, f->type, BITWISE_OR, offset, offset, @@ -133,6 +133,10 @@ Examples of arguments: - STRING: abcd write abcd to ro_data (using size), and pointer to it parse_arg() passes ro_data offset +- IOV: write (one!) struct iovec with iov_base pointer to tag + parse_arg() passes null offset + parse_field() gives back data offset + - STRUCT: 1, 2 write struct to ro_data, and pointer to it parse_arg() passes ro_data offset @@ -169,12 +173,38 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args, (tmp1 = json_value_get_object(jvalue)) && is_metadata_obj(tmp1)) { v = parse_metadata(g, f, &base_offset, offset, tmp1, dry_run, add); - if (v.v_num == 0) + if (!(f->flags & IOV) && v.v_num == 0) + return v; + } + + if (f->flags & IOV) { + struct gluten_offset iov; + struct iovec *iovp; + intptr_t *msg_iov; + + if (dry_run) return v; + + /* iov_base: v */ + /* iov_len: at the moment from field */ + msg_iov = (intptr_t *)gluten_ptr(&g->g, offset); + + iov = gluten_rw_alloc(g, sizeof(struct iovec)); + iovp = (struct iovec *)gluten_ptr(&g->g, iov); + iovp->iov_base = (void *)(intptr_t)base_offset->offset; + gluten_relocation_add(g, iov); + + iovp->iov_len = f->size; + + *msg_iov = iov.offset; + gluten_relocation_add(g, offset); + + return v; } if (!jvalue && !(f->flags & SIZE)) return v; + switch (f->type) { case USHORT: case INT: @@ -249,12 +279,28 @@ static union value parse_field(struct gluten_ctx *g, struct arg *args, tmp1 = json_value_get_object(jvalue); f_value = json_object_get_value(tmp1, f_inner->name); - debug(" parse struct internal value:%s", + debug(" parse struct, field %s, internal value:%s", + f_inner->name, json_serialize_to_string(f_value)); - if (!f_value) + if (!f_value && !(f_inner->flags & SIZE)) continue; - parse_field(g, args, &struct_start, index, f_inner, - f_value, false, add); + + if (f_inner->size && f_inner->type == SELECT) { + struct gluten_offset ptr_offset; + intptr_t *link; + + ptr_offset = gluten_rw_alloc(g, f_inner->size); + parse_field(g, args, &ptr_offset, index, f_inner, + f_value, false, add); + + link = (intptr_t *)gluten_ptr(&g->g, offset); + *link = ptr_offset.offset; + gluten_relocation_add(g, offset); + } else { + parse_field(g, args, &struct_start, index, f_inner, + f_value, false, add); + } + if (base_offset->type == OFFSET_NULL) *base_offset = struct_start; } @@ -278,6 +324,9 @@ bool arg_needs_temp(struct field *f, int pos, JSON_Value *jvalue, if (f->flags & COPY_ON_CALL) return true; + if (f->flags & IOV) + return true; + if (f->flags & SIZE) return false; -- cgit v1.2.3