From 1ae37339c083b30bc564af4e608725c514b2e6b7 Mon Sep 17 00:00:00 2001 From: Hideyuki Tai Date: Tue, 30 Jul 2013 13:03:10 -0400 Subject: [PATCH 1/1] Fixed a bug that failed specifying the value 0 on VLAN ID field for a match condition, and enabled to match VLAN untagged frames on OpenFlow switches. - Fixed MatchType class to allow the value 0 on VLAN ID field for VLAN untagged frames. - Changed FlowConverter class to convert the value 0 on VLAN ID field of SAL Flow into the value 0xffff of OF Flow, and vice-versa. Signed-off-by: Hideyuki Tai --- .../openflow/internal/FlowConverter.java | 26 ++++++++-- .../internal/FlowProgrammerServiceTest.java | 49 +++++++++++++++++++ .../controller/sal/match/MatchType.java | 5 +- .../controller/sal/match/MatchTest.java | 11 +++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java index 756a6895dc..2b8f6553d6 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java @@ -76,6 +76,13 @@ import org.slf4j.LoggerFactory; public class FlowConverter { protected static final Logger logger = LoggerFactory .getLogger(FlowConverter.class); + + /* + * The value 0xffff (OFP_VLAN_NONE) is used to indicate + * that no VLAN ID is set for OF Flow. + */ + private static final short OFP_VLAN_NONE = (short) 0xffff; + private Flow flow; // SAL Flow private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match private List actionsList; // OF 1.0 actions @@ -143,6 +150,9 @@ public class FlowConverter { if (match.isPresent(MatchType.DL_VLAN)) { short vlan = (Short) match.getField(MatchType.DL_VLAN) .getValue(); + if (vlan == MatchType.DL_VLAN_NONE) { + vlan = OFP_VLAN_NONE; + } if (!isIPv6) { ofMatch.setDataLayerVirtualLan(vlan); wildcards &= ~OFMatch.OFPFW_DL_VLAN; @@ -514,9 +524,13 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_TYPE, ofMatch.getDataLayerType())); } - if (ofMatch.getDataLayerVirtualLan() != 0) { + short vlan = ofMatch.getDataLayerVirtualLan(); + if (vlan != 0) { + if (vlan == OFP_VLAN_NONE) { + vlan = MatchType.DL_VLAN_NONE; + } salMatch.setField(new MatchField(MatchType.DL_VLAN, - ofMatch.getDataLayerVirtualLan())); + vlan)); } if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) { salMatch.setField(MatchType.DL_VLAN_PR, ofMatch @@ -582,9 +596,13 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_TYPE, v6Match.getDataLayerType())); } - if (v6Match.getDataLayerVirtualLan() != 0) { + short vlan = v6Match.getDataLayerVirtualLan(); + if (vlan != 0) { + if (vlan == OFP_VLAN_NONE) { + vlan = MatchType.DL_VLAN_NONE; + } salMatch.setField(new MatchField(MatchType.DL_VLAN, - v6Match.getDataLayerVirtualLan())); + vlan)); } if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) { salMatch.setField(MatchType.DL_VLAN_PR, v6Match diff --git a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java index 297223392d..ad225d94dd 100644 --- a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java +++ b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerServiceTest.java @@ -179,6 +179,55 @@ public class FlowProgrammerServiceTest { } } + @Test + public void testVlanNoneIdFlowConversion() throws Exception { + Node node = NodeCreator.createOFNode(1000l); + + /* + * The value 0 is used to indicate that no VLAN ID is set + * for SAL Flow. + */ + short vlan = (short) 0; + + /* + * Create a SAL Flow aFlow + */ + Match match = new Match(); + match.setField(MatchType.DL_VLAN, vlan); + + List actions = new ArrayList(); + + Flow aFlow = new Flow(match, actions); + + /* + * Convert the SAL aFlow to OF Flow + */ + FlowConverter salToOF = new FlowConverter(aFlow); + OFMatch ofMatch = salToOF.getOFMatch(); + List ofActions = salToOF.getOFActions(); + + /* + * The value 0xffff (OFP_VLAN_NONE) is used to indicate + * that no VLAN ID is set for OF Flow. + */ + Assert.assertEquals((short) 0xffff, ofMatch.getDataLayerVirtualLan()); + + /* + * Convert the OF Flow to SAL Flow bFlow + */ + FlowConverter ofToSal = new FlowConverter(ofMatch, ofActions); + Flow bFlow = ofToSal.getFlow(node); + Match bMatch = bFlow.getMatch(); + + /* + * Verify the converted SAL flow bFlow is equivalent to the original SAL Flow + */ + Assert + .assertTrue(((Short) match.getField(MatchType.DL_VLAN) + .getValue()).equals((Short) bMatch.getField( + MatchType.DL_VLAN).getValue())); + } + @Test public void testV6toSALFlowConversion() throws Exception { Node node = NodeCreator.createOFNode(12l); diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java index 85e505671e..1c964267b1 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java @@ -25,7 +25,7 @@ public enum MatchType { IN_PORT("inPort", 1 << 0, NodeConnector.class, 1, 0), DL_SRC("dlSrc", 1 << 1, Byte[].class, 0, 0xffffffffffffL), DL_DST("dlDst", 1 << 2, Byte[].class, 0, 0xffffffffffffL), - DL_VLAN("dlVlan", 1 << 3, Short.class, 1, 0xfff), // 2 bytes + DL_VLAN("dlVlan", 1 << 3, Short.class, 0, 0xfff), // 2 bytes DL_VLAN_PR("dlVlanPriority", 1 << 4, Byte.class, 0, 0x7), // 3 bits DL_OUTER_VLAN("dlOuterVlan", 1 << 5, Short.class, 1, 0xfff), DL_OUTER_VLAN_PR("dlOuterVlanPriority", 1 << 6, Short.class, 0, 0x7), @@ -37,6 +37,9 @@ public enum MatchType { TP_SRC("tpSrc", 1 << 12, Short.class, 1, 0xffff), // 2 bytes TP_DST("tpDst", 1 << 13, Short.class, 1, 0xffff); // 2 bytes + // Used to indicate that no VLAN ID is set. + public static final short DL_VLAN_NONE = (short) 0; + private String id; private int index; private Class dataType; diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java index cfa53fb7f3..55b5cabf11 100644 --- a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java +++ b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/match/MatchTest.java @@ -474,4 +474,15 @@ public class MatchTest { Assert.assertTrue(flipflip.equals(flipped)); } + + @Test + public void testVlanNone() throws Exception { + // The value 0 is used to indicate that no VLAN ID is set + short vlan = (short) 0; + MatchField field = new MatchField(MatchType.DL_VLAN, vlan); + + Assert.assertTrue(field != null); + Assert.assertTrue(field.getValue().equals(new Short(vlan))); + Assert.assertTrue(field.isValid()); + } } -- 2.36.6