#include "packet.h"
#include "log.h"
#include "mstp.h"
+#include "driver.h"
+#include "libnetlink.h"
static LIST_HEAD(bridges);
(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)
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";
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