...
You'll need to import the ConcurrentCircularBuffer into the PktInHistory package. It is available here. If your Floodlight version does not include this class, you can add the ConcurrentCircularBuffer.java file within the net.floodlightcontroller.util package of your controller. |
Now we have to define the behavior for what to do when the module receives a PacketIn message. This is done in the receive() function.
...
Info |
---|
You can find a more in-depth REST API tutorial here if you are curious about the 'how' and 'why' behind some things you're required to do below. |
We now have a complete module implementation, but no way to get information out of it! For this we'll need to do two things. Have our module export a service then tie it into the REST API Module.
...
Code Block |
---|
package net.floodlightcontroller.core.web.serializers; import java.io.IOException; import org.projectfloodlight.openflow.protocol.OFPacketIn; import org.projectfloodlight.openflow.protocol.OFPacketInReason; import org.projectfloodlight.openflow.protocol.OFType; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import net.floodlightcontroller.core.types.SwitchMessagePair; import net.floodlightcontroller.util.OFMessageUtils; public class SwitchMessagePairSerializer extends JsonSerializer<SwitchMessagePair> { @Override public void serialize(SwitchMessagePair m, JsonGenerator jGen, SerializerProvider arg2) throws IOException, JsonProcessingException { jGen.writeStartObject(); jGen.writeFieldName("message"); jGen.writeStartObject(); if (m.getMessage().getType() == OFType.PACKET_IN) { jGen.writeNumberField("bufferId", ((OFPacketIn)m.getMessage()).getBufferId().getInt()); jGen.writeNumberField("inPort", OFMessageUtils.getInPort((OFPacketIn)m.getMessage()).getPortNumber()); jGen.writeNumberField("packetDataLength", ((OFPacketIn)m.getMessage()).getData().length); jGen.writeBinaryField("packetData", ((OFPacketIn)m.getMessage()).getData()); jGen.writeStringField("reason", ((OFPacketIn)m.getMessage()).getReason().toString()); jGen.writeNumberField("totalLength", ((OFPacketIn)m.getMessage()).getTotalLen()); } jGen.writeStringField("type", m.getMessage().getType().toString()); jGen.writeStringField("version", m.getMessage().getVersion().toString()); jGen.writeNumberField("xid", m.getMessage().getXid()); jGen.writeEndObject(); jGen.writeFieldName("switch"); jGen.writeStartObject(); jGen.writeStringField("dpid", m.getSwitch().getId().toString()); jGen.writeEndObject(); jGen.writeEndObject(); } } |
Now we have to tell Jackson to use the serializer. We do this by annotating our class which will tell Jackson to use our serializer. Open up SwitchMessagePair and annotate the class as depicted below.
...
Code Block |
---|
$ curl -s http://localhost:8080/wm/pktinhistory/history/json | python -mjson.tool [ { "message": { "bufferId": 256, "inPort": 2, "length": 96, "lengthUpacketDataLength": 96, "packetData": "MzP/Uk+PLoqIUk+Pht1gAAAAABg6/wAAAAAAAAAAAAAAAAAAAAD/AgAAAAAAAAAAAAH/Uk+PhwAo2gAAAAD+gAAAAAAAACyKiP/+Uk+P", "reason": "NO_MATCH", "totalLength": 78, "type": "PACKET_IN", "version": 1, "xid": 0 }, "switch": { "dpid": "00:00:00:00:00:00:00:06" } }, { "message": { "bufferId": 260, "inPort": 1, "length": 96, "lengthUpacketDataLength": 96, "packetData": "MzP/Uk+PLoqIUk+Pht1gAAAAABg6/wAAAAAAAAAAAAAAAAAAAAD/AgAAAAAAAAAAAAH/Uk+PhwAo2gAAAAD+gAAAAAAAACyKiP/+Uk+P", "reason": "NO_MATCH", "totalLength": 78, "type": "PACKET_IN", "version": 1, "xid": 0 }, "switch": { "dpid": "00:00:00:00:00:00:00:05" } }, etc....etc.... |