summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
authordautor <karlo98.m@gmail.com>2024-11-16 20:12:45 +0100
committerdautor <karlo98.m@gmail.com>2024-11-16 20:12:45 +0100
commit9638b621fa567555e51c9bc61351a708221fd2ee (patch)
treed16248bfc8d0d7704da8c99585a580dda16f7518 /src/base
parent47778ccd67cbb3fb70dda706911d3166038ca010 (diff)
Add ng_pipe link
Diffstat (limited to 'src/base')
-rw-r--r--src/base/main.c101
-rw-r--r--src/base/state.c71
-rw-r--r--src/base/state.h16
3 files changed, 156 insertions, 32 deletions
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 <netgraph.h>
+#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);