lishuai
Committed by Gerrit Code Review

[ONOS-3499] Add the set treatments of ARP_SPA, ARP_SHA and ARP_OP.

Change-Id: I7e1927bcf26e7c25fede43aa864a1b71ae2e8b49
......@@ -489,6 +489,21 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
@Override
public Builder setArpSpa(IpAddress addr) {
return add(Instructions.modArpSpa(addr));
}
@Override
public Builder setArpSha(MacAddress addr) {
return add(Instructions.modArpSha(addr));
}
@Override
public Builder setArpOp(short op) {
return add(Instructions.modL3ArpOp(op));
}
@Override
public TrafficTreatment.Builder extension(ExtensionTreatment extension,
DeviceId deviceId) {
return add(Instructions.extension(extension, deviceId));
......
......@@ -424,6 +424,30 @@ public interface TrafficTreatment {
Builder setUdpDst(TpPort port);
/**
* Sets the arp src ip address.
*
* @param addr an ip
* @return a treatment builder
*/
Builder setArpSpa(IpAddress addr);
/**
* Sets the arp src mac address.
*
* @param addr a macaddress
* @return a treatment builder
*/
Builder setArpSha(MacAddress addr);
/**
* Sets the arp operation.
*
* @param op the value of arp operation.
* @return a treatment builder.
*/
Builder setArpOp(short op);
/**
* Uses an extension treatment.
*
* @param extension extension treatment
......
......@@ -35,6 +35,9 @@ import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSig
import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType;
......@@ -299,6 +302,39 @@ public final class Instructions {
}
/**
* Creates a L3 ARP IP src modification.
*
* @param addr the ip address to modify to
* @return a L3 modification
*/
public static L3ModificationInstruction modArpSpa(IpAddress addr) {
checkNotNull(addr, "Src l3 ARP IP address cannot be null");
return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
}
/**
* Creates a l3 ARP Ether src modification.
*
* @param addr the mac address to modify to
* @return a l3 modification
*/
public static L3ModificationInstruction modArpSha(MacAddress addr) {
checkNotNull(addr, "Src l3 ARP address cannot be null");
return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
}
/**
* Creates a l3 ARP operation modification.
*
* @param op the ARP operation to modify to
* @return a l3 modification
*/
public static L3ModificationInstruction modL3ArpOp(short op) {
checkNotNull(op, "Arp operation cannot be null");
return new ModArpOpInstruction(L3SubType.ARP_OP, op);
}
/**
* Creates a push MPLS header instruction.
*
* @return a L2 modification.
......
......@@ -20,6 +20,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
import java.util.Objects;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
/**
* Abstraction of a single traffic treatment step.
......@@ -68,7 +69,22 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Copy TTL in.
*/
TTL_IN
TTL_IN,
/**
* ARP IP src modification.
*/
ARP_SPA,
/**
* ARP Ether src modification.
*/
ARP_SHA,
/**
* Arp operation modification.
*/
ARP_OP
//TODO: remaining types
}
......@@ -133,6 +149,150 @@ public abstract class L3ModificationInstruction implements Instruction {
}
/**
* Represents a L3 ARP IP src/dst modification instruction.
*/
public static final class ModArpIPInstruction extends L3ModificationInstruction {
private final L3SubType subtype;
private final IpAddress ip;
ModArpIPInstruction(L3SubType subType, IpAddress addr) {
this.subtype = subType;
this.ip = addr;
}
@Override
public L3SubType subtype() {
return this.subtype;
}
public IpAddress ip() {
return this.ip;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("ip", ip).toString();
}
@Override
public int hashCode() {
return Objects.hash(type(), subtype(), ip);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ModArpIPInstruction) {
ModArpIPInstruction that = (ModArpIPInstruction) obj;
return Objects.equals(ip, that.ip) &&
Objects.equals(this.subtype(), that.subtype());
}
return false;
}
}
/**
* Represents a L3 ARP Ether src/dst modification instruction.
*/
public static final class ModArpEthInstruction extends L3ModificationInstruction {
private final L3SubType subtype;
private final MacAddress mac;
ModArpEthInstruction(L3SubType subType, MacAddress addr) {
this.subtype = subType;
this.mac = addr;
}
@Override
public L3SubType subtype() {
return this.subtype;
}
public MacAddress mac() {
return this.mac;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("mac", mac).toString();
}
@Override
public int hashCode() {
return Objects.hash(type(), subtype(), mac);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ModArpEthInstruction) {
ModArpEthInstruction that = (ModArpEthInstruction) obj;
return Objects.equals(mac, that.mac) &&
Objects.equals(this.subtype(), that.subtype());
}
return false;
}
}
/**
* Represents a L3 ARP operation modification instruction.
*/
public static final class ModArpOpInstruction extends L3ModificationInstruction {
private final L3SubType subtype;
private final short op;
ModArpOpInstruction(L3SubType subType, short op) {
this.subtype = subType;
this.op = op;
}
@Override
public L3SubType subtype() {
return this.subtype;
}
public long op() {
return this.op;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("op", op).toString();
}
@Override
public int hashCode() {
return Objects.hash(type(), subtype(), op);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ModArpOpInstruction) {
ModArpOpInstruction that = (ModArpOpInstruction) obj;
return Objects.equals(op, that.op) &&
Objects.equals(this.subtype(), that.subtype());
}
return false;
}
}
/**
* Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction
* (20 bits unsigned integer).
*/
......
......@@ -45,6 +45,9 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPc
import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
......@@ -61,6 +64,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.types.ArpOpcode;
import org.projectfloodlight.openflow.types.CircuitSignalID;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
......@@ -430,6 +434,19 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
int flowLabel = flowLabelInstruction.flowLabel();
oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
break;
case ARP_SPA:
ModArpIPInstruction aip = (ModArpIPInstruction) i;
ip4 = aip.ip().getIp4Address();
oxm = factory().oxms().arpSpa(IPv4Address.of(ip4.toInt()));
break;
case ARP_SHA:
ModArpEthInstruction ei = (ModArpEthInstruction) i;
oxm = factory().oxms().arpSha(MacAddress.of(ei.mac().toLong()));
break;
case ARP_OP:
ModArpOpInstruction oi = (ModArpOpInstruction) i;
oxm = factory().oxms().arpOp(ArpOpcode.of((int) oi.op()));
break;
case DEC_TTL:
return factory().actions().decNwTtl();
case TTL_IN:
......