From 9638b621fa567555e51c9bc61351a708221fd2ee Mon Sep 17 00:00:00 2001 From: dautor Date: Sat, 16 Nov 2024 20:12:45 +0100 Subject: Add ng_pipe link --- src/base/main.c | 101 +++++++++++++++++++++++++++++++++++++------------------ src/base/state.c | 71 ++++++++++++++++++++++++++++++++++++++ src/base/state.h | 16 +++++++++ 3 files changed, 156 insertions(+), 32 deletions(-) (limited to 'src/base') diff --git a/src/base/main.c b/src/base/main.c index 27ef1c2..60d76b4 100644 --- a/src/base/main.c +++ b/src/base/main.c @@ -1,5 +1,6 @@ #include "state.h" #include +#include "../util.h" static char const *Arg0; @@ -214,26 +215,30 @@ start_link_(link_ *R) fprintf(stderr, "Failed to create netgraph socket: %s\n", strerror(errno)); return -1; } - struct ngm_connect D; - char Path0[NG_PATHSIZ]; - strncpy(Path0, R->Peer[0].Address, sizeof(Path0)); - strncpy(D.path, R->Peer[1].Address, sizeof(D.path)); - strncpy(D.ourhook, R->Peer[0].Hook, sizeof(D.ourhook)); - strncpy(D.peerhook, R->Peer[1].Hook, sizeof(D.peerhook)); - if(NgSendMsg(Control, Path0, NGM_GENERIC_COOKIE, NGM_CONNECT, &D, sizeof(D)) == -1) - { - fprintf(stderr, - "ngctl connect %s %s %s %s: %s\n", - Path0, - D.path, - D.ourhook, - D.peerhook, - strerror(errno)); - close(Control); - return -1; + int Result; + switch(R->Configuration.Type) + { + case link_type_direct: + { + Result = + ng_connect(Control, R->Peer[0].Address, R->Peer[1].Address, R->Peer[0].Hook, R->Peer[1].Hook); + break; + } + case link_type_pipe: + { + Result = Create_pipe(&R->pipe.ID, + Control, + R->Peer[0].Address, + R->Peer[1].Address, + R->Peer[0].Hook, + R->Peer[1].Hook); + break; + } + case link_type_COUNT: + default: __builtin_unreachable(); } close(Control); - return 0; + return Result; } static int @@ -245,18 +250,32 @@ stop_link_(link_ *R) fprintf(stderr, "Failed to create netgraph socket: %s\n", strerror(errno)); return -1; } - struct ngm_rmhook D; - char Path0[NG_PATHSIZ]; - strncpy(Path0, R->Peer[0].Address, sizeof(Path0)); - strncpy(D.ourhook, R->Peer[0].Hook, sizeof(D.ourhook)); - if(NgSendMsg(Control, Path0, NGM_GENERIC_COOKIE, NGM_RMHOOK, &D, sizeof(D)) == -1) + switch(R->Configuration.Type) { - fprintf(stderr, "ngctl rmhook %s %s: %s\n", Path0, D.ourhook, strerror(errno)); - close(Control); - return -1; + case link_type_direct: + { + struct ngm_rmhook D; + char Path0[NG_PATHSIZ]; + strncpy(Path0, R->Peer[0].Address, sizeof(Path0)); + strncpy(D.ourhook, R->Peer[0].Hook, sizeof(D.ourhook)); + if(NgSendMsg(Control, Path0, NGM_GENERIC_COOKIE, NGM_RMHOOK, &D, sizeof(D)) == -1) + { + fprintf(stderr, "ngctl rmhook %s %s: %s\n", Path0, D.ourhook, strerror(errno)); + close(Control); + return -1; + } + close(Control); + return 0; + } + case link_type_pipe: + { + int Result = DestroyNetgraphNode(R->pipe.ID, Control); + close(Control); + return Result; + } + case link_type_COUNT: + default: __builtin_unreachable(); } - close(Control); - return 0; } static int @@ -265,7 +284,8 @@ start_link(experiment *E, char const *NodeA, char const *InterfaceA, char const *NodeB, - char const *InterfaceB) + char const *InterfaceB, + link_type Type) { if(FindLinkIndex(E, Name) != SIZE_MAX) { @@ -278,6 +298,7 @@ start_link(experiment *E, C.Peer[0].Interface = strdup(InterfaceA); C.Peer[1].Node = strdup(NodeB); C.Peer[1].Interface = strdup(InterfaceB); + C.Type = Type; } link_ R; { // Start @@ -606,7 +627,7 @@ static void __attribute__((noreturn)) usage(void) "usage: %1$s show\n" " %1$s node start [node-name] [configuration]\n" " %1$s node stop [node-name]\n" - " %1$s link start [link-name] [node-A-name] [interface-A-name] [node-B-name] [interface-B-name]\n" + " %1$s link start [link-name] [node-A-name] [interface-A-name] [node-B-name] [interface-B-name] [?type]\n" " %1$s link stop [link-name]\n" " %1$s node cmd [node-name] [command...]\n" " %1$s node mod [node-name] [command...]\n", @@ -717,8 +738,24 @@ Command_link(experiment *E, fd StateFD, int ArgCount, char **Arg) int Result; if(strcmp(Command, "start") == 0) { - if(ArgCount != 4) usage(); - Result = start_link(E, LinkName, Arg[0], Arg[1], Arg[2], Arg[3]); + if(ArgCount == 4) + { + Result = start_link(E, LinkName, Arg[0], Arg[1], Arg[2], Arg[3], link_type_direct); + } else if(ArgCount == 5) + { + link_type Type; + if(FromString_link_type(Arg[4], &Type) == -1) + { + fprintf(stderr, "Unknown link type '%s'\n", Arg[4]); + Result = -1; + } else + { + Result = start_link(E, LinkName, Arg[0], Arg[1], Arg[2], Arg[3], Type); + } + } else + { + usage(); + } } else if(strcmp(Command, "stop") == 0) { if(ArgCount != 0) usage(); diff --git a/src/base/state.c b/src/base/state.c index 50ebe4e..652c943 100644 --- a/src/base/state.c +++ b/src/base/state.c @@ -103,12 +103,50 @@ error: return Error; } +int +FromString_link_type(char const *S, link_type *Type) +{ + for(link_type i = 0; i < link_type_COUNT; ++i) + { + if(strcmp(link_type_Names[i], S) == 0) + { + *Type = i; + return 0; + } + } + return -1; +} + +char * +Parse_link_type(link_type *E, ucl_object_t const *root, char const *Position) +{ + if(root == NULL) + { + *E = link_type_direct; + return NULL; + } + char *Error; + UCL_CHECK_ROOT(STRING); + char const *S = ucl_object_tostring(root); + if(FromString_link_type(S, E) == 0) return NULL; + asprintf(&Error, "%s invalid link type '%s'", Position, S); +error: + return Error; +} + char * Parse_link_configuration(link_configuration *E, ucl_object_t const *root, char const *Position) { char *Error; size_t EndpointAt = 0; UCL_CHECK_ROOT(OBJECT); + { + char *NewPosition; + asprintf(&NewPosition, "%s.type", Position); + Error = Parse_link_type(&E->Type, ucl_object_lookup(root, "type"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } ucl_object_t const *peer0 = ucl_object_lookup(root, "peer0"); { char *NewPosition; @@ -149,6 +187,25 @@ Parse_link(link_ *E, ucl_object_t const *root, char const *Position) if(Error != NULL) goto error; Configuration = true; } + switch(E->Configuration.Type) + { + case link_type_direct: break; + case link_type_pipe: + { + ucl_object_t const *id = ucl_object_lookup(root, "id"); + UCL_CHECK(id, INT); + s64 ID = ucl_object_toint(id); + if(ID < 0 || ID > INT32_MAX) + { + asprintf(&Error, "%s id invalid (%ld)", Position, ID); + goto error; + } + E->pipe.ID = (u32)ID; + break; + } + case link_type_COUNT: + default: __builtin_unreachable(); + } ucl_object_t const *peer0 = ucl_object_lookup(root, "peer0"); { char *NewPosition; @@ -308,6 +365,8 @@ void Save_link_configuration(jprint_state *S, link_configuration const *E) { JPrintObjectBegin(S); + JPrintMember(S, "type"); + JPrint_string(S, link_type_Names[E->Type]); JPrintMember(S, "peer0"); Save_endpoint_configuration(S, E->Peer + 0); JPrintMember(S, "peer1"); @@ -321,6 +380,18 @@ Save_link(jprint_state *S, link_ const *E) JPrintObjectBegin(S); JPrintMember(S, "configuration"); Save_link_configuration(S, &E->Configuration); + switch(E->Configuration.Type) + { + case link_type_direct: break; + case link_type_pipe: + { + JPrintMember(S, "id"); + JPrint_ssize_t(S, E->pipe.ID); + break; + } + case link_type_COUNT: + default: __builtin_unreachable(); + } JPrintMember(S, "peer0"); Save_endpoint(S, E->Peer + 0); JPrintMember(S, "peer1"); diff --git a/src/base/state.h b/src/base/state.h index 3bbccb5..82db1e0 100644 --- a/src/base/state.h +++ b/src/base/state.h @@ -14,9 +14,12 @@ struct char *Interface; } typedef endpoint_configuration; +NAMED_ENUM(link_type, direct, pipe, ); + struct { endpoint_configuration Peer[2]; + link_type Type; } typedef link_configuration; struct @@ -24,6 +27,16 @@ struct char *Name; link_configuration Configuration; endpoint Peer[2]; + union + { + struct + { + } direct; + struct + { + u32 ID; + } pipe; + }; } typedef link_; struct @@ -47,6 +60,8 @@ struct link_ *Link; } typedef experiment; +int FromString_link_type(char const *, link_type *); + void Free_endpoint(endpoint *); void Free_endpoint_configuration(endpoint_configuration *); void Free_link_configuration(link_configuration *); @@ -57,6 +72,7 @@ void Free_experiment(experiment *); char *Parse_endpoint(endpoint *, ucl_object_t const *, char const *Position); char *Parse_endpoint_configuration(endpoint_configuration *, ucl_object_t const *, char const *Position); +char *Parse_link_type(link_type *, ucl_object_t const *, char const *Position); char *Parse_link_configuration(link_configuration *, ucl_object_t const *, char const *Position); char *Parse_link(link_ *, ucl_object_t const *, char const *Position); char *Parse_node_configuration(node_configuration *, ucl_object_t const *, char const *Position); -- cgit v1.2.3