package net.floodlightcontroller.core.web.serializers; import java.io.IOException; import java.util.Iterator; import java.util.List; import net.floodlightcontroller.core.web.OFFlowStatsEntryMod; import net.onrc.onos.core.drivermanager.OFSwitchImplDellOSR; import net.onrc.onos.core.drivermanager.OFSwitchImplSpringOpenTTP; import net.onrc.onos.core.packet.IPv4; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.ser.std.SerializerBase; import org.projectfloodlight.openflow.protocol.OFActionType; import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; import org.projectfloodlight.openflow.protocol.OFInstructionType; import org.projectfloodlight.openflow.protocol.OFMatchV3; import org.projectfloodlight.openflow.protocol.OFOxmList; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.action.OFActionGroup; import org.projectfloodlight.openflow.protocol.action.OFActionOutput; import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls; import org.projectfloodlight.openflow.protocol.action.OFActionSetField; import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable; import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions; import org.projectfloodlight.openflow.protocol.match.MatchFields; import org.projectfloodlight.openflow.protocol.oxm.OFOxm; public class OFFlowStatsEntryModSerializer extends SerializerBase<OFFlowStatsEntryMod> { protected OFFlowStatsEntryModSerializer(){ super(OFFlowStatsEntryMod.class); } @Override public void serialize(OFFlowStatsEntryMod FlowStatsEntryMod, JsonGenerator jGen, SerializerProvider sp) throws IOException, JsonGenerationException { OFFlowStatsEntry flowStatsEntry = FlowStatsEntryMod.getFlowStatsEntry(); OFOxmList matches = ((OFMatchV3)flowStatsEntry.getMatch()).getOxmList(); OFSwitchImplSpringOpenTTP sw = (OFSwitchImplSpringOpenTTP)FlowStatsEntryMod.getSwitch(); List<OFInstruction> instructions = flowStatsEntry.getInstructions(); jGen.writeStartObject(); jGen.writeNumberField("byteCount", flowStatsEntry.getByteCount().getValue()); jGen.writeNumberField("packetCount", flowStatsEntry.getPacketCount().getValue()); jGen.writeNumberField("priority", flowStatsEntry.getPriority()); jGen.writeNumberField("cookie", flowStatsEntry.getCookie().getValue()); jGen.writeNumberField("durationNsec", flowStatsEntry.getDurationNsec()); jGen.writeNumberField("durationSec", flowStatsEntry.getDurationSec()); jGen.writeObjectField("flags", flowStatsEntry.getFlags()); jGen.writeNumberField("hardTimeout", flowStatsEntry.getHardTimeout()); jGen.writeNumberField("idleTimeout", flowStatsEntry.getIdleTimeout()); jGen.writeFieldName("match"); jGen.writeStartObject(); Iterator<OFOxm<?>> match= matches.iterator(); while(match.hasNext()){ OFOxm<?> matchGeneric = match.next(); if (matchGeneric.getMatchField().id == MatchFields.IPV4_DST){ /* * Current Implementation for mask sof CPQD switches and DELL is opposite */ if(sw instanceof OFSwitchImplDellOSR){ jGen.writeStringField("networkDestination", matchGeneric.getValue().toString() +"/" +(matchGeneric.isMasked() ? OFFlowStatsEntryModSerializer.covertToMask( IPv4.toIPv4Address( matchGeneric.getMask().toString())) : "32")); } else if(sw instanceof OFSwitchImplSpringOpenTTP){ jGen.writeStringField("networkDestination", matchGeneric.getValue().toString() +"/" +(matchGeneric.isMasked() ? (32 -OFFlowStatsEntryModSerializer.covertToMask( IPv4.toIPv4Address( matchGeneric.getMask().toString()))):"32")); } } else if (matchGeneric.getMatchField().id == MatchFields.IPV4_SRC){ jGen.writeStringField("networkSource", matchGeneric.getValue().toString() +"/" +(matchGeneric.isMasked() ? OFFlowStatsEntryModSerializer.covertToMask( IPv4.toIPv4Address( matchGeneric.getMask().toString())):"0")); } else if (matchGeneric.getMatchField().id == MatchFields.ETH_DST){ jGen.writeStringField("dataLayerDestination", matchGeneric.getValue().toString()); } else if (matchGeneric.getMatchField().id == MatchFields.ETH_SRC){ jGen.writeStringField("dataLayerSource", matchGeneric.getValue().toString()); } else if (matchGeneric.getMatchField().id == MatchFields.ETH_TYPE){ jGen.writeStringField("dataLayerType", "0x"+(matchGeneric.getValue().toString())); } else if (matchGeneric.getMatchField().id == MatchFields.IN_PORT){ jGen.writeNumberField("inputPort", Integer.parseInt(matchGeneric.getValue().toString())); } else if (matchGeneric.getMatchField().id == MatchFields.MPLS_TC){ jGen.writeNumberField("mplsTc", Integer.decode(matchGeneric.getValue().toString())); } else if (matchGeneric.getMatchField().id == MatchFields.MPLS_BOS){ jGen.writeStringField("mplsBos", matchGeneric.getValue().toString()); } else if (matchGeneric.getMatchField().id == MatchFields.MPLS_LABEL){ jGen.writeNumberField("mplsLabel", Integer.decode(matchGeneric.getValue().toString())); } else if (matchGeneric.getMatchField().id == MatchFields.IP_PROTO){ jGen.writeNumberField("networkProtocol", Integer.parseInt(matchGeneric.getValue().toString())); } //TODO: Ask Saurav about the implementation of tcp and udp. else if (matchGeneric.getMatchField().id == MatchFields.TCP_DST || matchGeneric.getMatchField().id == MatchFields.UDP_DST){ jGen.writeNumberField("transportDestination", Integer.parseInt(matchGeneric.getValue().toString())); } else if (matchGeneric.getMatchField().id == MatchFields.TCP_SRC || matchGeneric.getMatchField().id == MatchFields.UDP_SRC){ jGen.writeNumberField("transportSource", Integer.parseInt(matchGeneric.getValue().toString())); } } jGen.writeEndObject(); jGen.writeFieldName("instructions"); jGen.writeStartArray(); jGen.writeStartObject(); List<OFAction> actions = null; for (OFInstruction instruction: instructions){ if(instruction.getType().equals(OFInstructionType.APPLY_ACTIONS)){ actions = ((OFInstructionApplyActions)instruction).getActions(); } else if(instruction.getType().equals(OFInstructionType.WRITE_ACTIONS)){ actions = ((OFInstructionWriteActions)instruction).getActions(); } else if(instruction.getType().equals(OFInstructionType.CLEAR_ACTIONS)){ jGen.writeFieldName(instruction.getType().name()); jGen.writeStartObject(); jGen.writeStringField(instruction.getType().name(), "True"); jGen.writeEndObject(); continue; } else if(instruction.getType().equals(OFInstructionType.GOTO_TABLE)){ jGen.writeFieldName(instruction.getType().name()); jGen.writeStartObject(); if(((OFInstructionGotoTable)instruction).getTableId().getValue()== sw.getTableId("ip").getValue()){ jGen.writeStringField("tableId", "ip"); } else if(((OFInstructionGotoTable)instruction).getTableId().getValue()== sw.getTableId("mpls").getValue()){ jGen.writeStringField("tableId", "mpls"); } else if(((OFInstructionGotoTable)instruction).getTableId().getValue()== sw.getTableId("acl").getValue()){ jGen.writeStringField("tableId", "acl"); } else{ jGen.writeNumberField("tableId" , ((OFInstructionGotoTable)instruction).getTableId().getValue()); } jGen.writeEndObject(); continue; }//*/ else{ continue; } jGen.writeObjectFieldStart(instruction.getType().name()); for (OFAction action : actions){ if (action.getType().equals(OFActionType.GROUP)){ jGen.writeNumberField("group", ((OFActionGroup)action).getGroup().getGroupNumber()); } else if (action.getType().equals(OFActionType.OUTPUT)){ if (((OFActionOutput)action).getPort().getPortNumber() == -3){ //Controller port jGen.writeStringField("output", "CONTROLLER"); } else{ jGen.writeNumberField("output", ((OFActionOutput)action).getPort().getPortNumber()); } } else if(action.getType().compareTo(OFActionType.COPY_TTL_IN) == 0 || action.getType().compareTo(OFActionType.COPY_TTL_OUT) == 0 || action.getType().compareTo(OFActionType.DEC_MPLS_TTL) == 0 || action.getType().compareTo(OFActionType.DEC_NW_TTL) == 0 || action.getType().compareTo(OFActionType.POP_PBB) == 0 || action.getType().compareTo(OFActionType.POP_VLAN) == 0){ jGen.writeStringField(action.getType().name(), "True"); } else if(action.getType().compareTo(OFActionType.POP_MPLS) == 0){ jGen.writeStringField("POP_MPLS", "0x"+((OFActionPopMpls)action).getEthertype().toString()); } else if (action.getType().equals(OFActionType.SET_FIELD)){ //TODO Support for more setFields if (((OFActionSetField)action).getField().toString().contains("OFOxmEthSrcVer13")){ jGen.writeStringField("SET_DL_SRC", ((OFActionSetField)action).getField().getValue().toString()); } else if (((OFActionSetField)action).getField().toString().contains("OFOxmEthDstVer13")){ jGen.writeStringField("SET_DL_DST", ((OFActionSetField)action).getField().getValue().toString()); } else if (((OFActionSetField)action).getField().toString().contains("OFOxmNwDstVer13")){ jGen.writeStringField("SET_NW_SRC", ((OFActionSetField)action).getField().getValue().toString()); } else if (((OFActionSetField)action).getField().toString().contains("OFOxmNwDstVer13")){ jGen.writeStringField("SET_NW_DST", ((OFActionSetField)action).getField().getValue().toString()); } else if (((OFActionSetField)action).getField().toString().contains("OFOxmMplsLabelVer13")){ jGen.writeStringField("PUSH_MPLS", ((OFActionSetField)action).getField().getValue().toString()); } } } jGen.writeEndObject(); } jGen.writeEndObject(); jGen.writeEndArray(); jGen.writeEndObject(); } /** * Get the number of 1's in the 32bit integer * Use full to convert wildcard mask(x.x.x.x) to \x notation * for example * ("0.0.0.255") to int to "/8" or * ("0.0.255.255") to int to "/16" * @param x * @return */ public static int covertToMask(int x) { x = x - ((x >>> 1) & 0x55555555); x = (x & 0x33333333) + ((x >>> 2) & 0x33333333); x = (x + (x >>> 4)) & 0x0F0F0F0F; x = x + (x >>> 8); x = x + (x >>> 16); /* * For current implementation of CPQD we have to return * 32 - (x & 0x0000003F) */ return (x & 0x0000003F); } }