Use kernel indentation style. Existing style was too odd.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
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 <net/if.h> which conflicts with <linux/if.h> */
/* 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);
}
-
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);
#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 */
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) \
/* 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 <slave> 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 <slave> 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();
}
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 */
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
static const char SNAPSHOT[] = "v0.1";
-
/* RFC 2863 operational status */
enum {
IF_OPER_UNKNOWN,
[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");
fprintf(fp, "Deleted ");
fprintf(fp, "%d: %s ", ifi->ifi_index,
- tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
-
+ tb[IFLA_IFNAME] ? (char *)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
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;
}
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;
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)
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");
+ }
}
{
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;
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);
}
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);
}
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);
}
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;
}
#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 <base.h>
-
-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);
}
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);
#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
#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
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, "[<bridge> ... ]\t\tshow bridge state" },
- { 1, 32, "showport", cmd_showport, "<bridge> [<port> ... ]\tshow port state" },
- { 1, 32, "showportdetail", cmd_showportdetail, "<bridge> [<port> ... ]\tshow port state (detail)" },
- { 2, 0, "rstp", cmd_rstp, "<bridge> {on|off}\tenable/disable rstpd control" },
- { 2, 0, "setbridgestate", cmd_setbridgestate, "<bridge> {on|off}\tstart/stop rstp (when enabled)" },
- { 2, 0, "setbridgeprio", cmd_setbridgeprio, "<bridge> <priority>\tset bridge priority (0-61440)" },
- { 2, 0, "sethello", cmd_setbridgehello, "<bridge> <hellotime>\tset bridge hello time (1-10)" },
- { 2, 0, "setmaxage", cmd_setbridgemaxage, "<bridge> <maxage>\tset bridge max age (6-40)" },
- { 2, 0, "setfdelay", cmd_setbridgefdelay, "<bridge> <fwd_delay>\tset bridge forward delay (4-30)" },
- { 2, 0, "setforcevers", cmd_setbridgeforcevers, "<bridge> {normal|slow}\tnormal RSTP or force to STP" },
- { 3, 0, "setportprio", cmd_setportprio, "<bridge> <port> <priority>\tset port priority (0-240)" },
- { 3, 0, "setportpathcost", cmd_setportpathcost, "<bridge> <port> <cost>\tset port path cost" },
- { 3, 0, "setportedge", cmd_setportedge, "<bridge> <port> {yes|no}\tconfigure if it is an edge port" },
- { 3, 0, "setportnonstp", cmd_setportnonstp, "<bridge> <port> {yes|no}\tdisable STP for the port" },
- { 3, 0, "setportp2p", cmd_setportp2p, "<bridge> <port> {yes|no|auto}\tset whether p2p connection" },
- { 2, 0, "portmcheck", cmd_portmcheck, "<bridge> <port>\ttry to get back from STP to RSTP mode" },
- { 1, 0, "debuglevel", cmd_debuglevel, "<level>\t\tLevel of verbosity" },
+ {0, 32, "showbridge", cmd_showbridge,
+ "[<bridge> ... ]\t\tshow bridge state"},
+ {1, 32, "showport", cmd_showport,
+ "<bridge> [<port> ... ]\tshow port state"},
+ {1, 32, "showportdetail", cmd_showportdetail,
+ "<bridge> [<port> ... ]\tshow port state (detail)"},
+ {2, 0, "rstp", cmd_rstp,
+ "<bridge> {on|off}\tenable/disable rstpd control"},
+ {2, 0, "setbridgestate", cmd_setbridgestate,
+ "<bridge> {on|off}\tstart/stop rstp (when enabled)"},
+ {2, 0, "setbridgeprio", cmd_setbridgeprio,
+ "<bridge> <priority>\tset bridge priority (0-61440)"},
+ {2, 0, "sethello", cmd_setbridgehello,
+ "<bridge> <hellotime>\tset bridge hello time (1-10)"},
+ {2, 0, "setmaxage", cmd_setbridgemaxage,
+ "<bridge> <maxage>\tset bridge max age (6-40)"},
+ {2, 0, "setfdelay", cmd_setbridgefdelay,
+ "<bridge> <fwd_delay>\tset bridge forward delay (4-30)"},
+ {2, 0, "setforcevers", cmd_setbridgeforcevers,
+ "<bridge> {normal|slow}\tnormal RSTP or force to STP"},
+ {3, 0, "setportprio", cmd_setportprio,
+ "<bridge> <port> <priority>\tset port priority (0-240)"},
+ {3, 0, "setportpathcost", cmd_setportpathcost,
+ "<bridge> <port> <cost>\tset port path cost"},
+ {3, 0, "setportedge", cmd_setportedge,
+ "<bridge> <port> {yes|no}\tconfigure if it is an edge port"},
+ {3, 0, "setportnonstp", cmd_setportnonstp,
+ "<bridge> <port> {yes|no}\tdisable STP for the port"},
+ {3, 0, "setportp2p", cmd_setportp2p,
+ "<bridge> <port> {yes|no|auto}\tset whether p2p connection"},
+ {2, 0, "portmcheck", cmd_portmcheck,
+ "<bridge> <port>\ttry to get back from STP to RSTP mode"},
+ {1, 0, "debuglevel", cmd_debuglevel, "<level>\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];
}
{
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);
}
}
#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;
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;
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);
return cmd->func(argc, argv);
-help:
+ help:
help();
return 1;
}
#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
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);
}
#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) \
#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; })
#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; })
#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; })
return r; \
}
-
-
#endif
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;
}
#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);
void ctl_socket_cleanup(void);
#endif
-
-
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;
}
#include <sys/time.h>
#include <time.h>
-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);
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;
}
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;
}
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);
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)
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)
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,
};
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;
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;
return -1;
}
- h = (struct nlmsghdr*)buf;
+ h = (struct nlmsghdr *)buf;
while (NLMSG_OK(h, status)) {
int err;
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;
if (err < 0)
return err;
-skip_it:
+ skip_it:
h = NLMSG_NEXT(h, status);
}
if (msg.msg_flags & MSG_TRUNC) {
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 = {
.msg_iov = &iov,
.msg_iovlen = 1,
};
- char buf[16384];
+ char buf[16384];
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
return -1;
}
- memset(buf,0,sizeof(buf));
+ memset(buf, 0, sizeof(buf));
iov.iov_base = buf;
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);
}
}
/* 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");
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");
}
}
-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;
.msg_iov = &iov,
.msg_iovlen = 1,
};
- char buf[8192];
+ char buf[8192];
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
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");
}
}
-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;
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;
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);
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);
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;
}
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);
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);
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;
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;
}
#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
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 *********************/
#include <stdarg.h>
#include <time.h>
-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);
}
#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
*/
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;
}