diff --git a/code/bngblaster/src/bbl_ctrl.c b/code/bngblaster/src/bbl_ctrl.c index 1ce603f0..c4ec6ffe 100644 --- a/code/bngblaster/src/bbl_ctrl.c +++ b/code/bngblaster/src/bbl_ctrl.c @@ -222,6 +222,8 @@ struct action actions[] = { {"isis-database", isis_ctrl_database, true}, {"isis-load-mrt", isis_ctrl_load_mrt, false}, {"isis-lsp-update", isis_ctrl_lsp_update, false}, + {"isis-lsp-purge", isis_ctrl_lsp_purge, false}, + {"isis-lsp-flap", isis_ctrl_lsp_flap, false}, {"isis-teardown", isis_ctrl_teardown, false}, {"bgp-sessions", bgp_ctrl_sessions, true}, {"bgp-disconnect", bgp_ctrl_disconnect, false}, diff --git a/code/bngblaster/src/isis/isis.c b/code/bngblaster/src/isis/isis.c index 9fcd4f3a..2c3e8dc7 100644 --- a/code/bngblaster/src/isis/isis.c +++ b/code/bngblaster/src/isis/isis.c @@ -183,7 +183,7 @@ isis_teardown() for(int i=0; ilevel[i].adjacency) { isis_lsp_self_update(instance, i+1); - isis_lsp_purge_external(instance, i+1); + isis_lsp_purge_all_external(instance, i+1); } } diff --git a/code/bngblaster/src/isis/isis_adjacency.c b/code/bngblaster/src/isis/isis_adjacency.c index 522c69f4..33549e50 100644 --- a/code/bngblaster/src/isis/isis_adjacency.c +++ b/code/bngblaster/src/isis/isis_adjacency.c @@ -102,7 +102,7 @@ isis_adjacency_up(isis_adjacency_s *adjacency) adjacency->state = ISIS_ADJACENCY_STATE_UP; timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_tx, - "ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_sx_job); + "ISIS TX", 0, config->lsp_tx_interval * MSEC, adjacency, &isis_lsp_tx_job); timer_add_periodic(&g_ctx->timer_root, &adjacency->timer_retry, "ISIS RETRY", config->lsp_retry_interval, 0, adjacency, &isis_lsp_retry_job); diff --git a/code/bngblaster/src/isis/isis_ctrl.c b/code/bngblaster/src/isis/isis_ctrl.c index 72900b0c..510017b6 100644 --- a/code/bngblaster/src/isis/isis_ctrl.c +++ b/code/bngblaster/src/isis/isis_ctrl.c @@ -9,6 +9,37 @@ #include "isis.h" #include "../bbl_ctrl.h" +isis_lsp_flap_s *g_isis_lsp_flap = NULL; + + +#define ISIS_CTRL_ARG_INSTANCE(_arguments, _fd, _instance_id, _instance) \ + do { \ + if(json_unpack(_arguments, "{s:i}", "instance", &_instance_id) != 0) { \ + return bbl_ctrl_status(_fd, "error", 400, "missing ISIS instance"); \ + } \ + /* Search for matching instance */ \ + _instance = g_ctx->isis_instances; \ + while(_instance) { \ + if(_instance->config->id == _instance_id) { \ + break; \ + } \ + _instance = _instance->next; \ + } \ + if(!_instance) { \ + return bbl_ctrl_status(_fd, "error", 404, "ISIS instance not found"); \ + } \ + } while(0) + +#define ISIS_CTRL_ARG_LEVEL(_arguments, _fd, _level) \ + do { \ + if(json_unpack(_arguments, "{s:i}", "level", &_level) != 0) { \ + return bbl_ctrl_status(_fd, "error", 400, "missing ISIS level"); \ + } \ + if(!(_level == ISIS_LEVEL_1 || _level == ISIS_LEVEL_2)) { \ + return bbl_ctrl_status(_fd, "error", 400, "invalid ISIS level"); \ + } \ + } while(0) + static json_t * isis_ctrl_adjacency(isis_adjacency_s *adjacency) { @@ -180,36 +211,15 @@ isis_ctrl_database(int fd, uint32_t session_id __attribute__((unused)), json_t * json_t *root = NULL; json_t *database = NULL; isis_instance_s *instance = NULL; - int instance_id = 0; int level = 0; /* Unpack further arguments */ - if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) { - return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance"); - } - if(json_unpack(arguments, "{s:i}", "level", &level) != 0) { - return bbl_ctrl_status(fd, "error", 400, "missing ISIS level"); - } - if(!(level == ISIS_LEVEL_1 || level == ISIS_LEVEL_2)) { - return bbl_ctrl_status(fd, "error", 400, "invalid ISIS level"); - } - - /* Search for matching instance */ - instance = g_ctx->isis_instances; - while(instance) { - if(instance->config->id == instance_id) { - break; - } - instance = instance->next; - } - - if(!instance) { - return bbl_ctrl_status(fd, "error", 400, "ISIS instance not found"); - } + ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance); + ISIS_CTRL_ARG_LEVEL(arguments, fd, level); if(!instance->level[level-1].lsdb) { - return bbl_ctrl_status(fd, "error", 400, "ISIS database not found"); + return bbl_ctrl_status(fd, "error", 404, "ISIS database not found"); } database = isis_ctrl_database_entries(instance->level[level-1].lsdb); @@ -235,31 +245,15 @@ int isis_ctrl_load_mrt(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) { char *file_path; + isis_instance_s *instance = NULL; int instance_id = 0; - isis_instance_s *instance = NULL; - /* Unpack further arguments */ + ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance); + if(json_unpack(arguments, "{s:s}", "file", &file_path) != 0) { return bbl_ctrl_status(fd, "error", 400, "missing MRT file"); } - if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) { - return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance"); - } - - /* Search for matching instance */ - instance = g_ctx->isis_instances; - while(instance) { - if(instance->config->id == instance_id) { - break; - } - instance = instance->next; - } - - if(!instance) { - return bbl_ctrl_status(fd, "error", 404, "ISIS instance not found"); - } - if(!isis_mrt_load(instance, file_path, false)) { return bbl_ctrl_status(fd, "error", 500, "failed to load ISIS MRT file"); } @@ -274,35 +268,19 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t json_t *value; size_t pdu_count; - int instance_id = 0; - isis_instance_s *instance = NULL; isis_pdu_s pdu = {0}; - const char *pdu_string; uint16_t pdu_string_len; uint8_t buf[ISIS_MAX_PDU_LEN]; uint16_t len; + isis_instance_s *instance = NULL; + int instance_id = 0; /* Unpack further arguments */ - if(json_unpack(arguments, "{s:i}", "instance", &instance_id) != 0) { - return bbl_ctrl_status(fd, "error", 400, "missing ISIS instance"); - } - - /* Search for matching instance */ - instance = g_ctx->isis_instances; - while(instance) { - if(instance->config->id == instance_id) { - break; - } - instance = instance->next; - } - - if(!instance) { - return bbl_ctrl_status(fd, "error", 404, "ISIS instance not found"); - } + ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance); /* Process PDU array */ value = json_object_get(arguments, "pdu"); @@ -323,7 +301,7 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t return bbl_ctrl_status(fd, "error", 500, "failed to decode ISIS PDU"); } /* Update external LSP */ - if(!isis_lsp_update_external(instance, &pdu)) { + if(!isis_lsp_update_external(instance, &pdu, false)) { return bbl_ctrl_status(fd, "error", 500, "failed to update ISIS LSP"); } } @@ -333,6 +311,151 @@ isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t return bbl_ctrl_status(fd, "ok", 200, NULL); } +int +isis_ctrl_lsp_purge(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + json_t *value; + + isis_lsp_s *lsp = NULL; + uint64_t lsp_id; + + hb_tree *lsdb; + void **search = NULL; + + isis_instance_s *instance = NULL; + int instance_id = 0; + int level = 0; + + /* Unpack further arguments */ + ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance); + ISIS_CTRL_ARG_LEVEL(arguments, fd, level); + + if(!instance->level[level-1].lsdb) { + return bbl_ctrl_status(fd, "error", 404, "ISIS database not found"); + } + + value = json_object_get(arguments, "id"); + if(json_is_string(value)) { + if(!isis_str_to_lsp_id(json_string_value(value), &lsp_id)) { + return bbl_ctrl_status(fd, "error", 400, "invalid ISIS LSP identifier"); + } + lsdb = instance->level[level-1].lsdb; + search = hb_tree_search(lsdb, &lsp_id); + if(search) { + lsp = *search; + if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) { + isis_lsp_purge(lsp); + } else { + return bbl_ctrl_status(fd, "error", 500, "failed to purge ISIS LSP"); + } + } else { + return bbl_ctrl_status(fd, "error", 404, "ISIS LSP not found"); + } + } else { + return bbl_ctrl_status(fd, "error", 400, "missing ISIS LSP identifier"); + } + return bbl_ctrl_status(fd, "ok", 200, NULL); +} + +void +isis_ctrl_lsp_flap_job(timer_s *timer) +{ + isis_lsp_flap_s *flap = timer->data; + uint32_t seq; + + if(flap) { + seq = be32toh(*(uint32_t*)PDU_OFFSET(&flap->pdu, ISIS_OFFSET_LSP_SEQ)); + *(uint32_t*)PDU_OFFSET(&flap->pdu, ISIS_OFFSET_LSP_SEQ) = htobe32(++seq); + + if(!isis_lsp_update_external(flap->instance, &flap->pdu, true)) { + LOG(ISIS, "Failed to flap ISIS LSP %s\n", isis_lsp_id_to_str(&flap->id)); + } + flap->free = true; + } +} + +static isis_lsp_flap_s * +isis_ctrl_lsp_flap_new(isis_lsp_s *lsp) +{ + isis_lsp_flap_s *flap = g_isis_lsp_flap; + + while(flap) { + if(flap->free) { + break; + } + flap = flap->next; + } + if(!flap) { + flap = calloc(1, sizeof(isis_lsp_flap_s)); + flap->next = g_isis_lsp_flap; + g_isis_lsp_flap = flap; + } + + flap->free = false; + flap->timer = NULL; + flap->id = lsp->id; + flap->instance = lsp->instance; + memcpy(&flap->pdu, &lsp->pdu, sizeof(isis_pdu_s)); + + return flap; +} + +int +isis_ctrl_lsp_flap(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments) +{ + json_t *value; + + isis_lsp_s *lsp = NULL; + uint64_t lsp_id; + + time_t timer = 30; + hb_tree *lsdb; + void **search = NULL; + + isis_lsp_flap_s *flap; + + isis_instance_s *instance = NULL; + int instance_id = 0; + int level = 0; + + /* Unpack further arguments */ + ISIS_CTRL_ARG_INSTANCE(arguments, fd, instance_id, instance); + ISIS_CTRL_ARG_LEVEL(arguments, fd, level); + + if(!instance->level[level-1].lsdb) { + return bbl_ctrl_status(fd, "error", 404, "ISIS database not found"); + } + + value = json_object_get(arguments, "timer"); + if(json_is_number(value)) { + timer = json_number_value(value); + } + + value = json_object_get(arguments, "id"); + if(json_is_string(value)) { + if(!isis_str_to_lsp_id(json_string_value(value), &lsp_id)) { + return bbl_ctrl_status(fd, "error", 400, "invalid ISIS LSP identifier"); + } + lsdb = instance->level[level-1].lsdb; + search = hb_tree_search(lsdb, &lsp_id); + if(search) { + lsp = *search; + if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) { + flap = isis_ctrl_lsp_flap_new(lsp); + timer_add(&g_ctx->timer_root, &flap->timer, "ISIS FLAP", timer, 0, flap, &isis_ctrl_lsp_flap_job); + isis_lsp_purge(lsp); + } else { + return bbl_ctrl_status(fd, "error", 500, "failed to flap ISIS LSP"); + } + } else { + return bbl_ctrl_status(fd, "error", 404, "ISIS LSP not found"); + } + } else { + return bbl_ctrl_status(fd, "error", 400, "missing ISIS LSP identifier"); + } + return bbl_ctrl_status(fd, "ok", 200, NULL); +} + int isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))) { diff --git a/code/bngblaster/src/isis/isis_ctrl.h b/code/bngblaster/src/isis/isis_ctrl.h index 0f384582..d307da62 100644 --- a/code/bngblaster/src/isis/isis_ctrl.h +++ b/code/bngblaster/src/isis/isis_ctrl.h @@ -21,6 +21,12 @@ isis_ctrl_load_mrt(int fd, uint32_t session_id __attribute__((unused)), json_t * int isis_ctrl_lsp_update(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); +int +isis_ctrl_lsp_purge(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); + +int +isis_ctrl_lsp_flap(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments); + int isis_ctrl_teardown(int fd, uint32_t session_id __attribute__((unused)), json_t *arguments __attribute__((unused))); diff --git a/code/bngblaster/src/isis/isis_def.h b/code/bngblaster/src/isis/isis_def.h index e7235862..bf1219ae 100644 --- a/code/bngblaster/src/isis/isis_def.h +++ b/code/bngblaster/src/isis/isis_def.h @@ -382,4 +382,16 @@ typedef struct isis_flood_entry_ { struct timespec tx_timestamp; } isis_flood_entry_s; +typedef struct isis_lsp_flap_ { + uint64_t id; /* LSP-ID */ + + isis_instance_s *instance; + isis_pdu_s pdu; + + bool free; + struct timer_ *timer; + + struct isis_lsp_flap_ *next; +} isis_lsp_flap_s; + #endif \ No newline at end of file diff --git a/code/bngblaster/src/isis/isis_lsp.c b/code/bngblaster/src/isis/isis_lsp.c index eefb330e..7170d18b 100644 --- a/code/bngblaster/src/isis/isis_lsp.c +++ b/code/bngblaster/src/isis/isis_lsp.c @@ -148,7 +148,6 @@ void isis_lsp_gc_job(timer_s *timer) { isis_instance_s *instance = timer->data; - isis_lsp_s *lsp; hb_itor *itor; bool next; @@ -277,7 +276,7 @@ isis_lsp_refresh_job(timer_s *timer) } void -isis_lsp_sx_job(timer_s *timer) +isis_lsp_tx_job(timer_s *timer) { isis_adjacency_s *adjacency = timer->data; isis_flood_entry_s *entry; @@ -703,77 +702,87 @@ ACK: } /** - * isis_lsp_purge_external + * isis_lsp_purge + * + * @param lsp ISIS LSP + */ +void +isis_lsp_purge(isis_lsp_s *lsp) +{ + isis_pdu_s *pdu; + isis_auth_type auth_type = ISIS_AUTH_NONE; + + isis_config_s *config = lsp->instance->config; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + lsp->seq++; + lsp->timestamp.tv_sec = now.tv_sec; + lsp->timestamp.tv_nsec = now.tv_nsec; + + lsp->lifetime = 0; + isis_lsp_lifetime(lsp); + + /* Build PDU */ + pdu = &lsp->pdu; + if(lsp->level == ISIS_LEVEL_1) { + isis_pdu_init(pdu, ISIS_PDU_L1_LSP); + auth_type = config->level1_auth; + lsp->auth_key = config->level1_key; + } else { + isis_pdu_init(pdu, ISIS_PDU_L2_LSP); + auth_type = config->level2_auth; + lsp->auth_key = config->level2_key; + } + + /* PDU header. */ + isis_pdu_add_u16(pdu, 0); + isis_pdu_add_u16(pdu, 0); + isis_pdu_add_u64(pdu, lsp->id); + isis_pdu_add_u32(pdu, lsp->seq); + isis_pdu_add_u16(pdu, 0); + isis_pdu_add_u8(pdu, 0x03); + + /* TLV section. */ + isis_pdu_add_tlv_auth(pdu, auth_type, lsp->auth_key); + + /* Update length and authentication. */ + isis_pdu_update_len(pdu); + isis_pdu_update_auth(pdu, lsp->auth_key); + + /* Set checksum and lifetime to zero. */ + *(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_LIFETIME) = 0; + *(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_CHECKSUM) = 0; + + isis_lsp_flood(lsp); +} + +/** + * isis_lsp_purge_all_external * * @param instance ISIS instance * @param level ISIS level */ void -isis_lsp_purge_external(isis_instance_s *instance, uint8_t level) +isis_lsp_purge_all_external(isis_instance_s *instance, uint8_t level) { - isis_config_s *config = instance->config; hb_tree *lsdb = instance->level[level-1].lsdb; isis_lsp_s *lsp; hb_itor *itor; bool next; - isis_pdu_s *pdu; - isis_auth_type auth_type = ISIS_AUTH_NONE; - - struct timespec now; - if(!lsdb) { return; } - clock_gettime(CLOCK_MONOTONIC, &now); - itor = hb_itor_new(lsdb); next = hb_itor_first(itor); while(next) { lsp = *hb_itor_datum(itor); if(lsp && lsp->source.type == ISIS_SOURCE_EXTERNAL) { - lsp->seq++; - lsp->timestamp.tv_sec = now.tv_sec; - lsp->timestamp.tv_nsec = now.tv_nsec; - - lsp->lifetime = 0; - isis_lsp_lifetime(lsp); - - /* Build PDU */ - pdu = &lsp->pdu; - if(level == ISIS_LEVEL_1) { - isis_pdu_init(pdu, ISIS_PDU_L1_LSP); - auth_type = config->level1_auth; - lsp->auth_key = config->level1_key; - } else { - isis_pdu_init(pdu, ISIS_PDU_L2_LSP); - auth_type = config->level2_auth; - lsp->auth_key = config->level2_key; - } - - /* PDU header. */ - isis_pdu_add_u16(pdu, 0); - isis_pdu_add_u16(pdu, 0); - isis_pdu_add_u64(pdu, lsp->id); - isis_pdu_add_u32(pdu, lsp->seq); - isis_pdu_add_u16(pdu, 0); - isis_pdu_add_u8(pdu, 0x03); - - /* TLV section. */ - isis_pdu_add_tlv_auth(pdu, auth_type, lsp->auth_key); - - /* Update length and authentication. */ - isis_pdu_update_len(pdu); - isis_pdu_update_auth(pdu, lsp->auth_key); - - /* Set checksum and lifetime to zero. */ - *(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_LIFETIME) = 0; - *(uint16_t*)PDU_OFFSET(pdu, ISIS_OFFSET_LSP_CHECKSUM) = 0; - - isis_lsp_flood(lsp); + isis_lsp_purge(lsp); } next = hb_itor_next(itor); } @@ -784,9 +793,10 @@ isis_lsp_purge_external(isis_instance_s *instance, uint8_t level) * * @param instance ISIS instance * @param pdu received ISIS PDU + * @param refresh automatically refresh LSP */ bool -isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu) +isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu, bool refresh) { uint8_t level; @@ -854,7 +864,8 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu) if(lsp->lifetime < ISIS_DEFAULT_LSP_LIFETIME_MIN) { /* Increase ISIS lifetime. */ lsp->lifetime = ISIS_DEFAULT_LSP_LIFETIME_MIN; - isis_lsp_refresh(lsp); + isis_lsp_refresh(lsp); + refresh = false; } refresh_interval = lsp->lifetime - 300; timer_add_periodic(&g_ctx->timer_root, &lsp->timer_refresh, @@ -864,6 +875,10 @@ isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu) isis_lsp_lifetime(lsp); } - isis_lsp_flood(lsp); + if(refresh) { + isis_lsp_refresh(lsp); + } else { + isis_lsp_flood(lsp); + } return true; } \ No newline at end of file diff --git a/code/bngblaster/src/isis/isis_lsp.h b/code/bngblaster/src/isis/isis_lsp.h index cc156f9a..a4f64d3b 100644 --- a/code/bngblaster/src/isis/isis_lsp.h +++ b/code/bngblaster/src/isis/isis_lsp.h @@ -34,7 +34,7 @@ void isis_lsp_lifetime(isis_lsp_s *lsp); void -isis_lsp_sx_job(timer_s *timer); +isis_lsp_tx_job(timer_s *timer); isis_lsp_s * isis_lsp_new(uint64_t id, uint8_t level, isis_instance_s *instance); @@ -46,9 +46,12 @@ void isis_lsp_handler_rx(bbl_network_interface_s *interface, isis_pdu_s *pdu, uint8_t level); void -isis_lsp_purge_external(isis_instance_s *instance, uint8_t level); +isis_lsp_purge(isis_lsp_s *lsp); + +void +isis_lsp_purge_all_external(isis_instance_s *instance, uint8_t level); bool -isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu); +isis_lsp_update_external(isis_instance_s *instance, isis_pdu_s *pdu, bool refresh); #endif \ No newline at end of file diff --git a/code/bngblaster/src/isis/isis_utils.c b/code/bngblaster/src/isis/isis_utils.c index 732a769c..3642dae4 100644 --- a/code/bngblaster/src/isis/isis_utils.c +++ b/code/bngblaster/src/isis/isis_utils.c @@ -197,6 +197,30 @@ isis_system_id_to_str(uint8_t *system_id) return ret; } +/** + * isis_str_to_lsp_id + * + * @param str IS-IS lsp-id string + * @param lsp_id IS-IS lsp-id (8 bytes) + * @return true if successful + */ +bool +isis_str_to_lsp_id(const char *str, uint64_t *lsp_id) +{ + sscanf(str, "%hx.%hx.%hx.%hhx-%hhx", + &((uint16_t*)lsp_id)[3], + &((uint16_t*)lsp_id)[2], + &((uint16_t*)lsp_id)[1], + &((uint8_t*)lsp_id)[1], + &((uint8_t*)lsp_id)[0]); + + ((uint16_t*)lsp_id)[3] = ((uint16_t*)lsp_id)[3]; + ((uint16_t*)lsp_id)[2] = ((uint16_t*)lsp_id)[2]; + ((uint16_t*)lsp_id)[1] = ((uint16_t*)lsp_id)[1]; + + return true; +} + /** * isis_lsp_id_to_str * diff --git a/code/bngblaster/src/isis/isis_utils.h b/code/bngblaster/src/isis/isis_utils.h index ec4993b9..843913f1 100644 --- a/code/bngblaster/src/isis/isis_utils.h +++ b/code/bngblaster/src/isis/isis_utils.h @@ -36,6 +36,9 @@ isis_str_to_system_id(const char *str, uint8_t *system_id); char * isis_system_id_to_str(uint8_t *system_id); +bool +isis_str_to_lsp_id(const char *str, uint64_t *lsp_id); + char * isis_lsp_id_to_str(uint64_t *lsp_id); diff --git a/code/common/src/logging.h b/code/common/src/logging.h index 1555a624..64c271c9 100644 --- a/code/common/src/logging.h +++ b/code/common/src/logging.h @@ -89,7 +89,7 @@ extern uint8_t g_log_buf_cur; } \ } \ } \ - } while(0) + } while(0) #define LOG_NOARG(log_id_, fmt_) \ do { \ @@ -114,7 +114,7 @@ extern uint8_t g_log_buf_cur; } \ } \ } \ - } while(0) + } while(0) #else #define LOG(log_id_, fmt_, ...) \ @@ -128,7 +128,7 @@ extern uint8_t g_log_buf_cur; fprintf(stdout, "%s "fmt_, log_format_timestamp(), ##__VA_ARGS__); \ } \ } \ - } while(0) + } while(0) #define LOG_NOARG(log_id_, fmt_) \ do { \ @@ -141,7 +141,7 @@ extern uint8_t g_log_buf_cur; fprintf(stdout, "%s "fmt_, log_format_timestamp()); \ } \ } \ - } while(0) + } while(0) #endif