diff --git a/code/bngblaster/src/bbl_config.c b/code/bngblaster/src/bbl_config.c index 895efd81..5945437f 100644 --- a/code/bngblaster/src/bbl_config.c +++ b/code/bngblaster/src/bbl_config.c @@ -1316,6 +1316,10 @@ json_parse_config(json_t *root, bbl_ctx_s *ctx) { if (json_is_number(value)) { ctx->config.sessions_start_delay = json_number_value(value); } + value = json_object_get(section, "autostart"); + if (json_is_boolean(value)) { + ctx->config.sessions_autostart = json_boolean_value(value); + } } /* IPoE Configuration */ @@ -2191,6 +2195,7 @@ bbl_config_init_defaults (bbl_ctx_s *ctx) { ctx->config.sessions_max_outstanding = 800; ctx->config.sessions_start_rate = 400; ctx->config.sessions_stop_rate = 400; + ctx->config.sessions_autostart = true; ctx->config.pppoe_discovery_timeout = 5; ctx->config.pppoe_discovery_retry = 10; ctx->config.ppp_mru = 1492; diff --git a/code/bngblaster/src/bbl_ctrl.c b/code/bngblaster/src/bbl_ctrl.c index fd9b1fa0..559274df 100644 --- a/code/bngblaster/src/bbl_ctrl.c +++ b/code/bngblaster/src/bbl_ctrl.c @@ -421,7 +421,7 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* argum if(session) { session_json = bbl_session_json(session); if(!session_json) { - bbl_ctrl_status(fd, "error", 500, "internal error"); + return bbl_ctrl_status(fd, "error", 500, "internal error"); } root = json_pack("{ss si so*}", @@ -442,6 +442,42 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* argum } } +ssize_t +bbl_ctrl_session_start(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* arguments __attribute__((unused))) { + bbl_session_s *session; + + if(g_teardown) { + return bbl_ctrl_status(fd, "error", 405, "teardown"); + } + + if(session_id == 0) { + /* session-id is mandatory */ + return bbl_ctrl_status(fd, "error", 400, "missing session-id"); + } + + session = bbl_session_get(ctx, session_id); + if(session) { + if(session->session_state == BBL_TERMINATED && + session->reconnect_delay == 0) { + ctx->sessions_flapped++; + session->stats.flapped++; + session->session_state = BBL_IDLE; + bbl_session_reset(session); + if(ctx->sessions_terminated) { + ctx->sessions_terminated--; + } + } else if(session->session_state != BBL_IDLE || + CIRCLEQ_NEXT(session, session_idle_qnode) || + CIRCLEQ_PREV(session, session_idle_qnode)) { + return bbl_ctrl_status(fd, "error", 405, "wrong session state"); + } + CIRCLEQ_INSERT_TAIL(&ctx->sessions_idle_qhead, session, session_idle_qnode); + return bbl_ctrl_status(fd, "ok", 200, NULL); + } else { + return bbl_ctrl_status(fd, "warning", 404, "session not found"); + } +} + static json_t * bbl_ctrl_interfaces_json(bbl_interface_s *interace, const char *type) { return json_pack("{ss si ss si si si si si si si si}", @@ -1338,6 +1374,7 @@ struct action actions[] = { {"ip6cp-close", bbl_ctrl_session_ip6cp_close}, {"session-counters", bbl_ctrl_session_counters}, {"session-info", bbl_ctrl_session_info}, + {"session-start", bbl_ctrl_session_start}, {"session-traffic", bbl_ctrl_session_traffic_stats}, {"session-traffic-enabled", bbl_ctrl_session_traffic_start}, {"session-traffic-start", bbl_ctrl_session_traffic_start}, diff --git a/code/bngblaster/src/bbl_ctx.h b/code/bngblaster/src/bbl_ctx.h index a44a151a..b816f33b 100644 --- a/code/bngblaster/src/bbl_ctx.h +++ b/code/bngblaster/src/bbl_ctx.h @@ -189,7 +189,8 @@ typedef struct bbl_ctx_ uint16_t sessions_start_rate; uint16_t sessions_stop_rate; uint16_t sessions_start_delay; - + bool sessions_autostart; + bool iterate_outer_vlan; /* Static */ diff --git a/code/bngblaster/src/bbl_session.c b/code/bngblaster/src/bbl_session.c index f6d48b4a..c03bb456 100644 --- a/code/bngblaster/src/bbl_session.c +++ b/code/bngblaster/src/bbl_session.c @@ -128,7 +128,7 @@ bbl_session_get(bbl_ctx_s *ctx, uint32_t session_id) return ctx->session_list[session_id-1]; } -static void +void bbl_session_reset(bbl_session_s *session) { /* Reset session for reconnect */ memset(&session->server_mac, 0xff, ETH_ADDR_LEN); /* init with broadcast MAC */ @@ -653,7 +653,9 @@ bbl_sessions_init(bbl_ctx_s *ctx) session->interface = access_config->access_if; session->network_interface = bbl_get_network_interface(ctx, access_config->network_interface); session->session_state = BBL_IDLE; - CIRCLEQ_INSERT_TAIL(&ctx->sessions_idle_qhead, session, session_idle_qnode); + if(ctx->config.sessions_autostart) { + CIRCLEQ_INSERT_TAIL(&ctx->sessions_idle_qhead, session, session_idle_qnode); + } ctx->sessions++; if(session->access_type == ACCESS_TYPE_PPPOE) { ctx->sessions_pppoe++; diff --git a/code/bngblaster/src/bbl_session.h b/code/bngblaster/src/bbl_session.h index 8730f7a9..c777cc4e 100644 --- a/code/bngblaster/src/bbl_session.h +++ b/code/bngblaster/src/bbl_session.h @@ -418,6 +418,9 @@ session_state_string(uint32_t state); bbl_session_s * bbl_session_get(bbl_ctx_s *ctx, uint32_t session_id); +void +bbl_session_reset(bbl_session_s *session); + void bbl_session_update_state(bbl_ctx_s *ctx, bbl_session_s *session, session_state_t state); diff --git a/docsrc/sources/api/sessions.rst b/docsrc/sources/api/sessions.rst index c93f3b66..737cf711 100644 --- a/docsrc/sources/api/sessions.rst +++ b/docsrc/sources/api/sessions.rst @@ -37,6 +37,10 @@ - Terminate session - - `session-id`, `reconnect-delay` + * - `session-start` + - Start session manually + - `session-id` + - The argument ``reconnect-delay`` is only applicable in combination with ``session-id`` and reconnect enabled in configuration. This argument allows to delay the session diff --git a/docsrc/sources/configuration/sessions.rst b/docsrc/sources/configuration/sessions.rst index 29bf936a..9544d003 100644 --- a/docsrc/sources/configuration/sessions.rst +++ b/docsrc/sources/configuration/sessions.rst @@ -28,6 +28,9 @@ * - `start-delay` - Wait N seconds after all interface are resolved before starting sessions - 0 + * - `autostart` + - Start sessions automatically + - true Per default sessions are created by iteration over inner VLAN range first and outer VLAN second. Which can be changed by ``iterate-vlan-outer`` to iterate