From: Vitalii Demianets Date: Tue, 27 Sep 2011 07:32:10 +0000 (+0000) Subject: Translate CIST states to the Linux bridge code X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fef685fcabe1c658b3a915f52112ec64bed4b559;p=people%2Fms%2Fmstpd.git Translate CIST states to the Linux bridge code git-svn-id: http://svn.code.sf.net/p/mstpd/code/trunk@6 fbe50366-0c72-4402-a84b-5d246361dba7 --- diff --git a/.depend b/.depend index 4cb4bcd..afd477c 100644 --- a/.depend +++ b/.depend @@ -1,20 +1,21 @@ # DO NOT DELETE -bridge_track.o: bridge_ctl.h netif_utils.h packet.h log.h ctl_socket_server.h -bridge_track.o: mstp.h +bridge_track.o: bridge_ctl.h ctl_functions.h mstp.h list.h netif_utils.h +bridge_track.o: packet.h log.h ctl_socket_server.h driver.h libnetlink.h brmon.o: libnetlink.h bridge_ctl.h netif_utils.h epoll_loop.h -ctl_main.o: ctl_socket_client.h ctl_functions.h mstp.h bridge_ctl.h log.h -ctl_main.o: ctl_socket_server.h -ctl_socket_client.o: ctl_functions.h mstp.h bridge_ctl.h log.h +ctl_main.o: ctl_socket_client.h ctl_functions.h mstp.h bridge_ctl.h list.h +ctl_main.o: log.h ctl_socket_server.h +ctl_socket_client.o: ctl_functions.h mstp.h bridge_ctl.h list.h log.h ctl_socket_client.o: ctl_socket_server.h ctl_socket_server.o: ctl_socket_client.h ctl_functions.h mstp.h bridge_ctl.h -ctl_socket_server.o: epoll_loop.h log.h ctl_socket_server.h +ctl_socket_server.o: list.h epoll_loop.h log.h ctl_socket_server.h +driver_deps.o: log.h ctl_socket_server.h mstp.h bridge_ctl.h list.h epoll_loop.o: epoll_loop.h bridge_ctl.h -hmac_md5.o: mstp.h bridge_ctl.h +hmac_md5.o: mstp.h bridge_ctl.h list.h libnetlink.o: libnetlink.h main.o: epoll_loop.h bridge_ctl.h netif_utils.h packet.h log.h -main.o: ctl_socket_server.h mstp.h -mstp.o: mstp.h bridge_ctl.h log.h ctl_socket_server.h +main.o: ctl_socket_server.h mstp.h list.h +mstp.o: mstp.h bridge_ctl.h list.h log.h ctl_socket_server.h netif_utils.o: log.h ctl_socket_server.h packet.o: epoll_loop.h netif_utils.h bridge_ctl.h packet.h log.h packet.o: ctl_socket_server.h diff --git a/Makefile b/Makefile index d7bc4ec..f01f513 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ version := 0.01 DSOURCES = main.c epoll_loop.c brmon.c bridge_track.c libnetlink.c mstp.c \ - packet.c netif_utils.c ctl_socket_server.c hmac_md5.c + packet.c netif_utils.c ctl_socket_server.c hmac_md5.c driver_deps.c DOBJECTS = $(DSOURCES:.c=.o) diff --git a/bridge_ctl.h b/bridge_ctl.h index 1d241ae..8b4e3b2 100644 --- a/bridge_ctl.h +++ b/bridge_ctl.h @@ -81,8 +81,6 @@ extern struct rtnl_handle rth_state; int init_bridge_ops(void); -int bridge_set_state(int ifindex, int state); - int bridge_notify(int br_index, int if_index, bool newlink, bool up); void bridge_bpdu_rcv(int ifindex, const unsigned char *data, int len); diff --git a/bridge_track.c b/bridge_track.c index 044fea1..ae22c69 100644 --- a/bridge_track.c +++ b/bridge_track.c @@ -34,6 +34,8 @@ #include "packet.h" #include "log.h" #include "mstp.h" +#include "driver.h" +#include "libnetlink.h" static LIST_HEAD(bridges); @@ -431,6 +433,28 @@ void bridge_bpdu_rcv(int if_index, const unsigned char *data, int len) (bpdu_t *)(data + sizeof(*h)), l - LLC_PDU_LEN_U); } +static int br_set_state(struct rtnl_handle *rth, unsigned ifindex, __u8 state) +{ + struct + { + 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_type = RTM_SETLINK; + req.ifi.ifi_family = AF_BRIDGE; + req.ifi.ifi_index = ifindex; + + addattr8(&req.n, sizeof(req.buf), IFLA_PROTINFO, state); + + return rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL); +} + /* External actions for MSTP protocol */ void MSTP_OUT_set_state(per_tree_port_t *ptp, int new_state) @@ -439,7 +463,11 @@ void MSTP_OUT_set_state(per_tree_port_t *ptp, int new_state) port_t *ifc = ptp->port; bridge_t *br = ifc->bridge; - switch(new_state) + if(ptp->state == new_state) + return; + ptp->state = driver_set_new_state(ptp, new_state); + + switch(ptp->state) { case BR_STATE_LISTENING: state_name = "listening"; @@ -454,21 +482,22 @@ void MSTP_OUT_set_state(per_tree_port_t *ptp, int new_state) state_name = "blocking"; break; default: - ERROR_MSTINAME(br, ifc, ptp, "attempt to set invalid state %d", - new_state); - new_state = BR_STATE_DISABLED; case BR_STATE_DISABLED: state_name = "disabled"; break; } - - if(ptp->state == new_state) - return; - - /* TODO: command driver to put the br:port:tree into new state */ - - ptp->state = new_state; INFO_MSTINAME(br, ifc, ptp, "entering %s state", state_name); + + /* Translate new CIST state to the kernel bridge code */ + if(0 == ptp->MSTID) + { /* CIST */ + if(ifc->sysdeps.up) + { + if(0 > br_set_state(&rth_state, ifc->sysdeps.if_index, ptp->state)) + ERROR_PRTNAME(br, ifc, "Couldn't set kernel bridge state %s", + state_name); + } + } } /* This function initiates process of flushing diff --git a/driver.h b/driver.h new file mode 100644 index 0000000..07a5211 --- /dev/null +++ b/driver.h @@ -0,0 +1,17 @@ +/* + * driver.h Driver-specific code. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Vitalii Demianets + */ + +#ifndef _MSTP_DRIVER_H +#define _MSTP_DRIVER_H + +int driver_set_new_state(per_tree_port_t *ptp, int new_state); + +#endif /* _MSTP_DRIVER_H */ diff --git a/driver_deps.c b/driver_deps.c new file mode 100644 index 0000000..e979665 --- /dev/null +++ b/driver_deps.c @@ -0,0 +1,28 @@ +/* + * driver_deps.c Driver-specific code. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Vitalii Demianets + */ + +#include +#include +#include +#include + +#include "log.h" +#include "mstp.h" + +/* + * Set new state (BR_STATE_xxx) for the given port and MSTI. + * Return new actual state (BR_STATE_xxx) from driver. + */ +int driver_set_new_state(per_tree_port_t *ptp, int new_state) +{ + /* TODO: insert driver-specific code here */ + return new_state; +}