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;
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;
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;
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.OFOxmMplsBos;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsLabel;
......@@ -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
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
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 */
else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
jsonGenerator.writeNumberField(MatchUtils.STR_DL_TYPE, ((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue());
......@@ -220,7 +236,11 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
jsonGenerator.writeNumberField(MatchUtils.STR_ICMP_CODE, ((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());
}
} 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 */
else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
jsonGenerator.writeNumberField(MatchUtils.STR_NW_PROTO, ((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber());
......@@ -228,7 +248,13 @@ public class OFActionListSerializer extends JsonSerializer<List<OFAction>> {
jsonGenerator.writeStringField(MatchUtils.STR_NW_SRC, ((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());
} 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());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
jsonGenerator.writeNumberField(MatchUtils.STR_NW_DSCP, ((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue());
......
......@@ -24,6 +24,7 @@ import java.util.Map;
import net.floodlightcontroller.core.annotations.LogMessageCategory;
import net.floodlightcontroller.core.util.AppCookie;
import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryPusherResource;
import net.floodlightcontroller.util.ActionUtils;
import net.floodlightcontroller.util.InstructionUtils;
......@@ -137,7 +138,7 @@ public class StaticFlowEntries {
* @param name The name of this static flow 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>();
entry.put(StaticFlowEntryPusher.COLUMN_NAME, name);
entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw);
......@@ -271,6 +272,35 @@ public class StaticFlowEntries {
case ARP_TPA:
entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, match.get(MatchField.ARP_TPA).toString());
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:
entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, match.get(MatchField.MPLS_LABEL).getValue());
break;
......@@ -293,6 +323,10 @@ public class StaticFlowEntries {
} // end switch-case
} // end while
int result = StaticFlowEntryPusherResource.checkActions(entry);
if (result == -1)
throw new Exception("Invalid action/instructions");
return entry;
}
......@@ -458,6 +492,34 @@ public class StaticFlowEntries {
case StaticFlowEntryPusher.COLUMN_ARP_DPA:
entry.put(StaticFlowEntryPusher.COLUMN_ARP_DPA, jp.getText());
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:
entry.put(StaticFlowEntryPusher.COLUMN_MPLS_LABEL, jp.getText());
break;
......
......@@ -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_SPA = MatchUtils.STR_ARP_SPA;
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_TC = MatchUtils.STR_MPLS_TC;
......@@ -164,6 +176,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
COLUMN_ICMP_TYPE, COLUMN_ICMP_CODE,
COLUMN_ARP_OPCODE, COLUMN_ARP_SHA, COLUMN_ARP_DHA,
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_METADATA, COLUMN_TUNNEL_ID, COLUMN_PBB_ISID,
/* end newly added matches */
......@@ -408,6 +427,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
log.debug("ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName);
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
}
......@@ -754,8 +780,13 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
@Override
public void addFlow(String name, OFFlowMod fm, DatapathId swDpid) {
Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid.toString(), name);
storageSourceService.insertRowAsync(TABLE_NAME, fmMap);
try {
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
......
......@@ -32,6 +32,7 @@ import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.staticflowentry.StaticFlowEntries;
import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
import net.floodlightcontroller.storage.IStorageSourceService;
import net.floodlightcontroller.util.MatchUtils;
/**
* Pushes a static flow entry to the storage source
......@@ -43,137 +44,236 @@ public class StaticFlowEntryPusherResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
/**
* Checks to see if the user matches IP information without
* checking for the correct ether-type (2048).
* @param rows The Map that is a string representation of
* the static flow.
* @reutrn True if they checked the ether-type, false otherwise
* Validates if all the mandatory fields are set properly while adding an IPv6 flow
* @param Map containing the fields of the flow
* @return state indicating whether a flow is valid or not
*/
private boolean checkMatchIp(Map<String, Object> rows) {
boolean matchEther = false;
String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
if (val != null) {
int type = 0;
// check both hex and decimal
if (val.startsWith("0x")) {
type = Integer.parseInt(val.substring(2), 16);
private int checkFlow(Map<String, Object> rows) {
//Declaring & Initializing flags
int state = 0;
boolean dl_type = false;
boolean nw_proto = false;
boolean nw_layer = false;
boolean icmp6_type = false;
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 {
try {
type = Integer.parseInt(val);
} catch (NumberFormatException e) { /* fail silently */}
nw_protocol = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO));
}
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) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
(matchEther == false))
return false;
if (nw_layer == true || nw_proto == true) {
if (dl_type == true) {
if (!(ip4 == true || ip6 == true)) {
//invalid dl_type
state = 2;
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
* 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.
* Validates actions/instructions
*
* This function will perform the same error checking that will happen
* automatically later when the OFFlowMod is composed and built. This is
* somewhat redundant, since the flow entry will only be sent to the
* switch if it's valid, but this is the only way to tell the user something
* wasn't correct in their flow definition.
* -1 --> IPv4/IPv6 conflict
* 0 --> no IPv4 or IPv6 actions
* 1 --> IPv4 only actions
* 2 --> IPv6 only actions
*
* @param row
* @return A String describing the error if there is one; the empty string if all checks
*
private String validateFlowEntry(Map<String, Object> row) {
/*
* First, build the match string and try to turn it into a
* Match.Builder with all the fields set. Then, before the
* it's built, check all prerequisites.
*
IOFSwitchService switchService = (IOFSwitchService) getContext()
.getAttributes()
.get(IOFSwitchService.class.getCanonicalName());
String switchName = (String) row.get(StaticFlowEntryPusher.COLUMN_SWITCH);
String entryName = (String) row.get(StaticFlowEntryPusher.COLUMN_NAME);
String matchString;
DatapathId dpid;
try {
dpid = DatapathId.of(switchName);
} catch (NumberFormatException e) {
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());
* @param Map containing the fields of the flow
* @return state indicating whether a flow is valid or not
*/
public static int checkActions(Map<String, Object> entry) {
boolean ip6 = false;
boolean ip4 = false;
String actions = null;
if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS) ||
entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS) ||
entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS)) {
actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_ACTIONS);
}
else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) {
actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS);
}
else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) {
actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS);
}
}
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
......@@ -195,19 +295,39 @@ public class StaticFlowEntryPusherResource extends ServerResource {
try {
rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
String status = null;
if (!checkMatchIp(rowValues)) {
int state = checkFlow(rowValues);
if (state == 1) {
status = "Warning! Must specify eth_type of IPv4/IPv6 to " +
"match on IPv4/IPv6 fields! The flow has been discarded.";
log.error(status);
} else {
status = "Entry pushed";
} else if (state == 2) {
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 + "\"}");
} catch (IOException e) {
log.error("Error parsing push flow mod request: " + fmJson, e);
return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
}
}
}
@Delete
......
......@@ -46,11 +46,19 @@ 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;
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;
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.OFOxmMplsLabel;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmMplsTc;
......@@ -67,6 +75,8 @@ import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.ICMPv4Code;
import org.projectfloodlight.openflow.types.ICMPv4Type;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IPv6Address;
import org.projectfloodlight.openflow.types.IPv6FlowLabel;
import org.projectfloodlight.openflow.types.IpDscp;
import org.projectfloodlight.openflow.types.IpEcn;
import org.projectfloodlight.openflow.types.IpProtocol;
......@@ -134,192 +144,208 @@ public class ActionUtils {
*/
/**
* Returns a String representation of all the OpenFlow actions.
* @param actions; A list of OFActions to encode into one string
* @return A dpctl-style string of the actions
*/
@LogMessageDoc(level="ERROR",
message="Could not decode action {action}",
explanation="A static flow entry contained an invalid action",
recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
public static String actionsToString(List<OFAction> actions, Logger log) {
StringBuilder sb = new StringBuilder();
for (OFAction a : actions) {
if (sb.length() > 0) {
sb.append(',');
}
switch(a.getType()) {
case OUTPUT:
sb.append(STR_OUTPUT + "=" + Integer.toString(((OFActionOutput)a).getPort().getPortNumber()));
break;
case ENQUEUE:
long queue = ((OFActionEnqueue)a).getQueueId();
OFPort port = ((OFActionEnqueue)a).getPort();
sb.append(STR_ENQUEUE + "=" + Integer.toString(port.getPortNumber()) + ":0x" + String.format("%02x", queue));
break;
case STRIP_VLAN:
sb.append(STR_VLAN_STRIP);
break;
case POP_VLAN:
sb.append(STR_VLAN_POP);
break;
case PUSH_VLAN:
sb.append(STR_VLAN_PUSH + "=" + Integer.toString(((OFActionPushVlan)a).getEthertype().getValue()));
break;
case SET_VLAN_VID:
sb.append(STR_VLAN_SET_VID + "=" + Short.toString(((OFActionSetVlanVid)a).getVlanVid().getVlan()));
break;
case SET_VLAN_PCP:
sb.append(STR_VLAN_SET_PCP + "=" + Byte.toString(((OFActionSetVlanPcp)a).getVlanPcp().getValue()));
break;
case SET_QUEUE:
sb.append(STR_QUEUE_SET + "=" + Long.toString(((OFActionSetQueue)a).getQueueId()));
case SET_DL_SRC:
sb.append(STR_DL_SRC_SET + "=" + ((OFActionSetDlSrc)a).getDlAddr().toString());
break;
case SET_DL_DST:
sb.append(STR_DL_DST_SET + "=" + ((OFActionSetDlDst)a).getDlAddr().toString());
break;
case SET_NW_ECN:
sb.append(STR_NW_ECN_SET + "=" + Byte.toString(((OFActionSetNwEcn)a).getNwEcn().getEcnValue()));
break;
case SET_NW_TOS:
sb.append(STR_NW_TOS_SET + "=" + Short.toString(((OFActionSetNwTos)a).getNwTos()));
break;
case SET_NW_TTL:
sb.append(STR_NW_TTL_SET + "=" + Short.toString(((OFActionSetNwTtl)a).getNwTtl()));
break;
case DEC_NW_TTL:
sb.append(STR_NW_TTL_DEC);
break;
case SET_MPLS_LABEL:
sb.append(STR_MPLS_LABEL_SET + "=" + Long.toString(((OFActionSetMplsLabel)a).getMplsLabel()));
break;
case SET_MPLS_TC:
sb.append(STR_MPLS_TC_SET + "=" + Short.toString(((OFActionSetMplsTc)a).getMplsTc()));
break;
case SET_MPLS_TTL:
sb.append(STR_MPLS_TTL_SET + "=" + Short.toString(((OFActionSetMplsTtl)a).getMplsTtl()));
break;
case DEC_MPLS_TTL:
sb.append(STR_MPLS_TTL_DEC);
break;
case PUSH_MPLS:
sb.append(STR_MPLS_PUSH + "=" + Integer.toString(((OFActionPushMpls)a).getEthertype().getValue()));
break;
case POP_MPLS:
sb.append(STR_MPLS_POP + "=" + Integer.toString(((OFActionPopMpls)a).getEthertype().getValue()));
break;
case SET_NW_SRC:
sb.append(STR_NW_SRC_SET + "=" + ((OFActionSetNwSrc)a).getNwAddr().toString());
break;
case SET_NW_DST:
sb.append(STR_NW_DST_SET + "=" + ((OFActionSetNwDst)a).getNwAddr().toString());
break;
case SET_TP_SRC:
sb.append(STR_TP_SRC_SET + "=" + ((OFActionSetTpSrc)a).getTpPort().toString());
break;
case SET_TP_DST:
sb.append(STR_TP_DST_SET + "=" + ((OFActionSetTpDst)a).getTpPort().toString());
break;
case COPY_TTL_IN:
sb.append(STR_TTL_IN_COPY);
break;
case COPY_TTL_OUT:
sb.append(STR_TTL_OUT_COPY);
break;
case PUSH_PBB:
sb.append(STR_PBB_PUSH + "=" + Integer.toString(((OFActionPushPbb)a).getEthertype().getValue()));
break;
case POP_PBB:
sb.append(STR_PBB_POP);
break;
case EXPERIMENTER:
sb.append(STR_EXPERIMENTER + "=" + Long.toString(((OFActionExperimenter)a).getExperimenter()));
break;
case GROUP:
sb.append(STR_GROUP + "=" + Integer.toString(((OFActionGroup)a).getGroup().getGroupNumber()));
break;
case SET_FIELD:
log.debug("Got Set-Field action. Setting " + ((OFActionSetField)a));
/* ARP */
if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_OPCODE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString());
}
/* DATA LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_TYPE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN_PCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmVlanPcp) ((OFActionSetField) a).getField()).getValue().getValue()));
}
/* ICMP */
else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()));
}
/* NETWORK LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_PROTO + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { //TODO @Ryan ECN and DSCP need to have their own columns for OF1.3....
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_ECN + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DSCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()));
}
/* TRANSPORT LAYER, TCP, UDP, and SCTP */
else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
}
/* MPLS */
else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_LABEL + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_TC + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()));
} // MPLS_BOS not implemented in loxi
/* METADATA */
else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_METADATA + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()));
} else {
log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
}
break;
default:
log.error("Could not decode action: {}", a);
break;
}
}
return sb.toString();
}
* Returns a String representation of all the OpenFlow actions.
* @param actions; A list of OFActions to encode into one string
* @return A dpctl-style string of the actions
*/
@LogMessageDoc(level="ERROR",
message="Could not decode action {action}",
explanation="A static flow entry contained an invalid action",
recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
public static String actionsToString(List<OFAction> actions, Logger log) {
StringBuilder sb = new StringBuilder();
for (OFAction a : actions) {
if (sb.length() > 0) {
sb.append(',');
}
switch(a.getType()) {
case OUTPUT:
sb.append(STR_OUTPUT + "=" + Integer.toString(((OFActionOutput)a).getPort().getPortNumber()));
break;
case ENQUEUE:
long queue = ((OFActionEnqueue)a).getQueueId();
OFPort port = ((OFActionEnqueue)a).getPort();
sb.append(STR_ENQUEUE + "=" + Integer.toString(port.getPortNumber()) + ":0x" + String.format("%02x", queue));
break;
case STRIP_VLAN:
sb.append(STR_VLAN_STRIP);
break;
case POP_VLAN:
sb.append(STR_VLAN_POP);
break;
case PUSH_VLAN:
sb.append(STR_VLAN_PUSH + "=" + Integer.toString(((OFActionPushVlan)a).getEthertype().getValue()));
break;
case SET_VLAN_VID:
sb.append(STR_VLAN_SET_VID + "=" + Short.toString(((OFActionSetVlanVid)a).getVlanVid().getVlan()));
break;
case SET_VLAN_PCP:
sb.append(STR_VLAN_SET_PCP + "=" + Byte.toString(((OFActionSetVlanPcp)a).getVlanPcp().getValue()));
break;
case SET_QUEUE:
sb.append(STR_QUEUE_SET + "=" + Long.toString(((OFActionSetQueue)a).getQueueId()));
case SET_DL_SRC:
sb.append(STR_DL_SRC_SET + "=" + ((OFActionSetDlSrc)a).getDlAddr().toString());
break;
case SET_DL_DST:
sb.append(STR_DL_DST_SET + "=" + ((OFActionSetDlDst)a).getDlAddr().toString());
break;
case SET_NW_ECN:
sb.append(STR_NW_ECN_SET + "=" + Byte.toString(((OFActionSetNwEcn)a).getNwEcn().getEcnValue()));
break;
case SET_NW_TOS:
sb.append(STR_NW_TOS_SET + "=" + Short.toString(((OFActionSetNwTos)a).getNwTos()));
break;
case SET_NW_TTL:
sb.append(STR_NW_TTL_SET + "=" + Short.toString(((OFActionSetNwTtl)a).getNwTtl()));
break;
case DEC_NW_TTL:
sb.append(STR_NW_TTL_DEC);
break;
case SET_MPLS_LABEL:
sb.append(STR_MPLS_LABEL_SET + "=" + Long.toString(((OFActionSetMplsLabel)a).getMplsLabel()));
break;
case SET_MPLS_TC:
sb.append(STR_MPLS_TC_SET + "=" + Short.toString(((OFActionSetMplsTc)a).getMplsTc()));
break;
case SET_MPLS_TTL:
sb.append(STR_MPLS_TTL_SET + "=" + Short.toString(((OFActionSetMplsTtl)a).getMplsTtl()));
break;
case DEC_MPLS_TTL:
sb.append(STR_MPLS_TTL_DEC);
break;
case PUSH_MPLS:
sb.append(STR_MPLS_PUSH + "=" + Integer.toString(((OFActionPushMpls)a).getEthertype().getValue()));
break;
case POP_MPLS:
sb.append(STR_MPLS_POP + "=" + Integer.toString(((OFActionPopMpls)a).getEthertype().getValue()));
break;
case SET_NW_SRC:
sb.append(STR_NW_SRC_SET + "=" + ((OFActionSetNwSrc)a).getNwAddr().toString());
break;
case SET_NW_DST:
sb.append(STR_NW_DST_SET + "=" + ((OFActionSetNwDst)a).getNwAddr().toString());
break;
case SET_TP_SRC:
sb.append(STR_TP_SRC_SET + "=" + ((OFActionSetTpSrc)a).getTpPort().toString());
break;
case SET_TP_DST:
sb.append(STR_TP_DST_SET + "=" + ((OFActionSetTpDst)a).getTpPort().toString());
break;
case COPY_TTL_IN:
sb.append(STR_TTL_IN_COPY);
break;
case COPY_TTL_OUT:
sb.append(STR_TTL_OUT_COPY);
break;
case PUSH_PBB:
sb.append(STR_PBB_PUSH + "=" + Integer.toString(((OFActionPushPbb)a).getEthertype().getValue()));
break;
case POP_PBB:
sb.append(STR_PBB_POP);
break;
case EXPERIMENTER:
sb.append(STR_EXPERIMENTER + "=" + Long.toString(((OFActionExperimenter)a).getExperimenter()));
break;
case GROUP:
sb.append(STR_GROUP + "=" + Integer.toString(((OFActionGroup)a).getGroup().getGroupNumber()));
break;
case SET_FIELD:
log.debug("Got Set-Field action. Setting " + ((OFActionSetField)a));
/* ARP */
if (((OFActionSetField)a).getField() instanceof OFOxmArpOp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_OPCODE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmArpOp) ((OFActionSetField) a).getField()).getValue().getOpcode()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSha) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSha) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTha) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DHA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTha) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpSpa) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_SPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpSpa) ((OFActionSetField) a).getField()).getValue().toString()); // ipaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmArpTpa) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ARP_DPA + MatchUtils.SET_FIELD_DELIM + ((OFOxmArpTpa) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdSll) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_SSL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdSll) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTll) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_TTL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdTll) ((OFActionSetField) a).getField()).getValue().toString()); // macaddress formats string already
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6NdTarget) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_ND_TARGET + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6NdTarget) ((OFActionSetField) a).getField()).getValue().toString());
}
/* DATA LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmEthType) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_TYPE + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmEthType) ((OFActionSetField) a).getField()).getValue().getValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmEthSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthSrc) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmEthDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmEthDst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanVid) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmVlanVid) ((OFActionSetField) a).getField()).getValue().getVlan()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmVlanPcp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_DL_VLAN_PCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmVlanPcp) ((OFActionSetField) a).getField()).getValue().getValue()));
}
/* ICMP */
else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Code) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Code) ((OFActionSetField) a).getField()).getValue().getCode()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv4Type) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMP_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv4Type) ((OFActionSetField) a).getField()).getValue().getType()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Code) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMPV6_CODE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv6Code) ((OFActionSetField) a).getField()).getValue().getRaw()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIcmpv6Type) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_ICMPV6_TYPE + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIcmpv6Type) ((OFActionSetField) a).getField()).getValue().getRaw()));
}
/* NETWORK LAYER */
else if (((OFActionSetField)a).getField() instanceof OFOxmIpProto) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_PROTO + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmIpProto) ((OFActionSetField) a).getField()).getValue().getIpProtocolNumber()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Src) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Src) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv4Dst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv4Dst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Src) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_SRC + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Src) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Dst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_DST + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Dst) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpv6Flabel) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_IPV6_FLOW_LABEL + MatchUtils.SET_FIELD_DELIM + ((OFOxmIpv6Flabel) ((OFActionSetField) a).getField()).getValue().toString());
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpEcn) { //TODO @Ryan ECN and DSCP need to have their own columns for OF1.3....
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_ECN + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpEcn) ((OFActionSetField) a).getField()).getValue().getEcnValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmIpDscp) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_NW_DSCP + MatchUtils.SET_FIELD_DELIM + Byte.toString(((OFOxmIpDscp) ((OFActionSetField) a).getField()).getValue().getDscpValue()));
}
/* TRANSPORT LAYER, TCP, UDP, and SCTP */
else if (((OFActionSetField)a).getField() instanceof OFOxmTcpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmTcpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_TCP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmTcpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmUdpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_UDP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmUdpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpSrc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_SRC + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpSrc) ((OFActionSetField) a).getField()).getValue().getPort()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmSctpDst) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_SCTP_DST + MatchUtils.SET_FIELD_DELIM + Integer.toString(((OFOxmSctpDst) ((OFActionSetField) a).getField()).getValue().getPort()));
}
/* MPLS */
else if (((OFActionSetField)a).getField() instanceof OFOxmMplsLabel) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_LABEL + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMplsLabel) ((OFActionSetField) a).getField()).getValue().getValue()));
} else if (((OFActionSetField)a).getField() instanceof OFOxmMplsTc) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_MPLS_TC + MatchUtils.SET_FIELD_DELIM + Short.toString(((OFOxmMplsTc) ((OFActionSetField) a).getField()).getValue().getValue()));
} // MPLS_BOS not implemented in loxi
/* METADATA */
else if (((OFActionSetField)a).getField() instanceof OFOxmMetadata) {
sb.append(STR_FIELD_SET + "=" + MatchUtils.STR_METADATA + MatchUtils.SET_FIELD_DELIM + Long.toString(((OFOxmMetadata) ((OFActionSetField) a).getField()).getValue().getValue().getValue()));
} else {
log.error("Could not decode Set-Field action field: {}", ((OFActionSetField) a));
}
break;
default:
log.error("Could not decode action: {}", a);
break;
}
}
return sb.toString();
}
/**
* Parses OFFlowMod actions from strings.
* @param fmb The OFFlowMod.Builder to set the actions for
......@@ -335,7 +361,7 @@ public class ActionUtils {
if (bigString != null) {
bigString = bigString.toLowerCase();
String[] bigStringSplit = bigString.split(","); // split into separate action=value or action=key@value pairs
String[] tmp;
ArrayDeque<String[]> actionToDecode = new ArrayDeque<String[]>();
for (int i = 0; i < bigStringSplit.length; i++) {
......@@ -345,7 +371,7 @@ public class ActionUtils {
}
actionToDecode.add(tmp); // actionToDecode contains [key, value] pairs. Create a queue of pairs to process.
}
while (!actionToDecode.isEmpty()) {
String[] keyPair = actionToDecode.pollFirst();
String key;
......@@ -358,9 +384,9 @@ public class ActionUtils {
key = keyPair[0];
pair = keyPair[1];
}
OFAction a = null;
switch (key) {
case STR_OUTPUT:
a = decode_output(pair, fmb.getVersion(), log);
......@@ -415,6 +441,25 @@ public class ActionUtils {
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildArpTpa().setValue(IPv4Address.of(actionData[1])).build())
.build();
break;
//sanjivini
case MatchUtils.STR_IPV6_ND_SSL:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdSll().setValue(MacAddress.of(actionData[1])).build())
.build();
break;
case MatchUtils.STR_IPV6_ND_TTL:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdTll().setValue(MacAddress.of(actionData[1])).build())
.build();
break;
case MatchUtils.STR_IPV6_ND_TARGET:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6NdTarget().setValue(IPv6Address.of(actionData[1])).build())
.build();
break;
//sanjivini
case MatchUtils.STR_DL_TYPE:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
......@@ -477,9 +522,35 @@ public class ActionUtils {
} else {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv4Type().setValue(ICMPv4Type.of(Short.parseShort(actionData[1]))).build())
.build();
.build();
}
break;
//sanjivini
case MatchUtils.STR_ICMPV6_CODE:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Code().setValue(U8.of(Short.parseShort(actionData[1].replaceFirst("0x", ""), 16))).build())
.build();
} else {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Code().setValue(U8.of(Short.parseShort(actionData[1]))).build())
.build();
}
break;
case MatchUtils.STR_ICMPV6_TYPE:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Type().setValue(U8.of(Short.parseShort(actionData[1].replaceFirst("0x", ""), 16))).build())
.build();
} else {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIcmpv6Type().setValue(U8.of(Short.parseShort(actionData[1]))).build())
.build();
}
break;
//sanjivini
case MatchUtils.STR_NW_PROTO:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
......@@ -501,6 +572,31 @@ public class ActionUtils {
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv4Dst().setValue(IPv4Address.of(actionData[1])).build())
.build();
break;
//sanjivini
case MatchUtils.STR_IPV6_SRC:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Src().setValue(IPv6Address.of(actionData[1])).build())
.build();
break;
case MatchUtils.STR_IPV6_DST:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Dst().setValue(IPv6Address.of(actionData[1])).build())
.build();
break;
case MatchUtils.STR_IPV6_FLOW_LABEL:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Flabel().setValue(IPv6FlowLabel.of(Integer.parseInt(actionData[1].replaceFirst("0x", ""), 16))).build())
.build();
} else {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildIpv6Flabel().setValue(IPv6FlowLabel.of(Integer.parseInt(actionData[1]))).build())
.build();
}
break;
//sanjivini
case MatchUtils.STR_NW_ECN:
if (actionData[1].startsWith("0x")) {
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
......@@ -577,8 +673,8 @@ public class ActionUtils {
break;
case MatchUtils.STR_MPLS_BOS:
a = OFFactories.getFactory(fmb.getVersion()).actions().buildSetField()
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildMplsBos().setValue(OFBooleanValue.of(Boolean.parseBoolean(actionData[1]))).build()) // interprets anything other than "true" as false
.build();
.setField(OFFactories.getFactory(fmb.getVersion()).oxms().buildMplsBos().setValue(OFBooleanValue.of(Boolean.parseBoolean(actionData[1]))).build()) // interprets anything other than "true" as false
.build();
break;
case MatchUtils.STR_METADATA:
if (actionData[1].startsWith("0x")) {
......@@ -967,7 +1063,7 @@ public class ActionUtils {
}
return null;
}
/**
* Parse set_dl_dst actions.
* The key and delimiter for the action should be omitted, and only the
......
......@@ -28,7 +28,7 @@ import sun.reflect.generics.reflectiveObjects.NotImplementedException;
*
*/
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_ACTIONS = "instruction_write_actions";
public static final String STR_APPLY_ACTIONS = "instruction_apply_actions";
......@@ -169,7 +169,7 @@ public class InstructionUtils {
* @param log
* @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);
}
......@@ -200,7 +200,7 @@ public class InstructionUtils {
* @param log
* @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);
}
......
......@@ -13,6 +13,9 @@ import org.projectfloodlight.openflow.types.ICMPv4Code;
import org.projectfloodlight.openflow.types.ICMPv4Type;
import org.projectfloodlight.openflow.types.IPv4Address;
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.IpEcn;
import org.projectfloodlight.openflow.types.IpProtocol;
......@@ -330,6 +333,9 @@ public class MatchUtils {
* on unexpected key or value
*/
public static Match fromString(String match, OFVersion ofVersion) throws IllegalArgumentException {
boolean ver10 = false;
if (match.equals("") || match.equalsIgnoreCase("any") || match.equalsIgnoreCase("all") || match.equals("[]")) {
match = "Match[]";
}
......@@ -356,6 +362,14 @@ public class MatchUtils {
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()) {
IpProtocol ipProto = null;
String[] key_value = llValues.pollFirst(); // pop off the first element; this completely removes it from the queue.
......@@ -396,6 +410,28 @@ public class MatchUtils {
case STR_NW_SRC:
mb.setMasked(MatchField.IPV4_SRC, IPv4AddressWithMask.of(key_value[1]));
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:
if (key_value[1].startsWith("0x")) {
mb.setExact(MatchField.IP_PROTO, IpProtocol.of(Short.valueOf(key_value[1].replaceFirst("0x", ""), 16)));
......@@ -504,6 +540,45 @@ public class MatchUtils {
mb.setExact(MatchField.ICMPV4_CODE, ICMPv4Code.of(Short.parseShort(key_value[1])));
}
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:
if (key_value[1].startsWith("0x")) {
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