From 11904a35cdd18e8b2ea6d15c3c7ead81a0f871c5 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 21 Mar 2007 16:31:39 -0700 Subject: [PATCH] reindent source Use kernel indentation style. Existing style was too odd. Signed-off-by: Stephen Hemminger --- bpdu_sock.c | 160 +++-- bpdu_sock.h | 2 +- bridge_track.c | 1381 ++++++++++++++++++++++--------------------- brmon.c | 204 +++---- brstate.c | 64 +- ctl_cli_wrap.c | 54 +- ctl_functions.h | 15 +- ctl_main.c | 1197 +++++++++++++++++++------------------ ctl_socket.c | 164 ++--- ctl_socket.h | 75 ++- ctl_socket_client.c | 212 +++---- ctl_socket_client.h | 3 +- ctl_socket_server.h | 2 - epoll_loop.c | 147 +++-- epoll_loop.h | 13 +- libnetlink.c | 156 ++--- log.h | 36 +- main.c | 113 ++-- netif_utils.c | 132 ++--- 19 files changed, 2131 insertions(+), 1999 deletions(-) diff --git a/bpdu_sock.c b/bpdu_sock.c index 4eb8b57..6ebfbb3 100644 --- a/bpdu_sock.c +++ b/bpdu_sock.c @@ -50,104 +50,102 @@ static const uint8_t stp_mc[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; void bpdu_send(struct epoll_event_handler *h, unsigned char *data, int len) { - struct sockaddr_llc to; - memset(&to, 0, sizeof(to)); - to.sllc_family = AF_LLC; - to.sllc_arphrd = ARPHRD_ETHER; - to.sllc_sap = LLC_SAP_BSPAN; - memcpy(to.sllc_mac, stp_mc, ETH_ALEN); - - if (fcntl(h->fd, F_SETFL, 0) < 0) - ERROR("Error unsetting O_NONBLOCK: %m"); - - int l = sendto(h->fd, data, len, 0, (struct sockaddr *)&to, sizeof(to)); - if (l < 0) - ERROR("sendto failed: %m"); - else if (l != len) - ERROR("short write in sendto: %d instead of %d", l, len); - - if (fcntl(h->fd, F_SETFL, O_NONBLOCK) < 0) - ERROR("Error setting O_NONBLOCK: %m"); + struct sockaddr_llc to; + memset(&to, 0, sizeof(to)); + to.sllc_family = AF_LLC; + to.sllc_arphrd = ARPHRD_ETHER; + to.sllc_sap = LLC_SAP_BSPAN; + memcpy(to.sllc_mac, stp_mc, ETH_ALEN); + + if (fcntl(h->fd, F_SETFL, 0) < 0) + ERROR("Error unsetting O_NONBLOCK: %m"); + + int l = sendto(h->fd, data, len, 0, (struct sockaddr *)&to, sizeof(to)); + if (l < 0) + ERROR("sendto failed: %m"); + else if (l != len) + ERROR("short write in sendto: %d instead of %d", l, len); + + if (fcntl(h->fd, F_SETFL, O_NONBLOCK) < 0) + ERROR("Error setting O_NONBLOCK: %m"); } void bpdu_rcv_handler(uint32_t events, struct epoll_event_handler *h) { - struct sockaddr_llc from; - socklen_t fromlen = sizeof(from); - int cc; - unsigned char buf[2048]; - - cc = recvfrom(h->fd, &buf, sizeof(buf), 0, - (struct sockaddr *) &from, &fromlen); - if (cc <= 0) { - ERROR("recvfrom failed: %m"); - return; - } - -#if 0 - printf("Src %02x:%02x:%02x:%02x:%02x:%02x\n", - from.sllc_mac[0], from.sllc_mac[1], - from.sllc_mac[2], from.sllc_mac[3], - from.sllc_mac[4], from.sllc_mac[5]); - int i, j; - for (i = 0; i < cc; i += 16) { - for (j = 0; j < 16 && i+j < cc; j++) - printf(" %02x", buf[i+j]); - printf("\n"); - } - printf("\n"); - fflush(stdout); + struct sockaddr_llc from; + socklen_t fromlen = sizeof(from); + int cc; + unsigned char buf[2048]; + + cc = recvfrom(h->fd, &buf, sizeof(buf), 0, + (struct sockaddr *)&from, &fromlen); + if (cc <= 0) { + ERROR("recvfrom failed: %m"); + return; + } +#if 0 + printf("Src %02x:%02x:%02x:%02x:%02x:%02x\n", + from.sllc_mac[0], from.sllc_mac[1], + from.sllc_mac[2], from.sllc_mac[3], + from.sllc_mac[4], from.sllc_mac[5]); + int i, j; + for (i = 0; i < cc; i += 16) { + for (j = 0; j < 16 && i + j < cc; j++) + printf(" %02x", buf[i + j]); + printf("\n"); + } + printf("\n"); + fflush(stdout); #endif - bpdu_rcv(h->arg, buf, cc); + bpdu_rcv(h->arg, buf, cc); } - /* We added name as an arg here because we can't do if_indextoname here, That needs which conflicts with */ /* Needs fixing. Socket should be closed in case of errors */ int bpdu_sock_create(struct epoll_event_handler *h, - int if_index, char *name, struct ifdata *arg) + int if_index, char *name, struct ifdata *arg) { - struct sockaddr_llc llc_addr; - memset(&llc_addr, 0, sizeof(llc_addr)); - llc_addr.sllc_family = AF_LLC; - llc_addr.sllc_arphrd = ARPHRD_ETHER; - llc_addr.sllc_sap = LLC_SAP_BSPAN; - - int s; - TSTM((s = socket(AF_LLC, SOCK_DGRAM, 0)) >= 0, -1, "%m"); - - TST(get_hwaddr(name, llc_addr.sllc_mac) == 0, -1); - - TSTM(bind(s, (struct sockaddr *) &llc_addr, sizeof(llc_addr)) == 0, -1, - "Can't bind to LLC SAP %#x: %m", llc_addr.sllc_sap); - { - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, name, IFNAMSIZ); - ifr.ifr_hwaddr.sa_family = AF_UNSPEC; - memcpy(ifr.ifr_hwaddr.sa_data, stp_mc, ETH_ALEN); - - TSTM(ioctl(s, SIOCADDMULTI, &ifr) == 0, -1, - "can't set multicast address for %s: %m", ifr.ifr_name); - } - - TSTM(fcntl(s, F_SETFL, O_NONBLOCK) == 0, -1, "%m"); - - h->fd = s; - h->arg = arg; - h->handler = bpdu_rcv_handler; + struct sockaddr_llc llc_addr; + memset(&llc_addr, 0, sizeof(llc_addr)); + llc_addr.sllc_family = AF_LLC; + llc_addr.sllc_arphrd = ARPHRD_ETHER; + llc_addr.sllc_sap = LLC_SAP_BSPAN; + + int s; + + TSTM((s = socket(AF_LLC, SOCK_DGRAM, 0)) >= 0, -1, "%m"); - if (add_epoll(h) < 0) - return -1; + TST(get_hwaddr(name, llc_addr.sllc_mac) == 0, -1); - return 0; + TSTM(bind(s, (struct sockaddr *)&llc_addr, sizeof(llc_addr)) == 0, -1, + "Can't bind to LLC SAP %#x: %m", llc_addr.sllc_sap); + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, IFNAMSIZ); + ifr.ifr_hwaddr.sa_family = AF_UNSPEC; + memcpy(ifr.ifr_hwaddr.sa_data, stp_mc, ETH_ALEN); + + TSTM(ioctl(s, SIOCADDMULTI, &ifr) == 0, -1, + "can't set multicast address for %s: %m", ifr.ifr_name); + } + + TSTM(fcntl(s, F_SETFL, O_NONBLOCK) == 0, -1, "%m"); + + h->fd = s; + h->arg = arg; + h->handler = bpdu_rcv_handler; + + if (add_epoll(h) < 0) + return -1; + + return 0; } void bpdu_sock_delete(struct epoll_event_handler *h) { - remove_epoll(h); - close(h->fd); + remove_epoll(h); + close(h->fd); } - diff --git a/bpdu_sock.h b/bpdu_sock.h index 14413e4..d402070 100644 --- a/bpdu_sock.h +++ b/bpdu_sock.h @@ -32,7 +32,7 @@ struct ifdata; void bpdu_send(struct epoll_event_handler *h, unsigned char *data, int len); int bpdu_sock_create(struct epoll_event_handler *h, - int if_index, char *name, struct ifdata *ifdata); + int if_index, char *name, struct ifdata *ifdata); void bpdu_sock_delete(struct epoll_event_handler *h); diff --git a/bridge_track.c b/bridge_track.c index f761840..bf4a2da 100644 --- a/bridge_track.c +++ b/bridge_track.c @@ -42,46 +42,44 @@ #include "log.h" - /*------------------------------------------------------------*/ -struct ifdata -{ - int if_index; - struct ifdata *next; - int up; - char name[IFNAMSIZ]; - - int is_bridge; - /* If bridge */ - struct ifdata *bridge_next; - struct ifdata *port_list; - int do_stp; - int stp_up; - struct stp_instance *stp; - UID_BRIDGE_ID_T bridge_id; - /* Bridge config */ - UID_STP_MODE_T stp_enabled; - int bridge_priority; - int max_age; - int hello_time; - int forward_delay; - int force_version; - int hold_time; - - /* If port */ - int speed; - int duplex; - struct ifdata *master; - struct ifdata *port_next; - /* STP port index */ - int port_index; - /* STP port config */ - int port_priority; - int admin_port_path_cost; - ADMIN_P2P_T admin_point2point; - unsigned char admin_edge; - unsigned char admin_non_stp; /* 1- doesn't participate in STP, 1 - regular */ +struct ifdata { + int if_index; + struct ifdata *next; + int up; + char name[IFNAMSIZ]; + + int is_bridge; + /* If bridge */ + struct ifdata *bridge_next; + struct ifdata *port_list; + int do_stp; + int stp_up; + struct stp_instance *stp; + UID_BRIDGE_ID_T bridge_id; + /* Bridge config */ + UID_STP_MODE_T stp_enabled; + int bridge_priority; + int max_age; + int hello_time; + int forward_delay; + int force_version; + int hold_time; + + /* If port */ + int speed; + int duplex; + struct ifdata *master; + struct ifdata *port_next; + /* STP port index */ + int port_index; + /* STP port config */ + int port_priority; + int admin_port_path_cost; + ADMIN_P2P_T admin_point2point; + unsigned char admin_edge; + unsigned char admin_non_stp; /* 1- doesn't participate in STP, 1 - regular */ }; /* Instances */ @@ -89,204 +87,204 @@ struct ifdata *current_br = NULL; void instance_begin(struct ifdata *br) { - if (current_br) { - ERROR("BUG: Trying to set instance over existing instance."); - ERROR("%d", *(int *)0); /* ABORT */ - } - current_br = br; - STP_IN_instance_begin(br->stp); + if (current_br) { + ERROR("BUG: Trying to set instance over existing instance."); + ERROR("%d", *(int *)0); /* ABORT */ + } + current_br = br; + STP_IN_instance_begin(br->stp); } void instance_end(void) { - STP_IN_instance_end(current_br->stp); - current_br = NULL; + STP_IN_instance_end(current_br->stp); + current_br = NULL; } struct ifdata *find_port(int port_index) { - struct ifdata *ifc = current_br->port_list; - while (ifc && ifc->port_index != port_index) - ifc=ifc->port_next; - return ifc; + struct ifdata *ifc = current_br->port_list; + while (ifc && ifc->port_index != port_index) + ifc = ifc->port_next; + return ifc; } - /*************************************************************/ /* Bridge and port defaults */ UID_STP_CFG_T default_bridge_stp_cfg = { - .field_mask = BR_CFG_ALL, - .bridge_priority = DEF_BR_PRIO, - .max_age = DEF_BR_MAXAGE, - .hello_time = DEF_BR_HELLOT, - .forward_delay = DEF_BR_FWDELAY, - .force_version = DEF_FORCE_VERS, /*NORMAL_RSTP*/ + .field_mask = BR_CFG_ALL, + .bridge_priority = DEF_BR_PRIO, + .max_age = DEF_BR_MAXAGE, + .hello_time = DEF_BR_HELLOT, + .forward_delay = DEF_BR_FWDELAY, + .force_version = DEF_FORCE_VERS, /*NORMAL_RSTP */ }; -void update_bridge_stp_config(struct ifdata *br, UID_STP_CFG_T *cfg) +void update_bridge_stp_config(struct ifdata *br, UID_STP_CFG_T * cfg) { - if (cfg->field_mask & BR_CFG_PRIO) - br->bridge_priority = cfg->bridge_priority; - if (cfg->field_mask & BR_CFG_AGE) - br->max_age = cfg->max_age; - if (cfg->field_mask & BR_CFG_HELLO) - br->hello_time = cfg->hello_time; - if (cfg->field_mask & BR_CFG_DELAY) - br->forward_delay = cfg->forward_delay; - if (cfg->field_mask & BR_CFG_FORCE_VER) - br->force_version = cfg->force_version; + if (cfg->field_mask & BR_CFG_PRIO) + br->bridge_priority = cfg->bridge_priority; + if (cfg->field_mask & BR_CFG_AGE) + br->max_age = cfg->max_age; + if (cfg->field_mask & BR_CFG_HELLO) + br->hello_time = cfg->hello_time; + if (cfg->field_mask & BR_CFG_DELAY) + br->forward_delay = cfg->forward_delay; + if (cfg->field_mask & BR_CFG_FORCE_VER) + br->force_version = cfg->force_version; } UID_STP_PORT_CFG_T default_port_stp_cfg = { - .field_mask = PT_CFG_ALL, - .port_priority = DEF_PORT_PRIO, - .admin_non_stp = DEF_ADMIN_NON_STP, - .admin_edge = False, // DEF_ADMIN_EDGE, - .admin_port_path_cost = ADMIN_PORT_PATH_COST_AUTO, - .admin_point2point = DEF_P2P, + .field_mask = PT_CFG_ALL, + .port_priority = DEF_PORT_PRIO, + .admin_non_stp = DEF_ADMIN_NON_STP, + .admin_edge = False, // DEF_ADMIN_EDGE, + .admin_port_path_cost = ADMIN_PORT_PATH_COST_AUTO, + .admin_point2point = DEF_P2P, }; -void update_port_stp_config(struct ifdata *ifc, UID_STP_PORT_CFG_T *cfg) +void update_port_stp_config(struct ifdata *ifc, UID_STP_PORT_CFG_T * cfg) { - if (cfg->field_mask & PT_CFG_PRIO) - ifc->port_priority = cfg->port_priority; - if (cfg->field_mask & PT_CFG_NON_STP) - ifc->admin_non_stp = cfg->admin_non_stp; - if (cfg->field_mask & PT_CFG_EDGE) - ifc->admin_edge = cfg->admin_edge; - if (cfg->field_mask & PT_CFG_COST) - ifc->admin_port_path_cost = cfg->admin_port_path_cost; - if (cfg->field_mask & PT_CFG_P2P) - ifc->admin_point2point = cfg->admin_point2point; + if (cfg->field_mask & PT_CFG_PRIO) + ifc->port_priority = cfg->port_priority; + if (cfg->field_mask & PT_CFG_NON_STP) + ifc->admin_non_stp = cfg->admin_non_stp; + if (cfg->field_mask & PT_CFG_EDGE) + ifc->admin_edge = cfg->admin_edge; + if (cfg->field_mask & PT_CFG_COST) + ifc->admin_port_path_cost = cfg->admin_port_path_cost; + if (cfg->field_mask & PT_CFG_P2P) + ifc->admin_point2point = cfg->admin_point2point; } /**************************************************************/ int add_port_stp(struct ifdata *ifc) -{ /* Bridge is ifc->master */ - char name[IFNAMSIZ]; - TST(if_indextoname(ifc->if_index, name) != 0, -1); - TST((ifc->port_index = get_bridge_portno(ifc->name)) >= 0, -1); - - /* Add port to STP */ - instance_begin(ifc->master); - int r = STP_IN_port_create(0, ifc->port_index); - if (r == 0) { /* Update bridge ID */ - UID_STP_STATE_T state; - STP_IN_stpm_get_state(0, &state); - ifc->master->bridge_id = state.bridge_id; - } - instance_end(); - if ( r/* check for failure */) { - ERROR("Couldn't add port for ifindex %d to STP", ifc->if_index); - return -1; - } - return 0; +{ /* Bridge is ifc->master */ + char name[IFNAMSIZ]; + TST(if_indextoname(ifc->if_index, name) != 0, -1); + TST((ifc->port_index = get_bridge_portno(ifc->name)) >= 0, -1); + + /* Add port to STP */ + instance_begin(ifc->master); + int r = STP_IN_port_create(0, ifc->port_index); + if (r == 0) { /* Update bridge ID */ + UID_STP_STATE_T state; + STP_IN_stpm_get_state(0, &state); + ifc->master->bridge_id = state.bridge_id; + } + instance_end(); + if (r /* check for failure */ ) { + ERROR("Couldn't add port for ifindex %d to STP", ifc->if_index); + return -1; + } + return 0; } void remove_port_stp(struct ifdata *ifc) { - /* Remove port from STP */ - instance_begin(ifc->master); - int r = STP_IN_port_delete(0, ifc->port_index); - instance_end(); - ifc->port_index = -1; - if (r != 0) { - ERROR("removing port %s failed for bridge %s: %s", - ifc->name, ifc->master->name, STP_IN_get_error_explanation(r)); - } + /* Remove port from STP */ + instance_begin(ifc->master); + int r = STP_IN_port_delete(0, ifc->port_index); + instance_end(); + ifc->port_index = -1; + if (r != 0) { + ERROR("removing port %s failed for bridge %s: %s", + ifc->name, ifc->master->name, + STP_IN_get_error_explanation(r)); + } } int init_rstplib_instance(struct ifdata *br) { - br->stp = STP_IN_instance_create(); - if (br->stp == NULL) { - ERROR("Couldn't create STP instance for bridge %s", br->name); - return -1; - } + br->stp = STP_IN_instance_create(); + if (br->stp == NULL) { + ERROR("Couldn't create STP instance for bridge %s", br->name); + return -1; + } - BITMAP_T ports; BitmapClear(&ports); - instance_begin(br); - int r = STP_IN_stpm_create(0, br->name, &ports); - instance_end(); - if (r != 0) { - ERROR("stpm create failed for bridge %s: %s", - br->name, STP_IN_get_error_explanation(r)); - return -1; - } + BITMAP_T ports; + BitmapClear(&ports); + instance_begin(br); + int r = STP_IN_stpm_create(0, br->name, &ports); + instance_end(); + if (r != 0) { + ERROR("stpm create failed for bridge %s: %s", + br->name, STP_IN_get_error_explanation(r)); + return -1; + } - return 0; + return 0; } void clear_rstplib_instance(struct ifdata *br) { - instance_begin(br); - int r = STP_IN_delete_all(); - instance_end(); - if (r != 0) { - ERROR("stpm delete failed for bridge %s: %s", - br->name, STP_IN_get_error_explanation(r)); - } - - STP_IN_instance_delete(br->stp); - br->stp = NULL; + instance_begin(br); + int r = STP_IN_delete_all(); + instance_end(); + if (r != 0) { + ERROR("stpm delete failed for bridge %s: %s", + br->name, STP_IN_get_error_explanation(r)); + } + + STP_IN_instance_delete(br->stp); + br->stp = NULL; } int init_bridge_stp(struct ifdata *br) { - if (br->stp_up) { - ERROR("STP already started"); - return 0; - } - - /* Init STP state */ - TST(init_rstplib_instance(br) == 0, -1); - - struct ifdata *p = br->port_list; - while (p) { - if (add_port_stp(p) != 0) - break; - p = p->port_next; - } - if (p) { - struct ifdata *q = br->port_list; - while (q != p) { - remove_port_stp(q); - q = q->port_next; - } - /* Clear bridge STP state */ - clear_rstplib_instance(br); - return -1; - } - br->stp_up = 1; - return 0; + if (br->stp_up) { + ERROR("STP already started"); + return 0; + } + + /* Init STP state */ + TST(init_rstplib_instance(br) == 0, -1); + + struct ifdata *p = br->port_list; + while (p) { + if (add_port_stp(p) != 0) + break; + p = p->port_next; + } + if (p) { + struct ifdata *q = br->port_list; + while (q != p) { + remove_port_stp(q); + q = q->port_next; + } + /* Clear bridge STP state */ + clear_rstplib_instance(br); + return -1; + } + br->stp_up = 1; + return 0; } void clear_bridge_stp(struct ifdata *br) { - if (!br->stp_up) - return; - br->stp_up = 0; - struct ifdata *p = br->port_list; - while (p) { - remove_port_stp(p); - p = p->port_next; - } - /* Clear bridge STP state */ - clear_rstplib_instance(br); + if (!br->stp_up) + return; + br->stp_up = 0; + struct ifdata *p = br->port_list; + while (p) { + remove_port_stp(p); + p = p->port_next; + } + /* Clear bridge STP state */ + clear_rstplib_instance(br); } - struct ifdata *if_head = NULL; struct ifdata *br_head = NULL; struct ifdata *find_if(int if_index) { - struct ifdata *p = if_head; - while (p && p->if_index != if_index) - p = p->next; - return p; + struct ifdata *p = if_head; + while (p && p->if_index != if_index) + p = p->next; + return p; } #define ADD_TO_LIST(_list, _next, _ifc) \ @@ -310,281 +308,289 @@ struct ifdata *find_if(int if_index) /* If br is NULL, new interface is a bridge, else it is a port of br */ struct ifdata *create_if(int if_index, struct ifdata *br) { - struct ifdata *p; - TST((p = malloc(sizeof(*p))) != NULL, NULL); - - /* Init fields */ - p->if_index = if_index; - p->is_bridge = (br == NULL); - memset(p->name, 0, sizeof(p->name)); - if_indextoname(if_index, p->name); - if (p->is_bridge) { - INFO("Add bridge %s", p->name); - /* Init slave list */ - p->port_list = NULL; - - p->do_stp = 0; - p->up = 0; - p->stp_up = 0; - p->stp = NULL; - update_bridge_stp_config(p, &default_bridge_stp_cfg); - ADD_TO_LIST(br_head, bridge_next, p); /* Add to bridge list */ - } - else { - INFO("Add iface %s to bridge %s", p->name, br->name); - p->up = 0; - p->speed = 0; - p->duplex = 0; - p->master = br; - update_port_stp_config(p, &default_port_stp_cfg); - ADD_TO_LIST(br->port_list, port_next, p); /* Add to bridge port list */ - if (br->stp_up) { - add_port_stp(p); - } - } - /* Add to interface list */ - ADD_TO_LIST(if_head, next, p); - - return p; + struct ifdata *p; + TST((p = malloc(sizeof(*p))) != NULL, NULL); + + /* Init fields */ + p->if_index = if_index; + p->is_bridge = (br == NULL); + memset(p->name, 0, sizeof(p->name)); + if_indextoname(if_index, p->name); + if (p->is_bridge) { + INFO("Add bridge %s", p->name); + /* Init slave list */ + p->port_list = NULL; + + p->do_stp = 0; + p->up = 0; + p->stp_up = 0; + p->stp = NULL; + update_bridge_stp_config(p, &default_bridge_stp_cfg); + ADD_TO_LIST(br_head, bridge_next, p); /* Add to bridge list */ + } else { + INFO("Add iface %s to bridge %s", p->name, br->name); + p->up = 0; + p->speed = 0; + p->duplex = 0; + p->master = br; + update_port_stp_config(p, &default_port_stp_cfg); + ADD_TO_LIST(br->port_list, port_next, p); /* Add to bridge port list */ + if (br->stp_up) { + add_port_stp(p); + } + } + /* Add to interface list */ + ADD_TO_LIST(if_head, next, p); + + return p; } void delete_if(struct ifdata *ifc) { - INFO("Delete iface %s", ifc->name); - if (ifc->is_bridge) { /* Bridge: */ - /* Stop STP */ - clear_bridge_stp(ifc); - /* Delete ports */ - while (ifc->port_list) - delete_if(ifc->port_list); - /* Remove from bridge list */ - REMOVE_FROM_LIST(br_head, bridge_next, ifc, - "Can't find interface ifindex %d bridge list", - ifc->if_index); - } - else { /* Port */ - if (ifc->master->stp_up) - remove_port_stp(ifc); - /* Remove from bridge port list */ - REMOVE_FROM_LIST(ifc->master->port_list, port_next, ifc, - "Can't find interface ifindex %d on br %d's port list", - ifc->if_index, ifc->master->if_index); - } - /* Remove from bridge interface list */ - REMOVE_FROM_LIST(if_head, next, ifc, - "Can't find interface ifindex %d on iflist", - ifc->if_index); + INFO("Delete iface %s", ifc->name); + if (ifc->is_bridge) { /* Bridge: */ + /* Stop STP */ + clear_bridge_stp(ifc); + /* Delete ports */ + while (ifc->port_list) + delete_if(ifc->port_list); + /* Remove from bridge list */ + REMOVE_FROM_LIST(br_head, bridge_next, ifc, + "Can't find interface ifindex %d bridge list", + ifc->if_index); + } else { /* Port */ + if (ifc->master->stp_up) + remove_port_stp(ifc); + /* Remove from bridge port list */ + REMOVE_FROM_LIST(ifc->master->port_list, port_next, ifc, + "Can't find interface ifindex %d on br %d's port list", + ifc->if_index, ifc->master->if_index); + } + /* Remove from bridge interface list */ + REMOVE_FROM_LIST(if_head, next, ifc, + "Can't find interface ifindex %d on iflist", + ifc->if_index); } void set_br_up(struct ifdata *br, int up) { - if (up != br->up) { - br->up = up; - if (br->do_stp) - up?(void)init_bridge_stp(br):clear_bridge_stp(br); - } + if (up != br->up) { + br->up = up; + if (br->do_stp) + up ? (void)init_bridge_stp(br) : clear_bridge_stp(br); + } } void set_if_up(struct ifdata *ifc, int up) { - INFO("Port %s : %s", ifc->name, (up?"up":"down")); - int speed = -1; - int duplex = -1; - int notify_flags = 0; - const int NOTIFY_UP = 1, NOTIFY_SPEED = 2, NOTIFY_DUPLEX = 4; - if (!up) { /* Down */ - if (ifc->up) { - ifc->up = up; - notify_flags |= NOTIFY_UP; - } - } - else { /* Up */ - int r = ethtool_get_speed_duplex(ifc->name, &speed, &duplex); - if (r < 0) { /* Didn't succeed */ - } - if (speed < 0) speed = 10; - if (duplex < 0) duplex = 0; /* Assume half duplex */ - - if (speed != ifc->speed) { - ifc->speed = speed; - notify_flags |= NOTIFY_SPEED; - } - if (duplex != ifc->duplex) { - ifc->duplex = duplex; - notify_flags |= NOTIFY_DUPLEX; - } - if (!ifc->up) { - ifc->up = 1; - notify_flags |= NOTIFY_UP; - } - } - if (notify_flags && ifc->master->stp_up) { - instance_begin(ifc->master); - - if (notify_flags & NOTIFY_SPEED) - STP_IN_changed_port_speed(ifc->port_index, speed); - if (notify_flags & NOTIFY_DUPLEX) - STP_IN_changed_port_duplex(ifc->port_index); - if (notify_flags & NOTIFY_UP) - STP_IN_enable_port(ifc->port_index, ifc->up); - - instance_end(); - } + INFO("Port %s : %s", ifc->name, (up ? "up" : "down")); + int speed = -1; + int duplex = -1; + int notify_flags = 0; + const int NOTIFY_UP = 1, NOTIFY_SPEED = 2, NOTIFY_DUPLEX = 4; + if (!up) { /* Down */ + if (ifc->up) { + ifc->up = up; + notify_flags |= NOTIFY_UP; + } + } else { /* Up */ + int r = ethtool_get_speed_duplex(ifc->name, &speed, &duplex); + if (r < 0) { /* Didn't succeed */ + } + if (speed < 0) + speed = 10; + if (duplex < 0) + duplex = 0; /* Assume half duplex */ + + if (speed != ifc->speed) { + ifc->speed = speed; + notify_flags |= NOTIFY_SPEED; + } + if (duplex != ifc->duplex) { + ifc->duplex = duplex; + notify_flags |= NOTIFY_DUPLEX; + } + if (!ifc->up) { + ifc->up = 1; + notify_flags |= NOTIFY_UP; + } + } + if (notify_flags && ifc->master->stp_up) { + instance_begin(ifc->master); + + if (notify_flags & NOTIFY_SPEED) + STP_IN_changed_port_speed(ifc->port_index, speed); + if (notify_flags & NOTIFY_DUPLEX) + STP_IN_changed_port_duplex(ifc->port_index); + if (notify_flags & NOTIFY_UP) + STP_IN_enable_port(ifc->port_index, ifc->up); + + instance_end(); + } } /*------------------------------------------------------------*/ int bridge_notify(int br_index, int if_index, int newlink, int up) { - if (up) up = 1; - LOG("br_index %d, if_index %d, up %d", br_index, if_index, up); - - struct ifdata *br = NULL; - if (br_index >= 0) { - br = find_if(br_index); - if (br && !br->is_bridge) { - ERROR("Notification shows non bridge interface %d as bridge.", br_index); - return -1; - } - if (!br) - br = create_if(br_index, NULL); - if (!br) { - ERROR("Couldn't create data for bridge interface %d", br_index); - return -1; - } - /* Bridge must be up if we get such notifications */ - if (!br->up) - set_br_up(br, 1); - } - - struct ifdata *ifc = find_if(if_index); - - if (br) { - if (ifc) { - if (ifc->is_bridge) { - ERROR("Notification shows bridge interface %d as slave of %d", - if_index, br_index); - return -1; - } - if (ifc->master != br) { - INFO("Device %d has come to bridge %d. " - "Missed notify for deletion from bridge %d", - if_index, br_index, ifc->master->if_index); - delete_if(ifc); - ifc = NULL; - } - } - if (!ifc) - ifc = create_if(if_index, br); - if (!ifc) { - ERROR("Couldn't create data for interface %d (master %d)", - if_index, br_index); - return -1; - } - if (!newlink && !is_bridge_slave(br->name, ifc->name)) { - /* brctl delif generates a DELLINK, but so does ifconfig down. - So check and delete if it has been removed. - */ - delete_if(ifc); - return 0; - } - if (ifc->up != up) - set_if_up(ifc, up); /* And speed and duplex */ - } - else { /* No br_index */ - if (!newlink) { - /* DELLINK not from bridge means interface unregistered. */ - /* Cleanup removed bridge or removed bridge slave */ - if (ifc) - delete_if(ifc); - return 0; - } - else { /* This may be a new link */ - if (!ifc) { - char ifname[IFNAMSIZ]; - if (if_indextoname(if_index, ifname) && is_bridge(ifname)) { - ifc = create_if(if_index, NULL); - if (!ifc) { - ERROR("Couldn't create data for bridge interface %d", if_index); - return -1; - } - } - } - if (ifc && !ifc->is_bridge && - !is_bridge_slave(ifc->master->name, ifc->name)) { - /* Interface might have left bridge and we might have missed deletion */ - delete_if(ifc); - return 0; - } - if (ifc && ifc->up != up) { - if (ifc->is_bridge) - set_br_up(ifc, up); - else - set_if_up(ifc, up); - } - } - } - return 0; + if (up) + up = 1; + LOG("br_index %d, if_index %d, up %d", br_index, if_index, up); + + struct ifdata *br = NULL; + if (br_index >= 0) { + br = find_if(br_index); + if (br && !br->is_bridge) { + ERROR + ("Notification shows non bridge interface %d as bridge.", + br_index); + return -1; + } + if (!br) + br = create_if(br_index, NULL); + if (!br) { + ERROR("Couldn't create data for bridge interface %d", + br_index); + return -1; + } + /* Bridge must be up if we get such notifications */ + if (!br->up) + set_br_up(br, 1); + } + + struct ifdata *ifc = find_if(if_index); + + if (br) { + if (ifc) { + if (ifc->is_bridge) { + ERROR + ("Notification shows bridge interface %d as slave of %d", + if_index, br_index); + return -1; + } + if (ifc->master != br) { + INFO("Device %d has come to bridge %d. " + "Missed notify for deletion from bridge %d", + if_index, br_index, ifc->master->if_index); + delete_if(ifc); + ifc = NULL; + } + } + if (!ifc) + ifc = create_if(if_index, br); + if (!ifc) { + ERROR + ("Couldn't create data for interface %d (master %d)", + if_index, br_index); + return -1; + } + if (!newlink && !is_bridge_slave(br->name, ifc->name)) { + /* brctl delif generates a DELLINK, but so does ifconfig down. + So check and delete if it has been removed. + */ + delete_if(ifc); + return 0; + } + if (ifc->up != up) + set_if_up(ifc, up); /* And speed and duplex */ + } else { /* No br_index */ + if (!newlink) { + /* DELLINK not from bridge means interface unregistered. */ + /* Cleanup removed bridge or removed bridge slave */ + if (ifc) + delete_if(ifc); + return 0; + } else { /* This may be a new link */ + if (!ifc) { + char ifname[IFNAMSIZ]; + if (if_indextoname(if_index, ifname) + && is_bridge(ifname)) { + ifc = create_if(if_index, NULL); + if (!ifc) { + ERROR + ("Couldn't create data for bridge interface %d", + if_index); + return -1; + } + } + } + if (ifc && !ifc->is_bridge && + !is_bridge_slave(ifc->master->name, ifc->name)) { + /* Interface might have left bridge and we might have missed deletion */ + delete_if(ifc); + return 0; + } + if (ifc && ifc->up != up) { + if (ifc->is_bridge) + set_br_up(ifc, up); + else + set_if_up(ifc, up); + } + } + } + return 0; } void bridge_bpdu_rcv(int if_index, const unsigned char *data, int len) { - LOG("ifindex %d, len %d", if_index, len); - struct ifdata *ifc = find_if(if_index); - TST(ifc && !ifc->is_bridge, ); - TST(ifc->up && ifc->master->stp_up, ); - BPDU_T bpdu; - memset(&bpdu.eth, 0, sizeof(bpdu.eth)); - if (len > sizeof(bpdu) - sizeof(bpdu.eth)) - len = sizeof(bpdu) - sizeof(bpdu.eth); - memcpy(&bpdu.hdr, data, len); - /* Do some validation */ - TST(len >= 4, ); - TST(bpdu.hdr.protocol[0] == 0 && bpdu.hdr.protocol[1] == 0, ); - switch (bpdu.hdr.bpdu_type) { - case BPDU_RSTP: - TST(len >= 36, ); - case BPDU_CONFIG_TYPE: - TST(len >= 35, ); - /* 802.1w doesn't ask for this */ - // TST(ntohs(*(uint16_t*)bpdu.body.message_age) - // < ntohs(*(uint16_t*)bpdu.body.max_age), ); - TST(memcmp(bpdu.body.bridge_id, &ifc->master->bridge_id, 8) != 0 || - (ntohs(*(uint16_t *)bpdu.body.port_id) & 0xfff) != ifc->port_index, ); - break; - case BPDU_TOPO_CHANGE_TYPE: - break; - default: - TST(0, ); - } - - // dump_hex(data, len); - instance_begin(ifc->master); - int r = STP_IN_rx_bpdu(0, ifc->port_index, &bpdu, len + sizeof(bpdu.eth)); - if (r) - ERROR("STP_IN_rx_bpdu on port %s returned %s", ifc->name, - STP_IN_get_error_explanation(r)); - instance_end(); + LOG("ifindex %d, len %d", if_index, len); + struct ifdata *ifc = find_if(if_index); + TST(ifc && !ifc->is_bridge,); + TST(ifc->up && ifc->master->stp_up,); + BPDU_T bpdu; + memset(&bpdu.eth, 0, sizeof(bpdu.eth)); + if (len > sizeof(bpdu) - sizeof(bpdu.eth)) + len = sizeof(bpdu) - sizeof(bpdu.eth); + memcpy(&bpdu.hdr, data, len); + /* Do some validation */ + TST(len >= 4,); + TST(bpdu.hdr.protocol[0] == 0 && bpdu.hdr.protocol[1] == 0,); + switch (bpdu.hdr.bpdu_type) { + case BPDU_RSTP: + TST(len >= 36,); + case BPDU_CONFIG_TYPE: + TST(len >= 35,); + /* 802.1w doesn't ask for this */ + // TST(ntohs(*(uint16_t*)bpdu.body.message_age) + // < ntohs(*(uint16_t*)bpdu.body.max_age), ); + TST(memcmp(bpdu.body.bridge_id, &ifc->master->bridge_id, 8) != 0 + || (ntohs(*(uint16_t *) bpdu.body.port_id) & 0xfff) != + ifc->port_index,); + break; + case BPDU_TOPO_CHANGE_TYPE: + break; + default: + TST(0,); + } + + // dump_hex(data, len); + instance_begin(ifc->master); + int r = + STP_IN_rx_bpdu(0, ifc->port_index, &bpdu, len + sizeof(bpdu.eth)); + if (r) + ERROR("STP_IN_rx_bpdu on port %s returned %s", ifc->name, + STP_IN_get_error_explanation(r)); + instance_end(); } void bridge_one_second(void) { - // LOG(""); - struct ifdata *br; - for (br = br_head; br; br = br->bridge_next) { - if (br->stp_up) { - instance_begin(br); - STP_IN_one_second(); - instance_end(); - } - } - - /* To get information about port changes when bridge is down */ - /* But won't work so well since we will not sense deletions */ - static int count = 0; - count++; - if (count % 60 == 0) - bridge_get_configuration(); + // LOG(""); + struct ifdata *br; + for (br = br_head; br; br = br->bridge_next) { + if (br->stp_up) { + instance_begin(br); + STP_IN_one_second(); + instance_end(); + } + } + + /* To get information about port changes when bridge is down */ + /* But won't work so well since we will not sense deletions */ + static int count = 0; + count++; + if (count % 60 == 0) + bridge_get_configuration(); } @@ -592,187 +598,181 @@ void bridge_one_second(void) int flush_port(char *sys_name) { - FILE *f = fopen(sys_name, "w"); - TSTM(f, -1, "Couldn't open flush file %s for write.", sys_name); - int r = fwrite("1", 1, 1, f); - fclose(f); - TST(r == 1, -1); - return 0; + FILE *f = fopen(sys_name, "w"); + TSTM(f, -1, "Couldn't open flush file %s for write.", sys_name); + int r = fwrite("1", 1, 1, f); + fclose(f); + TST(r == 1, -1); + return 0; } int -STP_OUT_flush_lt (IN int port_index, IN int vlan_id, - IN LT_FLASH_TYPE_T type, IN char* reason) -{ - LOG("port index %d, flash type %d, reason %s", port_index, type, reason); - TST(vlan_id == 0, 0); - - char fname[128]; - if (port_index == 0) {/* i.e. passed port_index was 0 */ - sprintf(fname, "/sys/class/net/%s/bridge/flush", current_br->name); - flush_port(fname); - } - else if (type == LT_FLASH_ONLY_THE_PORT) { - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - sprintf(fname, "/sys/class/net/%s/brif/%s/flush", - current_br->name, port->name); - flush_port(fname); - } - else if (type == LT_FLASH_ALL_PORTS_EXCLUDE_THIS) { - struct ifdata *port; - for (port = current_br->port_list; port; port = port->port_next) { - if (port->port_index != port_index) { - sprintf(fname, "/sys/class/net/%s/brif/%s/flush", - current_br->name, port->name); - flush_port(fname); - } - } - } - else - TST(0, 0); - - return 0; -} - -void /* for bridge id calculation */ -STP_OUT_get_port_mac (IN int port_index, OUT unsigned char* mac) -{ - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, ); - get_hwaddr(port->name, mac); -} - -unsigned long -STP_OUT_get_port_oper_speed (IN unsigned int port_index) -{ - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - LOG("Speed: %d", port->speed); - return port->speed; -} - -int /* 1- Up, 0- Down */ -STP_OUT_get_port_link_status (IN int port_index) -{ - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - LOG("Link status: %d", port->up); - return port->up; -} - -int /* 1- Full, 0- Half */ -STP_OUT_get_duplex (IN int port_index) -{ - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - LOG("Duplex: %d", port->duplex); - return port->duplex; +STP_OUT_flush_lt(IN int port_index, IN int vlan_id, + IN LT_FLASH_TYPE_T type, IN char *reason) +{ + LOG("port index %d, flash type %d, reason %s", port_index, type, + reason); + TST(vlan_id == 0, 0); + + char fname[128]; + if (port_index == 0) { /* i.e. passed port_index was 0 */ + sprintf(fname, "/sys/class/net/%s/bridge/flush", + current_br->name); + flush_port(fname); + } else if (type == LT_FLASH_ONLY_THE_PORT) { + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + sprintf(fname, "/sys/class/net/%s/brif/%s/flush", + current_br->name, port->name); + flush_port(fname); + } else if (type == LT_FLASH_ALL_PORTS_EXCLUDE_THIS) { + struct ifdata *port; + for (port = current_br->port_list; port; port = port->port_next) { + if (port->port_index != port_index) { + sprintf(fname, + "/sys/class/net/%s/brif/%s/flush", + current_br->name, port->name); + flush_port(fname); + } + } + } else + TST(0, 0); + + return 0; } -int -STP_OUT_set_port_state (IN int port_index, IN int vlan_id, IN RSTP_PORT_STATE state) -{ - LOG("port index %d, state %d", port_index, state); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - TST(vlan_id == 0, 0); - - int br_state; - switch (state) { - case UID_PORT_DISCARDING: - br_state = BR_STATE_BLOCKING; break; - case UID_PORT_LEARNING: - br_state = BR_STATE_LEARNING; break; - case UID_PORT_FORWARDING: - br_state = BR_STATE_FORWARDING; break; - default: - fprintf(stderr, "set_port_state: Unexpected state %d\n", state); - return -1; - } - if (port->up) - bridge_set_state(port->if_index, br_state); - return 0; +void /* for bridge id calculation */ STP_OUT_get_port_mac(IN int port_index, + OUT unsigned char + *mac) +{ + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL,); + get_hwaddr(port->name, mac); } -int -STP_OUT_set_hardware_mode (int vlan_id, UID_STP_MODE_T mode) +unsigned long STP_OUT_get_port_oper_speed(IN unsigned int port_index) { - LOG("vlan id %d, mode %d", vlan_id, mode); - return 0; + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + LOG("Speed: %d", port->speed); + return port->speed; } -int -STP_OUT_tx_bpdu (IN int port_index, IN int vlan_id, - IN unsigned char* bpdu, - IN size_t bpdu_len) +int /* 1- Up, 0- Down */ STP_OUT_get_port_link_status(IN int port_index) { - LOG("port index %d, len %zd", port_index, bpdu_len); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - TST(vlan_id == 0, 0); - // dump_hex(bpdu + sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T), - // bpdu_len - (sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T))); - bridge_send_bpdu(port->if_index, - bpdu + sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T), - bpdu_len); // The length we get excludes headers! - return 0; + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + LOG("Link status: %d", port->up); + return port->up; } -const char * -STP_OUT_get_port_name (IN int port_index) +int /* 1- Full, 0- Half */ STP_OUT_get_duplex(IN int port_index) { - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - return port->name; + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + LOG("Duplex: %d", port->duplex); + return port->duplex; +} + +int +STP_OUT_set_port_state(IN int port_index, IN int vlan_id, + IN RSTP_PORT_STATE state) +{ + LOG("port index %d, state %d", port_index, state); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + TST(vlan_id == 0, 0); + + int br_state; + switch (state) { + case UID_PORT_DISCARDING: + br_state = BR_STATE_BLOCKING; + break; + case UID_PORT_LEARNING: + br_state = BR_STATE_LEARNING; + break; + case UID_PORT_FORWARDING: + br_state = BR_STATE_FORWARDING; + break; + default: + fprintf(stderr, "set_port_state: Unexpected state %d\n", state); + return -1; + } + if (port->up) + bridge_set_state(port->if_index, br_state); + return 0; +} + +int STP_OUT_set_hardware_mode(int vlan_id, UID_STP_MODE_T mode) +{ + LOG("vlan id %d, mode %d", vlan_id, mode); + return 0; } int -STP_OUT_get_init_stpm_cfg (IN int vlan_id, - INOUT UID_STP_CFG_T* cfg) +STP_OUT_tx_bpdu(IN int port_index, IN int vlan_id, + IN unsigned char *bpdu, IN size_t bpdu_len) { - LOG(""); - TST(vlan_id == 0, 0); + LOG("port index %d, len %zd", port_index, bpdu_len); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + TST(vlan_id == 0, 0); + // dump_hex(bpdu + sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T), + // bpdu_len - (sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T))); + bridge_send_bpdu(port->if_index, bpdu + sizeof(MAC_HEADER_T) + sizeof(ETH_HEADER_T), bpdu_len); // The length we get excludes headers! + return 0; +} - cfg->bridge_priority = current_br->bridge_priority; - cfg->max_age = current_br->max_age; - cfg->hello_time = current_br->hello_time; - cfg->forward_delay = current_br->forward_delay; - cfg->force_version = current_br->force_version; +const char *STP_OUT_get_port_name(IN int port_index) +{ + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + return port->name; +} - return 0; +int STP_OUT_get_init_stpm_cfg(IN int vlan_id, INOUT UID_STP_CFG_T * cfg) +{ + LOG(""); + TST(vlan_id == 0, 0); + + cfg->bridge_priority = current_br->bridge_priority; + cfg->max_age = current_br->max_age; + cfg->hello_time = current_br->hello_time; + cfg->forward_delay = current_br->forward_delay; + cfg->force_version = current_br->force_version; + + return 0; } int -STP_OUT_get_init_port_cfg (IN int vlan_id, - IN int port_index, - INOUT UID_STP_PORT_CFG_T* cfg) +STP_OUT_get_init_port_cfg(IN int vlan_id, + IN int port_index, INOUT UID_STP_PORT_CFG_T * cfg) { - LOG("port index %d", port_index); - struct ifdata *port = find_port(port_index); - TST(port != NULL, 0); - TST(vlan_id == 0, 0); + LOG("port index %d", port_index); + struct ifdata *port = find_port(port_index); + TST(port != NULL, 0); + TST(vlan_id == 0, 0); - cfg->port_priority = port->port_priority; - cfg->admin_non_stp = port->admin_non_stp; - cfg->admin_edge = port->admin_edge; - cfg->admin_port_path_cost = port->admin_port_path_cost; - cfg->admin_point2point = port->admin_point2point; + cfg->port_priority = port->port_priority; + cfg->admin_non_stp = port->admin_non_stp; + cfg->admin_edge = port->admin_edge; + cfg->admin_port_path_cost = port->admin_port_path_cost; + cfg->admin_point2point = port->admin_point2point; - return 0; + return 0; } -extern void stp_trace (const char* fmt, ...) +extern void stp_trace(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vDprintf(LOG_LEVEL_RSTPLIB, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + vDprintf(LOG_LEVEL_RSTPLIB, fmt, ap); + va_end(ap); } /* Commands and status */ @@ -794,126 +794,129 @@ extern void stp_trace (const char* fmt, ...) int CTL_enable_bridge_rstp(int br_index, int enable) { - INFO("bridge %d, enable %d", br_index, enable); - int r = 0; - if (enable) enable = 1; - struct ifdata *br = find_if(br_index); - if (br == NULL) { - char ifname[IFNAMSIZ]; - if (if_indextoname(br_index, ifname) && is_bridge(ifname)) - br = create_if(br_index, NULL); - } - if (br == NULL || !br->is_bridge) return Err_Interface_not_a_bridge; - if (br->do_stp != enable) { - br->do_stp = enable; - if (br->up) - r = enable?init_bridge_stp(br):(clear_bridge_stp(br), 0); - } - return r; + INFO("bridge %d, enable %d", br_index, enable); + int r = 0; + if (enable) + enable = 1; + struct ifdata *br = find_if(br_index); + if (br == NULL) { + char ifname[IFNAMSIZ]; + if (if_indextoname(br_index, ifname) && is_bridge(ifname)) + br = create_if(br_index, NULL); + } + if (br == NULL || !br->is_bridge) + return Err_Interface_not_a_bridge; + if (br->do_stp != enable) { + br->do_stp = enable; + if (br->up) + r = enable ? init_bridge_stp(br) + : (clear_bridge_stp(br), 0); + } + return r; } int CTL_get_bridge_state(int br_index, - UID_STP_CFG_T *cfg, UID_STP_STATE_T *state) -{ - LOG("bridge %d", br_index); - CTL_CHECK_BRIDGE; - int r; - instance_begin(br); - r = STP_IN_stpm_get_state (0, state); - if (r) { - ERROR("Error getting bridge state for %d: %s", br_index, - STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - r = STP_IN_stpm_get_cfg(0, cfg); - if (r) { - ERROR("Error getting bridge config for %d: %s", br_index, - STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - instance_end(); - return 0; -} - -int CTL_set_bridge_config(int br_index, - UID_STP_CFG_T *cfg) -{ - INFO("bridge %d, flags %#lx", br_index, cfg->field_mask); - CTL_CHECK_BRIDGE; - int r; - instance_begin(br); - r = STP_IN_stpm_set_cfg (0, NULL, cfg); - if (r) { - ERROR("Error setting bridge config for %d: %s", br_index, - STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - instance_end(); - /* Change init config in ifdata so it will be applied if we - disable and enable rstp*/ - update_bridge_stp_config(br, cfg); - return 0; + UID_STP_CFG_T * cfg, UID_STP_STATE_T * state) +{ + LOG("bridge %d", br_index); + CTL_CHECK_BRIDGE; + int r; + instance_begin(br); + r = STP_IN_stpm_get_state(0, state); + if (r) { + ERROR("Error getting bridge state for %d: %s", br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + r = STP_IN_stpm_get_cfg(0, cfg); + if (r) { + ERROR("Error getting bridge config for %d: %s", br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + instance_end(); + return 0; +} + +int CTL_set_bridge_config(int br_index, UID_STP_CFG_T * cfg) +{ + INFO("bridge %d, flags %#lx", br_index, cfg->field_mask); + CTL_CHECK_BRIDGE; + int r; + instance_begin(br); + r = STP_IN_stpm_set_cfg(0, NULL, cfg); + if (r) { + ERROR("Error setting bridge config for %d: %s", br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + instance_end(); + /* Change init config in ifdata so it will be applied if we + disable and enable rstp */ + update_bridge_stp_config(br, cfg); + return 0; } int CTL_get_port_state(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg, UID_STP_PORT_STATE_T *state) -{ - LOG("bridge %d port %d", br_index, port_index); - CTL_CHECK_BRIDGE_PORT; - int r; - instance_begin(br); - state->port_no = port->port_index; - r = STP_IN_port_get_state (0, state); - if (r) { - ERROR("Error getting port state for port %d, bridge %d: %s", - port->port_index, br_index, STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - r = STP_IN_port_get_cfg(0, port->port_index, cfg); - if (r) { - ERROR("Error getting port config for port %d, bridge %d: %s", - port->port_index, br_index, STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - instance_end(); - return 0; - -} - -int CTL_set_port_config(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg) -{ - INFO("bridge %d, port %d, flags %#lx", br_index, port_index, - cfg->field_mask); - CTL_CHECK_BRIDGE_PORT; - int r; - instance_begin(br); - r = STP_IN_set_port_cfg (0, port->port_index, cfg); - if (r) { - ERROR("Error setting port config for port %d, bridge %d: %s", - port->port_index, br_index, STP_IN_get_error_explanation(r)); - instance_end(); - return r; - } - instance_end(); - /* Change init config in ifdata so it will be applied if we - disable and enable rstp*/ - update_port_stp_config(port, cfg); - return 0; + UID_STP_PORT_CFG_T * cfg, UID_STP_PORT_STATE_T * state) +{ + LOG("bridge %d port %d", br_index, port_index); + CTL_CHECK_BRIDGE_PORT; + int r; + instance_begin(br); + state->port_no = port->port_index; + r = STP_IN_port_get_state(0, state); + if (r) { + ERROR("Error getting port state for port %d, bridge %d: %s", + port->port_index, br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + r = STP_IN_port_get_cfg(0, port->port_index, cfg); + if (r) { + ERROR("Error getting port config for port %d, bridge %d: %s", + port->port_index, br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + instance_end(); + return 0; + +} + +int CTL_set_port_config(int br_index, int port_index, UID_STP_PORT_CFG_T * cfg) +{ + INFO("bridge %d, port %d, flags %#lx", br_index, port_index, + cfg->field_mask); + CTL_CHECK_BRIDGE_PORT; + int r; + instance_begin(br); + r = STP_IN_set_port_cfg(0, port->port_index, cfg); + if (r) { + ERROR("Error setting port config for port %d, bridge %d: %s", + port->port_index, br_index, + STP_IN_get_error_explanation(r)); + instance_end(); + return r; + } + instance_end(); + /* Change init config in ifdata so it will be applied if we + disable and enable rstp */ + update_port_stp_config(port, cfg); + return 0; } int CTL_set_debug_level(int level) { - INFO("level %d", level); - log_level = level; - return 0; + INFO("level %d", level); + log_level = level; + return 0; } - #undef CTL_CHECK_BRIDGE_PORT #undef CTL_CHECK_BRIDGE diff --git a/brmon.c b/brmon.c index 4afe5e1..644532f 100644 --- a/brmon.c +++ b/brmon.c @@ -30,7 +30,6 @@ static const char SNAPSHOT[] = "v0.1"; - /* RFC 2863 operational status */ enum { IF_OPER_UNKNOWN, @@ -56,53 +55,50 @@ static const char *port_states[] = { [BR_STATE_BLOCKING] = "blocking", }; - static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = arg; struct ifinfomsg *ifi = NLMSG_DATA(n); - struct rtattr * tb[IFLA_MAX+1]; + struct rtattr *tb[IFLA_MAX + 1]; int len = n->nlmsg_len; char b1[IFNAMSIZ]; int af_family = ifi->ifi_family; - if (n->nlmsg_type == NLMSG_DONE) - return 0; - + if (n->nlmsg_type == NLMSG_DONE) + return 0; + len -= NLMSG_LENGTH(sizeof(*ifi)); if (len < 0) { - return -1; - } - + return -1; + } #if 0 if (filter.ifindex && ifi->ifi_index != filter.ifindex) return 0; - if (filter.up && !(ifi->ifi_flags&IFF_UP)) + if (filter.up && !(ifi->ifi_flags & IFF_UP)) return 0; #endif - if (ifi->ifi_family != AF_BRIDGE && ifi->ifi_family != AF_UNSPEC) - return 0; + if (ifi->ifi_family != AF_BRIDGE && ifi->ifi_family != AF_UNSPEC) + return 0; - if (n->nlmsg_type != RTM_NEWLINK && - n->nlmsg_type != RTM_DELLINK) - return 0; + if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) + return 0; parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); - /* Check if we got this from bonding */ - if (tb[IFLA_MASTER] && af_family != AF_BRIDGE) - return 0; + /* Check if we got this from bonding */ + if (tb[IFLA_MASTER] && af_family != AF_BRIDGE) + return 0; - /* Check for BPDU */ - if (tb[IFLA_PRIORITY] && af_family == AF_BRIDGE) { - bridge_bpdu_rcv(ifi->ifi_index, - RTA_DATA(tb[IFLA_PRIORITY]), - RTA_PAYLOAD(tb[IFLA_PRIORITY])); - return 0; - } + /* Check for BPDU */ + if (tb[IFLA_PRIORITY] && af_family == AF_BRIDGE) { + bridge_bpdu_rcv(ifi->ifi_index, + RTA_DATA(tb[IFLA_PRIORITY]), + RTA_PAYLOAD(tb[IFLA_PRIORITY])); + return 0; + } if (tb[IFLA_IFNAME] == NULL) { fprintf(stderr, "BUG: nil ifname\n"); @@ -113,61 +109,68 @@ static int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, fprintf(fp, "Deleted "); fprintf(fp, "%d: %s ", ifi->ifi_index, - tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : ""); - + tb[IFLA_IFNAME] ? (char *)RTA_DATA(tb[IFLA_IFNAME]) : ""); if (tb[IFLA_OPERSTATE]) { - int state = *(int*)RTA_DATA(tb[IFLA_OPERSTATE]); + int state = *(int *)RTA_DATA(tb[IFLA_OPERSTATE]); switch (state) { - case IF_OPER_UNKNOWN: - fprintf(fp, "Unknown "); break; + case IF_OPER_UNKNOWN: + fprintf(fp, "Unknown "); + break; case IF_OPER_NOTPRESENT: - fprintf(fp, "Not Present "); break; + fprintf(fp, "Not Present "); + break; case IF_OPER_DOWN: - fprintf(fp, "Down "); break; + fprintf(fp, "Down "); + break; case IF_OPER_LOWERLAYERDOWN: - fprintf(fp, "Lowerlayerdown "); break; + fprintf(fp, "Lowerlayerdown "); + break; case IF_OPER_TESTING: - fprintf(fp, "Testing "); break; + fprintf(fp, "Testing "); + break; case IF_OPER_DORMANT: - fprintf(fp, "Dormant "); break; + fprintf(fp, "Dormant "); + break; case IF_OPER_UP: - fprintf(fp, "Up "); break; + fprintf(fp, "Up "); + break; default: fprintf(fp, "State(%d) ", state); } } - + if (tb[IFLA_MTU]) - fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); + fprintf(fp, "mtu %u ", *(int *)RTA_DATA(tb[IFLA_MTU])); if (tb[IFLA_MASTER]) { - fprintf(fp, "master %s ", - if_indextoname(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); + fprintf(fp, "master %s ", + if_indextoname(*(int *)RTA_DATA(tb[IFLA_MASTER]), b1)); } if (tb[IFLA_PROTINFO]) { - uint8_t state = *(uint8_t *)RTA_DATA(tb[IFLA_PROTINFO]); + uint8_t state = *(uint8_t *) RTA_DATA(tb[IFLA_PROTINFO]); if (state <= BR_STATE_BLOCKING) fprintf(fp, "state %s", port_states[state]); else fprintf(fp, "state (%d)", state); } - fprintf(fp, "\n"); fflush(fp); - { - int newlink = (n->nlmsg_type == RTM_NEWLINK); - int up = 0; - if (newlink && tb[IFLA_OPERSTATE]) { - int state = *(int*)RTA_DATA(tb[IFLA_OPERSTATE]); - up = (state == IF_OPER_UP) || (state == IF_OPER_UNKNOWN); - } - - bridge_notify((tb[IFLA_MASTER]?*(int*)RTA_DATA(tb[IFLA_MASTER]):-1), - ifi->ifi_index, newlink, up); - } + { + int newlink = (n->nlmsg_type == RTM_NEWLINK); + int up = 0; + if (newlink && tb[IFLA_OPERSTATE]) { + int state = *(int *)RTA_DATA(tb[IFLA_OPERSTATE]); + up = (state == IF_OPER_UP) + || (state == IF_OPER_UNKNOWN); + } + + bridge_notify((tb[IFLA_MASTER] ? *(int *) + RTA_DATA(tb[IFLA_MASTER]) : -1), ifi->ifi_index, + newlink, up); + } return 0; } @@ -186,8 +189,7 @@ static int matches(const char *cmd, const char *pattern) return memcmp(pattern, cmd, len); } -int -main(int argc, char **argv) +int main(int argc, char **argv) { struct rtnl_handle rth; unsigned groups = ~RTMGRP_TC; @@ -199,20 +201,23 @@ main(int argc, char **argv) printf("brmon %s\n", SNAPSHOT); exit(0); } else if (matches(argv[1], "link") == 0) { - llink=1; + llink = 1; groups = 0; } else if (matches(argv[1], "bridge") == 0) { - laddr=1; + laddr = 1; groups = 0; } else if (strcmp(argv[1], "all") == 0) { groups = ~RTMGRP_TC; } else if (matches(argv[1], "help") == 0) { usage(); } else { - fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]); + fprintf(stderr, + "Argument \"%s\" is unknown, try \"rtmon help\".\n", + argv[1]); exit(-1); } - argc--; argv++; + argc--; + argv++; } if (llink) @@ -248,53 +253,54 @@ struct rtnl_handle rth_state; void br_ev_handler(uint32_t events, struct epoll_event_handler *h) { - if (rtnl_listen(&rth, dump_msg, stdout) < 0) { - fprintf(stderr, "Error on bridge monitoring socket\n"); - exit(-1); - } + if (rtnl_listen(&rth, dump_msg, stdout) < 0) { + fprintf(stderr, "Error on bridge monitoring socket\n"); + exit(-1); + } } int init_bridge_ops(void) { - if (rtnl_open(&rth, ~RTMGRP_TC) < 0) { - fprintf(stderr, "Couldn't open rtnl socket for monitoring\n"); - return -1; - } - - if (rtnl_open(&rth_state, 0) < 0) { - fprintf(stderr, "Couldn't open rtnl socket for setting state\n"); - return -1; - } - - if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { - fprintf(stderr, "Cannot send dump request: %m\n"); - return -1; - } - - if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) { - fprintf(stderr, "Dump terminated\n"); - return -1; - } - - if (fcntl(rth.fd, F_SETFL, O_NONBLOCK) < 0) { - fprintf(stderr, "Error setting O_NONBLOCK: %m\n"); - return -1; - } - - br_handler.fd = rth.fd; - br_handler.arg = NULL; - br_handler.handler = br_ev_handler; - - if (add_epoll(&br_handler) < 0) - return -1; - - return 0; + if (rtnl_open(&rth, ~RTMGRP_TC) < 0) { + fprintf(stderr, "Couldn't open rtnl socket for monitoring\n"); + return -1; + } + + if (rtnl_open(&rth_state, 0) < 0) { + fprintf(stderr, + "Couldn't open rtnl socket for setting state\n"); + return -1; + } + + if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { + fprintf(stderr, "Cannot send dump request: %m\n"); + return -1; + } + + if (rtnl_dump_filter(&rth, dump_msg, stdout, NULL, NULL) < 0) { + fprintf(stderr, "Dump terminated\n"); + return -1; + } + + if (fcntl(rth.fd, F_SETFL, O_NONBLOCK) < 0) { + fprintf(stderr, "Error setting O_NONBLOCK: %m\n"); + return -1; + } + + br_handler.fd = rth.fd; + br_handler.arg = NULL; + br_handler.handler = br_ev_handler; + + if (add_epoll(&br_handler) < 0) + return -1; + + return 0; } /* Send message. Response is through bridge_notify */ void bridge_get_configuration(void) { - if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { - fprintf(stderr, "Cannot send dump request: %m\n"); - } + if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETLINK) < 0) { + fprintf(stderr, "Cannot send dump request: %m\n"); + } } diff --git a/brstate.c b/brstate.c index f0f9d36..c264dc7 100644 --- a/brstate.c +++ b/brstate.c @@ -39,8 +39,8 @@ static int portstate(const char *name) { int i; - for (i = 0; i < sizeof(port_states)/sizeof(port_states[0]); i++) { - if (strcasecmp(name, port_states[i]) == 0) + for (i = 0; i < sizeof(port_states) / sizeof(port_states[0]); i++) { + if (strcasecmp(name, port_states[i]) == 0) return i; } return -1; @@ -50,43 +50,43 @@ static int portstate(const char *name) static int br_set_state(struct rtnl_handle *rth, unsigned ifindex, __u8 state) { struct { - struct nlmsghdr n; - struct ifinfomsg ifi; - char buf[256]; + struct nlmsghdr n; + struct ifinfomsg ifi; + char buf[256]; } req; memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_REPLACE; + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE; req.n.nlmsg_type = RTM_SETLINK; req.ifi.ifi_family = AF_BRIDGE; req.ifi.ifi_index = ifindex; addattr32(&req.n, sizeof(req.buf), IFLA_PROTINFO, state); - + return rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL); } static int br_send_bpdu(struct rtnl_handle *rth, unsigned ifindex, - const unsigned char *data, int len) + const unsigned char *data, int len) { struct { - struct nlmsghdr n; - struct ifinfomsg ifi; - char buf[256]; + struct nlmsghdr n; + struct ifinfomsg ifi; + char buf[256]; } req; memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_REPLACE; + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_REPLACE; req.n.nlmsg_type = RTM_SETLINK; req.ifi.ifi_family = AF_BRIDGE; req.ifi.ifi_index = ifindex; addattr_l(&req.n, sizeof(req.buf), IFLA_PRIORITY, data, len); - + return rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL); } @@ -97,10 +97,8 @@ int main(int argc, char **argv) int err, brstate; struct rtnl_handle rth; - if (argc != 3) { - fprintf(stderr, - "Usage: brstate ifname state\n"); + fprintf(stderr, "Usage: brstate ifname state\n"); exit(-1); } @@ -114,18 +112,17 @@ int main(int argc, char **argv) fprintf(stderr, "brstate: unknown interface '%s'\n", argv[1]); exit(1); } - + brstate = portstate(argv[2]); if (brstate < 0) { - fprintf(stderr, "brstate: unknown port state '%s'\n", - argv[2]); + fprintf(stderr, "brstate: unknown port state '%s'\n", argv[2]); exit(1); } err = br_set_state(&rth, ifindex, brstate); if (err) { fprintf(stderr, "brstate: set %d, %d failed %d\n", - ifindex, brstate, err); + ifindex, brstate, err); exit(1); } @@ -140,21 +137,22 @@ extern struct rtnl_handle rth_state; int bridge_set_state(int ifindex, int brstate) { - int err = br_set_state(&rth_state, ifindex, brstate); - if (err < 0) { - fprintf(stderr, "Couldn't set bridge state, ifindex %d, state %d\n", - ifindex, brstate); - return -1; - } - return 0; + int err = br_set_state(&rth_state, ifindex, brstate); + if (err < 0) { + fprintf(stderr, + "Couldn't set bridge state, ifindex %d, state %d\n", + ifindex, brstate); + return -1; + } + return 0; } int bridge_send_bpdu(int ifindex, const unsigned char *data, int len) { - int err = br_send_bpdu(&rth_state, ifindex, data, len); - if (err < 0) { - fprintf(stderr, "Couldn't send bpdu, ifindex %d\n", ifindex); - return -1; - } - return 0; + int err = br_send_bpdu(&rth_state, ifindex, data, len); + if (err < 0) { + fprintf(stderr, "Couldn't send bpdu, ifindex %d\n", ifindex); + return -1; + } + return 0; } diff --git a/ctl_cli_wrap.c b/ctl_cli_wrap.c index 7b17964..72665a8 100644 --- a/ctl_cli_wrap.c +++ b/ctl_cli_wrap.c @@ -28,40 +28,38 @@ #include "log.h" CLIENT_SIDE_FUNCTION(enable_bridge_rstp) -CLIENT_SIDE_FUNCTION(get_bridge_state) -CLIENT_SIDE_FUNCTION(set_bridge_config) -CLIENT_SIDE_FUNCTION(get_port_state) -CLIENT_SIDE_FUNCTION(set_port_config) -CLIENT_SIDE_FUNCTION(set_debug_level) - + CLIENT_SIDE_FUNCTION(get_bridge_state) + CLIENT_SIDE_FUNCTION(set_bridge_config) + CLIENT_SIDE_FUNCTION(get_port_state) + CLIENT_SIDE_FUNCTION(set_port_config) + CLIENT_SIDE_FUNCTION(set_debug_level) #include - -const char *CTL_error_explanation (int err_no) +const char *CTL_error_explanation(int err_no) { #define CHOOSE(a) #a - static const char* rstp_error_names[] = RSTP_ERRORS; - static const char *ctl_error_names[] = { CTL_ERRORS }; - + static const char *rstp_error_names[] = RSTP_ERRORS; + static const char *ctl_error_names[] = { CTL_ERRORS }; + #undef CHOOSE - if (err_no < 0) - return "Error doing ctl command"; - else if (err_no >= STP_OK && err_no < STP_LAST_DUMMY) - return rstp_error_names[err_no]; - else if (err_no > Err_Dummy_Start && err_no < Err_Dummy_End) - return ctl_error_names[err_no - Err_Dummy_Start - 1]; + if (err_no < 0) + return "Error doing ctl command"; + else if (err_no >= STP_OK && err_no < STP_LAST_DUMMY) + return rstp_error_names[err_no]; + else if (err_no > Err_Dummy_Start && err_no < Err_Dummy_End) + return ctl_error_names[err_no - Err_Dummy_Start - 1]; - static char buf[32]; - sprintf(buf, "Unknown error code %d", err_no); - return buf; + static char buf[32]; + sprintf(buf, "Unknown error code %d", err_no); + return buf; } -void Dprintf(int level, const char* fmt, ...) +void Dprintf(int level, const char *fmt, ...) { - char logbuf[256]; - logbuf[sizeof(logbuf) - 1] = 0; - va_list ap; - va_start(ap, fmt); - vsnprintf(logbuf, sizeof(logbuf) - 1, fmt, ap); - va_end(ap); - printf("%s\n", logbuf); + char logbuf[256]; + logbuf[sizeof(logbuf) - 1] = 0; + va_list ap; + va_start(ap, fmt); + vsnprintf(logbuf, sizeof(logbuf) - 1, fmt, ap); + va_end(ap); + printf("%s\n", logbuf); } diff --git a/ctl_functions.h b/ctl_functions.h index cf15fe9..9d630f6 100644 --- a/ctl_functions.h +++ b/ctl_functions.h @@ -31,16 +31,14 @@ int CTL_enable_bridge_rstp(int br_index, int enable); int CTL_get_bridge_state(int br_index, - UID_STP_CFG_T *cfg, UID_STP_STATE_T *state); + UID_STP_CFG_T * cfg, UID_STP_STATE_T * state); -int CTL_set_bridge_config(int br_index, - UID_STP_CFG_T *cfg); +int CTL_set_bridge_config(int br_index, UID_STP_CFG_T * cfg); int CTL_get_port_state(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg, UID_STP_PORT_STATE_T *state); + UID_STP_PORT_CFG_T * cfg, UID_STP_PORT_STATE_T * state); -int CTL_set_port_config(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg); +int CTL_set_port_config(int br_index, int port_index, UID_STP_PORT_CFG_T * cfg); int CTL_set_debug_level(int level); @@ -53,9 +51,8 @@ int CTL_set_debug_level(int level); #define CHOOSE(a) a enum Errors { - Err_Dummy_Start = 1000, - CTL_ERRORS - Err_Dummy_End + Err_Dummy_Start = 1000, + CTL_ERRORS Err_Dummy_End }; #undef CHOOSE diff --git a/ctl_main.c b/ctl_main.c index 8d25844..8eaa76d 100644 --- a/ctl_main.c +++ b/ctl_main.c @@ -27,157 +27,180 @@ #define STP_IN_get_error_explanation CTL_error_explanation -static void -print_bridge_id (UID_BRIDGE_ID_T *bridge_id, unsigned char cr) -{ - printf("%04lX-%02x%02x%02x%02x%02x%02x", - (unsigned long) bridge_id->prio, - (unsigned char) bridge_id->addr[0], - (unsigned char) bridge_id->addr[1], - (unsigned char) bridge_id->addr[2], - (unsigned char) bridge_id->addr[3], - (unsigned char) bridge_id->addr[4], - (unsigned char) bridge_id->addr[5]); - if (cr) - printf("\n"); -} - -static char * -stp_state2str (RSTP_PORT_STATE stp_port_state, int detail) -{ - if (detail) { - switch (stp_port_state) { - case UID_PORT_DISABLED: return "Disabled"; - case UID_PORT_DISCARDING: return "Discarding"; - case UID_PORT_LEARNING: return "Learning"; - case UID_PORT_FORWARDING: return "Forwarding"; - case UID_PORT_NON_STP: return "NoStp"; - default: return "Unknown"; - } - } - - switch (stp_port_state) { - case UID_PORT_DISABLED: return "Dis"; - case UID_PORT_DISCARDING: return "Blk"; - case UID_PORT_LEARNING: return "Lrn"; - case UID_PORT_FORWARDING: return "Fwd"; - case UID_PORT_NON_STP: return "Non"; - default: return "Unk"; - } -} - -static void CLI_out_port_id (int port, unsigned char cr) -{ - static char ifname[IFNAMSIZ]; - if (if_indextoname(port, ifname)) - printf("%s", ifname); - else - printf ("Ifindex %02d", port); - if (cr) - printf("\n"); +static void print_bridge_id(UID_BRIDGE_ID_T * bridge_id, unsigned char cr) +{ + printf("%04lX-%02x%02x%02x%02x%02x%02x", + (unsigned long)bridge_id->prio, + (unsigned char)bridge_id->addr[0], + (unsigned char)bridge_id->addr[1], + (unsigned char)bridge_id->addr[2], + (unsigned char)bridge_id->addr[3], + (unsigned char)bridge_id->addr[4], + (unsigned char)bridge_id->addr[5]); + if (cr) + printf("\n"); +} + +static char *stp_state2str(RSTP_PORT_STATE stp_port_state, int detail) +{ + if (detail) { + switch (stp_port_state) { + case UID_PORT_DISABLED: + return "Disabled"; + case UID_PORT_DISCARDING: + return "Discarding"; + case UID_PORT_LEARNING: + return "Learning"; + case UID_PORT_FORWARDING: + return "Forwarding"; + case UID_PORT_NON_STP: + return "NoStp"; + default: + return "Unknown"; + } + } + + switch (stp_port_state) { + case UID_PORT_DISABLED: + return "Dis"; + case UID_PORT_DISCARDING: + return "Blk"; + case UID_PORT_LEARNING: + return "Lrn"; + case UID_PORT_FORWARDING: + return "Fwd"; + case UID_PORT_NON_STP: + return "Non"; + default: + return "Unk"; + } +} + +static void CLI_out_port_id(int port, unsigned char cr) +{ + static char ifname[IFNAMSIZ]; + if (if_indextoname(port, ifname)) + printf("%s", ifname); + else + printf("Ifindex %02d", port); + if (cr) + printf("\n"); } int get_index_die(const char *ifname, const char *doc, int die) { - int r = if_nametoindex(ifname); - if (r == 0) { - fprintf(stderr, "Can't find index for %s %s. Not a valid interface.\n", - doc, ifname); - if (die) - exit(1); - return -1; - } - return r; + int r = if_nametoindex(ifname); + if (r == 0) { + fprintf(stderr, + "Can't find index for %s %s. Not a valid interface.\n", + doc, ifname); + if (die) + exit(1); + return -1; + } + return r; } int get_index(const char *ifname, const char *doc) { - return get_index_die(ifname, doc, 1); + return get_index_die(ifname, doc, 1); } -static int cmd_rstp(int argc, char *const* argv) +static int cmd_rstp(int argc, char *const *argv) { - int stp, r; - int br_index = get_index(argv[1], "bridge"); + int stp, r; + int br_index = get_index(argv[1], "bridge"); - if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes") - || !strcmp(argv[2], "1")) - stp = 1; - else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no") - || !strcmp(argv[2], "0")) - stp = 0; - else { - fprintf(stderr, "expect on/off for argument\n"); - return 1; - } - r = CTL_enable_bridge_rstp(br_index, stp); - if (r) { - fprintf(stderr, "Failed to enable/disable RSTP: %s\n", - CTL_error_explanation(r)); - return -1; - } - return 0; + if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes") + || !strcmp(argv[2], "1")) + stp = 1; + else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no") + || !strcmp(argv[2], "0")) + stp = 0; + else { + fprintf(stderr, "expect on/off for argument\n"); + return 1; + } + r = CTL_enable_bridge_rstp(br_index, stp); + if (r) { + fprintf(stderr, "Failed to enable/disable RSTP: %s\n", + CTL_error_explanation(r)); + return -1; + } + return 0; } static int do_showbridge(const char *br_name) { - UID_STP_STATE_T uid_state; - UID_STP_CFG_T uid_cfg; - - int br_index = get_index_die(br_name, "bridge", 0); - if (br_index < 0) - return -1; - - int r = CTL_get_bridge_state(br_index, &uid_cfg, &uid_state); - if (r) { - fprintf(stderr, "Failed to get bridge state: %s\n", - CTL_error_explanation(r)); - return -1; - } - + UID_STP_STATE_T uid_state; + UID_STP_CFG_T uid_cfg; + + int br_index = get_index_die(br_name, "bridge", 0); + if (br_index < 0) + return -1; + + int r = CTL_get_bridge_state(br_index, &uid_cfg, &uid_state); + if (r) { + fprintf(stderr, "Failed to get bridge state: %s\n", + CTL_error_explanation(r)); + return -1; + } #if 0 - printf("Interface: %-7s (tag:%d) State: ", - uid_state.vlan_name, (int) uid_state.vlan_id); + printf("Interface: %-7s (tag:%d) State: ", + uid_state.vlan_name, (int)uid_state.vlan_id); #else - printf("Bridge: %-7s State:", - uid_state.vlan_name); + printf("Bridge: %-7s State:", + uid_state.vlan_name); #endif - switch (uid_state.stp_enabled) { - case STP_ENABLED: printf("enabled\n"); break; - case STP_DISABLED: printf("disabled\n");break; - default: printf("unknown\n"); return 0; - } - - printf("BridgeId: "); print_bridge_id (&uid_state.bridge_id, 0); - printf(" Bridge Proirity: %lu (0x%lX)\n", - (unsigned long) uid_state.bridge_id.prio, (unsigned long) uid_state.bridge_id.prio); - if (uid_cfg.force_version < 2) - printf("Force Version: stp\n"); - - printf("Designated Root: "); print_bridge_id (&uid_state.designated_root, 1); - if (uid_state.root_port) { - printf("Root Port: %04lx", (unsigned long) uid_state.root_port); - // CLI_out_port_id (uid_state.root_port & 0xfff, False); - // printf("not implemented"); // XXX - printf(", Root Cost: %-lu\n", (unsigned long) uid_state.root_path_cost); - } else { - printf("Root Port: none\n"); - } - - if (uid_state.Topo_Change) - printf ("Topology Change Count: %lu\n", uid_state.Topo_Change_Count); - else - printf ("Time Since Topology Change: %lu\n", uid_state.timeSince_Topo_Change); - - printf ("Max Age: %2d Bridge Max Age: %-2d\n", - (int) uid_state.max_age, (int) uid_cfg.max_age); - printf ("Hello Time: %2d Bridge Hello Time: %-2d\n", - (int) uid_state.hello_time, (int) uid_cfg.hello_time); - printf ("Forward Delay: %2d Bridge Forward Delay: %-2d\n", - (int) uid_state.forward_delay, (int) uid_cfg.forward_delay); - printf ("Hold Time: %2d\n", (int) uid_cfg.hold_time); - - return 0; + switch (uid_state.stp_enabled) { + case STP_ENABLED: + printf("enabled\n"); + break; + case STP_DISABLED: + printf("disabled\n"); + break; + default: + printf("unknown\n"); + return 0; + } + + printf("BridgeId: "); + print_bridge_id(&uid_state.bridge_id, 0); + printf(" Bridge Proirity: %lu (0x%lX)\n", + (unsigned long)uid_state.bridge_id.prio, + (unsigned long)uid_state.bridge_id.prio); + if (uid_cfg.force_version < 2) + printf("Force Version: stp\n"); + + printf("Designated Root: "); + print_bridge_id(&uid_state.designated_root, 1); + if (uid_state.root_port) { + printf("Root Port: %04lx", + (unsigned long)uid_state.root_port); + // CLI_out_port_id (uid_state.root_port & 0xfff, False); + // printf("not implemented"); // XXX + printf(", Root Cost: %-lu\n", + (unsigned long)uid_state.root_path_cost); + } else { + printf("Root Port: none\n"); + } + + if (uid_state.Topo_Change) + printf("Topology Change Count: %lu\n", + uid_state.Topo_Change_Count); + else + printf("Time Since Topology Change: %lu\n", + uid_state.timeSince_Topo_Change); + + printf("Max Age: %2d Bridge Max Age: %-2d\n", + (int)uid_state.max_age, (int)uid_cfg.max_age); + printf("Hello Time: %2d Bridge Hello Time: %-2d\n", + (int)uid_state.hello_time, (int)uid_cfg.hello_time); + printf("Forward Delay: %2d Bridge Forward Delay: %-2d\n", + (int)uid_state.forward_delay, (int)uid_cfg.forward_delay); + printf("Hold Time: %2d\n", (int)uid_cfg.hold_time); + + return 0; } #define SYSFS_PATH_MAX 256 @@ -185,526 +208,574 @@ static int do_showbridge(const char *br_name) static int isbridge(const struct dirent *entry) { - char path[SYSFS_PATH_MAX]; - struct stat st; - - snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "/%s/bridge", - entry->d_name); - return stat(path, &st) == 0 && S_ISDIR(st.st_mode); -} - -static int cmd_showbridge(int argc, char *const* argv) -{ - int i, count = 0; - int r = 0; - struct dirent **namelist; - - if (argc > 1) { - count = argc - 1; - } - else { - count = scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort); - if (count < 0) { - fprintf(stderr, "Error getting list of all bridges\n"); - return -1; - } - } - - for (i = 0; i < count; i++) { - const char *name; - if (argc > 1) - name = argv[i+1]; - else - name = namelist[i]->d_name; - - int err = do_showbridge(name); - if (err) - r = err; - } - - if (argc <= 1) { - for (i = 0; i < count; i++) - free(namelist[i]); - free(namelist); - } - - return r; + char path[SYSFS_PATH_MAX]; + struct stat st; + + snprintf(path, SYSFS_PATH_MAX, SYSFS_CLASS_NET "/%s/bridge", + entry->d_name); + return stat(path, &st) == 0 && S_ISDIR(st.st_mode); +} + +static int cmd_showbridge(int argc, char *const *argv) +{ + int i, count = 0; + int r = 0; + struct dirent **namelist; + + if (argc > 1) { + count = argc - 1; + } else { + count = + scandir(SYSFS_CLASS_NET, &namelist, isbridge, alphasort); + if (count < 0) { + fprintf(stderr, "Error getting list of all bridges\n"); + return -1; + } + } + + for (i = 0; i < count; i++) { + const char *name; + if (argc > 1) + name = argv[i + 1]; + else + name = namelist[i]->d_name; + + int err = do_showbridge(name); + if (err) + r = err; + } + + if (argc <= 1) { + for (i = 0; i < count; i++) + free(namelist[i]); + free(namelist); + } + + return r; } int detail = 0; static int do_showport(int br_index, const char *port_name, - UID_STP_STATE_T *uid_state) -{ - UID_STP_PORT_STATE_T uid_port; - UID_STP_PORT_CFG_T uid_cfg; - int r = 0; - int port_index = get_index_die(port_name, "port", 0); - if (port_index < 0) - return -1; - - memset (&uid_cfg, 0, sizeof (UID_STP_PORT_CFG_T)); - r = CTL_get_port_state(br_index, port_index, &uid_cfg, &uid_port); - if (r) { - fprintf(stderr, "Failed to get port state for port %d: %s\n", - port_index, CTL_error_explanation(r)); - return -1; - } - - if (detail) { - printf("Stp Port "); CLI_out_port_id (port_index, False); + UID_STP_STATE_T * uid_state) +{ + UID_STP_PORT_STATE_T uid_port; + UID_STP_PORT_CFG_T uid_cfg; + int r = 0; + int port_index = get_index_die(port_name, "port", 0); + if (port_index < 0) + return -1; + + memset(&uid_cfg, 0, sizeof(UID_STP_PORT_CFG_T)); + r = CTL_get_port_state(br_index, port_index, &uid_cfg, &uid_port); + if (r) { + fprintf(stderr, "Failed to get port state for port %d: %s\n", + port_index, CTL_error_explanation(r)); + return -1; + } + + if (detail) { + printf("Stp Port "); + CLI_out_port_id(port_index, False); #if 0 - printf(": PortId: %04lx in vlan '%s' with tag %d:\n", - (unsigned long) uid_port.port_id, uid_state->vlan_name, (int) uid_state->vlan_id); + printf(": PortId: %04lx in vlan '%s' with tag %d:\n", + (unsigned long)uid_port.port_id, uid_state->vlan_name, + (int)uid_state->vlan_id); #else - printf(": PortId: %04lx in Bridge '%s':\n", - (unsigned long) uid_port.port_id, uid_state->vlan_name); + printf(": PortId: %04lx in Bridge '%s':\n", + (unsigned long)uid_port.port_id, uid_state->vlan_name); #endif - printf ("Priority: %-d\n", (int) (uid_port.port_id >> 8)); - printf ("State: %-16s", stp_state2str (uid_port.state, 1)); - printf (" Uptime: %-9lu\n", uid_port.uptime); - printf ("PortPathCost: admin: "); - if (ADMIN_PORT_PATH_COST_AUTO == uid_cfg.admin_port_path_cost) - printf ("%-9s", "Auto"); - else - printf ("%-9lu", uid_cfg.admin_port_path_cost); - printf (" oper: %-9lu\n", uid_port.oper_port_path_cost); - - printf ("Point2Point: admin: "); - switch (uid_cfg.admin_point2point) { - case P2P_FORCE_TRUE: - printf ("%-9s", "ForceYes"); - break; - case P2P_FORCE_FALSE: - printf ("%-9s", "ForceNo"); - break; - case P2P_AUTO: - printf ("%-9s", "Auto"); - break; - } - printf (" oper: %-9s\n", uid_port.oper_point2point ? "Yes" : "No"); - printf ("Edge: admin: %-9s oper: %-9s\n", - uid_cfg.admin_edge ? "Y" : "N", - uid_port.oper_edge ? "Y" : "N"); - printf ("Partner: oper: %-9s\n", - uid_port.oper_stp_neigb ? "Slow" : "Rapid"); - - if (' ' != uid_port.role) { - if ('-' != uid_port.role) { - printf("PathCost: %-lu\n", (unsigned long) (uid_port.path_cost)); - printf("Designated Root: "); print_bridge_id (&uid_port.designated_root, 1); - printf("Designated Cost: %-ld\n", (unsigned long) uid_port.designated_cost); - printf("Designated Bridge: "); print_bridge_id (&uid_port.designated_bridge, 1); - printf("Designated Port: %-4lx\n\r", (unsigned long) uid_port.designated_port); - } - printf("Role: "); - switch (uid_port.role) { - case 'A': printf("Alternate\n"); break; - case 'B': printf("Backup\n"); break; - case 'R': printf("Root\n"); break; - case 'D': printf("Designated\n"); break; - case '-': printf("NonStp\n"); break; - default: printf("Unknown(%c)\n", uid_port.role); break; - } - - if ('R' == uid_port.role || 'D' == uid_port.role) { - /* printf("Tc: %c ", uid_port.tc ? 'Y' : 'n'); */ - printf("TcAck: %c ", - uid_port.top_change_ack ? 'Y' : 'N'); - printf("TcWhile: %3d\n", (int) uid_port.tcWhile); - } - } - - if (UID_PORT_DISABLED == uid_port.state || '-' == uid_port.role) { + printf("Priority: %-d\n", + (int)(uid_port.port_id >> 8)); + printf("State: %-16s", + stp_state2str(uid_port.state, 1)); + printf(" Uptime: %-9lu\n", uid_port.uptime); + printf("PortPathCost: admin: "); + if (ADMIN_PORT_PATH_COST_AUTO == uid_cfg.admin_port_path_cost) + printf("%-9s", "Auto"); + else + printf("%-9lu", uid_cfg.admin_port_path_cost); + printf(" oper: %-9lu\n", uid_port.oper_port_path_cost); + + printf("Point2Point: admin: "); + switch (uid_cfg.admin_point2point) { + case P2P_FORCE_TRUE: + printf("%-9s", "ForceYes"); + break; + case P2P_FORCE_FALSE: + printf("%-9s", "ForceNo"); + break; + case P2P_AUTO: + printf("%-9s", "Auto"); + break; + } + printf(" oper: %-9s\n", + uid_port.oper_point2point ? "Yes" : "No"); + printf("Edge: admin: %-9s oper: %-9s\n", + uid_cfg.admin_edge ? "Y" : "N", + uid_port.oper_edge ? "Y" : "N"); + printf("Partner: oper: %-9s\n", + uid_port.oper_stp_neigb ? "Slow" : "Rapid"); + + if (' ' != uid_port.role) { + if ('-' != uid_port.role) { + printf("PathCost: %-lu\n", + (unsigned long)(uid_port.path_cost)); + printf("Designated Root: "); + print_bridge_id(&uid_port.designated_root, 1); + printf("Designated Cost: %-ld\n", + (unsigned long)uid_port.designated_cost); + printf("Designated Bridge: "); + print_bridge_id(&uid_port.designated_bridge, 1); + printf("Designated Port: %-4lx\n\r", + (unsigned long)uid_port.designated_port); + } + printf("Role: "); + switch (uid_port.role) { + case 'A': + printf("Alternate\n"); + break; + case 'B': + printf("Backup\n"); + break; + case 'R': + printf("Root\n"); + break; + case 'D': + printf("Designated\n"); + break; + case '-': + printf("NonStp\n"); + break; + default: + printf("Unknown(%c)\n", uid_port.role); + break; + } + + if ('R' == uid_port.role || 'D' == uid_port.role) { + /* printf("Tc: %c ", uid_port.tc ? 'Y' : 'n'); */ + printf("TcAck: %c ", + uid_port.top_change_ack ? 'Y' : 'N'); + printf("TcWhile: %3d\n", + (int)uid_port.tcWhile); + } + } + + if (UID_PORT_DISABLED == uid_port.state || '-' == uid_port.role) { #if 0 - printf("helloWhen: %3d ", (int) uid_port.helloWhen); - printf("lnkWhile: %3d\n", (int) uid_port.lnkWhile); - printf("fdWhile: %3d\n", (int) uid_port.fdWhile); + printf("helloWhen: %3d ", + (int)uid_port.helloWhen); + printf("lnkWhile: %3d\n", (int)uid_port.lnkWhile); + printf("fdWhile: %3d\n", (int)uid_port.fdWhile); #endif - } else if ('-' != uid_port.role) { - printf("fdWhile: %3d ", (int) uid_port.fdWhile); - printf("rcvdInfoWhile: %3d\n", (int) uid_port.rcvdInfoWhile); - printf("rbWhile: %3d ", (int) uid_port.rbWhile); - printf("rrWhile: %3d\n", (int) uid_port.rrWhile); + } else if ('-' != uid_port.role) { + printf("fdWhile: %3d ", (int)uid_port.fdWhile); + printf("rcvdInfoWhile: %3d\n", + (int)uid_port.rcvdInfoWhile); + printf("rbWhile: %3d ", (int)uid_port.rbWhile); + printf("rrWhile: %3d\n", (int)uid_port.rrWhile); #if 0 - printf("mdelayWhile: %3d ", (int) uid_port.mdelayWhile); - printf("lnkWhile: %3d\n", (int) uid_port.lnkWhile); - printf("helloWhen: %3d ", (int) uid_port.helloWhen); - printf("txCount: %3d\n", (int) uid_port.txCount); + printf("mdelayWhile: %3d ", + (int)uid_port.mdelayWhile); + printf("lnkWhile: %3d\n", (int)uid_port.lnkWhile); + printf("helloWhen: %3d ", + (int)uid_port.helloWhen); + printf("txCount: %3d\n", (int)uid_port.txCount); #endif - } - - printf("RSTP BPDU rx: %lu\n", (unsigned long) uid_port.rx_rstp_bpdu_cnt); - printf("CONFIG BPDU rx: %lu\n", (unsigned long) uid_port.rx_cfg_bpdu_cnt); - printf("TCN BPDU rx: %lu\n", (unsigned long) uid_port.rx_tcn_bpdu_cnt); - } else { - printf("%c%c%c ", - (uid_port.oper_point2point) ? ' ' : '*', - (uid_port.oper_edge) ? 'E' : ' ', - (uid_port.oper_stp_neigb) ? 's' : ' '); - CLI_out_port_id (port_index, False); - printf(" %04lx %3s ", (unsigned long) uid_port.port_id, - stp_state2str (uid_port.state, 0)); - printf (" "); - print_bridge_id (&uid_port.designated_root, 0); - printf(" "); - print_bridge_id (&uid_port.designated_bridge, 0); - printf(" %4lx %c", (unsigned long) uid_port.designated_port, uid_port.role); - printf ("\n"); - } - return 0; + } + + printf("RSTP BPDU rx: %lu\n", + (unsigned long)uid_port.rx_rstp_bpdu_cnt); + printf("CONFIG BPDU rx: %lu\n", + (unsigned long)uid_port.rx_cfg_bpdu_cnt); + printf("TCN BPDU rx: %lu\n", + (unsigned long)uid_port.rx_tcn_bpdu_cnt); + } else { + printf("%c%c%c ", + (uid_port.oper_point2point) ? ' ' : '*', + (uid_port.oper_edge) ? 'E' : ' ', + (uid_port.oper_stp_neigb) ? 's' : ' '); + CLI_out_port_id(port_index, False); + printf(" %04lx %3s ", (unsigned long)uid_port.port_id, + stp_state2str(uid_port.state, 0)); + printf(" "); + print_bridge_id(&uid_port.designated_root, 0); + printf(" "); + print_bridge_id(&uid_port.designated_bridge, 0); + printf(" %4lx %c", (unsigned long)uid_port.designated_port, + uid_port.role); + printf("\n"); + } + return 0; } static int not_dot_dotdot(const struct dirent *entry) { - const char *n = entry->d_name; - - return !(n[0] == '.' && (n[1] == 0 || (n[1] == '.' && n[2] == 0))); -} - -static int cmd_showport(int argc, char *const* argv) -{ - UID_STP_STATE_T uid_state; - UID_STP_CFG_T uid_br_cfg; - int r = 0; - - int br_index = get_index(argv[1], "bridge"); - - r = CTL_get_bridge_state(br_index, &uid_br_cfg, &uid_state); - if (r) { - fprintf(stderr, "Failed to get bridge state: %s\n", - CTL_error_explanation(r)); - return -1; - } - - int i, count = 0; - struct dirent **namelist; - - if (argc > 2) { - count = argc - 2; - } - else { - char buf[SYSFS_PATH_MAX]; - snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]); - count = scandir(buf, &namelist, not_dot_dotdot, alphasort); - if (count < 0) { - fprintf(stderr, "Error getting list of all ports of bridge %s\n", - argv[1]); - return -1; - } - } - - for (i = 0; i < count; i++) { - const char *name; - if (argc > 2) - name = argv[i+2]; - else - name = namelist[i]->d_name; - - int err = do_showport(br_index, name, &uid_state); - if (err) - r = err; - } - - if (argc <= 2) { - for (i = 0; i < count; i++) - free(namelist[i]); - free(namelist); - } - - return r; -} - -static int cmd_showportdetail(int argc, char *const* argv) -{ - detail = 1; - return cmd_showport(argc, argv); + const char *n = entry->d_name; + + return !(n[0] == '.' && (n[1] == 0 || (n[1] == '.' && n[2] == 0))); } -unsigned int getuint(const char *s) +static int cmd_showport(int argc, char *const *argv) { - char *end; - long l; - l = strtoul(s, &end, 0); - if (*s == 0 || *end != 0 || l > INT_MAX) { - fprintf(stderr, "Invalid unsigned int arg %s\n", s); - exit(1); - } - return l; + UID_STP_STATE_T uid_state; + UID_STP_CFG_T uid_br_cfg; + int r = 0; + + int br_index = get_index(argv[1], "bridge"); + + r = CTL_get_bridge_state(br_index, &uid_br_cfg, &uid_state); + if (r) { + fprintf(stderr, "Failed to get bridge state: %s\n", + CTL_error_explanation(r)); + return -1; + } + + int i, count = 0; + struct dirent **namelist; + + if (argc > 2) { + count = argc - 2; + } else { + char buf[SYSFS_PATH_MAX]; + snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]); + count = scandir(buf, &namelist, not_dot_dotdot, alphasort); + if (count < 0) { + fprintf(stderr, + "Error getting list of all ports of bridge %s\n", + argv[1]); + return -1; + } + } + + for (i = 0; i < count; i++) { + const char *name; + if (argc > 2) + name = argv[i + 2]; + else + name = namelist[i]->d_name; + + int err = do_showport(br_index, name, &uid_state); + if (err) + r = err; + } + + if (argc <= 2) { + for (i = 0; i < count; i++) + free(namelist[i]); + free(namelist); + } + + return r; } -int getenum(const char *s, const char *opt[]) +static int cmd_showportdetail(int argc, char *const *argv) { - int i; - for (i = 0; opt[i] != NULL; i++) - if (strcmp(s, opt[i]) == 0) - return i; - - fprintf(stderr, "Invalid argument %s: expecting one of ", s); - for (i = 0; opt[i] != NULL; i++) - fprintf(stderr, "%s%s", opt[i], (opt[i+1]?", ":"\n")); - - exit(1); + detail = 1; + return cmd_showport(argc, argv); } -int getyesno(const char *s, const char *yes, const char *no) +unsigned int getuint(const char *s) { - /* Reverse yes and no so error message looks more normal */ - const char *opt[] = { yes, no, NULL }; - return 1 - getenum(s, opt); + char *end; + long l; + l = strtoul(s, &end, 0); + if (*s == 0 || *end != 0 || l > INT_MAX) { + fprintf(stderr, "Invalid unsigned int arg %s\n", s); + exit(1); + } + return l; } -static int set_bridge_cfg_value (int br_index, unsigned long value, - unsigned long val_mask) +int getenum(const char *s, const char *opt[]) { - UID_STP_CFG_T uid_cfg; - char* val_name; - int rc; - - uid_cfg.field_mask = val_mask; - switch (val_mask) { - case BR_CFG_STATE: - uid_cfg.stp_enabled = value; - val_name = "state"; - break; - case BR_CFG_PRIO: - uid_cfg.bridge_priority = value; - val_name = "priority"; - break; - case BR_CFG_AGE: - uid_cfg.max_age = value; - val_name = "max_age"; - break; - case BR_CFG_HELLO: - uid_cfg.hello_time = value; - val_name = "hello_time"; - break; - case BR_CFG_DELAY: - uid_cfg.forward_delay = value; - val_name = "forward_delay"; - break; - case BR_CFG_FORCE_VER: - uid_cfg.force_version = value; - val_name = "force_version"; - break; - case BR_CFG_AGE_MODE: - case BR_CFG_AGE_TIME: - default: printf ("Invalid value mask 0X%lx\n", val_mask); return -1; - break; - } + int i; + for (i = 0; opt[i] != NULL; i++) + if (strcmp(s, opt[i]) == 0) + return i; + + fprintf(stderr, "Invalid argument %s: expecting one of ", s); + for (i = 0; opt[i] != NULL; i++) + fprintf(stderr, "%s%s", opt[i], (opt[i + 1] ? ", " : "\n")); + + exit(1); +} + +int getyesno(const char *s, const char *yes, const char *no) +{ + /* Reverse yes and no so error message looks more normal */ + const char *opt[] = { yes, no, NULL }; + return 1 - getenum(s, opt); +} + +static int set_bridge_cfg_value(int br_index, unsigned long value, + unsigned long val_mask) +{ + UID_STP_CFG_T uid_cfg; + char *val_name; + int rc; + + uid_cfg.field_mask = val_mask; + switch (val_mask) { + case BR_CFG_STATE: + uid_cfg.stp_enabled = value; + val_name = "state"; + break; + case BR_CFG_PRIO: + uid_cfg.bridge_priority = value; + val_name = "priority"; + break; + case BR_CFG_AGE: + uid_cfg.max_age = value; + val_name = "max_age"; + break; + case BR_CFG_HELLO: + uid_cfg.hello_time = value; + val_name = "hello_time"; + break; + case BR_CFG_DELAY: + uid_cfg.forward_delay = value; + val_name = "forward_delay"; + break; + case BR_CFG_FORCE_VER: + uid_cfg.force_version = value; + val_name = "force_version"; + break; + case BR_CFG_AGE_MODE: + case BR_CFG_AGE_TIME: + default: + printf("Invalid value mask 0X%lx\n", val_mask); + return -1; + break; + } - rc = CTL_set_bridge_config(br_index, &uid_cfg); + rc = CTL_set_bridge_config(br_index, &uid_cfg); - if (0 != rc) { - printf ("Can't change rstp bridge %s:%s\n", val_name, STP_IN_get_error_explanation (rc)); - return -1; - } - return 0; + if (0 != rc) { + printf("Can't change rstp bridge %s:%s\n", val_name, + STP_IN_get_error_explanation(rc)); + return -1; + } + return 0; } -static int cmd_setbridgestate(int argc, char *const* argv) +static int cmd_setbridgestate(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, - getyesno(argv[2], "on", "off"), - BR_CFG_STATE); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, + getyesno(argv[2], "on", "off"), + BR_CFG_STATE); } -static int cmd_setbridgeprio(int argc, char *const* argv) +static int cmd_setbridgeprio(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_PRIO); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_PRIO); } -static int cmd_setbridgemaxage(int argc, char *const* argv) +static int cmd_setbridgemaxage(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_AGE); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_AGE); } -static int cmd_setbridgehello(int argc, char *const* argv) +static int cmd_setbridgehello(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_HELLO); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_HELLO); } -static int cmd_setbridgefdelay(int argc, char *const* argv) +static int cmd_setbridgefdelay(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_DELAY); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, getuint(argv[2]), BR_CFG_DELAY); } -static int cmd_setbridgeforcevers(int argc, char *const* argv) +static int cmd_setbridgeforcevers(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - return set_bridge_cfg_value(br_index, - 2 * getyesno(argv[2], "normal", "slow"), - BR_CFG_FORCE_VER); + int br_index = get_index(argv[1], "bridge"); + return set_bridge_cfg_value(br_index, + 2 * getyesno(argv[2], "normal", "slow"), + BR_CFG_FORCE_VER); } - static int -set_port_cfg_value (int br_index, int port_index, - unsigned long value, - unsigned long val_mask) -{ - UID_STP_PORT_CFG_T uid_cfg; - int rc; - char *val_name; - - BitmapClear(&uid_cfg.port_bmp); - uid_cfg.field_mask = val_mask; - switch (val_mask) { - case PT_CFG_MCHECK: - val_name = "mcheck"; - break; - case PT_CFG_COST: - uid_cfg.admin_port_path_cost = value; - val_name = "path cost"; - break; - case PT_CFG_PRIO: - uid_cfg.port_priority = value; - val_name = "priority"; - break; - case PT_CFG_P2P: - uid_cfg.admin_point2point = (ADMIN_P2P_T) value; - val_name = "p2p flag"; - break; - case PT_CFG_EDGE: - uid_cfg.admin_edge = value; - val_name = "adminEdge"; - break; - case PT_CFG_NON_STP: - uid_cfg.admin_non_stp = value; - val_name = "adminNonStp"; - break; +set_port_cfg_value(int br_index, int port_index, + unsigned long value, unsigned long val_mask) +{ + UID_STP_PORT_CFG_T uid_cfg; + int rc; + char *val_name; + + BitmapClear(&uid_cfg.port_bmp); + uid_cfg.field_mask = val_mask; + switch (val_mask) { + case PT_CFG_MCHECK: + val_name = "mcheck"; + break; + case PT_CFG_COST: + uid_cfg.admin_port_path_cost = value; + val_name = "path cost"; + break; + case PT_CFG_PRIO: + uid_cfg.port_priority = value; + val_name = "priority"; + break; + case PT_CFG_P2P: + uid_cfg.admin_point2point = (ADMIN_P2P_T) value; + val_name = "p2p flag"; + break; + case PT_CFG_EDGE: + uid_cfg.admin_edge = value; + val_name = "adminEdge"; + break; + case PT_CFG_NON_STP: + uid_cfg.admin_non_stp = value; + val_name = "adminNonStp"; + break; #ifdef STP_DBG - case PT_CFG_DBG_SKIP_TX: - uid_cfg.skip_tx = value; - val_name = "skip tx"; - break; - case PT_CFG_DBG_SKIP_RX: - uid_cfg.skip_rx = value; - val_name = "skip rx"; - break; + case PT_CFG_DBG_SKIP_TX: + uid_cfg.skip_tx = value; + val_name = "skip tx"; + break; + case PT_CFG_DBG_SKIP_RX: + uid_cfg.skip_rx = value; + val_name = "skip rx"; + break; #endif - case PT_CFG_STATE: - default: - printf ("Invalid value mask 0X%lx\n", val_mask); - return -1; - } + case PT_CFG_STATE: + default: + printf("Invalid value mask 0X%lx\n", val_mask); + return -1; + } - rc = CTL_set_port_config(br_index, port_index, &uid_cfg); + rc = CTL_set_port_config(br_index, port_index, &uid_cfg); - if (0 != rc) { - printf ("can't change rstp port[s] %s: %s\n", - val_name, STP_IN_get_error_explanation (rc)); - return -1; - } - return 0; + if (0 != rc) { + printf("can't change rstp port[s] %s: %s\n", + val_name, STP_IN_get_error_explanation(rc)); + return -1; + } + return 0; } -static int cmd_setportprio(int argc, char *const* argv) +static int cmd_setportprio(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - return set_port_cfg_value(br_index, port_index, - getuint(argv[3]), PT_CFG_PRIO); + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + return set_port_cfg_value(br_index, port_index, + getuint(argv[3]), PT_CFG_PRIO); } -static int cmd_setportpathcost(int argc, char *const* argv) +static int cmd_setportpathcost(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - return set_port_cfg_value(br_index, port_index, - getuint(argv[3]), PT_CFG_COST); + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + return set_port_cfg_value(br_index, port_index, + getuint(argv[3]), PT_CFG_COST); } -static int cmd_setportedge(int argc, char *const* argv) +static int cmd_setportedge(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - return set_port_cfg_value(br_index, port_index, - getyesno(argv[3], "yes", "no"), PT_CFG_EDGE); + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + return set_port_cfg_value(br_index, port_index, + getyesno(argv[3], "yes", "no"), PT_CFG_EDGE); } -static int cmd_setportnonstp(int argc, char *const* argv) +static int cmd_setportnonstp(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - return set_port_cfg_value(br_index, port_index, - getyesno(argv[3], "yes", "no"), PT_CFG_NON_STP); + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + return set_port_cfg_value(br_index, port_index, + getyesno(argv[3], "yes", "no"), + PT_CFG_NON_STP); } -static int cmd_setportp2p(int argc, char *const* argv) +static int cmd_setportp2p(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - const char *opts[] = {"yes", "no", "auto", NULL }; - int vals[] = { P2P_FORCE_TRUE, P2P_FORCE_FALSE, P2P_AUTO }; + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + const char *opts[] = { "yes", "no", "auto", NULL }; + int vals[] = { P2P_FORCE_TRUE, P2P_FORCE_FALSE, P2P_AUTO }; - return set_port_cfg_value(br_index, port_index, - vals[getenum(argv[3], opts)], PT_CFG_P2P); + return set_port_cfg_value(br_index, port_index, + vals[getenum(argv[3], opts)], PT_CFG_P2P); } -static int cmd_portmcheck(int argc, char *const* argv) +static int cmd_portmcheck(int argc, char *const *argv) { - int br_index = get_index(argv[1], "bridge"); - int port_index = get_index(argv[2], "port"); - return set_port_cfg_value(br_index, port_index, 0, PT_CFG_MCHECK); + int br_index = get_index(argv[1], "bridge"); + int port_index = get_index(argv[2], "port"); + return set_port_cfg_value(br_index, port_index, 0, PT_CFG_MCHECK); } -static int cmd_debuglevel(int argc, char *const* argv) +static int cmd_debuglevel(int argc, char *const *argv) { - return CTL_set_debug_level(getuint(argv[1])); + return CTL_set_debug_level(getuint(argv[1])); } -struct command -{ - int nargs; - int optargs; - const char *name; - int (*func)(int argc, char *const* argv); - const char *help; +struct command { + int nargs; + int optargs; + const char *name; + int (*func) (int argc, char *const *argv); + const char *help; }; static const struct command commands[] = { - { 0, 32, "showbridge", cmd_showbridge, "[ ... ]\t\tshow bridge state" }, - { 1, 32, "showport", cmd_showport, " [ ... ]\tshow port state" }, - { 1, 32, "showportdetail", cmd_showportdetail, " [ ... ]\tshow port state (detail)" }, - { 2, 0, "rstp", cmd_rstp, " {on|off}\tenable/disable rstpd control" }, - { 2, 0, "setbridgestate", cmd_setbridgestate, " {on|off}\tstart/stop rstp (when enabled)" }, - { 2, 0, "setbridgeprio", cmd_setbridgeprio, " \tset bridge priority (0-61440)" }, - { 2, 0, "sethello", cmd_setbridgehello, " \tset bridge hello time (1-10)" }, - { 2, 0, "setmaxage", cmd_setbridgemaxage, " \tset bridge max age (6-40)" }, - { 2, 0, "setfdelay", cmd_setbridgefdelay, " \tset bridge forward delay (4-30)" }, - { 2, 0, "setforcevers", cmd_setbridgeforcevers, " {normal|slow}\tnormal RSTP or force to STP" }, - { 3, 0, "setportprio", cmd_setportprio, " \tset port priority (0-240)" }, - { 3, 0, "setportpathcost", cmd_setportpathcost, " \tset port path cost" }, - { 3, 0, "setportedge", cmd_setportedge, " {yes|no}\tconfigure if it is an edge port" }, - { 3, 0, "setportnonstp", cmd_setportnonstp, " {yes|no}\tdisable STP for the port" }, - { 3, 0, "setportp2p", cmd_setportp2p, " {yes|no|auto}\tset whether p2p connection" }, - { 2, 0, "portmcheck", cmd_portmcheck, " \ttry to get back from STP to RSTP mode" }, - { 1, 0, "debuglevel", cmd_debuglevel, "\t\tLevel of verbosity" }, + {0, 32, "showbridge", cmd_showbridge, + "[ ... ]\t\tshow bridge state"}, + {1, 32, "showport", cmd_showport, + " [ ... ]\tshow port state"}, + {1, 32, "showportdetail", cmd_showportdetail, + " [ ... ]\tshow port state (detail)"}, + {2, 0, "rstp", cmd_rstp, + " {on|off}\tenable/disable rstpd control"}, + {2, 0, "setbridgestate", cmd_setbridgestate, + " {on|off}\tstart/stop rstp (when enabled)"}, + {2, 0, "setbridgeprio", cmd_setbridgeprio, + " \tset bridge priority (0-61440)"}, + {2, 0, "sethello", cmd_setbridgehello, + " \tset bridge hello time (1-10)"}, + {2, 0, "setmaxage", cmd_setbridgemaxage, + " \tset bridge max age (6-40)"}, + {2, 0, "setfdelay", cmd_setbridgefdelay, + " \tset bridge forward delay (4-30)"}, + {2, 0, "setforcevers", cmd_setbridgeforcevers, + " {normal|slow}\tnormal RSTP or force to STP"}, + {3, 0, "setportprio", cmd_setportprio, + " \tset port priority (0-240)"}, + {3, 0, "setportpathcost", cmd_setportpathcost, + " \tset port path cost"}, + {3, 0, "setportedge", cmd_setportedge, + " {yes|no}\tconfigure if it is an edge port"}, + {3, 0, "setportnonstp", cmd_setportnonstp, + " {yes|no}\tdisable STP for the port"}, + {3, 0, "setportp2p", cmd_setportp2p, + " {yes|no|auto}\tset whether p2p connection"}, + {2, 0, "portmcheck", cmd_portmcheck, + " \ttry to get back from STP to RSTP mode"}, + {1, 0, "debuglevel", cmd_debuglevel, "\t\tLevel of verbosity"}, }; const struct command *command_lookup(const char *cmd) { int i; - for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) { + for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { if (!strcmp(cmd, commands[i].name)) return &commands[i]; } @@ -716,7 +787,7 @@ void command_helpall(void) { int i; - for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) { + for (i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { printf("\t%-10s\t%s\n", commands[i].name, commands[i].help); } } @@ -731,18 +802,18 @@ static void help() #define PACKAGE_VERSION2(v, b) "rstp, " #v "-" #b #define PACKAGE_VERSION(v, b) PACKAGE_VERSION2(v, b) -int main(int argc, char *const* argv) +int main(int argc, char *const *argv) { const struct command *cmd; int f; static const struct option options[] = { - { .name = "help", .val = 'h' }, - { .name = "version", .val = 'V' }, - { 0 } + {.name = "help",.val = 'h'}, + {.name = "version",.val = 'V'}, + {0} }; - while ((f = getopt_long(argc, argv, "Vh", options, NULL)) != EOF) - switch(f) { + while ((f = getopt_long(argc, argv, "Vh", options, NULL)) != EOF) + switch (f) { case 'h': help(); return 0; @@ -753,10 +824,10 @@ int main(int argc, char *const* argv) fprintf(stderr, "Unknown option '%c'\n", f); goto help; } - + if (argc == optind) goto help; - + if (ctl_client_init()) { fprintf(stderr, "can't setup control connection\n"); return 1; @@ -768,7 +839,7 @@ int main(int argc, char *const* argv) fprintf(stderr, "never heard of command [%s]\n", argv[0]); goto help; } - + if (argc < cmd->nargs + 1 || argc > cmd->nargs + cmd->optargs + 1) { printf("Incorrect number of arguments for command\n"); printf("Usage: rstpctl %s %s\n", cmd->name, cmd->help); @@ -777,7 +848,7 @@ int main(int argc, char *const* argv) return cmd->func(argc, argv); -help: + help: help(); return 1; } diff --git a/ctl_socket.c b/ctl_socket.c index c41728a..f37e8b1 100644 --- a/ctl_socket.c +++ b/ctl_socket.c @@ -35,46 +35,44 @@ #include "epoll_loop.h" #include "log.h" - int server_socket(void) { - struct sockaddr_un sa; - int s; - - TST (strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa.sun_path), -1); + struct sockaddr_un sa; + int s; - s = socket(PF_UNIX, SOCK_DGRAM, 0); - if (s < 0) { - ERROR("Couldn't open unix socket: %m"); - return -1; - } - - set_socket_address(&sa, RSTP_SERVER_SOCK_NAME); - - if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) { - ERROR("Couldn't bind socket: %m"); - close(s); - return -1; - } + TST(strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa.sun_path), -1); - return s; -} + s = socket(PF_UNIX, SOCK_DGRAM, 0); + if (s < 0) { + ERROR("Couldn't open unix socket: %m"); + return -1; + } + + set_socket_address(&sa, RSTP_SERVER_SOCK_NAME); + if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) { + ERROR("Couldn't bind socket: %m"); + close(s); + return -1; + } + + return s; +} int handle_message(int cmd, void *inbuf, int lin, void *outbuf, int *lout) { - switch (cmd) { - SERVER_MESSAGE_CASE(enable_bridge_rstp); - SERVER_MESSAGE_CASE(get_bridge_state); - SERVER_MESSAGE_CASE(set_bridge_config); - SERVER_MESSAGE_CASE(get_port_state); - SERVER_MESSAGE_CASE(set_port_config); - SERVER_MESSAGE_CASE(set_debug_level); - - default: - ERROR("CTL: Unknown command %d", cmd); - return -1; - } + switch (cmd) { + SERVER_MESSAGE_CASE(enable_bridge_rstp); + SERVER_MESSAGE_CASE(get_bridge_state); + SERVER_MESSAGE_CASE(set_bridge_config); + SERVER_MESSAGE_CASE(get_port_state); + SERVER_MESSAGE_CASE(set_port_config); + SERVER_MESSAGE_CASE(set_debug_level); + + default: + ERROR("CTL: Unknown command %d", cmd); + return -1; + } } #define msg_buf_len 1024 @@ -83,63 +81,69 @@ unsigned char msg_outbuf[1024]; void ctl_rcv_handler(uint32_t events, struct epoll_event_handler *p) { - struct ctl_msg_hdr mhdr; - struct msghdr msg; - struct sockaddr_un sa; - struct iovec iov[2]; - int l; - - msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); - msg.msg_iov = iov; msg.msg_iovlen = 2; - msg.msg_control = NULL; msg.msg_controllen = 0; - iov[0].iov_base = &mhdr; iov[0].iov_len = sizeof(mhdr); - iov[1].iov_base = msg_inbuf; iov[1].iov_len = msg_buf_len; - l = recvmsg(p->fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); - TST(l > 0, ); - if (msg.msg_flags != 0 || l < sizeof(mhdr) || - l != sizeof(mhdr) + mhdr.lin || - mhdr.lout > msg_buf_len || mhdr.cmd < 0) { - ERROR("CTL: Unexpected message. Ignoring"); - return; - } - - - if (mhdr.lout) - mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin, - msg_outbuf, &mhdr.lout); - else - mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin, - NULL, NULL); - - if (mhdr.res < 0) - mhdr.lout = 0; - iov[1].iov_base = msg_outbuf; iov[1].iov_len = mhdr.lout; - l = sendmsg(p->fd, &msg, MSG_NOSIGNAL); - if (l < 0) - ERROR("CTL: Couldn't send response: %m"); - else if (l != sizeof(mhdr) + mhdr.lout) { - ERROR("CTL: Couldn't send full response, sent %d bytes instead of %zd.", - l, sizeof(mhdr) + mhdr.lout); - } + struct ctl_msg_hdr mhdr; + struct msghdr msg; + struct sockaddr_un sa; + struct iovec iov[2]; + int l; + + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = iov; + msg.msg_iovlen = 2; + msg.msg_control = NULL; + msg.msg_controllen = 0; + iov[0].iov_base = &mhdr; + iov[0].iov_len = sizeof(mhdr); + iov[1].iov_base = msg_inbuf; + iov[1].iov_len = msg_buf_len; + l = recvmsg(p->fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); + TST(l > 0,); + if (msg.msg_flags != 0 || l < sizeof(mhdr) || + l != sizeof(mhdr) + mhdr.lin || + mhdr.lout > msg_buf_len || mhdr.cmd < 0) { + ERROR("CTL: Unexpected message. Ignoring"); + return; + } + + if (mhdr.lout) + mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin, + msg_outbuf, &mhdr.lout); + else + mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin, + NULL, NULL); + + if (mhdr.res < 0) + mhdr.lout = 0; + iov[1].iov_base = msg_outbuf; + iov[1].iov_len = mhdr.lout; + l = sendmsg(p->fd, &msg, MSG_NOSIGNAL); + if (l < 0) + ERROR("CTL: Couldn't send response: %m"); + else if (l != sizeof(mhdr) + mhdr.lout) { + ERROR + ("CTL: Couldn't send full response, sent %d bytes instead of %zd.", + l, sizeof(mhdr) + mhdr.lout); + } } struct epoll_event_handler ctl_handler; int ctl_socket_init(void) { - int s = server_socket(); - if (s < 0) - return -1; + int s = server_socket(); + if (s < 0) + return -1; - ctl_handler.fd = s; - ctl_handler.handler = ctl_rcv_handler; - - TST(add_epoll(&ctl_handler) == 0, -1); - return 0; + ctl_handler.fd = s; + ctl_handler.handler = ctl_rcv_handler; + + TST(add_epoll(&ctl_handler) == 0, -1); + return 0; } void ctl_socket_cleanup(void) { - remove_epoll(&ctl_handler); - close(ctl_handler.fd); + remove_epoll(&ctl_handler); + close(ctl_handler.fd); } diff --git a/ctl_socket.h b/ctl_socket.h index 5e7d96f..089a717 100644 --- a/ctl_socket.h +++ b/ctl_socket.h @@ -30,12 +30,11 @@ #include "ctl_functions.h" -struct ctl_msg_hdr -{ - int cmd; - int lin; - int lout; - int res; +struct ctl_msg_hdr { + int cmd; + int lin; + int lout; + int res; }; #define set_socket_address(sa, string) \ @@ -54,8 +53,12 @@ int CTL_enable_bridge_rstp(int br_index, int enable); #endif #define CMD_CODE_enable_bridge_rstp 101 #define enable_bridge_rstp_ARGS (int br_index, int enable) -struct enable_bridge_rstp_IN { int br_index; int enable; }; -struct enable_bridge_rstp_OUT { }; +struct enable_bridge_rstp_IN { + int br_index; + int enable; +}; +struct enable_bridge_rstp_OUT { +}; #define enable_bridge_rstp_COPY_IN \ ({ in->br_index = br_index; in->enable = enable; }) #define enable_bridge_rstp_COPY_OUT ({ (void)0; }) @@ -63,25 +66,33 @@ struct enable_bridge_rstp_OUT { }; #if 0 int CTL_get_bridge_state(int br_index, - UID_STP_CFG_T *cfg, UID_STP_STATE_T *state); + UID_STP_CFG_T * cfg, UID_STP_STATE_T * state); #endif #define CMD_CODE_get_bridge_state 102 #define get_bridge_state_ARGS (int br_index, UID_STP_CFG_T *cfg, UID_STP_STATE_T *state) -struct get_bridge_state_IN { int br_index; }; -struct get_bridge_state_OUT { UID_STP_CFG_T cfg; UID_STP_STATE_T state; }; +struct get_bridge_state_IN { + int br_index; +}; +struct get_bridge_state_OUT { + UID_STP_CFG_T cfg; + UID_STP_STATE_T state; +}; #define get_bridge_state_COPY_IN \ ({ in->br_index = br_index; }) #define get_bridge_state_COPY_OUT ({ *cfg = out->cfg; *state = out->state; }) #define get_bridge_state_CALL (in->br_index, &out->cfg, &out->state) #if 0 -int CTL_set_bridge_config(int br_index, - UID_STP_CFG_T *cfg); +int CTL_set_bridge_config(int br_index, UID_STP_CFG_T * cfg); #endif #define CMD_CODE_set_bridge_config 103 #define set_bridge_config_ARGS (int br_index, UID_STP_CFG_T *cfg) -struct set_bridge_config_IN { int br_index; UID_STP_CFG_T cfg; }; -struct set_bridge_config_OUT { }; +struct set_bridge_config_IN { + int br_index; + UID_STP_CFG_T cfg; +}; +struct set_bridge_config_OUT { +}; #define set_bridge_config_COPY_IN \ ({ in->br_index = br_index; in->cfg = *cfg; }) #define set_bridge_config_COPY_OUT ({ (void)0; }) @@ -89,38 +100,50 @@ struct set_bridge_config_OUT { }; #if 0 int CTL_get_port_state(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg, UID_STP_PORT_STATE_T *state); + UID_STP_PORT_CFG_T * cfg, UID_STP_PORT_STATE_T * state); #endif #define CMD_CODE_get_port_state 104 #define get_port_state_ARGS (int br_index, int port_index, UID_STP_PORT_CFG_T *cfg, UID_STP_PORT_STATE_T *state) -struct get_port_state_IN { int br_index; int port_index; }; -struct get_port_state_OUT { UID_STP_PORT_CFG_T cfg; UID_STP_PORT_STATE_T state; }; +struct get_port_state_IN { + int br_index; + int port_index; +}; +struct get_port_state_OUT { + UID_STP_PORT_CFG_T cfg; + UID_STP_PORT_STATE_T state; +}; #define get_port_state_COPY_IN \ ({ in->br_index = br_index; in->port_index = port_index; }) #define get_port_state_COPY_OUT ({ *cfg = out->cfg; *state = out->state; }) #define get_port_state_CALL (in->br_index, in->port_index, &out->cfg, &out->state) #if 0 -int CTL_set_port_config(int br_index, int port_index, - UID_STP_PORT_CFG_T *cfg); +int CTL_set_port_config(int br_index, int port_index, UID_STP_PORT_CFG_T * cfg); #endif #define CMD_CODE_set_port_config 105 #define set_port_config_ARGS (int br_index, int port_index, UID_STP_PORT_CFG_T *cfg) -struct set_port_config_IN { int br_index; int port_index; UID_STP_PORT_CFG_T cfg; }; -struct set_port_config_OUT { }; +struct set_port_config_IN { + int br_index; + int port_index; + UID_STP_PORT_CFG_T cfg; +}; +struct set_port_config_OUT { +}; #define set_port_config_COPY_IN \ ({ in->br_index = br_index; in->port_index = port_index; in->cfg = *cfg; }) #define set_port_config_COPY_OUT ({ (void)0; }) #define set_port_config_CALL (in->br_index, in->port_index, &in->cfg) - #if 0 int CTL_set_debug_level(int level); #endif #define CMD_CODE_set_debug_level 106 #define set_debug_level_ARGS (int level) -struct set_debug_level_IN { int level; }; -struct set_debug_level_OUT { }; +struct set_debug_level_IN { + int level; +}; +struct set_debug_level_OUT { +}; #define set_debug_level_COPY_IN \ ({ in->level = level; }) #define set_debug_level_COPY_OUT ({ (void)0; }) @@ -162,6 +185,4 @@ int CTL_ ## name name ## _ARGS \ return r; \ } - - #endif diff --git a/ctl_socket_client.c b/ctl_socket_client.c index 66be8d2..46d5851 100644 --- a/ctl_socket_client.c +++ b/ctl_socket_client.c @@ -38,113 +38,123 @@ static int fd = -1; int ctl_client_init(void) { - struct sockaddr_un sa_svr; - int s; - TST (strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa_svr.sun_path), -1); - - s = socket(PF_UNIX, SOCK_DGRAM, 0); - if (s < 0) { - ERROR("Couldn't open unix socket: %m"); - return -1; - } - - set_socket_address(&sa_svr, RSTP_SERVER_SOCK_NAME); - - struct sockaddr_un sa; - char tmpname[64]; - sprintf(tmpname, "RSTPCTL_%d", getpid()); - set_socket_address(&sa, tmpname); - /* We need this bind. The autobind on connect isn't working properly. - The server doesn't get a proper sockaddr in recvmsg if we don't do this. - */ - if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) { - ERROR("Couldn't bind socket: %m"); - close(s); - return -1; - } - - if (connect(s, (struct sockaddr *)&sa_svr, sizeof(sa_svr)) != 0) { - ERROR("Couldn't connect to server"); - close(s); - return -1; - } - fd = s; - - return 0; + struct sockaddr_un sa_svr; + int s; + TST(strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa_svr.sun_path), -1); + + s = socket(PF_UNIX, SOCK_DGRAM, 0); + if (s < 0) { + ERROR("Couldn't open unix socket: %m"); + return -1; + } + + set_socket_address(&sa_svr, RSTP_SERVER_SOCK_NAME); + + struct sockaddr_un sa; + char tmpname[64]; + sprintf(tmpname, "RSTPCTL_%d", getpid()); + set_socket_address(&sa, tmpname); + /* We need this bind. The autobind on connect isn't working properly. + The server doesn't get a proper sockaddr in recvmsg if we don't do this. + */ + if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) { + ERROR("Couldn't bind socket: %m"); + close(s); + return -1; + } + + if (connect(s, (struct sockaddr *)&sa_svr, sizeof(sa_svr)) != 0) { + ERROR("Couldn't connect to server"); + close(s); + return -1; + } + fd = s; + + return 0; } void ctl_client_cleanup(void) { - if (fd >= 0) { - close(fd); - fd = -1; - } + if (fd >= 0) { + close(fd); + fd = -1; + } } int send_ctl_message(int cmd, void *inbuf, int lin, void *outbuf, int *lout, - int *res) + int *res) { - struct ctl_msg_hdr mhdr; - struct msghdr msg; - struct iovec iov[2]; - int l; - - msg.msg_name = NULL; msg.msg_namelen = 0; - msg.msg_iov = iov; msg.msg_iovlen = 2; - msg.msg_control = NULL; msg.msg_controllen = 0; - - mhdr.cmd = cmd; - mhdr.lin = lin; - mhdr.lout = lout != NULL ? *lout : 0; - iov[0].iov_base = &mhdr; iov[0].iov_len = sizeof(mhdr); - iov[1].iov_base = (void *)inbuf; iov[1].iov_len = lin; - - l = sendmsg(fd, &msg, 0); - if (l < 0) { - ERROR("Error sending message to server: %m"); - return -1; - } - if (l != sizeof(mhdr) + lin) { - ERROR("Error sending message to server: Partial write"); - return -1; - } - - iov[1].iov_base = outbuf; - iov[1].iov_len = lout != NULL ? *lout : 0; - - { - struct pollfd pfd; - int timeout = 5000; /* 5 s */ - int r; - - pfd.fd = fd; - pfd.events = POLLIN; - do { - r = poll(&pfd, 1, timeout); - if (r == 0) { - ERROR("Error getting message from server: Timeout"); - return -1; - } - if (r < 0) { - ERROR("Error getting message from server: poll error: %m"); - return -1; - } - } while ((pfd.revents & (POLLERR | POLLHUP | POLLNVAL | POLLIN)) == 0); - - l = recvmsg(fd, &msg, 0); - if (l < 0) { - ERROR("Error getting message from server: %m"); - return -1; - } - if (l < sizeof(mhdr) || l != sizeof(mhdr) + mhdr.lout || mhdr.cmd != cmd) { - ERROR("Error getting message from server: Bad format"); - return -1; - } - } - if (lout) - *lout = mhdr.lout; - if (res) - *res = mhdr.res; - - return 0; + struct ctl_msg_hdr mhdr; + struct msghdr msg; + struct iovec iov[2]; + int l; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 2; + msg.msg_control = NULL; + msg.msg_controllen = 0; + + mhdr.cmd = cmd; + mhdr.lin = lin; + mhdr.lout = lout != NULL ? *lout : 0; + iov[0].iov_base = &mhdr; + iov[0].iov_len = sizeof(mhdr); + iov[1].iov_base = (void *)inbuf; + iov[1].iov_len = lin; + + l = sendmsg(fd, &msg, 0); + if (l < 0) { + ERROR("Error sending message to server: %m"); + return -1; + } + if (l != sizeof(mhdr) + lin) { + ERROR("Error sending message to server: Partial write"); + return -1; + } + + iov[1].iov_base = outbuf; + iov[1].iov_len = lout != NULL ? *lout : 0; + + { + struct pollfd pfd; + int timeout = 5000; /* 5 s */ + int r; + + pfd.fd = fd; + pfd.events = POLLIN; + do { + r = poll(&pfd, 1, timeout); + if (r == 0) { + ERROR + ("Error getting message from server: Timeout"); + return -1; + } + if (r < 0) { + ERROR + ("Error getting message from server: poll error: %m"); + return -1; + } + } while ((pfd. + revents & (POLLERR | POLLHUP | POLLNVAL | POLLIN)) == + 0); + + l = recvmsg(fd, &msg, 0); + if (l < 0) { + ERROR("Error getting message from server: %m"); + return -1; + } + if (l < sizeof(mhdr) || l != sizeof(mhdr) + mhdr.lout + || mhdr.cmd != cmd) { + ERROR("Error getting message from server: Bad format"); + return -1; + } + } + if (lout) + *lout = mhdr.lout; + if (res) + *res = mhdr.res; + + return 0; } diff --git a/ctl_socket_client.h b/ctl_socket_client.h index 2bfc9ea..5d8a7d3 100644 --- a/ctl_socket_client.h +++ b/ctl_socket_client.h @@ -26,8 +26,7 @@ #define CTL_SOCKET_CLIENT_H int send_ctl_message(int cmd, void *inbuf, int lin, void *outbuf, int *lout, - int *res); - + int *res); int ctl_client_init(void); diff --git a/ctl_socket_server.h b/ctl_socket_server.h index 9b74172..88f6bf4 100644 --- a/ctl_socket_server.h +++ b/ctl_socket_server.h @@ -29,5 +29,3 @@ int ctl_socket_init(void); void ctl_socket_cleanup(void); #endif - - diff --git a/epoll_loop.c b/epoll_loop.c index 230dacc..33c3068 100644 --- a/epoll_loop.c +++ b/epoll_loop.c @@ -39,103 +39,102 @@ struct timeval nexttimeout; int init_epoll(void) { - int r = epoll_create(128); - if (r < 0) { - fprintf(stderr, "epoll_create failed: %m\n"); - return -1; - } - epoll_fd = r; - return 0; + int r = epoll_create(128); + if (r < 0) { + fprintf(stderr, "epoll_create failed: %m\n"); + return -1; + } + epoll_fd = r; + return 0; } int add_epoll(struct epoll_event_handler *h) { - struct epoll_event ev = - { - .events = EPOLLIN, - .data.ptr = h, - }; - h->ref_ev = NULL; - int r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->fd, &ev); - if (r < 0) { - fprintf(stderr, "epoll_ctl_add: %m\n"); - return -1; - } - return 0; + struct epoll_event ev = { + .events = EPOLLIN, + .data.ptr = h, + }; + h->ref_ev = NULL; + int r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, h->fd, &ev); + if (r < 0) { + fprintf(stderr, "epoll_ctl_add: %m\n"); + return -1; + } + return 0; } int remove_epoll(struct epoll_event_handler *h) { - int r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->fd, NULL); - if (r < 0) { - fprintf(stderr, "epoll_ctl_del: %m\n"); - return -1; - } - if (h->ref_ev && h->ref_ev->data.ptr == h) { - h->ref_ev->data.ptr = NULL; - h->ref_ev = NULL; - } - return 0; + int r = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, h->fd, NULL); + if (r < 0) { + fprintf(stderr, "epoll_ctl_del: %m\n"); + return -1; + } + if (h->ref_ev && h->ref_ev->data.ptr == h) { + h->ref_ev->data.ptr = NULL; + h->ref_ev = NULL; + } + return 0; } void clear_epoll(void) { - if (epoll_fd >= 0) - close(epoll_fd); + if (epoll_fd >= 0) + close(epoll_fd); } int time_diff(struct timeval *second, struct timeval *first) { - return (second->tv_sec - first->tv_sec)*1000 - + (second->tv_usec - first->tv_usec)/1000; + return (second->tv_sec - first->tv_sec) * 1000 + + (second->tv_usec - first->tv_usec) / 1000; } void run_timeouts(void) { - bridge_one_second(); - nexttimeout.tv_sec++; + bridge_one_second(); + nexttimeout.tv_sec++; } int epoll_main_loop(void) { - gettimeofday(&nexttimeout, NULL); - nexttimeout.tv_sec++; + gettimeofday(&nexttimeout, NULL); + nexttimeout.tv_sec++; #define EV_SIZE 8 - struct epoll_event ev[EV_SIZE]; - - while (1) { - int r, i; - int timeout; - - struct timeval tv; - gettimeofday(&tv, NULL); - timeout = time_diff(&nexttimeout, &tv); - if (timeout < 0) { - run_timeouts(); - timeout = 0; - } - - r = epoll_wait(epoll_fd, ev, EV_SIZE, timeout); - if (r < 0 && errno != EINTR) { - fprintf(stderr, "epoll_wait: %m\n"); - return -1; - } - for (i = 0; i < r; i++) { - struct epoll_event_handler *p = ev[i].data.ptr; - if (p != NULL) - p->ref_ev = &ev[i]; - } - for (i = 0; i < r; i++) { - struct epoll_event_handler *p = ev[i].data.ptr; - if (p && p->handler) - p->handler(ev[i].events, p); - } - for (i = 0; i < r; i++) { - struct epoll_event_handler *p = ev[i].data.ptr; - if (p != NULL) - p->ref_ev = NULL; - } - } - - return 0; + struct epoll_event ev[EV_SIZE]; + + while (1) { + int r, i; + int timeout; + + struct timeval tv; + gettimeofday(&tv, NULL); + timeout = time_diff(&nexttimeout, &tv); + if (timeout < 0) { + run_timeouts(); + timeout = 0; + } + + r = epoll_wait(epoll_fd, ev, EV_SIZE, timeout); + if (r < 0 && errno != EINTR) { + fprintf(stderr, "epoll_wait: %m\n"); + return -1; + } + for (i = 0; i < r; i++) { + struct epoll_event_handler *p = ev[i].data.ptr; + if (p != NULL) + p->ref_ev = &ev[i]; + } + for (i = 0; i < r; i++) { + struct epoll_event_handler *p = ev[i].data.ptr; + if (p && p->handler) + p->handler(ev[i].events, p); + } + for (i = 0; i < r; i++) { + struct epoll_event_handler *p = ev[i].data.ptr; + if (p != NULL) + p->ref_ev = NULL; + } + } + + return 0; } diff --git a/epoll_loop.h b/epoll_loop.h index f9cfbee..14d0423 100644 --- a/epoll_loop.h +++ b/epoll_loop.h @@ -30,13 +30,12 @@ #include #include -struct epoll_event_handler -{ - int fd; - void *arg; - void (*handler)(uint32_t events, struct epoll_event_handler *p); - struct epoll_event *ref_ev; /* if set, epoll loop has reference to this, - so mark that ref as NULL while freeing */ +struct epoll_event_handler { + int fd; + void *arg; + void (*handler) (uint32_t events, struct epoll_event_handler * p); + struct epoll_event *ref_ev; /* if set, epoll loop has reference to this, + so mark that ref as NULL while freeing */ }; int init_epoll(void); diff --git a/libnetlink.c b/libnetlink.c index 151968b..089b99a 100644 --- a/libnetlink.c +++ b/libnetlink.c @@ -45,12 +45,14 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, return -1; } - if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) { + if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) + < 0) { perror("SO_SNDBUF"); return -1; } - if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) { + if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) + < 0) { perror("SO_RCVBUF"); return -1; } @@ -59,12 +61,13 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, rth->local.nl_family = AF_NETLINK; rth->local.nl_groups = subscriptions; - if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { + if (bind(rth->fd, (struct sockaddr *)&rth->local, sizeof(rth->local)) < + 0) { perror("Cannot bind netlink socket"); return -1; } addr_len = sizeof(rth->local); - if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { + if (getsockname(rth->fd, (struct sockaddr *)&rth->local, &addr_len) < 0) { perror("Cannot getsockname"); return -1; } @@ -73,7 +76,8 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, return -1; } if (rth->local.nl_family != AF_NETLINK) { - fprintf(stderr, "Wrong address family %d\n", rth->local.nl_family); + fprintf(stderr, "Wrong address family %d\n", + rth->local.nl_family); return -1; } rth->seq = time(NULL); @@ -99,13 +103,13 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) memset(&req, 0, sizeof(req)); req.nlh.nlmsg_len = sizeof(req); req.nlh.nlmsg_type = type; - req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; req.nlh.nlmsg_pid = 0; req.nlh.nlmsg_seq = rth->dump = ++rth->seq; req.g.rtgen_family = family; - return sendto(rth->fd, (void*)&req, sizeof(req), 0, - (struct sockaddr*)&nladdr, sizeof(nladdr)); + return sendto(rth->fd, (void *)&req, sizeof(req), 0, + (struct sockaddr *)&nladdr, sizeof(nladdr)); } int rtnl_send(struct rtnl_handle *rth, const char *buf, int len) @@ -115,7 +119,8 @@ int rtnl_send(struct rtnl_handle *rth, const char *buf, int len) memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; - return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); + return sendto(rth->fd, buf, len, 0, (struct sockaddr *)&nladdr, + sizeof(nladdr)); } int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) @@ -123,12 +128,13 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) struct nlmsghdr nlh; struct sockaddr_nl nladdr; struct iovec iov[2] = { - { .iov_base = &nlh, .iov_len = sizeof(nlh) }, - { .iov_base = req, .iov_len = len } + {.iov_base = &nlh,.iov_len = sizeof(nlh)} + , + {.iov_base = req,.iov_len = len} }; struct msghdr msg = { .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), + .msg_namelen = sizeof(nladdr), .msg_iov = iov, .msg_iovlen = 2, }; @@ -138,7 +144,7 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) nlh.nlmsg_len = NLMSG_LENGTH(len); nlh.nlmsg_type = type; - nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; + nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; nlh.nlmsg_pid = 0; nlh.nlmsg_seq = rth->dump = ++rth->seq; @@ -147,9 +153,7 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, - void *arg1, - rtnl_filter_t junk, - void *arg2) + void *arg1, rtnl_filter_t junk, void *arg2) { struct sockaddr_nl nladdr; struct iovec iov; @@ -181,7 +185,7 @@ int rtnl_dump_filter(struct rtnl_handle *rth, return -1; } - h = (struct nlmsghdr*)buf; + h = (struct nlmsghdr *)buf; while (NLMSG_OK(h, status)) { int err; @@ -199,8 +203,10 @@ int rtnl_dump_filter(struct rtnl_handle *rth, if (h->nlmsg_type == NLMSG_DONE) return 0; if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { + struct nlmsgerr *err = + (struct nlmsgerr *)NLMSG_DATA(h); + if (h->nlmsg_len < + NLMSG_LENGTH(sizeof(struct nlmsgerr))) { fprintf(stderr, "ERROR truncated\n"); } else { errno = -err->error; @@ -212,7 +218,7 @@ int rtnl_dump_filter(struct rtnl_handle *rth, if (err < 0) return err; -skip_it: + skip_it: h = NLMSG_NEXT(h, status); } if (msg.msg_flags & MSG_TRUNC) { @@ -228,15 +234,14 @@ skip_it: int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, - rtnl_filter_t junk, - void *jarg) + rtnl_filter_t junk, void *jarg) { int status; unsigned seq; struct nlmsghdr *h; struct sockaddr_nl nladdr; struct iovec iov = { - .iov_base = (void*) n, + .iov_base = (void *)n, .iov_len = n->nlmsg_len }; struct msghdr msg = { @@ -245,7 +250,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, .msg_iov = &iov, .msg_iovlen = 1, }; - char buf[16384]; + char buf[16384]; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -264,7 +269,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, return -1; } - memset(buf,0,sizeof(buf)); + memset(buf, 0, sizeof(buf)); iov.iov_base = buf; @@ -283,20 +288,22 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, return -1; } if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, "sender address length == %d\n", msg.msg_namelen); + fprintf(stderr, "sender address length == %d\n", + msg.msg_namelen); exit(1); } - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { + for (h = (struct nlmsghdr *)buf; status >= sizeof(*h);) { int err; int len = h->nlmsg_len; int l = len - sizeof(*h); - if (l<0 || len>status) { + if (l < 0 || len > status) { if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Truncated message\n"); return -1; } - fprintf(stderr, "!!!malformed message: len=%d\n", len); + fprintf(stderr, + "!!!malformed message: len=%d\n", len); exit(1); } @@ -310,19 +317,22 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, } /* Don't forget to skip that message. */ status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); + h = (struct nlmsghdr *)((char *)h + + NLMSG_ALIGN(len)); continue; } if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); + struct nlmsgerr *err = + (struct nlmsgerr *)NLMSG_DATA(h); if (l < sizeof(struct nlmsgerr)) { fprintf(stderr, "ERROR truncated\n"); } else { errno = -err->error; if (errno == 0) { if (answer) - memcpy(answer, h, h->nlmsg_len); + memcpy(answer, h, + h->nlmsg_len); return 0; } perror("RTNETLINK answers"); @@ -337,7 +347,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, fprintf(stderr, "Unexpected reply!!!\n"); status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); + h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); } if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Message truncated\n"); @@ -350,9 +360,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, } } -int rtnl_listen(struct rtnl_handle *rtnl, - rtnl_filter_t handler, - void *jarg) +int rtnl_listen(struct rtnl_handle *rtnl, rtnl_filter_t handler, void *jarg) { int status; struct nlmsghdr *h; @@ -364,7 +372,7 @@ int rtnl_listen(struct rtnl_handle *rtnl, .msg_iov = &iov, .msg_iovlen = 1, }; - char buf[8192]; + char buf[8192]; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -379,41 +387,43 @@ int rtnl_listen(struct rtnl_handle *rtnl, if (status < 0) { if (errno == EINTR) continue; - if (errno == EAGAIN) - return 0; + if (errno == EAGAIN) + return 0; perror("OVERRUN"); - return -1; + return -1; } if (status == 0) { fprintf(stderr, "EOF on netlink\n"); return -1; } if (msg.msg_namelen != sizeof(nladdr)) { - fprintf(stderr, "Sender address length == %d\n", msg.msg_namelen); + fprintf(stderr, "Sender address length == %d\n", + msg.msg_namelen); exit(1); } - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { + for (h = (struct nlmsghdr *)buf; status >= sizeof(*h);) { int err; int len = h->nlmsg_len; int l = len - sizeof(*h); - if (l<0 || len>status) { + if (l < 0 || len > status) { if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Truncated message\n"); return -1; } - fprintf(stderr, "!!!malformed message: len=%d\n", len); + fprintf(stderr, + "!!!malformed message: len=%d\n", len); exit(1); } err = handler(&nladdr, h, jarg); if (err < 0) { - fprintf(stderr, "Handler returned %d\n", err); - return err; - } + fprintf(stderr, "Handler returned %d\n", err); + return err; + } status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); + h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); } if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Message truncated\n"); @@ -426,13 +436,12 @@ int rtnl_listen(struct rtnl_handle *rtnl, } } -int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, - void *jarg) +int rtnl_from_file(FILE * rtnl, rtnl_filter_t handler, void *jarg) { int status; struct sockaddr_nl nladdr; - char buf[8192]; - struct nlmsghdr *h = (void*)buf; + char buf[8192]; + struct nlmsghdr *h = (void *)buf; memset(&nladdr, 0, sizeof(nladdr)); nladdr.nl_family = AF_NETLINK; @@ -455,10 +464,10 @@ int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, return 0; len = h->nlmsg_len; - type= h->nlmsg_type; + type = h->nlmsg_type; l = len - sizeof(*h); - if (l<0 || len>sizeof(buf)) { + if (l < 0 || len > sizeof(buf)) { fprintf(stderr, "!!!malformed message: len=%d @%lu\n", len, ftell(rtnl)); return -1; @@ -486,7 +495,9 @@ int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) int len = RTA_LENGTH(4); struct rtattr *rta; if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) { - fprintf(stderr,"addattr32: Error! max allowed bound %d exceeded\n",maxlen); + fprintf(stderr, + "addattr32: Error! max allowed bound %d exceeded\n", + maxlen); return -1; } rta = NLMSG_TAIL(n); @@ -504,7 +515,9 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, struct rtattr *rta; if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { - fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen); + fprintf(stderr, + "addattr_l ERROR: message exceeded bound of %d\n", + maxlen); return -1; } rta = NLMSG_TAIL(n); @@ -518,12 +531,14 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len) { if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) { - fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen); + fprintf(stderr, + "addraw_l ERROR: message exceeded bound of %d\n", + maxlen); return -1; } memcpy(NLMSG_TAIL(n), data, len); - memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len); + memset((void *)NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len); n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len); return 0; } @@ -534,10 +549,12 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data) struct rtattr *subrta; if (RTA_ALIGN(rta->rta_len) + len > maxlen) { - fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen); + fprintf(stderr, + "rta_addattr32: Error! max allowed bound %d exceeded\n", + maxlen); return -1; } - subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); + subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len)); subrta->rta_type = type; subrta->rta_len = len; memcpy(RTA_DATA(subrta), &data, 4); @@ -552,10 +569,12 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type, int len = RTA_LENGTH(alen); if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { - fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen); + fprintf(stderr, + "rta_addattr_l: Error! max allowed bound %d exceeded\n", + maxlen); return -1; } - subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); + subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len)); subrta->rta_type = type; subrta->rta_len = len; memcpy(RTA_DATA(subrta), data, alen); @@ -569,14 +588,16 @@ int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) while (RTA_OK(rta, len)) { if (rta->rta_type <= max) tb[rta->rta_type] = rta; - rta = RTA_NEXT(rta,len); + rta = RTA_NEXT(rta, len); } if (len) - fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); + fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, + rta->rta_len); return 0; } -int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len) +int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, + int len) { int i = 0; @@ -584,9 +605,10 @@ int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int l while (RTA_OK(rta, len)) { if (rta->rta_type <= max && i < max) tb[i++] = rta; - rta = RTA_NEXT(rta,len); + rta = RTA_NEXT(rta, len); } if (len) - fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len); + fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, + rta->rta_len); return i; } diff --git a/log.h b/log.h index e61a569..1452438 100644 --- a/log.h +++ b/log.h @@ -43,27 +43,37 @@ extern int log_level; #define PRINT(_level, _fmt, _args...) Dprintf(_level, _fmt, ##_args) -#define TSTM(x,y, _fmt, _args...) do if (!(x)) { PRINT(LOG_LEVEL_ERROR, "Error in %s at %s:%d verifying %s. " _fmt, __PRETTY_FUNCTION__, __FILE__, __LINE__, #x, ##_args); return y; } while (0) +#define TSTM(x,y, _fmt, _args...) \ + do if (!(x)) { \ + PRINT(LOG_LEVEL_ERROR, \ + "Error in %s at %s:%d verifying %s. " _fmt, \ + __PRETTY_FUNCTION__, __FILE__, __LINE__, \ + #x, ##_args); \ + return y; \ + } while (0) #define TST(x,y) TSTM(x,y,"") -#define LOG(_fmt, _args...) PRINT(LOG_LEVEL_DEBUG, "%s: " _fmt, __PRETTY_FUNCTION__, ##_args) +#define LOG(_fmt, _args...) \ + PRINT(LOG_LEVEL_DEBUG, "%s: " _fmt, __PRETTY_FUNCTION__, ##_args) -#define INFO(_fmt, _args...) PRINT(LOG_LEVEL_INFO, "%s: " _fmt, __PRETTY_FUNCTION__, ##_args) +#define INFO(_fmt, _args...) \ + PRINT(LOG_LEVEL_INFO, "%s: " _fmt, __PRETTY_FUNCTION__, ##_args) -#define ERROR(_fmt, _args...) PRINT(LOG_LEVEL_ERROR, "error, %s: " _fmt, __PRETTY_FUNCTION__, ##_args) +#define ERROR(_fmt, _args...) \ + PRINT(LOG_LEVEL_ERROR, "error, %s: " _fmt, __PRETTY_FUNCTION__, ##_args) static inline void dump_hex(void *b, int l) { - unsigned char *buf = b; - char logbuf[80]; - int i, j; - for (i = 0; i < l; i += 16) { - for (j = 0; j < 16 && i+j < l; j++) - sprintf(logbuf + j * 3, " %02x", buf[i+j]); - PRINT(LOG_LEVEL_INFO, "%s", logbuf); - } - PRINT(LOG_LEVEL_INFO, "\n"); + unsigned char *buf = b; + char logbuf[80]; + int i, j; + for (i = 0; i < l; i += 16) { + for (j = 0; j < 16 && i + j < l; j++) + sprintf(logbuf + j * 3, " %02x", buf[i + j]); + PRINT(LOG_LEVEL_INFO, "%s", logbuf); + } + PRINT(LOG_LEVEL_INFO, "\n"); } #endif diff --git a/main.c b/main.c index 3ff556d..4395976 100644 --- a/main.c +++ b/main.c @@ -40,39 +40,41 @@ int log_level = LOG_LEVEL_DEFAULT; int main(int argc, char *argv[]) { - int c; - while ((c = getopt(argc, argv, "dv:")) != -1) { - switch (c) { - case 'd': - become_daemon = 0; break; - case 'v': - { - char *end; - long l; - l = strtoul(optarg, &end, 0); - if (*optarg == 0 || *end != 0 || l > LOG_LEVEL_MAX) { - ERROR("Invalid loglevel %s", optarg); - exit(1); - } - log_level = l; - } - break; - default: - return -1; - } - } - - TST(init_epoll() == 0, -1); - TST(ctl_socket_init() == 0, -1); + int c; + while ((c = getopt(argc, argv, "dv:")) != -1) { + switch (c) { + case 'd': + become_daemon = 0; + break; + case 'v': + { + char *end; + long l; + l = strtoul(optarg, &end, 0); + if (*optarg == 0 || *end != 0 + || l > LOG_LEVEL_MAX) { + ERROR("Invalid loglevel %s", optarg); + exit(1); + } + log_level = l; + } + break; + default: + return -1; + } + } + + TST(init_epoll() == 0, -1); + TST(ctl_socket_init() == 0, -1); - TST(netsock_init() == 0, -1); - TST(init_bridge_ops() == 0, -1); - if (become_daemon) { - openlog("rstpd", 0, LOG_DAEMON); - daemon(0,0); - is_daemon = 1; - } - return epoll_main_loop(); + TST(netsock_init() == 0, -1); + TST(init_bridge_ops() == 0, -1); + if (become_daemon) { + openlog("rstpd", 0, LOG_DAEMON); + daemon(0, 0); + is_daemon = 1; + } + return epoll_main_loop(); } /*********************** Logging *********************/ @@ -80,31 +82,32 @@ int main(int argc, char *argv[]) #include #include -void vDprintf(int level, const char* fmt, va_list ap) +void vDprintf(int level, const char *fmt, va_list ap) { - if (level > log_level) - return; - - if (!is_daemon) { - char logbuf[256]; - logbuf[255] = 0; - time_t clock; - struct tm *local_tm; - time(&clock); - local_tm = localtime (&clock); - int l = strftime(logbuf, sizeof(logbuf)-1, "%F %T ", local_tm); - vsnprintf(logbuf + l, sizeof(logbuf) - l - 1, fmt, ap); - printf("%s\n", logbuf); - } - else { - vsyslog((level <= LOG_LEVEL_INFO) ? LOG_INFO : LOG_DEBUG, fmt, ap); - } + if (level > log_level) + return; + + if (!is_daemon) { + char logbuf[256]; + logbuf[255] = 0; + time_t clock; + struct tm *local_tm; + time(&clock); + local_tm = localtime(&clock); + int l = + strftime(logbuf, sizeof(logbuf) - 1, "%F %T ", local_tm); + vsnprintf(logbuf + l, sizeof(logbuf) - l - 1, fmt, ap); + printf("%s\n", logbuf); + } else { + vsyslog((level <= LOG_LEVEL_INFO) ? LOG_INFO : LOG_DEBUG, fmt, + ap); + } } -void Dprintf(int level, const char *fmt, ...) +void Dprintf(int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vDprintf(level, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + vDprintf(level, fmt, ap); + va_end(ap); } diff --git a/netif_utils.c b/netif_utils.c index a14e0c3..eeb12ff 100644 --- a/netif_utils.c +++ b/netif_utils.c @@ -40,62 +40,59 @@ #include "log.h" - - int netsock = -1; int netsock_init(void) { - LOG(""); - netsock = socket(AF_INET, SOCK_DGRAM, 0); - if (netsock < 0) { - ERROR("Couldn't open inet socket for ioctls: %m\n"); - return -1; - } - return 0; + LOG(""); + netsock = socket(AF_INET, SOCK_DGRAM, 0); + if (netsock < 0) { + ERROR("Couldn't open inet socket for ioctls: %m\n"); + return -1; + } + return 0; } int get_hwaddr(char *ifname, unsigned char *hwaddr) { - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl(netsock, SIOCGIFHWADDR, &ifr) < 0) { - ERROR("%s: get hw address failed: %m", ifname); - return -1; - } - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); - return 0; + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(netsock, SIOCGIFHWADDR, &ifr) < 0) { + ERROR("%s: get hw address failed: %m", ifname); + return -1; + } + memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); + return 0; } int ethtool_get_speed_duplex(char *ifname, int *speed, int *duplex) { - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - struct ethtool_cmd ecmd; - - ecmd.cmd = ETHTOOL_GSET; - ifr.ifr_data = (caddr_t)&ecmd; - if (ioctl(netsock, SIOCETHTOOL, &ifr) < 0) { - ERROR("Cannot get link status for %s: %m\n", ifname); - return -1; - } - *speed = ecmd.speed; /* Ethtool speed is in Mbps */ - *duplex = ecmd.duplex; /* We have same convention as ethtool. - 0 = half, 1 = full */ - return 0; + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + struct ethtool_cmd ecmd; + + ecmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t) & ecmd; + if (ioctl(netsock, SIOCETHTOOL, &ifr) < 0) { + ERROR("Cannot get link status for %s: %m\n", ifname); + return -1; + } + *speed = ecmd.speed; /* Ethtool speed is in Mbps */ + *duplex = ecmd.duplex; /* We have same convention as ethtool. + 0 = half, 1 = full */ + return 0; } - /********* Sysfs based utility functions *************/ /* This sysfs stuff might break with interface renames */ int is_bridge(char *if_name) { - char path[32 + IFNAMSIZ]; - sprintf(path, "/sys/class/net/%s/bridge", if_name); - return (access(path, R_OK) == 0); + char path[32 + IFNAMSIZ]; + sprintf(path, "/sys/class/net/%s/bridge", if_name); + return (access(path, R_OK) == 0); } /* This will work even less if the bridge port is renamed after being @@ -103,39 +100,38 @@ int is_bridge(char *if_name) */ int is_bridge_slave(char *br_name, char *if_name) { - char path[32 + 2 * IFNAMSIZ]; - sprintf(path, "/sys/class/net/%s/brif/%s", br_name, if_name); - return (access(path, R_OK) == 0); + char path[32 + 2 * IFNAMSIZ]; + sprintf(path, "/sys/class/net/%s/brif/%s", br_name, if_name); + return (access(path, R_OK) == 0); } int get_bridge_portno(char *if_name) { - char path[32 + IFNAMSIZ]; - sprintf(path, "/sys/class/net/%s/brport/port_no", if_name); - char buf[128]; - int fd; - long res = -1; - TSTM((fd = open(path, O_RDONLY)) >= 0, -1, "%m"); - int l; - TSTM((l = read(fd, buf, sizeof(buf) - 1)) >= 0, -1, "%m"); - if (l == 0) { - ERROR("Empty port index file"); - goto out; - } - else if (l == sizeof(buf) - 1) { - ERROR("port_index file too long"); - goto out; - } - buf[l] = 0; - if (buf[l-1] == '\n') - buf[l-1] = 0; - char *end; - res = strtoul(buf, &end, 0); - if (*end != 0 || res > INT_MAX) { - ERROR("Invalid port index %s", buf); - res = -1; - } - out: - close(fd); - return res; + char path[32 + IFNAMSIZ]; + sprintf(path, "/sys/class/net/%s/brport/port_no", if_name); + char buf[128]; + int fd; + long res = -1; + TSTM((fd = open(path, O_RDONLY)) >= 0, -1, "%m"); + int l; + TSTM((l = read(fd, buf, sizeof(buf) - 1)) >= 0, -1, "%m"); + if (l == 0) { + ERROR("Empty port index file"); + goto out; + } else if (l == sizeof(buf) - 1) { + ERROR("port_index file too long"); + goto out; + } + buf[l] = 0; + if (buf[l - 1] == '\n') + buf[l - 1] = 0; + char *end; + res = strtoul(buf, &end, 0); + if (*end != 0 || res > INT_MAX) { + ERROR("Invalid port index %s", buf); + res = -1; + } + out: + close(fd); + return res; } -- 2.39.2