Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 1 | package net.floodlightcontroller.core.web.serializers; |
| 2 | |
| 3 | import java.io.IOException; |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 4 | import java.util.Iterator; |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 5 | import java.util.List; |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 6 | import java.util.Set; |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 7 | |
| 8 | import net.floodlightcontroller.core.web.OFFlowStatsEntryMod; |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 9 | import net.onrc.onos.core.packet.IPv4; |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 10 | |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 11 | import org.projectfloodlight.openflow.protocol.action.*; |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 12 | import org.codehaus.jackson.JsonGenerationException; |
| 13 | import org.codehaus.jackson.JsonGenerator; |
| 14 | import org.codehaus.jackson.map.SerializerProvider; |
| 15 | import org.codehaus.jackson.map.ser.std.SerializerBase; |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 16 | import org.projectfloodlight.openflow.protocol.OFActionType; |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 17 | import org.projectfloodlight.openflow.protocol.OFFlowModFlags; |
| 18 | import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 19 | import org.projectfloodlight.openflow.protocol.OFInstructionType; |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 20 | import org.projectfloodlight.openflow.protocol.OFMatchV3; |
| 21 | import org.projectfloodlight.openflow.protocol.OFOxmList; |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 22 | import org.projectfloodlight.openflow.protocol.action.OFAction; |
| 23 | import org.projectfloodlight.openflow.protocol.instruction.*; |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 24 | import org.projectfloodlight.openflow.protocol.match.MatchFields; |
| 25 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 26 | |
| 27 | public class OFFlowStatsEntryModSerializer extends SerializerBase<OFFlowStatsEntryMod> { |
| 28 | |
| 29 | protected OFFlowStatsEntryModSerializer(){ |
| 30 | super(OFFlowStatsEntryMod.class); |
| 31 | } |
| 32 | |
| 33 | @Override |
| 34 | public void serialize(OFFlowStatsEntryMod FlowStatsEntryMod, JsonGenerator jGen, |
| 35 | SerializerProvider sp) throws IOException, |
| 36 | JsonGenerationException { |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 37 | OFFlowStatsEntry flowStatsEntry = FlowStatsEntryMod.getFlowStatsEntry(); |
| 38 | OFOxmList matches = ((OFMatchV3)flowStatsEntry.getMatch()).getOxmList(); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 39 | |
| 40 | List<OFInstruction> instructions = flowStatsEntry.getInstructions(); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 41 | jGen.writeStartObject(); |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 42 | //System.out.println("flowstats:\n\n\n"+ flowStatsEntry); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 43 | jGen.writeNumberField("byteCount", flowStatsEntry.getByteCount().getValue()); |
Fahad Naeem Khan | f35e4f6 | 2014-10-07 16:45:39 -0700 | [diff] [blame] | 44 | jGen.writeNumberField("packetCount", flowStatsEntry.getPacketCount().getValue()); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 45 | jGen.writeNumberField("priority", flowStatsEntry.getPriority()); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 46 | jGen.writeNumberField("cookie", flowStatsEntry.getCookie().getValue()); |
| 47 | jGen.writeNumberField("durationNsec", flowStatsEntry.getDurationNsec()); |
| 48 | jGen.writeNumberField("durationSec", flowStatsEntry.getDurationSec()); |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 49 | jGen.writeObjectField("flags", flowStatsEntry.getFlags()); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 50 | jGen.writeNumberField("hardTimeout", flowStatsEntry.getHardTimeout()); |
| 51 | jGen.writeNumberField("idleTimeout", flowStatsEntry.getIdleTimeout()); |
| 52 | jGen.writeArrayFieldStart("match"); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 53 | jGen.writeStartObject(); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 54 | Iterator<OFOxm<?>> match= matches.iterator(); |
| 55 | while(match.hasNext()){ |
| 56 | OFOxm<?> matchGeneric = match.next(); |
| 57 | if (matchGeneric.getMatchField().id == MatchFields.IPV4_DST){ |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 58 | jGen.writeStringField("networkDestination", matchGeneric.getValue().toString() |
| 59 | +"/" |
| 60 | +(matchGeneric.isMasked() ? |
| 61 | OFFlowStatsEntryModSerializer.covertToMask( |
| 62 | IPv4.toIPv4Address( |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 63 | matchGeneric.getMask().toString())):"32")); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 64 | } |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 65 | else if (matchGeneric.getMatchField().id == MatchFields.IPV4_SRC){ |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 66 | jGen.writeStringField("networkSource", matchGeneric.getValue().toString() |
| 67 | +"/" |
| 68 | +(matchGeneric.isMasked() ? |
| 69 | OFFlowStatsEntryModSerializer.covertToMask( |
| 70 | IPv4.toIPv4Address( |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 71 | matchGeneric.getMask().toString())):"32")); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 72 | } |
| 73 | else if (matchGeneric.getMatchField().id == MatchFields.ETH_DST){ |
| 74 | jGen.writeStringField("dataLayerDestination", matchGeneric.getValue().toString()); |
| 75 | } |
| 76 | else if (matchGeneric.getMatchField().id == MatchFields.ETH_SRC){ |
| 77 | jGen.writeStringField("dataLayerSource", matchGeneric.getValue().toString()); |
| 78 | } |
| 79 | else if (matchGeneric.getMatchField().id == MatchFields.ETH_TYPE){ |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 80 | jGen.writeNumberField("dataLayerType", Integer.decode(matchGeneric.getValue().toString())); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 81 | } |
| 82 | else if (matchGeneric.getMatchField().id == MatchFields.IN_PORT){ |
| 83 | jGen.writeNumberField("inputPort", Integer.parseInt(matchGeneric.getValue().toString())); |
| 84 | } |
| 85 | else if (matchGeneric.getMatchField().id == MatchFields.MPLS_TC){ |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 86 | jGen.writeNumberField("mplsTc", Integer.decode(matchGeneric.getValue().toString())); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 87 | } |
| 88 | else if (matchGeneric.getMatchField().id == MatchFields.MPLS_LABEL){ |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 89 | jGen.writeNumberField("mplsLabel", Integer.decode(matchGeneric.getValue().toString())); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 90 | } |
| 91 | else if (matchGeneric.getMatchField().id == MatchFields.IP_PROTO){ |
| 92 | jGen.writeNumberField("networkProtocol", Integer.parseInt(matchGeneric.getValue().toString())); |
| 93 | } |
| 94 | //TODO: Ask Saurav about the implementation of tcp and udp. |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 95 | else if (matchGeneric.getMatchField().id == MatchFields.TCP_DST |
| 96 | || matchGeneric.getMatchField().id == MatchFields.UDP_DST){ |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 97 | jGen.writeNumberField("transportDestination", Integer.parseInt(matchGeneric.getValue().toString())); |
| 98 | } |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 99 | else if (matchGeneric.getMatchField().id == MatchFields.TCP_SRC |
| 100 | || matchGeneric.getMatchField().id == MatchFields.UDP_SRC){ |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 101 | jGen.writeNumberField("transportSource", Integer.parseInt(matchGeneric.getValue().toString())); |
| 102 | } |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 103 | } |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 104 | jGen.writeEndObject(); |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 105 | jGen.writeEndArray(); |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 106 | jGen.writeFieldName("instructions"); |
| 107 | jGen.writeStartArray(); |
| 108 | List<OFAction> actions = null; |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 109 | for (OFInstruction instruction: instructions){ |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 110 | |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 111 | if(instruction.getType().equals(OFInstructionType.APPLY_ACTIONS)){ |
| 112 | actions = ((OFInstructionApplyActions)instruction).getActions(); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 113 | } |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 114 | else if(instruction.getType().equals(OFInstructionType.WRITE_ACTIONS)){ |
| 115 | actions = ((OFInstructionWriteActions)instruction).getActions(); |
| 116 | } |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 117 | else if(instruction.getType().equals(OFInstructionType.GOTO_TABLE)){ |
| 118 | jGen.writeFieldName(instruction.getType().name()); |
| 119 | jGen.writeStartObject(); |
| 120 | jGen.writeNumberField("tableId" |
| 121 | , ((OFInstructionGotoTable)instruction).getTableId().getValue()); |
| 122 | jGen.writeEndObject(); |
| 123 | continue; |
| 124 | } |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 125 | else{ |
| 126 | continue; |
| 127 | } |
| 128 | jGen.writeStartObject(); |
| 129 | jGen.writeFieldName(instruction.getType().name()); |
| 130 | jGen.writeStartObject(); |
| 131 | for (OFAction action : actions){ |
| 132 | if (action.getType().equals(OFActionType.GROUP)){ |
| 133 | jGen.writeNumberField("group", ((OFActionGroup)action).getGroup().getGroupNumber()); |
| 134 | } |
| 135 | else if (action.getType().equals(OFActionType.OUTPUT)){ |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 136 | if (((OFActionOutput)action).getPort().getPortNumber() == -3){ |
| 137 | //Controller port |
| 138 | jGen.writeStringField("output", "CONTROLLER"); |
| 139 | } |
| 140 | else{ |
| 141 | jGen.writeNumberField("output", ((OFActionOutput)action).getPort().getPortNumber()); |
| 142 | } |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 143 | } |
| 144 | else if(action.getType().compareTo(OFActionType.POP_MPLS) == 0 |
| 145 | || action.getType().compareTo(OFActionType.COPY_TTL_IN) == 0 |
| 146 | || action.getType().compareTo(OFActionType.COPY_TTL_OUT) == 0 |
| 147 | || action.getType().compareTo(OFActionType.DEC_MPLS_TTL) == 0 |
| 148 | || action.getType().compareTo(OFActionType.DEC_NW_TTL) == 0 |
| 149 | || action.getType().compareTo(OFActionType.POP_PBB) == 0 |
| 150 | || action.getType().compareTo(OFActionType.POP_VLAN) == 0){ |
| 151 | jGen.writeStringField(action.getType().name(), "True"); |
| 152 | } |
| 153 | else if(action.getType().compareTo(OFActionType.COPY_TTL_IN) == 0){ |
| 154 | jGen.writeStringField("POP_MPLS", "True"); |
| 155 | } |
| 156 | else if (action.getType().equals(OFActionType.SET_FIELD)){ |
| 157 | //TODO Support for more setFields |
| 158 | if (((OFActionSetField)action).getField().toString().contains("OFOxmEthSrcVer13")){ |
| 159 | jGen.writeStringField("SET_DL_SRC", ((OFActionSetField)action).getField().getValue().toString()); |
| 160 | } |
| 161 | else if (((OFActionSetField)action).getField().toString().contains("OFOxmEthDstVer13")){ |
| 162 | jGen.writeStringField("SET_DL_DST", ((OFActionSetField)action).getField().getValue().toString()); |
| 163 | } |
| 164 | else if (((OFActionSetField)action).getField().toString().contains("OFOxmNwDstVer13")){ |
| 165 | jGen.writeStringField("SET_NW_SRC", ((OFActionSetField)action).getField().getValue().toString()); |
| 166 | } |
| 167 | else if (((OFActionSetField)action).getField().toString().contains("OFOxmNwDstVer13")){ |
| 168 | jGen.writeStringField("SET_NW_DST", ((OFActionSetField)action).getField().getValue().toString()); |
| 169 | } |
| 170 | else if (((OFActionSetField)action).getField().toString().contains("OFOxmMplsLabelVer13")){ |
| 171 | jGen.writeStringField("PUSH_MPLS", ((OFActionSetField)action).getField().getValue().toString()); |
| 172 | } |
| 173 | } |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 174 | } |
| 175 | jGen.writeEndObject(); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 176 | } |
Fahad Naeem Khan | d89448d | 2014-10-06 18:40:45 -0700 | [diff] [blame] | 177 | jGen.writeEndObject(); |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 178 | jGen.writeEndArray(); |
Fahad Naeem Khan | 0c1c7b3 | 2014-10-07 16:22:23 -0700 | [diff] [blame] | 179 | jGen.writeEndObject(); |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 180 | } |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 181 | /** |
| 182 | * Get the number of 1's in the 32bit integer |
| 183 | * Use full to convert wildcard mask(x.x.x.x) to \x notation |
| 184 | * for example |
| 185 | * ("0.0.0.255") to int to "/8" or |
| 186 | * ("0.0.255.255") to int to "/16" |
| 187 | * @param x |
| 188 | * @return |
| 189 | */ |
| 190 | |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 191 | public static int covertToMask(int x) { |
Fahad Naeem Khan | f59c285 | 2014-10-10 18:52:26 -0700 | [diff] [blame^] | 192 | x = x - ((x >>> 1) & 0x55555555); |
| 193 | x = (x & 0x33333333) + ((x >>> 2) & 0x33333333); |
| 194 | x = (x + (x >>> 4)) & 0x0F0F0F0F; |
| 195 | x = x + (x >>> 8); |
| 196 | x = x + (x >>> 16); |
| 197 | return 32 - (x & 0x0000003F); |
Fahad Naeem Khan | df19755 | 2014-10-10 14:59:00 -0700 | [diff] [blame] | 198 | } |
Fahad Naeem Khan | 8a8daf2 | 2014-10-06 14:07:43 -0700 | [diff] [blame] | 199 | |
| 200 | } |