diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java index 882a625c45cd3e8d4f7e860a42db8bb032a9b086..e0cbf88e0f94e4c6efdefc08c85a7d9ee6ba538f 100644 --- a/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java +++ b/src/main/java/net/floodlightcontroller/core/web/serializers/OFActionListSerializer.java @@ -41,7 +41,6 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc; import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Type; - import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Code; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv6Type; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp; @@ -49,7 +48,6 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Src; - import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Dst; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Flabel; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdSll; @@ -105,190 +103,199 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> { * @throws JsonProcessingException */ public static void serializeActions(JsonGenerator jsonGenerator, List<OFAction> actions) throws IOException, JsonProcessingException { - if (actions.isEmpty()) { - jsonGenerator.writeStringField("none", "drop"); - } + StringBuilder sb = new StringBuilder(); + int len = actions.size(); + int pos = 0; for (OFAction a : actions) { switch (a.getType()) { case OUTPUT: - jsonGenerator.writeStringField(ActionUtils.STR_OUTPUT, ((OFActionOutput)a).getPort().toString()); + sb.append(ActionUtils.STR_OUTPUT).append("=").append(((OFActionOutput)a).getPort().toString()); break; /* begin OF1.0 ONLY actions */ case SET_VLAN_VID: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_VID, ((OFActionSetVlanVid)a).getVlanVid().getVlan()); + sb.append(ActionUtils.STR_VLAN_SET_VID).append("=").append(((OFActionSetVlanVid)a).getVlanVid().getVlan()); break; case SET_VLAN_PCP: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_SET_PCP, ((OFActionSetVlanPcp)a).getVlanPcp().getValue()); + sb.append(ActionUtils.STR_VLAN_SET_PCP).append("=").append(((OFActionSetVlanPcp)a).getVlanPcp().getValue()); break; case SET_QUEUE: - jsonGenerator.writeNumberField(ActionUtils.STR_QUEUE_SET, ((OFActionSetQueue)a).getQueueId()); + sb.append(ActionUtils.STR_QUEUE_SET).append("=").append(((OFActionSetQueue)a).getQueueId()); break; case SET_DL_SRC: - jsonGenerator.writeStringField(ActionUtils.STR_DL_SRC_SET, ((OFActionSetDlSrc)a).getDlAddr().toString()); + sb.append(ActionUtils.STR_DL_SRC_SET).append("=").append(((OFActionSetDlSrc)a).getDlAddr().toString()); break; case SET_DL_DST: - jsonGenerator.writeStringField(ActionUtils.STR_DL_DST_SET, ((OFActionSetDlDst)a).getDlAddr().toString()); + sb.append(ActionUtils.STR_DL_DST_SET).append("=").append(((OFActionSetDlDst)a).getDlAddr().toString()); break; case SET_NW_SRC: - jsonGenerator.writeStringField(ActionUtils.STR_NW_SRC_SET, ((OFActionSetNwSrc)a).getNwAddr().toString()); + sb.append(ActionUtils.STR_NW_SRC_SET).append("=").append(((OFActionSetNwSrc)a).getNwAddr().toString()); break; case SET_NW_DST: - jsonGenerator.writeStringField(ActionUtils.STR_NW_DST_SET, ((OFActionSetNwDst)a).getNwAddr().toString()); + sb.append(ActionUtils.STR_NW_DST_SET).append("=").append(((OFActionSetNwDst)a).getNwAddr().toString()); break; case SET_NW_TOS: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_TOS_SET, ((OFActionSetNwTos)a).getNwTos()); + sb.append(ActionUtils.STR_NW_TOS_SET).append("=").append(((OFActionSetNwTos)a).getNwTos()); break; case SET_TP_SRC: - jsonGenerator.writeNumberField(ActionUtils.STR_TP_SRC_SET, ((OFActionSetTpSrc)a).getTpPort().getPort()); + sb.append(ActionUtils.STR_TP_SRC_SET).append("=").append(((OFActionSetTpSrc)a).getTpPort().getPort()); break; case SET_TP_DST: - jsonGenerator.writeNumberField(ActionUtils.STR_TP_DST_SET, ((OFActionSetTpDst)a).getTpPort().getPort()); + sb.append(ActionUtils.STR_TP_DST_SET).append("=").append(((OFActionSetTpDst)a).getTpPort().getPort()); break; /* end OF1.0 ONLY actions; begin OF1.1+ actions */ case ENQUEUE: - jsonGenerator.writeNumberField(ActionUtils.STR_ENQUEUE, ((OFActionEnqueue)a).getPort().getPortNumber()); + sb.append(ActionUtils.STR_ENQUEUE).append("=").append(((OFActionEnqueue)a).getPort().getPortNumber()); break; case GROUP: - jsonGenerator.writeStringField(ActionUtils.STR_GROUP, ((OFActionGroup)a).getGroup().toString()); + sb.append(ActionUtils.STR_GROUP).append("=").append(((OFActionGroup)a).getGroup().toString()); break; case STRIP_VLAN: - jsonGenerator.writeStringField(ActionUtils.STR_VLAN_STRIP, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_VLAN_STRIP).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case PUSH_VLAN: - jsonGenerator.writeNumberField(ActionUtils.STR_VLAN_PUSH, ((OFActionPushVlan)a).getEthertype().getValue()); + sb.append(ActionUtils.STR_VLAN_PUSH).append("=").append(((OFActionPushVlan)a).getEthertype().getValue()); break; case PUSH_MPLS: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_PUSH, ((OFActionPushMpls)a).getEthertype().getValue()); + sb.append(ActionUtils.STR_MPLS_PUSH).append("=").append(((OFActionPushMpls)a).getEthertype().getValue()); break; case PUSH_PBB: - jsonGenerator.writeNumberField(ActionUtils.STR_PBB_PUSH, ((OFActionPushPbb)a).getEthertype().getValue()); + sb.append(ActionUtils.STR_PBB_PUSH).append("=").append(((OFActionPushPbb)a).getEthertype().getValue()); break; case POP_VLAN: - jsonGenerator.writeStringField(ActionUtils.STR_VLAN_POP, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_VLAN_POP).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case POP_MPLS: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_POP, ((OFActionPopMpls)a).getEthertype().getValue()); + sb.append(ActionUtils.STR_MPLS_POP).append("=").append(((OFActionPopMpls)a).getEthertype().getValue()); break; case POP_PBB: - jsonGenerator.writeStringField(ActionUtils.STR_PBB_POP, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_PBB_POP).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case COPY_TTL_IN: - jsonGenerator.writeStringField(ActionUtils.STR_TTL_IN_COPY, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_TTL_IN_COPY).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case COPY_TTL_OUT: - jsonGenerator.writeStringField(ActionUtils.STR_TTL_OUT_COPY, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_TTL_OUT_COPY).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case DEC_NW_TTL: - jsonGenerator.writeStringField(ActionUtils.STR_NW_TTL_DEC, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_NW_TTL_DEC).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case DEC_MPLS_TTL: - jsonGenerator.writeStringField(ActionUtils.STR_MPLS_TTL_DEC, ActionUtils.STR_NOT_APPLICABLE); + sb.append(ActionUtils.STR_MPLS_TTL_DEC).append("=").append(ActionUtils.STR_NOT_APPLICABLE); break; case SET_MPLS_LABEL: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_LABEL_SET, ((OFActionSetMplsLabel)a).getMplsLabel()); + sb.append(ActionUtils.STR_MPLS_LABEL_SET).append("=").append(((OFActionSetMplsLabel)a).getMplsLabel()); break; case SET_MPLS_TC: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TC_SET, ((OFActionSetMplsTc)a).getMplsTc()); + sb.append(ActionUtils.STR_MPLS_TC_SET).append("=").append(((OFActionSetMplsTc)a).getMplsTc()); break; case SET_MPLS_TTL: - jsonGenerator.writeNumberField(ActionUtils.STR_MPLS_TTL_SET, ((OFActionSetMplsTtl)a).getMplsTtl()); + sb.append(ActionUtils.STR_MPLS_TTL_SET).append("=").append(((OFActionSetMplsTtl)a).getMplsTtl()); break; case SET_NW_ECN: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_ECN_SET, ((OFActionSetNwEcn)a).getNwEcn().getEcnValue()); + sb.append(ActionUtils.STR_NW_ECN_SET).append("=").append(((OFActionSetNwEcn)a).getNwEcn().getEcnValue()); break; case SET_NW_TTL: - jsonGenerator.writeNumberField(ActionUtils.STR_NW_TTL_SET, ((OFActionSetNwTtl)a).getNwTtl()); + sb.append(ActionUtils.STR_NW_TTL_SET).append("=").append(((OFActionSetNwTtl)a).getNwTtl()); break; case EXPERIMENTER: - jsonGenerator.writeNumberField(ActionUtils.STR_EXPERIMENTER, ((OFActionExperimenter)a).getExperimenter()); + sb.append(ActionUtils.STR_EXPERIMENTER).append("=").append(((OFActionExperimenter)a).getExperimenter()); break; case SET_FIELD: if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) { - jsonGenerator.writeNumberField(MatchUtils.STR_ARP_OPCODE, ((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()); + sb.append(MatchUtils.STR_ARP_OPCODE).append("=").append(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()); } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_SHA, ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already + sb.append(MatchUtils.STR_ARP_SHA).append("=").append(((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_DHA, ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_ARP_DHA).append("=").append(((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already + sb.append(MatchUtils.STR_ARP_SPA).append("=").append(((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) { - jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_ARP_DPA).append("=").append(((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdSll) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_SSL, ((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_ND_SSL).append("=").append(((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_TTL, ((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_ND_TTL).append("=").append(((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTarget) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_TARGET, ((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_ND_TARGET).append("=").append(((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString()); } /* DATA LAYER */ else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) { - jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()); + sb.append(MatchUtils.STR_DL_TYPE).append("=").append(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()); } else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) { - jsonGenerator.writeStringField(MatchUtils.STR_DL_SRC, ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_DL_SRC).append("=").append(((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) { - jsonGenerator.writeStringField(MatchUtils.STR_DL_DST, ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_DL_DST).append("=").append(((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) { - jsonGenerator.writeNumberField(MatchUtils.STR_DL_VLAN, ((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); + sb.append(MatchUtils.STR_DL_VLAN).append("=").append(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()); } else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) { } /* ICMP */ else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); + sb.append(MatchUtils.STR_ICMP_CODE).append("=").append(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); + sb.append(MatchUtils.STR_ICMP_TYPE).append("=").append(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Code) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMPV6_CODE, ((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()); + sb.append(MatchUtils.STR_ICMPV6_CODE).append("=").append(((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) { - jsonGenerator.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, ((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()); + sb.append(MatchUtils.STR_ICMPV6_TYPE).append("=").append(((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()); } /* NETWORK LAYER */ else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); + sb.append(MatchUtils.STR_NW_PROTO).append("=").append(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) { - jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_NW_SRC).append("=").append(((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) { - jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_NW_DST).append("=").append(((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_SRC, ((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_SRC).append("=").append(((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Dst) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_DST, ((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_DST).append("=").append(((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) { - jsonGenerator.writeStringField(MatchUtils.STR_IPV6_FLOW_LABEL, ((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_IPV6_FLOW_LABEL).append("=").append(((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); + sb.append(MatchUtils.STR_NW_ECN).append("=").append(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()); } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) { - jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); + sb.append(MatchUtils.STR_NW_DSCP).append("=").append(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); } /* TRANSPORT LAYER, TCP, UDP, and SCTP */ else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_TCP_SRC, ((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_TCP_SRC).append("=").append(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); } else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_TCP_DST, ((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_TCP_DST).append("=").append(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()); } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_UDP_SRC, ((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_UDP_SRC).append("=").append(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); } else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_UDP_DST, ((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_UDP_DST).append("=").append(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()); } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) { - jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_SRC, ((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_SCTP_SRC).append("=").append(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()); } else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) { - jsonGenerator.writeNumberField(MatchUtils.STR_SCTP_DST, ((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); + sb.append(MatchUtils.STR_SCTP_DST).append("=").append(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()); } /* MPLS */ else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) { - jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_LABEL, ((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); + sb.append(MatchUtils.STR_MPLS_LABEL).append("=").append(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()); } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) { - jsonGenerator.writeNumberField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); + sb.append(MatchUtils.STR_MPLS_TC).append("=").append(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()); } else if (((OFActionSetField)a).getField() instanceof OFOxmMplsBos) { - jsonGenerator.writeStringField(MatchUtils.STR_MPLS_TC, ((OFOxmMplsBos) ((OFActionSetField) a).getField()).getValue().toString()); + sb.append(MatchUtils.STR_MPLS_TC).append("=").append(((OFOxmMplsBos) ((OFActionSetField) a).getField()).getValue().toString()); } /* METADATA */ else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) { - jsonGenerator.writeNumberField(MatchUtils.STR_METADATA, ((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); + sb.append(MatchUtils.STR_METADATA).append("=").append(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()); } else { logger.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); - // need to get a logger in here somehow log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a)); } } // end switch over action type + pos++; + if (pos < len) { + sb.append(","); + } } // end for over all actions + + if (actions.isEmpty()) { + jsonGenerator.writeStringField("none", "drop"); + } else { + jsonGenerator.writeStringField("actions", sb.toString()); + } } // end method } diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java index 94a8686afe655dbfe2ff3ce3eb935c6fc14b24e1..36e8d8e16a0b3536c70d70cc4a6af58749dcab6f 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java @@ -206,116 +206,375 @@ public class StaticFlowEntries { MatchField mf = itr.next(); switch (mf.id) { case IN_PORT: // iterates over only exact/masked fields. No need to check for null entries. - entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, Integer.toString((match.get(MatchField.IN_PORT)).getPortNumber())); + if (match.supports(MatchField.IN_PORT) && match.isExact(MatchField.IN_PORT)) { + entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, match.get(MatchField.IN_PORT).toString()); + } else if (match.supportsMasked(MatchField.IN_PORT) && match.isPartiallyMasked(MatchField.IN_PORT)) { + entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, match.getMasked(MatchField.IN_PORT).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_IN_PORT, match.getVersion().toString()); + } break; case ETH_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, match.get(MatchField.ETH_SRC).toString()); + if (match.supports(MatchField.ETH_SRC) && match.isExact(MatchField.ETH_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, match.get(MatchField.ETH_SRC).toString()); + } else if (match.supportsMasked(MatchField.ETH_SRC) && match.isPartiallyMasked(MatchField.ETH_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, match.getMasked(MatchField.ETH_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_DL_SRC, match.getVersion().toString()); + } break; case ETH_DST: - entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, match.get(MatchField.ETH_DST).toString()); + if (match.supports(MatchField.ETH_DST) && match.isExact(MatchField.ETH_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, match.get(MatchField.ETH_DST).toString()); + } else if (match.supportsMasked(MatchField.ETH_DST) && match.isPartiallyMasked(MatchField.ETH_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, match.getMasked(MatchField.ETH_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_DL_DST, match.getVersion().toString()); + } break; case VLAN_VID: - entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, match.get(MatchField.VLAN_VID).getVlan()); + if (match.supports(MatchField.VLAN_VID) && match.isExact(MatchField.VLAN_VID)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, match.get(MatchField.VLAN_VID).toString()); + } else if (match.supportsMasked(MatchField.VLAN_VID) && match.isPartiallyMasked(MatchField.VLAN_VID)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, match.getMasked(MatchField.VLAN_VID).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_DL_VLAN, match.getVersion().toString()); + } break; case VLAN_PCP: - entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, Byte.toString(match.get(MatchField.VLAN_PCP).getValue())); + if (match.supports(MatchField.VLAN_PCP) && match.isExact(MatchField.VLAN_PCP)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, match.get(MatchField.VLAN_PCP).toString()); + } else if (match.supportsMasked(MatchField.VLAN_PCP) && match.isPartiallyMasked(MatchField.VLAN_PCP)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, match.getMasked(MatchField.VLAN_PCP).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, match.getVersion().toString()); + } break; case ETH_TYPE: - entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, match.get(MatchField.ETH_TYPE).getValue()); + if (match.supports(MatchField.ETH_TYPE) && match.isExact(MatchField.ETH_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, match.get(MatchField.ETH_TYPE).toString()); + } else if (match.supportsMasked(MatchField.ETH_TYPE) && match.isPartiallyMasked(MatchField.ETH_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, match.getMasked(MatchField.ETH_TYPE).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_DL_TYPE, match.getVersion().toString()); + } break; case IP_ECN: // TOS = [DSCP bits 0-5] + [ECN bits 6-7] --> bitwise OR to get TOS byte (have separate columns now though) - entry.put(StaticFlowEntryPusher.COLUMN_NW_ECN, Byte.toString(match.get(MatchField.IP_ECN).getEcnValue())); + if (match.supports(MatchField.IP_ECN) && match.isExact(MatchField.IP_ECN)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_ECN, match.get(MatchField.IP_ECN).toString()); + } else if (match.supportsMasked(MatchField.IP_ECN) && match.isPartiallyMasked(MatchField.IP_ECN)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_ECN, match.getMasked(MatchField.IP_ECN).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW_ECN, match.getVersion().toString()); + } break; case IP_DSCP: // Even for OF1.0, loxi will break ECN and DSCP up from the API's POV. This method is only invoked by a SFP service push from another module - entry.put(StaticFlowEntryPusher.COLUMN_NW_DSCP, Byte.toString((byte) (match.get(MatchField.IP_DSCP).getDscpValue()))); + if (match.supports(MatchField.IP_DSCP) && match.isExact(MatchField.IP_DSCP)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_DSCP, match.get(MatchField.IP_DSCP).toString()); + } else if (match.supportsMasked(MatchField.IP_DSCP) && match.isPartiallyMasked(MatchField.IP_DSCP)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_DSCP, match.getMasked(MatchField.IP_DSCP).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW_DSCP, match.getVersion().toString()); + } break; case IP_PROTO: - entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Short.toString(match.get(MatchField.IP_PROTO).getIpProtocolNumber())); + if (match.supports(MatchField.IP_PROTO) && match.isExact(MatchField.IP_PROTO)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, match.get(MatchField.IP_PROTO).toString()); + } else if (match.supportsMasked(MatchField.IP_PROTO) && match.isPartiallyMasked(MatchField.IP_PROTO)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, match.getMasked(MatchField.IP_PROTO).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW_PROTO, match.getVersion().toString()); + } break; case IPV4_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, match.get(MatchField.IPV4_SRC).toString()); + if (match.supports(MatchField.IPV4_SRC) && match.isExact(MatchField.IPV4_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, match.get(MatchField.IPV4_SRC).toString()); + } else if (match.supportsMasked(MatchField.IPV4_SRC) && match.isPartiallyMasked(MatchField.IPV4_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, match.getMasked(MatchField.IPV4_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW_SRC, match.getVersion().toString()); + } break; case IPV4_DST: - entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, match.get(MatchField.IPV4_DST).toString()); + if (match.supports(MatchField.IPV4_DST) && match.isExact(MatchField.IPV4_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, match.get(MatchField.IPV4_DST).toString()); + } else if (match.supportsMasked(MatchField.IPV4_DST) && match.isPartiallyMasked(MatchField.IPV4_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, match.getMasked(MatchField.IPV4_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW_DST, match.getVersion().toString()); + } break; case TCP_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_TCP_SRC, match.get(MatchField.TCP_SRC).getPort()); + if (match.supports(MatchField.TCP_SRC) && match.isExact(MatchField.TCP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_TCP_SRC, match.get(MatchField.TCP_SRC).toString()); + } else if (match.supportsMasked(MatchField.TCP_SRC) && match.isPartiallyMasked(MatchField.TCP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_TCP_SRC, match.getMasked(MatchField.TCP_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_TCP_SRC, match.getVersion().toString()); + } break; case UDP_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_UDP_SRC, match.get(MatchField.UDP_SRC).getPort()); + if (match.supports(MatchField.UDP_SRC) && match.isExact(MatchField.UDP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_UDP_SRC, match.get(MatchField.UDP_SRC).toString()); + } else if (match.supportsMasked(MatchField.UDP_SRC) && match.isPartiallyMasked(MatchField.UDP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_UDP_SRC, match.getMasked(MatchField.UDP_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_UDP_SRC, match.getVersion().toString()); + } break; case SCTP_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_SCTP_SRC, match.get(MatchField.SCTP_SRC).getPort()); + if (match.supports(MatchField.SCTP_SRC) && match.isExact(MatchField.SCTP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_SCTP_SRC, match.get(MatchField.SCTP_SRC).toString()); + } else if (match.supportsMasked(MatchField.SCTP_SRC) && match.isPartiallyMasked(MatchField.SCTP_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_SCTP_SRC, match.getMasked(MatchField.SCTP_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_SCTP_SRC, match.getVersion().toString()); + } break; case TCP_DST: - entry.put(StaticFlowEntryPusher.COLUMN_TCP_DST, match.get(MatchField.TCP_DST).getPort()); + if (match.supports(MatchField.TCP_DST) && match.isExact(MatchField.TCP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_TCP_DST, match.get(MatchField.TCP_DST).toString()); + } else if (match.supportsMasked(MatchField.TCP_DST) && match.isPartiallyMasked(MatchField.TCP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_TCP_DST, match.getMasked(MatchField.TCP_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_TCP_DST, match.getVersion().toString()); + } break; case UDP_DST: - entry.put(StaticFlowEntryPusher.COLUMN_UDP_DST, match.get(MatchField.UDP_DST).getPort()); + if (match.supports(MatchField.UDP_DST) && match.isExact(MatchField.UDP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_UDP_DST, match.get(MatchField.UDP_DST).toString()); + } else if (match.supportsMasked(MatchField.UDP_DST) && match.isPartiallyMasked(MatchField.UDP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_UDP_DST, match.getMasked(MatchField.UDP_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_UDP_DST, match.getVersion().toString()); + } break; case SCTP_DST: - entry.put(StaticFlowEntryPusher.COLUMN_SCTP_DST, match.get(MatchField.SCTP_DST).getPort()); + if (match.supports(MatchField.SCTP_DST) && match.isExact(MatchField.SCTP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_SCTP_DST, match.get(MatchField.SCTP_DST).toString()); + } else if (match.supportsMasked(MatchField.SCTP_DST) && match.isPartiallyMasked(MatchField.SCTP_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_SCTP_DST, match.getMasked(MatchField.SCTP_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_SCTP_DST, match.getVersion().toString()); + } break; case ICMPV4_TYPE: - entry.put(StaticFlowEntryPusher.COLUMN_ICMP_TYPE, match.get(MatchField.ICMPV4_TYPE).getType()); + if (match.supports(MatchField.ICMPV4_TYPE) && match.isExact(MatchField.ICMPV4_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP_TYPE, match.get(MatchField.ICMPV4_TYPE).toString()); + } else if (match.supportsMasked(MatchField.ICMPV4_TYPE) && match.isPartiallyMasked(MatchField.ICMPV4_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP_TYPE, match.getMasked(MatchField.ICMPV4_TYPE).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ICMP_TYPE, match.getVersion().toString()); + } break; case ICMPV4_CODE: - entry.put(StaticFlowEntryPusher.COLUMN_ICMP_CODE, match.get(MatchField.ICMPV4_CODE).getCode()); + if (match.supports(MatchField.ICMPV4_CODE) && match.isExact(MatchField.ICMPV4_CODE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP_CODE, match.get(MatchField.ICMPV4_CODE).toString()); + } else if (match.supportsMasked(MatchField.ICMPV4_CODE) && match.isPartiallyMasked(MatchField.ICMPV4_CODE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP_CODE, match.getMasked(MatchField.ICMPV4_CODE).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ICMP_CODE, match.getVersion().toString()); + } break; case ARP_OP: - entry.put(StaticFlowEntryPusher.COLUMN_ARP_OPCODE, match.get(MatchField.ARP_OP).getOpcode()); + if (match.supports(MatchField.ARP_OP) && match.isExact(MatchField.ARP_OP)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_OPCODE, match.get(MatchField.ARP_OP).toString()); + } else if (match.supportsMasked(MatchField.ARP_OP) && match.isPartiallyMasked(MatchField.ARP_OP)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_OPCODE, match.getMasked(MatchField.ARP_OP).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ARP_OPCODE, match.getVersion().toString()); + } break; case ARP_SHA: - entry.put(StaticFlowEntryPusher.COLUMN_ARP_SHA, match.get(MatchField.ARP_SHA).toString()); + if (match.supports(MatchField.ARP_SHA) && match.isExact(MatchField.ARP_SHA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_SHA, match.get(MatchField.ARP_SHA).toString()); + } else if (match.supportsMasked(MatchField.ARP_SHA) && match.isPartiallyMasked(MatchField.ARP_SHA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_SHA, match.getMasked(MatchField.ARP_SHA).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ARP_SHA, match.getVersion().toString()); + } break; case ARP_THA: - entry.put(StaticFlowEntryPusher.COLUMN_ARP_DHA, match.get(MatchField.ARP_THA).toString()); + if (match.supports(MatchField.ARP_THA) && match.isExact(MatchField.ARP_THA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_DHA, match.get(MatchField.ARP_THA).toString()); + } else if (match.supportsMasked(MatchField.ARP_THA) && match.isPartiallyMasked(MatchField.ARP_THA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_DHA, match.getMasked(MatchField.ARP_THA).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ARP_DHA, match.getVersion().toString()); + } break; case ARP_SPA: - entry.put(StaticFlowEntryPusher.COLUMN_ARP_SPA, match.get(MatchField.ARP_SPA).toString()); + if (match.supports(MatchField.ARP_SPA) && match.isExact(MatchField.ARP_SPA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_SPA, match.get(MatchField.ARP_SPA).toString()); + } else if (match.supportsMasked(MatchField.ARP_SPA) && match.isPartiallyMasked(MatchField.ARP_SPA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_SPA, match.getMasked(MatchField.ARP_SPA).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ARP_SPA, match.getVersion().toString()); + } break; case ARP_TPA: - entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString()); + if (match.supports(MatchField.ARP_TPA) && match.isExact(MatchField.ARP_TPA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString()); + } else if (match.supportsMasked(MatchField.ARP_TPA) && match.isPartiallyMasked(MatchField.ARP_TPA)) { + entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.getMasked(MatchField.ARP_TPA).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ARP_DPA, match.getVersion().toString()); + } break; case IPV6_SRC: - entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, match.get(MatchField.IPV6_SRC).toString()); + if (match.supports(MatchField.IPV6_SRC) && match.isExact(MatchField.IPV6_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, match.get(MatchField.IPV6_SRC).toString()); + } else if (match.supportsMasked(MatchField.IPV6_SRC) && match.isPartiallyMasked(MatchField.IPV6_SRC)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, match.getMasked(MatchField.IPV6_SRC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW6_SRC, match.getVersion().toString()); + } break; case IPV6_DST: - entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, match.get(MatchField.IPV6_DST).toString()); + if (match.supports(MatchField.IPV6_DST) && match.isExact(MatchField.IPV6_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, match.get(MatchField.IPV6_DST).toString()); + } else if (match.supportsMasked(MatchField.IPV6_DST) && match.isPartiallyMasked(MatchField.IPV6_DST)) { + entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, match.getMasked(MatchField.IPV6_DST).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_NW6_DST, match.getVersion().toString()); + } break; case IPV6_FLABEL: - entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.get(MatchField.IPV6_FLABEL).toString()); + if (match.supports(MatchField.IPV6_FLABEL) && match.isExact(MatchField.IPV6_FLABEL)) { + entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.get(MatchField.IPV6_FLABEL).toString()); + } else if (match.supportsMasked(MatchField.IPV6_FLABEL) && match.isPartiallyMasked(MatchField.IPV6_FLABEL)) { + entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.getMasked(MatchField.IPV6_FLABEL).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.getVersion().toString()); + } break; case ICMPV6_TYPE: - entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, String.valueOf(match.get(MatchField.ICMPV6_TYPE).getValue())); + if (match.supports(MatchField.ICMPV6_TYPE) && match.isExact(MatchField.ICMPV6_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, match.get(MatchField.ICMPV6_TYPE).toString()); + } else if (match.supportsMasked(MatchField.ICMPV6_TYPE) && match.isPartiallyMasked(MatchField.ICMPV6_TYPE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, match.getMasked(MatchField.ICMPV6_TYPE).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, match.getVersion().toString()); + } break; case ICMPV6_CODE: - entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.get(MatchField.ICMPV6_CODE).getValue()); + if (match.supports(MatchField.ICMPV6_CODE) && match.isExact(MatchField.ICMPV6_CODE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.get(MatchField.ICMPV6_CODE).toString()); + } else if (match.supportsMasked(MatchField.ICMPV6_CODE) && match.isPartiallyMasked(MatchField.ICMPV6_CODE)) { + entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.getMasked(MatchField.ICMPV6_CODE).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.getVersion().toString()); + } break; case IPV6_ND_SLL: - entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, match.get(MatchField.IPV6_ND_SLL).toString()); - break; + if (match.supports(MatchField.IPV6_ND_SLL) && match.isExact(MatchField.IPV6_ND_SLL)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, match.get(MatchField.IPV6_ND_SLL).toString()); + } else if (match.supportsMasked(MatchField.IPV6_ND_SLL) && match.isPartiallyMasked(MatchField.IPV6_ND_SLL)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, match.getMasked(MatchField.IPV6_ND_SLL).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ND_SLL, match.getVersion().toString()); + } + break; case IPV6_ND_TLL: - entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, match.get(MatchField.IPV6_ND_TLL).toString()); + if (match.supports(MatchField.IPV6_ND_TLL) && match.isExact(MatchField.IPV6_ND_TLL)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, match.get(MatchField.IPV6_ND_TLL).toString()); + } else if (match.supportsMasked(MatchField.IPV6_ND_TLL) && match.isPartiallyMasked(MatchField.IPV6_ND_TLL)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, match.getMasked(MatchField.IPV6_ND_TLL).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ND_TLL, match.getVersion().toString()); + } break; case IPV6_ND_TARGET: - entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, match.get(MatchField.IPV6_ND_TARGET).toString()); + if (match.supports(MatchField.IPV6_ND_TARGET) && match.isExact(MatchField.IPV6_ND_TARGET)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, match.get(MatchField.IPV6_ND_TARGET).toString()); + } else if (match.supportsMasked(MatchField.IPV6_ND_TARGET) && match.isPartiallyMasked(MatchField.IPV6_ND_TARGET)) { + entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, match.getMasked(MatchField.IPV6_ND_TARGET).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_ND_TARGET, match.getVersion().toString()); + } break; case MPLS_LABEL: - entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).getValue()); + if (match.supports(MatchField.MPLS_LABEL) && match.isExact(MatchField.MPLS_LABEL)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).toString()); + } else if (match.supportsMasked(MatchField.MPLS_LABEL) && match.isPartiallyMasked(MatchField.MPLS_LABEL)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.getMasked(MatchField.MPLS_LABEL).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.getVersion().toString()); + } break; case MPLS_TC: - entry.put(StaticFlowEntryPusher.COLUMN_MPLS_TC, match.get(MatchField.MPLS_TC).getValue()); + if (match.supports(MatchField.MPLS_TC) && match.isExact(MatchField.MPLS_TC)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_TC, match.get(MatchField.MPLS_TC).toString()); + } else if (match.supportsMasked(MatchField.MPLS_TC) && match.isPartiallyMasked(MatchField.MPLS_TC)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_TC, match.getMasked(MatchField.MPLS_TC).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_MPLS_TC, match.getVersion().toString()); + } break; case MPLS_BOS: - entry.put(StaticFlowEntryPusher.COLUMN_MPLS_BOS, match.get(MatchField.MPLS_BOS).getValue()); + if (match.supports(MatchField.MPLS_BOS) && match.isExact(MatchField.MPLS_BOS)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_BOS, match.get(MatchField.MPLS_BOS).toString()); + } else if (match.supportsMasked(MatchField.MPLS_BOS) && match.isPartiallyMasked(MatchField.MPLS_BOS)) { + entry.put(StaticFlowEntryPusher.COLUMN_MPLS_BOS, match.getMasked(MatchField.MPLS_BOS).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_MPLS_BOS, match.getVersion().toString()); + } break; case METADATA: - entry.put(StaticFlowEntryPusher.COLUMN_METADATA, match.get(MatchField.METADATA).getValue().getValue()); + if (match.supports(MatchField.METADATA) && match.isExact(MatchField.METADATA)) { + entry.put(StaticFlowEntryPusher.COLUMN_METADATA, match.get(MatchField.METADATA).toString()); + } else if (match.supportsMasked(MatchField.METADATA) && match.isPartiallyMasked(MatchField.METADATA)) { + entry.put(StaticFlowEntryPusher.COLUMN_METADATA, match.getMasked(MatchField.METADATA).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_METADATA, match.getVersion().toString()); + } break; case TUNNEL_ID: - entry.put(StaticFlowEntryPusher.COLUMN_TUNNEL_ID, match.get(MatchField.TUNNEL_ID).getValue()); - break; + if (match.supports(MatchField.TUNNEL_ID) && match.isExact(MatchField.TUNNEL_ID)) { + entry.put(StaticFlowEntryPusher.COLUMN_TUNNEL_ID, match.get(MatchField.TUNNEL_ID).toString()); + } else if (match.supportsMasked(MatchField.TUNNEL_ID) && match.isPartiallyMasked(MatchField.TUNNEL_ID)) { + entry.put(StaticFlowEntryPusher.COLUMN_TUNNEL_ID, match.getMasked(MatchField.TUNNEL_ID).toString()); + } else { + log.error("Got match for {} but protocol {} does not support said match. Ignoring match.", + StaticFlowEntryPusher.COLUMN_TUNNEL_ID, match.getVersion().toString()); + } + break; // case PBB_ISID not implemented in loxi default: log.error("Unhandled Match when parsing OFFlowMod: {}, {}", mf, mf.id); diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java index 89f351627bc8993bd321f66b332263410a46a41d..87367e0075bcb18e9d481a78f77f868de72e4437 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java @@ -362,7 +362,14 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, } // get the correct builder for the OF version supported by the switch - fmb = OFFactories.getFactory(switchService.getSwitch(DatapathId.of(switchName)).getOFFactory().getVersion()).buildFlowModify(); + try { + fmb = OFFactories.getFactory(switchService.getSwitch(DatapathId.of(switchName)).getOFFactory().getVersion()).buildFlowModify(); + } catch (NullPointerException e) { + /* switch was not connected/known */ + storageSourceService.deleteRowAsync(TABLE_NAME, entryName); + log.error("Deleting entry {}. Switch {} was not connected to the controller, and we need to know the OF protocol version to compose the flow mod.", entryName, switchName); + return; + } StaticFlowEntries.initDefaultFlowMod(fmb, entryName); @@ -587,16 +594,20 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, } // send flow_mod delete - OFFlowDeleteStrict flowMod = FlowModUtils.toFlowDeleteStrict(entriesFromStorage.get(dpid).get(entryName)); + if (switchService.getSwitch(DatapathId.of(dpid)) != null) { + OFFlowDeleteStrict flowMod = FlowModUtils.toFlowDeleteStrict(entriesFromStorage.get(dpid).get(entryName)); + + if (entriesFromStorage.containsKey(dpid) && entriesFromStorage.get(dpid).containsKey(entryName)) { + entriesFromStorage.get(dpid).remove(entryName); + } else { + log.debug("Tried to delete non-existent entry {} for switch {}", entryName, dpid); + return; + } - if (entriesFromStorage.containsKey(dpid) && entriesFromStorage.get(dpid).containsKey(entryName)) { - entriesFromStorage.get(dpid).remove(entryName); + writeFlowModToSwitch(DatapathId.of(dpid), flowMod); } else { - log.debug("Tried to delete non-existent entry {} for switch {}", entryName, dpid); - return; + log.debug("Not sending flow delete for disconnected switch."); } - - writeFlowModToSwitch(DatapathId.of(dpid), flowMod); return; } @@ -735,14 +746,14 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, msg.getMatch().equals(entry.getValue().getMatch()) && msg.getPriority() == entry.getValue().getPriority() && msg.getTableId().equals(entry.getValue().getTableId()) - ) { + ) { flowToRemove = entry.getKey(); break; } } - + log.debug("Flow to Remove: {}", flowToRemove); - + /* * Remove the flow. This will send the delete message to the switch, * since we cannot tell the storage listener rowsdeleted() that we diff --git a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java index f035adf653f336c244c064f522c1a23fa75fd3c5..87841aa6f58169888ff3eddd93ac71bf57c58847 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java +++ b/src/test/java/net/floodlightcontroller/core/internal/OFSwitchHandlerTestBase.java @@ -115,7 +115,7 @@ public abstract class OFSwitchHandlerTestBase { } } - @Before + public void setUpFeaturesReply() { getFeaturesReply(); this.featuresReply = getFeaturesReply(); @@ -132,6 +132,12 @@ public abstract class OFSwitchHandlerTestBase { @Before public void setUp() throws Exception { + /* + * This needs to be called explicitly to ensure the featuresReply is not null. + * Otherwise, there is no guarantee @Before will for setUpFeaturesReply() will + * call that function before our @Before setUp() here. + */ + setUpFeaturesReply(); switchManager = createMock(IOFSwitchManager.class); roleManager = createMock(RoleManager.class); sw = createMock(IOFSwitchBackend.class);