* @param reason
* the reason for the update
*/
public void alert(IOFSwitch sw, short portNum, OFPhysicalPort physicalPort,
OFPortReason reason) {
OFFlowMod updateFlow = new OFFlowMod();
OFFlowMod updateFlow2 = new OFFlowMod();
updateFlow.setType(OFType.FLOW_MOD);
updateFlow.setCommand(OFFlowMod.OFPFC_ADD);
updateFlow.setHardTimeout((short) 0);
updateFlow.setIdleTimeout((short) 0);
int portStatus = 0;
FlowscaleController.logger
.trace("current rules for group with update port");
for (OFRule rule : this.groupRules) {
FlowscaleController.logger.trace("rule match is {} and port is {}",
rule.getMatch().toString(), rule.getActions().get(0));
}
if (physicalPort == null) {
if (reason == OFPortReason.OFPPR_ADD) {
portStatus = 0;
} else if (reason == OFPortReason.OFPPR_DELETE) {
portStatus = 1;
}
} else if (reason == null) {
// just check that the last bit is zero then set the status to 0 or
// 1 meaning port is down
portStatus = physicalPort.getState();
if (portStatus % 2 == 0) {
portStatus = 0;
} else {
portStatus = 1;
}
}
FlowscaleController.logger.info(
"updating flows since there is a port modification at port {}",
physicalPort.getPortNumber());
switch (portStatus) {
case 0:
FlowscaleController.logger
.info("a port belonging to the group output ports is up");
if (!(outputPortsUp
.contains(new Short(physicalPort.getPortNumber())))) {
outputPortsUp.add(physicalPort.getPortNumber());
}
int ruleDistribution = this.outputPortsUp.size();
int i = 1;
FlowscaleController.logger.info(
"Modifying flows for switch {} to add port {}",
HexString.toHexString(sw.getId()),
physicalPort.getPortNumber());
ArrayList<OFRule> checkedRules = new ArrayList<OFRule>();
for (OFRule ofRule : this.groupRules) {
if (checkedRules.contains(ofRule)) {
continue;
}
if (i % ruleDistribution == 0) {
OFActionOutput ofActionOutput = new OFActionOutput();
ofActionOutput.setPort(portNum);
String thisMatchString = ofRule.getMatch().toString();
String otherMatchString = "";
OFRule otherDirectionRule = null;
if (thisMatchString.indexOf("nw_src") != -1) {
otherMatchString = thisMatchString.replace("nw_src",
"nw_dst");
} else if (thisMatchString.indexOf("nw_dst") != -1) {
otherMatchString = thisMatchString.replace("nw_dst",
"nw_src");
}
if (this.type == IP_TYPE) {
for (OFRule ofRule2 : this.groupRules) {
if (ofRule2.getMatch().toString()
.equals(otherMatchString)) {
otherDirectionRule = ofRule2;
checkedRules.add(ofRule2);
break;
}
}
}
ArrayList<OFAction> actionList = ofRule.getActions();
actionList.clear();
HashMap<Short, Short> switchMirrors = flowscaleController
.getSwitchFlowMirrorPortsHashMap().get(sw.getId());
actionList.add(ofActionOutput);
if (switchMirrors != null) {
Short mirrorPort = switchMirrors.get(portNum);
if (mirrorPort != null) {
OFActionOutput mirrorAction = new OFActionOutput();
mirrorAction.setPort(mirrorPort);
actionList.add(mirrorAction);
}
}
updateFlow.setMatch(ofRule.getMatch());
updateFlow.setBufferId(-1);
updateFlow.setPriority(ofRule.getPriority());
updateFlow.setActions(actionList);
updateFlow.setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
+ OFActionOutput.MINIMUM_LENGTH));
if (this.type == IP_TYPE) {
updateFlow2 = new OFFlowMod();
updateFlow2.setType(OFType.FLOW_MOD);
updateFlow2.setCommand(OFFlowMod.OFPFC_ADD);
updateFlow2.setHardTimeout((short) 0);
updateFlow2.setIdleTimeout((short) 0);
ArrayList<OFAction> actionList2 = otherDirectionRule
.getActions();
actionList2.clear();
HashMap<Short, Short> switchMirrors2 = flowscaleController
.getSwitchFlowMirrorPortsHashMap().get(
sw.getId());
actionList2.add(ofActionOutput);
if (switchMirrors2 != null) {
Short mirrorPort = switchMirrors2.get(portNum);
if (mirrorPort != null) {
OFActionOutput mirrorAction = new OFActionOutput();
mirrorAction.setPort(mirrorPort);
actionList2.add(mirrorAction);
}
}
updateFlow2.setMatch(otherDirectionRule.getMatch());
updateFlow2.setBufferId(-1);
updateFlow2.setPriority(otherDirectionRule
.getPriority());
updateFlow2.setActions(actionList2);
updateFlow2.setLength(U16.t(OFFlowMod.MINIMUM_LENGTH
+ OFActionOutput.MINIMUM_LENGTH));
}
try {
FlowscaleController.logger.trace("modifying flow {}",
updateFlow);
sw.getOutputStream().write(updateFlow);
if (this.type == IP_TYPE) {
sw.getOutputStream().write(updateFlow2);
}
} catch (IOException e) {
// TODO Auto-generated catch block
FlowscaleController.logger.error("{}", e);
}
}
i++;
}
FlowscaleController.logger.info("Modification of flows completed");
break;
case 1:
i = 0;
FlowscaleController.logger.trace("outputPortUp before removal {}",
outputPortsUp);
outputPortsUp.remove(new Short(physicalPort.getPortNumber()));
FlowscaleController.logger.trace("outputPortsUp after removal {}",
outputPortsUp);
FlowscaleController.logger
.info("port {} for switch {} is down so flows for this will be updated",
physicalPort.getPortNumber(),
HexString.toHexString(sw.getId()));
int count = 0;
ArrayList<OFRule> checkedRulesonPortDown = new ArrayList<OFRule>();
for (OFRule ofRule : this.groupRules) {
if (checkedRulesonPortDown.contains(ofRule)) {
continue;
}
OFActionOutput ofActionOutput = (OFActionOutput) ofRule
.getActions().get(0);
FlowscaleController.logger.trace(
"match here is {} and port is {}", ofRule.getMatch(),
ofActionOutput.getPort());
if (ofActionOutput.getPort() == portNum) {
short newPort = 0;
try {
newPort = this.outputPortsUp.get(i++
% outputPortsUp.size());
ofActionOutput.setPort(newPort);
} catch (ArithmeticException aeException) {
FlowscaleController.logger
.info("No group ports are up , ...no flows redirected");
continue;
}
ArrayList<OFAction> actionList = ofRule.getActions();
actionList.clear();
// add mirror ports if there are any
HashMap<Short, Short> switchMirrors = flowscaleController
.getSwitchFlowMirrorPortsHashMap().get(sw.getId());
actionList.add(ofActionOutput);
if (switchMirrors != null) {
Short mirrorPort = switchMirrors.get(newPort);
if (mirrorPort != null) {
OFActionOutput mirrorAction = new OFActionOutput();
mirrorAction.setPort(mirrorPort);
actionList.add(mirrorAction);
}
}
String thisMatchString = ofRule.getMatch().toString();
String otherMatchString = "";
OFRule otherDirectionRule = null;
if (thisMatchString.indexOf("nw_src") != -1) {
otherMatchString = thisMatchString.replace("nw_src",
"nw_dst");
} else if (thisMatchString.indexOf("nw_dst") != -1) {
otherMatchString = thisMatchString.replace("nw_dst",
"nw_src");
}
if (this.type == IP_TYPE) {
for (OFRule ofRule2 : this.groupRules) {
if (ofRule2.getMatch().toString()
.equals(otherMatchString)) {
otherDirectionRule = ofRule2;
checkedRulesonPortDown.add(ofRule2);
break;
}
}
}
updateFlow.setMatch(ofRule.getMatch());
updateFlow.setBufferId(-1);
updateFlow.setPriority(ofRule.getPriority());
updateFlow.setActions(actionList);
if (this.type == IP_TYPE) {
updateFlow2 = new OFFlowMod();
updateFlow2.setType(OFType.FLOW_MOD);
updateFlow2.setCommand(OFFlowMod.OFPFC_ADD);
updateFlow2.setHardTimeout((short) 0);
updateFlow2.setIdleTimeout((short) 0);
ArrayList<OFAction> actionList2 = otherDirectionRule
.getActions();
actionList2.clear();
HashMap<Short, Short> switchMirrors2 = flowscaleController
.getSwitchFlowMirrorPortsHashMap().get(
sw.getId());
actionList2.add(ofActionOutput);
if (switchMirrors2 != null) {
Short mirrorPort = switchMirrors2.get(portNum);
if (mirrorPort != null) {
OFActionOutput mirrorAction = new OFActionOutput();
mirrorAction.setPort(mirrorPort);
actionList2.add(mirrorAction);
}
}
updateFlow2.setMatch(otherDirectionRule.getMatch());
updateFlow2.setBufferId(-1);
updateFlow2.setPriority(otherDirectionRule.getPriority());
updateFlow2.setActions(actionList2);
}
try {
FlowscaleController.logger.trace("updating flow {}",