Java 类org.projectfloodlight.openflow.protocol.OFFactories 实例源码
项目:athena
文件:OFMessageDecoder.java
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer) throws Exception {
if (!channel.isConnected()) {
// In testing, I see decode being called AFTER decode last.
// This check avoids that from reading corrupted frames
return null;
}
// Note that a single call to decode results in reading a single
// OFMessage from the channel buffer, which is passed on to, and processed
// by, the controller (in OFChannelHandler).
// This is different from earlier behavior (with the original openflowj),
// where we parsed all the messages in the buffer, before passing on
// a list of the parsed messages to the controller.
// The performance *may or may not* not be as good as before.
OFMessageReader<OFMessage> reader = OFFactories.getGenericReader();
OFMessage message = reader.readFrom(buffer);
return message;
}
项目:athena
文件:RoleManager.java
/**
* Send NX role request message to the switch requesting the specified
* role.
*
* @param role role to request
*/
private int sendNxRoleRequest(RoleState role) throws IOException {
// Convert the role enum to the appropriate role to send
OFNiciraControllerRole roleToSend = OFNiciraControllerRole.ROLE_OTHER;
switch (role) {
case MASTER:
roleToSend = OFNiciraControllerRole.ROLE_MASTER;
break;
case SLAVE:
case EQUAL:
default:
// ensuring that the only two roles sent to 1.0 switches with
// Nicira role support, are MASTER and SLAVE
roleToSend = OFNiciraControllerRole.ROLE_OTHER;
log.debug("Sending Nx Role.SLAVE to switch {}.", sw);
}
int xid = sw.getNextTransactionId();
OFExperimenter roleRequest = OFFactories.getFactory(OFVersion.OF_10)
.buildNiciraControllerRoleRequest()
.setXid(xid)
.setRole(roleToSend)
.build();
sw.sendRoleRequest(roleRequest);
return xid;
}
项目:athena
文件:OpenFlowGroupProviderTest.java
@Test
public void groupStatsEvent() {
TestOpenFlowGroupProviderService testProviderService =
(TestOpenFlowGroupProviderService) providerService;
OFGroupStatsReply.Builder rep1 =
OFFactories.getFactory(OFVersion.OF_13).buildGroupStatsReply();
rep1.setXid(1);
controller.processPacket(dpid1, rep1.build());
OFGroupDescStatsReply.Builder rep2 =
OFFactories.getFactory(OFVersion.OF_13).buildGroupDescStatsReply();
assertNull("group entries is not set yet", testProviderService.getGroupEntries());
rep2.setXid(2);
controller.processPacket(dpid1, rep2.build());
assertNotNull("group entries should be set", testProviderService.getGroupEntries());
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_vlan_id actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. Data with a leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetVlanVid decode_set_vlan_id(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
VlanVid vlanid = VlanVid.ofVlan(get_short(n.group(1)));
OFActionSetVlanVid.Builder ab = OFFactories.getFactory(version).actions().buildSetVlanVid();
ab.setVlanVid(vlanid);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid VLAN in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_vlan_pcp actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. Data with a leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetVlanPcp decode_set_vlan_priority(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
VlanPcp prior = VlanPcp.of(get_byte(n.group(1)));
OFActionSetVlanPcp.Builder ab = OFFactories.getFactory(version).actions().buildSetVlanPcp();
ab.setVlanPcp(prior);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid VLAN priority in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_dl_src actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using MacAddress's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetDlSrc decode_set_src_mac(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(actionToDecode);
if (n.matches()) {
MacAddress macaddr = MacAddress.of(get_mac_addr(n, actionToDecode, log));
if (macaddr != null) {
OFActionSetDlSrc.Builder ab = OFFactories.getFactory(version).actions().buildSetDlSrc();
ab.setDlAddr(macaddr);
log.debug("action {}", ab.build());
return ab.build();
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_dl_dst actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using MacAddress's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetDlDst decode_set_dst_mac(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(actionToDecode);
if (n.matches()) {
MacAddress macaddr = MacAddress.of(get_mac_addr(n, actionToDecode, log));
if (macaddr != null) {
OFActionSetDlDst.Builder ab = OFFactories.getFactory(version).actions().buildSetDlDst();
ab.setDlAddr(macaddr);
log.debug("action {}", ab.build());
return ab.build();
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_tos actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. A leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetNwTos decode_set_tos_bits(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
byte tosbits = get_byte(n.group(1));
OFActionSetNwTos.Builder ab = OFFactories.getFactory(version).actions().buildSetNwTos();
ab.setNwTos(tosbits);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_tp_src actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. A leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetTpSrc decode_set_src_port(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
TransportPort portnum = TransportPort.of(get_int(n.group(1)));
OFActionSetTpSrc.Builder ab = OFFactories.getFactory(version).actions().buildSetTpSrc();
ab.setTpPort(portnum);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid src-port in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_tp_dst actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. A leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFAction decode_set_dst_port(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
TransportPort portnum = TransportPort.of(get_int(n.group(1)));
OFActionSetTpDst.Builder ab = OFFactories.getFactory(version).actions().buildSetTpDst();
ab.setTpPort(portnum);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:fresco_floodlight
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionGotoTable to
* an OFInstructionGotoTable. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void gotoTableFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (inst == null || inst.equals("")) {
return;
}
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Goto Table Instruction not supported in OpenFlow 1.0");
return;
}
OFInstructionGotoTable.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildGotoTable();
// Get the table ID
if (inst.startsWith("0x")) {
ib.setTableId(TableId.of(Integer.parseInt(inst.replaceFirst("0x", ""), 16)));
} else {
ib.setTableId(TableId.of(Integer.parseInt(inst))).build();
}
log.debug("Appending GotoTable instruction: {}", ib.build());
appendInstruction(fmb, ib.build());
log.debug("All instructions after append: {}", fmb.getInstructions());
}
项目:fresco_floodlight
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionClearActions to
* an OFInstructionClearActions. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void clearActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Clear Actions Instruction not supported in OpenFlow 1.0");
return;
}
if (inst != null && inst.trim().isEmpty()) { /* Allow the empty string, since this is what specifies clear (i.e. key clear does not have any defined values). */
OFInstructionClearActions i = OFFactories.getFactory(fmb.getVersion()).instructions().clearActions();
log.debug("Appending ClearActions instruction: {}", i);
appendInstruction(fmb, i);
log.debug("All instructions after append: {}", fmb.getInstructions());
} else {
log.error("Got non-empty or null string, but ClearActions should not have any String sub-fields: {}", inst);
}
}
项目:fresco_floodlight
文件:LinkDiscoveryManagerTest.java
private OFPacketIn createPacketIn(String srcMAC, String dstMAC,
String srcIp, String dstIp, short vlan) {
IPacket testPacket = new Ethernet()
.setDestinationMACAddress(dstMAC)
.setSourceMACAddress(srcMAC)
.setVlanID(vlan)
.setEtherType(EthType.IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress(srcIp)
.setDestinationAddress(dstIp)
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
byte[] testPacketSerialized = testPacket.serialize();
OFPacketIn pi;
// build out input packet
pi = OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
.setBufferId(OFBufferId.NO_BUFFER)
.setData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.build();
return pi;
}
项目:iTAP-controller
文件:ActionUtils.java
/**
* Parse set_vlan_id actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. Data with a leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetVlanVid decode_set_vlan_id(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
VlanVid vlanid = VlanVid.ofVlan(get_short(n.group(1)));
OFActionSetVlanVid.Builder ab = OFFactories.getFactory(version).actions().buildSetVlanVid();
ab.setVlanVid(vlanid);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid VLAN in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:iTAP-controller
文件:ActionUtils.java
/**
* Parse set_dl_src actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using MacAddress's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetDlSrc decode_set_src_mac(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(actionToDecode);
if (n.matches()) {
MacAddress macaddr = MacAddress.of(get_mac_addr(n, actionToDecode, log));
if (macaddr != null) {
OFActionSetDlSrc.Builder ab = OFFactories.getFactory(version).actions().buildSetDlSrc();
ab.setDlAddr(macaddr);
log.debug("action {}", ab.build());
return ab.build();
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:iTAP-controller
文件:ActionUtils.java
/**
* Parse set_dl_dst actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using MacAddress's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetDlDst decode_set_dst_mac(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(actionToDecode);
if (n.matches()) {
MacAddress macaddr = MacAddress.of(get_mac_addr(n, actionToDecode, log));
if (macaddr != null) {
OFActionSetDlDst.Builder ab = OFFactories.getFactory(version).actions().buildSetDlDst();
ab.setDlAddr(macaddr);
log.debug("action {}", ab.build());
return ab.build();
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:iTAP-controller
文件:ActionUtils.java
/**
* Parse set_tos actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. A leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetNwTos decode_set_tos_bits(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
byte tosbits = get_byte(n.group(1));
OFActionSetNwTos.Builder ab = OFFactories.getFactory(version).actions().buildSetNwTos();
ab.setNwTos(tosbits);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:iTAP-controller
文件:ActionUtils.java
/**
* Parse set_tp_dst actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. A leading 0x is permitted.
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFAction decode_set_dst_port(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((?:0x)?\\d+)").matcher(actionToDecode);
if (n.matches()) {
if (n.group(1) != null) {
try {
TransportPort portnum = TransportPort.of(get_short(n.group(1)));
OFActionSetTpDst.Builder ab = OFFactories.getFactory(version).actions().buildSetTpDst();
ab.setTpPort(portnum);
log.debug("action {}", ab.build());
return ab.build();
}
catch (NumberFormatException e) {
log.debug("Invalid dst-port in: {} (error ignored)", actionToDecode);
return null;
}
}
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
return null;
}
项目:iTAP-controller
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionGotoTable to
* an OFInstructionGotoTable. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void gotoTableFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (inst == null || inst.equals("")) {
return;
}
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Goto Table Instruction not supported in OpenFlow 1.0");
return;
}
OFInstructionGotoTable.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildGotoTable();
// Get the table ID
if (inst.startsWith("0x")) {
ib.setTableId(TableId.of(Integer.parseInt(inst.replaceFirst("0x", ""), 16)));
} else {
ib.setTableId(TableId.of(Integer.parseInt(inst))).build();
}
log.debug("Appending GotoTable instruction: {}", ib.build());
appendInstruction(fmb, ib.build());
log.debug("All instructions after append: {}", fmb.getInstructions());
}
项目:iTAP-controller
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionClearActions to
* an OFInstructionClearActions. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void clearActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Clear Actions Instruction not supported in OpenFlow 1.0");
return;
}
if (inst != null && inst.trim().isEmpty()) { /* Allow the empty string, since this is what specifies clear (i.e. key clear does not have any defined values). */
OFInstructionClearActions i = OFFactories.getFactory(fmb.getVersion()).instructions().clearActions();
log.debug("Appending ClearActions instruction: {}", i);
appendInstruction(fmb, i);
log.debug("All instructions after append: {}", fmb.getInstructions());
} else {
log.error("Got non-empty or null string, but ClearActions should not have any String sub-fields: {}", inst);
}
}
项目:iTAP-controller
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionMeter to
* an OFInstructionMeter. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void meterFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (inst == null || inst.isEmpty()) {
return;
}
if (fmb.getVersion().compareTo(OFVersion.OF_13) < 0) {
log.error("Goto Meter Instruction not supported in OpenFlow 1.0, 1.1, or 1.2");
return;
}
OFInstructionMeter.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildMeter();
if (inst.startsWith("0x")) {
ib.setMeterId(Long.valueOf(inst.replaceFirst("0x", ""), 16));
} else {
ib.setMeterId(Long.valueOf(inst));
}
log.debug("Appending (Goto)Meter instruction: {}", ib.build());
appendInstruction(fmb, ib.build());
log.debug("All instructions after append: {}", fmb.getInstructions());
}
项目:athena
文件:RoleManager.java
private int sendOF13RoleRequest(RoleState role) throws IOException {
// Convert the role enum to the appropriate role to send
OFControllerRole roleToSend = OFControllerRole.ROLE_NOCHANGE;
switch (role) {
case EQUAL:
roleToSend = OFControllerRole.ROLE_EQUAL;
break;
case MASTER:
roleToSend = OFControllerRole.ROLE_MASTER;
break;
case SLAVE:
roleToSend = OFControllerRole.ROLE_SLAVE;
break;
default:
log.warn("Sending default role.noChange to switch {}."
+ " Should only be used for queries.", sw);
}
int xid = sw.getNextTransactionId();
OFRoleRequest rrm = OFFactories.getFactory(OFVersion.OF_13)
.buildRoleRequest()
.setRole(roleToSend)
.setXid(xid)
//FIXME fix below when we actually use generation ids
.setGenerationId(U64.ZERO)
.build();
sw.sendRoleRequest(rrm);
return xid;
}
项目:athena
文件:OpenFlowGroupProviderTest.java
@Test
public void groupModFailure() {
TestOpenFlowGroupProviderService testProviderService =
(TestOpenFlowGroupProviderService) providerService;
GroupId groupId = new DefaultGroupId(1);
List<GroupBucket> bucketList = Lists.newArrayList();
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
builder.setOutput(PortNumber.portNumber(1));
GroupBucket bucket =
DefaultGroupBucket.createSelectGroupBucket(builder.build());
bucketList.add(bucket);
GroupBuckets buckets = new GroupBuckets(bucketList);
List<GroupOperation> operationList = Lists.newArrayList();
GroupOperation operation = GroupOperation.createAddGroupOperation(groupId,
GroupDescription.Type.SELECT, buckets);
operationList.add(operation);
GroupOperations operations = new GroupOperations(operationList);
provider.performGroupOperation(deviceId, operations);
OFGroupModFailedErrorMsg.Builder errorBuilder =
OFFactories.getFactory(OFVersion.OF_13).errorMsgs().buildGroupModFailedErrorMsg();
OFGroupMod.Builder groupBuilder = OFFactories.getFactory(OFVersion.OF_13).buildGroupModify();
groupBuilder.setGroupType(OFGroupType.ALL);
groupBuilder.setGroup(OFGroup.of(1));
errorBuilder.setCode(OFGroupModFailedCode.GROUP_EXISTS);
errorBuilder.setXid(provider.getXidAndAdd(0) - 1);
controller.processPacket(dpid1, errorBuilder.build());
assertNotNull("Operation failed should not be null",
testProviderService.failedOperation);
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse string and numerical port representations.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder. Data can be any signed integer
* as a string or the strings 'controller', 'local', 'ingress-port', 'normal',
* or 'flood'.
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionOutput decode_output(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("((all)|(controller)|(local)|(ingress-port)|(normal)|(flood))").matcher(actionToDecode);
OFActionOutput.Builder ab = OFFactories.getFactory(version).actions().buildOutput();
OFPort port = OFPort.ANY;
if (n.matches()) {
if (n.group(1) != null && n.group(1).equals("all"))
port = OFPort.ALL;
else if (n.group(1) != null && n.group(1).equals("controller"))
port = OFPort.CONTROLLER;
else if (n.group(1) != null && n.group(1).equals("local"))
port = OFPort.LOCAL;
else if (n.group(1) != null && n.group(1).equals("ingress-port"))
port = OFPort.IN_PORT;
else if (n.group(1) != null && n.group(1).equals("normal"))
port = OFPort.NORMAL;
else if (n.group(1) != null && n.group(1).equals("flood"))
port = OFPort.FLOOD;
ab.setPort(port);
ab.setMaxLen(Integer.MAX_VALUE);
log.debug("action {}", ab.build());
return ab.build();
}
else {
try {
port = OFPort.of(Integer.parseInt(actionToDecode));
ab.setPort(port);
ab.setMaxLen(Integer.MAX_VALUE);
return ab.build();
} catch (NumberFormatException e) {
log.error("Could not parse Integer port: '{}'", actionToDecode);
return null;
}
}
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_nw_src actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using IPv4AddressWithMask's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetNwSrc decode_set_src_ip(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(actionToDecode);
if (n.matches()) {
IPv4Address ipaddr = IPv4Address.of(get_ip_addr(n, actionToDecode, log));
OFActionSetNwSrc.Builder ab = OFFactories.getFactory(version).actions().buildSetNwSrc();
ab.setNwAddr(ipaddr);
log.debug("action {}", ab.build());
return ab.build();
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
}
项目:fresco_floodlight
文件:ActionUtils.java
/**
* Parse set_nw_dst actions.
* The key and delimiter for the action should be omitted, and only the
* data should be presented to this decoder.
*
* TODO should consider using IPv4AddressWithMask's built-in parser....
*
* @param actionToDecode; The action as a string to decode
* @param version; The OF version to create the action for
* @param log
* @return
*/
private static OFActionSetNwDst decode_set_dst_ip(String actionToDecode, OFVersion version, Logger log) {
Matcher n = Pattern.compile("(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(actionToDecode);
if (n.matches()) {
IPv4Address ipaddr = IPv4Address.of(get_ip_addr(n, actionToDecode, log));
OFActionSetNwDst.Builder ab = OFFactories.getFactory(version).actions().buildSetNwDst();
ab.setNwAddr(ipaddr);
log.debug("action {}", ab.build());
return ab.build();
}
else {
log.debug("Invalid action: '{}'", actionToDecode);
return null;
}
}
项目:fresco_floodlight
文件:MatchUtils.java
/**
* Retains all fields in the Match parent. Converts the parent to an
* equivalent Match of OFVersion version. No polite check is done to verify
* if MatchFields in parent are supported in a Match of OFVersion
* version. An exception will be thrown if there are any unsupported
* fields during the conversion process.
*
* Note that a Match.Builder is returned. This is a convenience for cases
* where MatchFields might be modified, added, or removed prior to being
* built (e.g. in Forwarding/Routing between switches of different OFVersions).
* Simply build the returned Match.Builder if you would like to treat this
* function as a strict copy-to-version.
*
* @param parent, the Match to convert
* @param version, the OFVersion to convert parent to
* @return a Match.Builder of the newly-converted Match
*/
@SuppressWarnings("unchecked")
public static Match.Builder convertToVersion(Match parent, OFVersion version) {
/* Builder retains a parent MatchField list, but list will not be used to
* build the new match if the builder's set methods have been invoked; only
* additions will be built, and all parent MatchFields will be ignored,
* even if they were not modified by the new builder. Create a builder, and
* walk through m's list of non-wildcarded MatchFields. Set them all in the
* new builder by invoking a set method for each. This will make them persist
* in the Match built from this builder if the user decides to add or subtract
* from the MatchField list.
*/
Match.Builder mb = OFFactories.getFactory(version).buildMatch();
Iterator<MatchField<?>> itr = parent.getMatchFields().iterator(); // only get exact or masked fields (not fully wildcarded)
while(itr.hasNext()) {
@SuppressWarnings("rawtypes")
MatchField mf = itr.next();
if (parent.isExact(mf)) {
mb.setExact(mf, parent.get(mf));
} else if (parent.isPartiallyMasked(mf)) {
mb.setMasked(mf, parent.getMasked(mf));
} else {
// it's either exact, masked, or wildcarded
// itr only contains exact and masked MatchFields
// we should never get here
}
}
return mb;
}
项目:fresco_floodlight
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionWriteActions to
* an OFInstructionWriteActions. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void writeActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Write Actions Instruction not supported in OpenFlow 1.0");
return;
}
OFFlowMod.Builder tmpFmb = OFFactories.getFactory(fmb.getVersion()).buildFlowModify(); // ActionUtils.fromString() will use setActions(), which should not be used for OF1.3; use temp to avoid overwriting any applyActions data
OFInstructionWriteActions.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildWriteActions();
ActionUtils.fromString(tmpFmb, inst, log);
ib.setActions(tmpFmb.getActions());
log.debug("Appending WriteActions instruction: {}", ib.build());
appendInstruction(fmb, ib.build());
log.debug("All instructions after append: {}", fmb.getInstructions()); }
项目:fresco_floodlight
文件:InstructionUtils.java
/**
* Convert the string representation of an OFInstructionApplyActions to
* an OFInstructionApplyActions. The instruction will be set within the
* OFFlowMod.Builder provided. Notice nothing is returned, but the
* side effect is the addition of an instruction in the OFFlowMod.Builder.
* @param fmb; The FMB in which to append the new instruction
* @param instStr; The string to parse the instruction from
* @param log
*/
public static void applyActionsFromString(OFFlowMod.Builder fmb, String inst, Logger log) {
if (fmb.getVersion().compareTo(OFVersion.OF_11) < 0) {
log.error("Apply Actions Instruction not supported in OpenFlow 1.0");
return;
}
OFFlowMod.Builder tmpFmb = OFFactories.getFactory(fmb.getVersion()).buildFlowModify();
OFInstructionApplyActions.Builder ib = OFFactories.getFactory(fmb.getVersion()).instructions().buildApplyActions();
ActionUtils.fromString(tmpFmb, inst, log);
ib.setActions(tmpFmb.getActions());
log.debug("Appending ApplyActions instruction: {}", ib.build());
appendInstruction(fmb, ib.build());
log.debug("All instructions after append: {}", fmb.getInstructions()); }
项目:fresco_floodlight
文件:FlowModUtils.java
public static OFFlowAdd toFlowAdd(OFFlowMod fm) {
OFVersion version = fm.getVersion();
OFFlowAdd.Builder b = OFFactories.getFactory(version).buildFlowAdd();
if (b.getVersion().compareTo(OFVersion.OF_10) == 0) {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
// cookie-mask not supported
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
// instructions not supported
.setMatch(fm.getMatch())
// out-group not supported
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
// table-id not supported
.setXid(fm.getXid())
.build();
} else {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
.setCookieMask(fm.getCookieMask()) // added in OF1.1
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
.setInstructions(fm.getInstructions()) // added in OF1.1
.setMatch(fm.getMatch())
.setOutGroup(fm.getOutGroup()) // added in OF1.1
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
.setTableId(fm.getTableId())
.setXid(fm.getXid())
.build();
}
}
项目:fresco_floodlight
文件:FlowModUtils.java
public static OFFlowDelete toFlowDelete(OFFlowMod fm) {
OFVersion version = fm.getVersion();
OFFlowDelete.Builder b = OFFactories.getFactory(version).buildFlowDelete();
if (b.getVersion().compareTo(OFVersion.OF_10) == 0) {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
// cookie-mask not supported
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
// instructions not supported
.setMatch(fm.getMatch())
// out-group not supported
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
// table-id not supported
.setXid(fm.getXid())
.build();
} else {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
.setCookieMask(fm.getCookieMask()) // added in OF1.1
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
.setInstructions(fm.getInstructions()) // added in OF1.1
.setMatch(fm.getMatch())
.setOutGroup(fm.getOutGroup()) // added in OF1.1
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
.setTableId(fm.getTableId())
.setXid(fm.getXid())
.build();
}
}
项目:fresco_floodlight
文件:FlowModUtils.java
public static OFFlowDeleteStrict toFlowDeleteStrict(OFFlowMod fm) {
OFVersion version = fm.getVersion();
OFFlowDeleteStrict.Builder b = OFFactories.getFactory(version).buildFlowDeleteStrict();
if (b.getVersion().compareTo(OFVersion.OF_10) == 0) {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
// cookie-mask not supported
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
// instructions not supported
.setMatch(fm.getMatch())
// out-group not supported
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
// table-id not supported
.setXid(fm.getXid())
.build();
} else {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
.setCookieMask(fm.getCookieMask()) // added in OF1.1
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
.setInstructions(fm.getInstructions()) // added in OF1.1
.setMatch(fm.getMatch())
.setOutGroup(fm.getOutGroup()) // added in OF1.1
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
.setTableId(fm.getTableId())
.setXid(fm.getXid())
.build();
}
}
项目:fresco_floodlight
文件:FlowModUtils.java
public static OFFlowModify toFlowModify(OFFlowMod fm) {
OFVersion version = fm.getVersion();
OFFlowModify.Builder b = OFFactories.getFactory(version).buildFlowModify();
if (b.getVersion().compareTo(OFVersion.OF_10) == 0) {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
// cookie-mask not supported
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
// instructions not supported
.setMatch(fm.getMatch())
// out-group not supported
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
// table-id not supported
.setXid(fm.getXid())
.build();
} else {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
.setCookieMask(fm.getCookieMask()) // added in OF1.1
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
.setInstructions(fm.getInstructions()) // added in OF1.1
.setMatch(fm.getMatch())
.setOutGroup(fm.getOutGroup()) // added in OF1.1
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
.setTableId(fm.getTableId())
.setXid(fm.getXid())
.build();
}
}
项目:fresco_floodlight
文件:FlowModUtils.java
public static OFFlowModifyStrict toFlowModifyStrict(OFFlowMod fm) {
OFVersion version = fm.getVersion();
OFFlowModifyStrict.Builder b = OFFactories.getFactory(version).buildFlowModifyStrict();
if (b.getVersion().compareTo(OFVersion.OF_10) == 0) {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
// cookie-mask not supported
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
// instructions not supported
.setMatch(fm.getMatch())
// out-group not supported
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
// table-id not supported
.setXid(fm.getXid())
.build();
} else {
return b.setActions(fm.getActions())
.setBufferId(fm.getBufferId())
.setCookie(fm.getCookie())
.setCookieMask(fm.getCookieMask()) // added in OF1.1
.setFlags(fm.getFlags())
.setHardTimeout(fm.getHardTimeout())
.setIdleTimeout(fm.getIdleTimeout())
.setInstructions(fm.getInstructions()) // added in OF1.1
.setMatch(fm.getMatch())
.setOutGroup(fm.getOutGroup()) // added in OF1.1
.setOutPort(fm.getOutPort())
.setPriority(fm.getPriority())
.setTableId(fm.getTableId())
.setXid(fm.getXid())
.build();
}
}
项目:fresco_floodlight
文件:OFSwitchHandshakeHandler.java
@Override
void processOFNiciraControllerRoleRequest(OFNiciraControllerRoleRequest m) {
OFControllerRole role;
switch (m.getRole()) {
case ROLE_MASTER:
role = OFControllerRole.ROLE_MASTER;
break;
case ROLE_SLAVE:
role = OFControllerRole.ROLE_SLAVE;
break;
case ROLE_OTHER:
role = OFControllerRole.ROLE_EQUAL;
break;
default:
log.error("Attempted to change to invalid Nicira role {}.", m.getRole().toString());
return;
}
/*
* This will get converted back to the correct factory of the switch later.
* We will use OFRoleRequest though to simplify the API between OF versions.
*/
sendRoleRequest(OFFactories.getFactory(OFVersion.OF_13).buildRoleRequest()
.setGenerationId(U64.ZERO)
.setXid(m.getXid())
.setRole(role)
.build());
}
项目:fresco_floodlight
文件:OFSwitchHandshakeHandler.java
@Override
void processOFNiciraControllerRoleRequest(OFNiciraControllerRoleRequest m) {
OFControllerRole role;
switch (m.getRole()) {
case ROLE_MASTER:
role = OFControllerRole.ROLE_MASTER;
break;
case ROLE_SLAVE:
role = OFControllerRole.ROLE_SLAVE;
break;
case ROLE_OTHER:
role = OFControllerRole.ROLE_EQUAL;
break;
default:
log.error("Attempted to change to invalid Nicira role {}.", m.getRole().toString());
return;
}
/*
* This will get converted back to the correct factory of the switch later.
* We will use OFRoleRequest though to simplify the API between OF versions.
*/
sendRoleRequest(OFFactories.getFactory(OFVersion.OF_13).buildRoleRequest()
.setGenerationId(U64.ZERO)
.setXid(m.getXid())
.setRole(role)
.build());
}
项目:fresco_floodlight
文件:OFSwitchHandshakeHandler.java
/**
* Create a new unconnected OFChannelHandler.
* @param controller
* @param broker
* @throws SwitchHandshakeHandlerException
*/
OFSwitchHandshakeHandler(@Nonnull IOFConnectionBackend connection,
@Nonnull OFFeaturesReply featuresReply,
@Nonnull IOFSwitchManager switchManager,
@Nonnull RoleManager roleManager,
@Nonnull Timer timer) {
Preconditions.checkNotNull(connection, "connection");
Preconditions.checkNotNull(featuresReply, "featuresReply");
Preconditions.checkNotNull(switchManager, "switchManager");
Preconditions.checkNotNull(roleManager, "roleManager");
Preconditions.checkNotNull(timer, "timer");
Preconditions.checkArgument(connection.getAuxId().equals(OFAuxId.MAIN),
"connection must be MAIN connection but is %s", connection);
this.switchManager = switchManager;
this.roleManager = roleManager;
this.mainConnection = connection;
this.auxConnections = new ConcurrentHashMap<OFAuxId, IOFConnectionBackend>();
this.featuresReply = featuresReply;
this.timer = timer;
this.switchManagerCounters = switchManager.getCounters();
this.factory = OFFactories.getFactory(featuresReply.getVersion());
this.roleChanger = new RoleChanger(DEFAULT_ROLE_TIMEOUT_NS);
setState(new InitState());
this.pendingPortStatusMsg = new ArrayList<OFPortStatus>();
connection.setListener(this);
}
项目:fresco_floodlight
文件:HubTest.java
@Before
public void setUp() throws Exception {
super.setUp();
mockFloodlightProvider = getMockFloodlightProvider();
hub = new Hub();
mockFloodlightProvider.addOFMessageListener(OFType.PACKET_IN, hub);
hub.setFloodlightProvider(mockFloodlightProvider);
// Build our test packet
this.testPacket = new Ethernet()
.setDestinationMACAddress("00:11:22:33:44:55")
.setSourceMACAddress("00:44:33:22:11:00")
.setEtherType(EthType.IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
// Build the PacketIn
this.packetIn = (OFPacketIn) OFFactories.getFactory(OFVersion.OF_13).buildPacketIn()
.setBufferId(OFBufferId.NO_BUFFER)
.setMatch(OFFactories.getFactory(OFVersion.OF_13).buildMatch()
.setExact(MatchField.IN_PORT, OFPort.of(1))
.build())
.setData(this.testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLen((short) this.testPacketSerialized.length).build();
}
项目:fresco_floodlight
文件:HubTest.java
@Test
public void testFloodNoBufferId() throws Exception {
// Mock up our expected behavior
IOFSwitch mockSwitch = createMock(IOFSwitch.class);
EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes();
// build our expected flooded packetOut
OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build();
List<OFAction> al = new ArrayList<OFAction>();
al.add(ao);
OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut()
.setActions(al)
.setBufferId(OFBufferId.NO_BUFFER)
.setXid(1)
.setInPort(OFPort.of(1))
.setData(this.testPacketSerialized).build();
Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes();
// Start recording the replay on the mocks
replay(mockSwitch);
// Get the listener and trigger the packet in
IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
OFType.PACKET_IN).get(0);
listener.receive(mockSwitch, this.packetIn,
parseAndAnnotate(this.packetIn));
// Verify the replay matched our expectations
verify(mockSwitch);
assertTrue(wc1.hasCaptured());
OFMessage m = wc1.getValue();
assertTrue(OFMessageUtils.equalsIgnoreXid(m, po));
}
项目:fresco_floodlight
文件:HubTest.java
@Test
public void testFloodBufferId() throws Exception {
MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
this.packetIn = this.packetIn.createBuilder()
.setBufferId(OFBufferId.of(10))
.setXid(1)
.build();
OFActionOutput ao = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput().setPort(OFPort.FLOOD).build();
List<OFAction> al = new ArrayList<OFAction>();
al.add(ao);
// build our expected flooded packetOut
OFPacketOut po = OFFactories.getFactory(OFVersion.OF_13).buildPacketOut()
.setActions(al)
.setXid(1)
.setBufferId(OFBufferId.of(10))
.setInPort(OFPort.of(1))
.build();
// Mock up our expected behavior
IOFSwitch mockSwitch = createMock(IOFSwitch.class);
EasyMock.expect(mockSwitch.getOFFactory()).andReturn(OFFactories.getFactory(OFVersion.OF_13)).anyTimes();
Capture<OFPacketOut> wc1 = new Capture<OFPacketOut>(CaptureType.ALL);
expect(mockSwitch.write(capture(wc1))).andReturn(true).anyTimes();
// Start recording the replay on the mocks
replay(mockSwitch);
// Get the listener and trigger the packet in
IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
OFType.PACKET_IN).get(0);
listener.receive(mockSwitch, this.packetIn,
parseAndAnnotate(this.packetIn));
// Verify the replay matched our expectations
verify(mockSwitch);
assertTrue(wc1.hasCaptured());
OFMessage m = wc1.getValue();
assertEquals(po, m);
}