From 6017777833520d8cfc27f804e9f651f2a86ee8e2 Mon Sep 17 00:00:00 2001 From: "Fabio M. Di Nitto" Date: Mon, 22 Nov 2010 22:32:43 +0100 Subject: [PATCH] vty: add start/stop commands to interface configure interface kronosnet0 2 baseport 50000 mtu 9000 ip 192.168.7.2 24 peer node1 1 link 192.168.5.1 link 192.168.4.1 exit start exit exit exit now starts the bridge and traffic is flowing! Signed-off-by: Fabio M. Di Nitto --- cfg.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ cfg.h | 9 +++++++ vty_cli_cmds.c | 34 ++++++++++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/cfg.c b/cfg.c index 99a5d5d..8dfbc35 100644 --- a/cfg.c +++ b/cfg.c @@ -1,5 +1,8 @@ #include "config.h" +#include +#include + #include "cfg.h" #include "knet.h" #include "utils.h" @@ -135,3 +138,70 @@ void knet_destroy_iface(struct knet_cfg *knet_iface) free(knet_iface); } } + +struct fds_io { + int fd_in; + int fd_out; + int done; +}; + + +/* this one needs to find a way to signal that it died */ + +static void *briswifwd_thread(void *arg) +{ + char buf[131072]; + ssize_t len = 0; + struct fds_io *fds = (struct fds_io *)arg; + int fd_in, fd_out; + + fd_in = fds->fd_in; + fd_out = fds->fd_out; + fds->done = 1; + + while ((len=read(fd_in, buf, sizeof(buf))) >= 0) + write(fd_out, buf, len); + + return NULL; +} + +int knet_start_bridge(struct knet_cfg *iface) +{ + struct fds_io fds; + int err = 0; + + fds.fd_in = iface->cfg_eth.knet_eth->knet_etherfd; + fds.fd_out = knet_handle_getfd(iface->cfg_ring.knet_h); + + fds.done = 0; + + err = pthread_create(&iface->cfg_bridge.eth2ring, NULL, + briswifwd_thread, (void *)&fds); + if (err) + goto out_clean; + + while(fds.done != 1) + usleep(1000); + + fds.fd_in = knet_handle_getfd(iface->cfg_ring.knet_h); + fds.fd_out = iface->cfg_eth.knet_eth->knet_etherfd; + fds.done = 0; + + err = pthread_create(&iface->cfg_bridge.ring2eth, NULL, + briswifwd_thread, (void *)&fds); + if (err) + pthread_cancel(iface->cfg_bridge.eth2ring); + + while(fds.done != 1) + usleep(1000); + +out_clean: + + return err; +} + +void knet_stop_bridge(struct knet_cfg *iface) +{ + pthread_cancel(iface->cfg_bridge.eth2ring); + pthread_cancel(iface->cfg_bridge.ring2eth); +} diff --git a/cfg.h b/cfg.h index 2320a92..a3b84b7 100644 --- a/cfg.h +++ b/cfg.h @@ -27,9 +27,15 @@ struct knet_cfg_ring { int base_port; }; +struct knet_cfg_bridge { + pthread_t eth2ring; + pthread_t ring2eth; +}; + struct knet_cfg { struct knet_cfg_eth cfg_eth; struct knet_cfg_ring cfg_ring; + struct knet_cfg_bridge cfg_bridge; struct knet_cfg *next; }; @@ -48,6 +54,9 @@ void knet_destroy_ip(struct knet_cfg *knet_iface, struct knet_cfg_ip *knet_ip); struct knet_cfg *knet_get_iface(const char *name, const int create); void knet_destroy_iface(struct knet_cfg *knet_iface); +int knet_start_bridge(struct knet_cfg *iface); +void knet_stop_bridge(struct knet_cfg *iface); + extern struct knet_cfg_top knet_cfg_head; #endif diff --git a/vty_cli_cmds.c b/vty_cli_cmds.c index ca28e49..7916612 100644 --- a/vty_cli_cmds.c +++ b/vty_cli_cmds.c @@ -482,6 +482,8 @@ static int knet_cmd_no_ip(struct knet_vty *vty); static int knet_cmd_baseport(struct knet_vty *vty); static int knet_cmd_peer(struct knet_vty *vty); static int knet_cmd_no_peer(struct knet_vty *vty); +static int knet_cmd_start(struct knet_vty *vty); +static int knet_cmd_stop(struct knet_vty *vty); /* peer node */ static int knet_cmd_link(struct knet_vty *vty); @@ -567,6 +569,8 @@ vty_node_cmds_t interface_cmds[] = { { "no", "revert command", NULL, NULL }, { "peer", "add peer endpoint", peer_params, knet_cmd_peer }, { "show", "show running config", NULL, knet_cmd_show_conf }, + { "start", "start forwarding engine", NULL, knet_cmd_start }, + { "stop", "stop forwarding engine", NULL, knet_cmd_stop }, { "who", "display users connected to CLI", NULL, knet_cmd_who }, { "write", "write current config to file", NULL, knet_cmd_write_conf }, { NULL, NULL, NULL, NULL }, @@ -1030,6 +1034,36 @@ static int knet_cmd_mtu(struct knet_vty *vty) return 0; } +static int knet_cmd_stop(struct knet_vty *vty) +{ + struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface; + + if (knet_set_down(knet_iface->cfg_eth.knet_eth) < 0) + knet_vty_write(vty, "Error: Unable to set interface %s down!%s", knet_iface->cfg_eth.name, telnet_newline); + + knet_stop_bridge(knet_iface); + + return 0; +} + +static int knet_cmd_start(struct knet_vty *vty) +{ + struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface; + + if (knet_start_bridge(knet_iface) < 0) { + knet_vty_write(vty, "Error: Unable to start forwarding thread!%s", telnet_newline); + return -1; + } + + if (knet_set_up(knet_iface->cfg_eth.knet_eth) < 0) { + knet_vty_write(vty, "Error: Unable to set interface %s up!%s", knet_iface->cfg_eth.name, telnet_newline); + knet_stop_bridge(knet_iface); + return -1; + } + + return 0; +} + static int knet_cmd_no_interface(struct knet_vty *vty) { int err = 0, paramlen = 0, paramoffset = 0; -- 2.39.5