Skip to content
Snippets Groups Projects
Commit 4dce73e9 authored by Ryan Izard's avatar Ryan Izard
Browse files

Merged IPv6 support for the Static Flow Pusher.

parents 70a1426d 6061bd30
No related branches found
No related tags found
No related merge requests found
...@@ -41,11 +41,21 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc; ...@@ -41,11 +41,21 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType; import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Code;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIcmpv4Type; 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; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpDscp;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpEcn;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpProto;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst; import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Dst;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4Src; 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;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTarget;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6NdTll;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv6Src;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadata; import org.projectfloodlight.openflow.protocol.oxm.OFOxmMetadata;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsBos; import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsBos;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel; import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
...@@ -203,7 +213,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> { ...@@ -203,7 +213,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already jsonGenerator.writeStringField(MatchUtils.STR_ARP_SPA, ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) { } else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString()); jsonGenerator.writeStringField(MatchUtils.STR_ARP_DPA, ((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());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) {
jsonGenerator.writeStringField(MatchUtils.STR_IPV6_ND_TTL, ((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());
}
/* DATA LAYER */ /* DATA LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) { else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()); jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
...@@ -220,7 +236,11 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> { ...@@ -220,7 +236,11 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()); jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) { } else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()); jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_TYPE, ((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());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) {
jsonGenerator.writeNumberField(MatchUtils.STR_ICMPV6_TYPE, ((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw());
}
/* NETWORK LAYER */ /* NETWORK LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) { else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()); jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber());
...@@ -228,7 +248,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> { ...@@ -228,7 +248,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString()); jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) { } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString()); jsonGenerator.writeStringField(MatchUtils.STR_NW_DST, ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { } else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) {
jsonGenerator.writeStringField(MatchUtils.STR_IPV6_SRC, ((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());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) {
jsonGenerator.writeStringField(MatchUtils.STR_IPV6_FLOW_LABEL, ((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()); jsonGenerator.writeNumberField(MatchUtils.STR_NW_ECN, ((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) { } else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()); jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue());
......
...@@ -24,6 +24,7 @@ import java.util.Map; ...@@ -24,6 +24,7 @@ import java.util.Map;
import net.floodlightcontroller.core.annotations.LogMessageCategory; import net.floodlightcontroller.core.annotations.LogMessageCategory;
import net.floodlightcontroller.core.util.AppCookie; import net.floodlightcontroller.core.util.AppCookie;
import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryPusherResource;
import net.floodlightcontroller.util.ActionUtils; import net.floodlightcontroller.util.ActionUtils;
import net.floodlightcontroller.util.InstructionUtils; import net.floodlightcontroller.util.InstructionUtils;
...@@ -137,7 +138,7 @@ public class StaticFlowEntries { ...@@ -137,7 +138,7 @@ public class StaticFlowEntries {
* @param name The name of this static flow entry * @param name The name of this static flow entry
* @return A Map representation of the storage entry * @return A Map representation of the storage entry
*/ */
public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) { public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) throws Exception {
Map<String, Object> entry = new HashMap<String, Object>(); Map<String, Object> entry = new HashMap<String, Object>();
entry.put(StaticFlowEntryPusher.COLUMN_NAME, name); entry.put(StaticFlowEntryPusher.COLUMN_NAME, name);
entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw); entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw);
...@@ -271,6 +272,35 @@ public class StaticFlowEntries { ...@@ -271,6 +272,35 @@ public class StaticFlowEntries {
case ARP_TPA: case ARP_TPA:
entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString()); entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString());
break; break;
//sanjivini
case IPV6_SRC:
entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, match.get(MatchField.IPV6_SRC).toString());
break;
case IPV6_DST:
entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, match.get(MatchField.IPV6_DST).toString());
break;
case IPV6_FLABEL:
entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, match.get(MatchField.IPV6_FLABEL).toString());
break;
case ICMPV6_TYPE:
entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, String.valueOf(match.get(MatchField.ICMPV6_TYPE).getValue()));
break;
case ICMPV6_CODE:
entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, match.get(MatchField.ICMPV6_CODE).getValue());
break;
case IPV6_ND_SLL:
entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, match.get(MatchField.IPV6_ND_SLL).toString());
break;
case IPV6_ND_TLL:
entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, match.get(MatchField.IPV6_ND_TLL).toString());
break;
case IPV6_ND_TARGET:
entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, match.get(MatchField.IPV6_ND_TARGET).toString());
break;
//sanjivini
case MPLS_LABEL: case MPLS_LABEL:
entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).getValue()); entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).getValue());
break; break;
...@@ -293,6 +323,10 @@ public class StaticFlowEntries { ...@@ -293,6 +323,10 @@ public class StaticFlowEntries {
} // end switch-case } // end switch-case
} // end while } // end while
int result = StaticFlowEntryPusherResource.checkActions(entry);
if (result == -1)
throw new Exception("Invalid action/instructions");
return entry; return entry;
} }
...@@ -458,6 +492,34 @@ public class StaticFlowEntries { ...@@ -458,6 +492,34 @@ public class StaticFlowEntries {
case StaticFlowEntryPusher.COLUMN_ARP_DPA: case StaticFlowEntryPusher.COLUMN_ARP_DPA:
entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, jp.getText()); entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, jp.getText());
break; break;
//sanjivini
case StaticFlowEntryPusher.COLUMN_NW6_SRC:
entry.put(StaticFlowEntryPusher.COLUMN_NW6_SRC, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_NW6_DST:
entry.put(StaticFlowEntryPusher.COLUMN_NW6_DST, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL:
entry.put(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_ICMP6_TYPE:
entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_ICMP6_CODE:
entry.put(StaticFlowEntryPusher.COLUMN_ICMP6_CODE, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_ND_SLL:
entry.put(StaticFlowEntryPusher.COLUMN_ND_SLL, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_ND_TLL:
entry.put(StaticFlowEntryPusher.COLUMN_ND_TLL, jp.getText());
break;
case StaticFlowEntryPusher.COLUMN_ND_TARGET:
entry.put(StaticFlowEntryPusher.COLUMN_ND_TARGET, jp.getText());
break;
//sanjivini
case StaticFlowEntryPusher.COLUMN_MPLS_LABEL: case StaticFlowEntryPusher.COLUMN_MPLS_LABEL:
entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, jp.getText()); entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, jp.getText());
break; break;
......
...@@ -131,6 +131,18 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, ...@@ -131,6 +131,18 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
public static final String COLUMN_ARP_DHA = MatchUtils.STR_ARP_DHA; public static final String COLUMN_ARP_DHA = MatchUtils.STR_ARP_DHA;
public static final String COLUMN_ARP_SPA = MatchUtils.STR_ARP_SPA; public static final String COLUMN_ARP_SPA = MatchUtils.STR_ARP_SPA;
public static final String COLUMN_ARP_DPA = MatchUtils.STR_ARP_DPA; public static final String COLUMN_ARP_DPA = MatchUtils.STR_ARP_DPA;
//sanjivini
//IPv6 related columns
public static final String COLUMN_NW6_SRC = MatchUtils.STR_IPV6_SRC;
public static final String COLUMN_NW6_DST = MatchUtils.STR_IPV6_DST;
public static final String COLUMN_IPV6_FLOW_LABEL = MatchUtils.STR_IPV6_FLOW_LABEL;
public static final String COLUMN_ICMP6_TYPE = MatchUtils.STR_ICMPV6_TYPE;
public static final String COLUMN_ICMP6_CODE = MatchUtils.STR_ICMPV6_CODE;
public static final String COLUMN_ND_SLL = MatchUtils.STR_IPV6_ND_SSL;
public static final String COLUMN_ND_TLL = MatchUtils.STR_IPV6_ND_TTL;
public static final String COLUMN_ND_TARGET = MatchUtils.STR_IPV6_ND_TARGET;
//sanjivini
public static final String COLUMN_MPLS_LABEL = MatchUtils.STR_MPLS_LABEL; public static final String COLUMN_MPLS_LABEL = MatchUtils.STR_MPLS_LABEL;
public static final String COLUMN_MPLS_TC = MatchUtils.STR_MPLS_TC; public static final String COLUMN_MPLS_TC = MatchUtils.STR_MPLS_TC;
...@@ -164,6 +176,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, ...@@ -164,6 +176,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
COLUMN_ICMP_TYPE, COLUMN_ICMP_CODE, COLUMN_ICMP_TYPE, COLUMN_ICMP_CODE,
COLUMN_ARP_OPCODE, COLUMN_ARP_SHA, COLUMN_ARP_DHA, COLUMN_ARP_OPCODE, COLUMN_ARP_SHA, COLUMN_ARP_DHA,
COLUMN_ARP_SPA, COLUMN_ARP_DPA, COLUMN_ARP_SPA, COLUMN_ARP_DPA,
//sanjivini
//IPv6 related matches
COLUMN_NW6_SRC, COLUMN_NW6_DST, COLUMN_ICMP6_TYPE, COLUMN_ICMP6_CODE,
COLUMN_IPV6_FLOW_LABEL, COLUMN_ND_SLL, COLUMN_ND_TLL, COLUMN_ND_TARGET,
//sanjivini
COLUMN_MPLS_LABEL, COLUMN_MPLS_TC, COLUMN_MPLS_BOS, COLUMN_MPLS_LABEL, COLUMN_MPLS_TC, COLUMN_MPLS_BOS,
COLUMN_METADATA, COLUMN_TUNNEL_ID, COLUMN_PBB_ISID, COLUMN_METADATA, COLUMN_TUNNEL_ID, COLUMN_PBB_ISID,
/* end newly added matches */ /* end newly added matches */
...@@ -408,6 +427,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, ...@@ -408,6 +427,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
log.debug("ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName); log.debug("ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName);
return; return;
} }
//sanjivini
catch (Exception e) {
log.error("OF version incompatible for the match: " + match);
e.printStackTrace();
return;
}
//sanjivini
entries.get(switchName).put(entryName, fmb.build()); // add the FlowMod message to the table entries.get(switchName).put(entryName, fmb.build()); // add the FlowMod message to the table
} }
...@@ -754,8 +780,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService, ...@@ -754,8 +780,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
@Override @Override
public void addFlow(String name, OFFlowMod fm, DatapathId swDpid) { public void addFlow(String name, OFFlowMod fm, DatapathId swDpid) {
Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid.toString(), name); try {
storageSourceService.insertRowAsync(TABLE_NAME, fmMap); Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid.toString(), name);
storageSourceService.insertRowAsync(TABLE_NAME, fmMap);
} catch (Exception e) {
log.error("Error! Check the fields specified for the flow.Make sure IPv4 fields are not mixed with IPv6 fields or all "
+ "mandatory fields are specified. ");
}
} }
@Override @Override
......
...@@ -32,6 +32,7 @@ import net.floodlightcontroller.core.annotations.LogMessageDoc; ...@@ -32,6 +32,7 @@ import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.staticflowentry.StaticFlowEntries; import net.floodlightcontroller.staticflowentry.StaticFlowEntries;
import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher; import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.IStorageSourceService;
import net.floodlightcontroller.util.MatchUtils;
/** /**
* Pushes a static flow entry to the storage source * Pushes a static flow entry to the storage source
...@@ -43,137 +44,236 @@ public class StaticFlowEntryPusherResource extends ServerResource { ...@@ -43,137 +44,236 @@ public class StaticFlowEntryPusherResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class); protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
/** /**
* Checks to see if the user matches IP information without * Validates if all the mandatory fields are set properly while adding an IPv6 flow
* checking for the correct ether-type (2048). * @param Map containing the fields of the flow
* @param rows The Map that is a string representation of * @return state indicating whether a flow is valid or not
* the static flow.
* @reutrn True if they checked the ether-type, false otherwise
*/ */
private boolean checkMatchIp(Map<String, Object> rows) { private int checkFlow(Map<String, Object> rows) {
boolean matchEther = false; //Declaring & Initializing flags
String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE); int state = 0;
if (val != null) { boolean dl_type = false;
int type = 0; boolean nw_proto = false;
// check both hex and decimal boolean nw_layer = false;
if (val.startsWith("0x")) { boolean icmp6_type = false;
type = Integer.parseInt(val.substring(2), 16); boolean icmp6_code = false;
boolean nd_target = false;
boolean nd_sll = false;
boolean nd_tll = false;
boolean ip6 = false;
boolean ip4 = false;
int eth_type = -1;
int nw_protocol = -1;
int icmp_type = -1;
//Determine the dl_type if set
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_DL_TYPE)) {
if (((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE)).startsWith("0x")) {
eth_type = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE)).replaceFirst("0x", ""), 16);
dl_type = true;
} else {
eth_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE));
dl_type = true;
}
if (eth_type == 0x86dd) { /* or 34525 */
ip6 = true;
dl_type = true;
} else if (eth_type == 0x800 || /* or 2048 */
eth_type == 0x806 || /* or 2054 */
eth_type == 0x8035) { /* or 32821*/
ip4 = true;
dl_type = true;
}
//else {
// state = 2;
// return state;
//}
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC)) {
nw_layer = true;
ip4 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_CODE) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_TYPE) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DHA) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SHA) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SPA) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DPA) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_OPCODE)) {
ip4 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_SRC) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_DST)) {
nw_layer = true;
ip6 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO)) {
nw_proto = true;
if (((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO)).startsWith("0x")) {
nw_protocol = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO)).replaceFirst("0x", ""), 16);
} else { } else {
try { nw_protocol = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO));
type = Integer.parseInt(val);
} catch (NumberFormatException e) { /* fail silently */}
} }
if (type == 2048) matchEther = true;
} }
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_CODE)) {
icmp6_code = true;
ip6 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)) {
icmp6_type = true;
ip6 = true;
if (((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP_TYPE)).startsWith("0x")) {
icmp_type = Integer.parseInt(((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)).replaceFirst("0x", ""), 16);
} else {
icmp_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE));
}
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_SLL)) {
nd_sll = true;
ip6 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TLL)) {
nd_tll = true;
ip6 = true;
}
if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TARGET)) {
nd_target = true;
ip6 = true;
}
if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) || if (nw_layer == true || nw_proto == true) {
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) || if (dl_type == true) {
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) || if (!(ip4 == true || ip6 == true)) {
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) && //invalid dl_type
(matchEther == false)) state = 2;
return false; return state;
}
}
else {
//dl_type not set
state = 1;
return state;
}
}
if (icmp6_type == true || icmp6_code == true ) {
if (nw_proto == true) {
if (nw_protocol != 0x3A) { /* or 58 */
//invalid nw_proto
state = 4;
return state;
}
}
else {
//nw_proto not set
state = 3;
return state;
}
}
if (nd_sll == true || nd_tll == true || nd_target == true) {
if (icmp6_type == true) {
//icmp_type must be set to 135/136 to set ipv6_nd_target
if (nd_target == true) {
if (!(icmp_type == 135 || icmp_type == 136)) {
//invalid icmp6_type
state = 6;
return state;
}
}
//icmp_type must be set to 136 to set ipv6_nd_tll
else if (nd_tll == true) {
if (!(icmp_type == 136)) {
//invalid icmp6_type
state = 6;
return state;
}
}
//icmp_type must be set to 135 to set ipv6_nd_sll
else if (nd_sll == true) {
if (!(icmp_type == 135)) {
//invalid icmp6_type
state = 6;
return state;
}
}
}
else {
//icmp6_type not set
state = 5;
return state;
}
}
int result = checkActions(rows);
if ((ip4 == true && ip6 == true) || (result == -1) ||
(result == 1 && ip6 == true) || (result == 2 && ip4 == true)) {
//ipv4 & ipv6 conflict
state = 7;
return state;
}
return state;
return true;
} }
/** /**
* The check for flow entry validity will happen only when the SFP's * Validates actions/instructions
* storage listener detects the row entry is inserted. This, unfortunately,
* is after the REST API returns the message to the user who's inserting
* the flow.
* *
* This function will perform the same error checking that will happen * -1 --> IPv4/IPv6 conflict
* automatically later when the OFFlowMod is composed and built. This is * 0 --> no IPv4 or IPv6 actions
* somewhat redundant, since the flow entry will only be sent to the * 1 --> IPv4 only actions
* switch if it's valid, but this is the only way to tell the user something * 2 --> IPv6 only actions
* wasn't correct in their flow definition.
* *
* @param row * @param Map containing the fields of the flow
* @return A String describing the error if there is one; the empty string if all checks * @return state indicating whether a flow is valid or not
* */
private String validateFlowEntry(Map<String, Object> row) { public static int checkActions(Map<String, Object> entry) {
/*
* First, build the match string and try to turn it into a boolean ip6 = false;
* Match.Builder with all the fields set. Then, before the boolean ip4 = false;
* it's built, check all prerequisites. String actions = null;
*
IOFSwitchService switchService = (IOFSwitchService) getContext() if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS) ||
.getAttributes() entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS) ||
.get(IOFSwitchService.class.getCanonicalName()); entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
String switchName = (String) row.get(StaticFlowEntryPusher.COLUMN_SWITCH); if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS)) {
String entryName = (String) row.get(StaticFlowEntryPusher.COLUMN_NAME); actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_ACTIONS);
String matchString; }
DatapathId dpid; else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) {
actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS);
try { }
dpid = DatapathId.of(switchName); else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
} catch (NumberFormatException e) { actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS);
return "Invalid switch DPID " + switchName + ".";
}
IOFSwitch theSwitch = switchService.getSwitch(DatapathId.of(switchName));
if (theSwitch == null) {
return "Switch " + switchName + " is not connected to the controller.";
}
for (String key : row.keySet()) {
// get the correct builder for the OF version supported by the switch
OFFlowModify.Builder fmb = theSwitch.getOFFactory().buildFlowModify();
StaticFlowEntries.initDefaultFlowMod(fmb, entryName);
if (row.get(key) == null
|| key.equals(StaticFlowEntryPusher.COLUMN_SWITCH)
|| key.equals(StaticFlowEntryPusher.COLUMN_NAME)
|| key.equals("id")
|| key.equals(StaticFlowEntryPusher.COLUMN_HARD_TIMEOUT)
|| key.equals(StaticFlowEntryPusher.COLUMN_IDLE_TIMEOUT)) {
continue;
}
if (key.equals(StaticFlowEntryPusher.COLUMN_ACTIVE)) {
if (!Boolean.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_ACTIVE))) {
log.debug("Flow entry is inactive; verifying it anyway.");
}
} else if (key.equals(StaticFlowEntryPusher.COLUMN_TABLE_ID)) {
if (fmb.getVersion() != OFVersion.OF_10) { // all except 1.0 support tables
fmb.setTableId(TableId.of(Integer.parseInt((String) row.get(key)))); // support multiple flow tables for OF1.1+
} else {
return "Tables not supported in OpenFlow 1.0.";
}
} else if (key.equals(StaticFlowEntryPusher.COLUMN_ACTIONS)) {
ActionUtils.fromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_ACTIONS), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_COOKIE)) {
fmb.setCookie(StaticFlowEntries.computeEntryCookie(Integer.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_COOKIE)), entryName));
} else if (key.equals(StaticFlowEntryPusher.COLUMN_PRIORITY)) {
fmb.setPriority(U16.t(Integer.valueOf((String) row.get(StaticFlowEntryPusher.COLUMN_PRIORITY))));
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) {
InstructionUtils.applyActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_CLEAR_ACTIONS)) {
InstructionUtils.clearActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_CLEAR_ACTIONS), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_EXPERIMENTER)) {
InstructionUtils.experimenterFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_EXPERIMENTER), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_METER)) {
InstructionUtils.meterFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_METER), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_TABLE)) {
InstructionUtils.gotoTableFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_GOTO_TABLE), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
InstructionUtils.writeActionsFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS), log);
} else if (key.equals(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_METADATA)) {
InstructionUtils.writeMetadataFromString(fmb, (String) row.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_METADATA), log);
} else { // the rest of the keys are for Match().fromString()
if (matchString.length() > 0) {
matchString.append(",");
}
matchString.append(key + "=" + row.get(key).toString());
} }
}
String match = matchString.toString();
fmb.setMatch(MatchUtils.fromString(match, fmb.getVersion())); if (actions.contains(MatchUtils.STR_ICMPV6_CODE) || actions.contains(MatchUtils.STR_ICMPV6_TYPE) ||
actions.contains(MatchUtils.STR_IPV6_DST) || actions.contains(MatchUtils.STR_IPV6_SRC) ||
actions.contains(MatchUtils.STR_IPV6_FLOW_LABEL) || actions.contains(MatchUtils.STR_IPV6_ND_SSL) ||
actions.contains(MatchUtils.STR_IPV6_ND_TARGET) || actions.contains(MatchUtils.STR_IPV6_ND_TTL)) {
ip6 = true;
}
if (actions.contains(MatchUtils.STR_NW_SRC) || actions.contains(MatchUtils.STR_NW_DST) ||
actions.contains(MatchUtils.STR_ARP_OPCODE) || actions.contains(MatchUtils.STR_ARP_SHA) ||
actions.contains(MatchUtils.STR_ARP_DHA) || actions.contains(MatchUtils.STR_ARP_SPA) ||
actions.contains(MatchUtils.STR_ARP_DPA) || actions.contains(MatchUtils.STR_ICMP_CODE) ||
actions.contains(MatchUtils.STR_ICMP_TYPE)) {
ip4 = true;
}
}
return ""; if (ip6 == false && ip4 == false) {
} */ return 0; // no actions involving ipv4 or ipv6
} else if (ip6 == false && ip4 == true) {
return 1; //ipv4
} else if (ip6 == true && ip4 == false) {
return 2; //ipv6
} else {
return -1; // conflict of ipv4 and ipv6 actions
}
}
/** /**
* Takes a Static Flow Pusher string in JSON format and parses it into * Takes a Static Flow Pusher string in JSON format and parses it into
...@@ -195,19 +295,39 @@ public class StaticFlowEntryPusherResource extends ServerResource { ...@@ -195,19 +295,39 @@ public class StaticFlowEntryPusherResource extends ServerResource {
try { try {
rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson); rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
String status = null; String status = null;
if (!checkMatchIp(rowValues)) {
int state = checkFlow(rowValues);
if (state == 1) {
status = "Warning! Must specify eth_type of IPv4/IPv6 to " + status = "Warning! Must specify eth_type of IPv4/IPv6 to " +
"match on IPv4/IPv6 fields! The flow has been discarded."; "match on IPv4/IPv6 fields! The flow has been discarded.";
log.error(status); log.error(status);
} else { } else if (state == 2) {
status = "Entry pushed"; status = "Warning! eth_type not recognized! The flow has been discarded.";
log.error(status);
} else if (state == 3) {
status = "Warning! Must specify ip_proto to match! The flow has been discarded.";
log.error(status);
} else if (state == 4) {
status = "Warning! ip_proto invalid! The flow has been discarded.";
log.error(status);
} else if (state == 5) {
status = "Warning! Must specify icmp6_type to match! The flow has been discarded.";
log.error(status);
} else if (state == 6) {
status = "Warning! icmp6_type invalid! The flow has been discarded.";
log.error(status);
} else if (state == 7) {
status = "Warning! IPv4 & IPv6 fields cannot be specified in the same flow! The flow has been discarded.";
log.error(status);
} else if (state == 0) {
status = "Entry pushed";
storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
} }
storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
return ("{\"status\" : \"" + status + "\"}"); return ("{\"status\" : \"" + status + "\"}");
} catch (IOException e) { } catch (IOException e) {
log.error("Error parsing push flow mod request: " + fmJson, e); log.error("Error parsing push flow mod request: " + fmJson, e);
return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}"; return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
} }
} }
@Delete @Delete
......
...@@ -28,7 +28,7 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException; ...@@ -28,7 +28,7 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException;
* *
*/ */
public class InstructionUtils { public class InstructionUtils {
public static final String STR_GOTO_TABLE = "goto_table"; public static final String STR_GOTO_TABLE = "instruction_goto_table";
public static final String STR_WRITE_METADATA = "instruction_write_metadata"; public static final String STR_WRITE_METADATA = "instruction_write_metadata";
public static final String STR_WRITE_ACTIONS = "instruction_write_actions"; public static final String STR_WRITE_ACTIONS = "instruction_write_actions";
public static final String STR_APPLY_ACTIONS = "instruction_apply_actions"; public static final String STR_APPLY_ACTIONS = "instruction_apply_actions";
...@@ -169,7 +169,7 @@ public class InstructionUtils { ...@@ -169,7 +169,7 @@ public class InstructionUtils {
* @param log * @param log
* @return * @return
*/ */
public static String writeActionsToString(OFInstructionWriteActions inst, Logger log) { public static String writeActionsToString(OFInstructionWriteActions inst, Logger log) throws Exception {
return ActionUtils.actionsToString(inst.getActions(), log); return ActionUtils.actionsToString(inst.getActions(), log);
} }
...@@ -200,7 +200,7 @@ public class InstructionUtils { ...@@ -200,7 +200,7 @@ public class InstructionUtils {
* @param log * @param log
* @return * @return
*/ */
public static String applyActionsToString(OFInstructionApplyActions inst, Logger log) { public static String applyActionsToString(OFInstructionApplyActions inst, Logger log) throws Exception {
return ActionUtils.actionsToString(inst.getActions(), log); return ActionUtils.actionsToString(inst.getActions(), log);
} }
......
...@@ -13,6 +13,9 @@ import org.projectfloodlight.openflow.types.ICMPv4Code; ...@@ -13,6 +13,9 @@ import org.projectfloodlight.openflow.types.ICMPv4Code;
import org.projectfloodlight.openflow.types.ICMPv4Type; import org.projectfloodlight.openflow.types.ICMPv4Type;
import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv4AddressWithMask; import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
import org.projectfloodlight.openflow.types.IPv6Address;
import org.projectfloodlight.openflow.types.IPv6AddressWithMask;
import org.projectfloodlight.openflow.types.IPv6FlowLabel;
import org.projectfloodlight.openflow.types.IpDscp; import org.projectfloodlight.openflow.types.IpDscp;
import org.projectfloodlight.openflow.types.IpEcn; import org.projectfloodlight.openflow.types.IpEcn;
import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.IpProtocol;
...@@ -330,6 +333,9 @@ public class MatchUtils { ...@@ -330,6 +333,9 @@ public class MatchUtils {
* on unexpected key or value * on unexpected key or value
*/ */
public static Match fromString(String match, OFVersion ofVersion) throws IllegalArgumentException { public static Match fromString(String match, OFVersion ofVersion) throws IllegalArgumentException {
boolean ver10 = false;
if (match.equals("") || match.equalsIgnoreCase("any") || match.equalsIgnoreCase("all") || match.equals("[]")) { if (match.equals("") || match.equalsIgnoreCase("any") || match.equalsIgnoreCase("all") || match.equals("[]")) {
match = "Match[]"; match = "Match[]";
} }
...@@ -356,6 +362,14 @@ public class MatchUtils { ...@@ -356,6 +362,14 @@ public class MatchUtils {
Match.Builder mb = OFFactories.getFactory(ofVersion).buildMatch(); Match.Builder mb = OFFactories.getFactory(ofVersion).buildMatch();
//sanjivini
//Determine if the OF version is 1.0 before adding a flow
if (ofVersion.equals(OFVersion.OF_10)) {
ver10 = true;
}
//sanjivini
while (!llValues.isEmpty()) { while (!llValues.isEmpty()) {
IpProtocol ipProto = null; IpProtocol ipProto = null;
String[] key_value = llValues.pollFirst(); // pop off the first element; this completely removes it from the queue. String[] key_value = llValues.pollFirst(); // pop off the first element; this completely removes it from the queue.
...@@ -396,6 +410,28 @@ public class MatchUtils { ...@@ -396,6 +410,28 @@ public class MatchUtils {
case STR_NW_SRC: case STR_NW_SRC:
mb.setMasked(MatchField.IPV4_SRC, IPv4AddressWithMask.of(key_value[1])); mb.setMasked(MatchField.IPV4_SRC, IPv4AddressWithMask.of(key_value[1]));
break; break;
//sanjivini
case STR_IPV6_DST:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
}
mb.setMasked(MatchField.IPV6_DST, IPv6AddressWithMask.of(key_value[1]));
break;
case STR_IPV6_SRC:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
}
mb.setMasked(MatchField.IPV6_SRC, IPv6AddressWithMask.of(key_value[1]));
break;
case STR_IPV6_FLOW_LABEL:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
}
mb.setExact(MatchField.IPV6_FLABEL, IPv6FlowLabel.of(Integer.parseInt(key_value[1])));
break;
//sanjivini
case STR_NW_PROTO: case STR_NW_PROTO:
if (key_value[1].startsWith("0x")) { if (key_value[1].startsWith("0x")) {
mb.setExact(MatchField.IP_PROTO, IpProtocol.of(Short.valueOf(key_value[1].replaceFirst("0x", ""), 16))); mb.setExact(MatchField.IP_PROTO, IpProtocol.of(Short.valueOf(key_value[1].replaceFirst("0x", ""), 16)));
...@@ -504,6 +540,45 @@ public class MatchUtils { ...@@ -504,6 +540,45 @@ public class MatchUtils {
mb.setExact(MatchField.ICMPV4_CODE, ICMPv4Code.of(Short.parseShort(key_value[1]))); mb.setExact(MatchField.ICMPV4_CODE, ICMPv4Code.of(Short.parseShort(key_value[1])));
} }
break; break;
//sanjivini
case STR_ICMPV6_TYPE:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
//throw new Exception("OF Version incompatible");
}
mb.setExact(MatchField.ICMPV6_TYPE, U8.of(Short.parseShort(key_value[1])));
break;
case STR_ICMPV6_CODE:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
//throw new Exception("OF Version incompatible");
}
mb.setExact(MatchField.ICMPV6_CODE, U8.of(Short.parseShort(key_value[1])));
break;
case STR_IPV6_ND_SSL:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
//throw new Exception("OF Version incompatible");
}
mb.setExact(MatchField.IPV6_ND_SLL, MacAddress.of(key_value[1]));
break;
case STR_IPV6_ND_TTL:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
//throw new Exception("OF Version incompatible");
}
mb.setExact(MatchField.IPV6_ND_TLL, MacAddress.of(key_value[1]));
break;
case STR_IPV6_ND_TARGET:
if (ver10 == true) {
throw new IllegalArgumentException("OF Version incompatible");
//throw new Exception("OF Version incompatible");
}
mb.setExact(MatchField.IPV6_ND_TARGET, IPv6Address.of(key_value[1]));
break;
//sanjivini
case STR_ARP_OPCODE: case STR_ARP_OPCODE:
if (key_value[1].startsWith("0x")) { if (key_value[1].startsWith("0x")) {
mb.setExact(MatchField.ARP_OP, ArpOpcode.of(Integer.parseInt(key_value[1].replaceFirst("0x", ""), 16))); mb.setExact(MatchField.ARP_OP, ArpOpcode.of(Integer.parseInt(key_value[1].replaceFirst("0x", ""), 16)));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment