Support double-tagged host
Change-Id: Ie4041a0b5159e7a8b3a9ed82b55ce3c26b520a3b
diff --git a/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
index b430020..ec0d9b5 100644
--- a/core/api/src/main/java/org/onosproject/net/DefaultHost.java
+++ b/core/api/src/main/java/org/onosproject/net/DefaultHost.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.net;
+import org.onlab.packet.EthType;
import org.onosproject.net.provider.ProviderId;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
@@ -37,8 +38,11 @@
private final VlanId vlan;
private final Set<HostLocation> locations;
private final Set<IpAddress> ips;
+ private final VlanId innerVlan;
+ private final EthType tpid;
private final boolean configured;
+ // TODO consider moving this constructor to a builder pattern.
/**
* Creates an end-station host using the supplied information.
*
@@ -78,24 +82,47 @@
/**
* Creates an end-station host using the supplied information.
*
- * @param providerId provider identity
- * @param id host identifier
- * @param mac host MAC address
- * @param vlan host VLAN identifier
- * @param locations set of host locations
- * @param ips host IP addresses
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param locations set of host locations
+ * @param ips host IP addresses
* @param configured true if configured via NetworkConfiguration
* @param annotations optional key/value annotations
*/
public DefaultHost(ProviderId providerId, HostId id, MacAddress mac,
VlanId vlan, Set<HostLocation> locations, Set<IpAddress> ips,
boolean configured, Annotations... annotations) {
+ this(providerId, id, mac, vlan, locations, ips, VlanId.NONE,
+ EthType.EtherType.UNKNOWN.ethType(), configured, annotations);
+ }
+
+ /**
+ * Creates an end-station host using the supplied information.
+ *
+ * @param providerId provider identity
+ * @param id host identifier
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param locations set of host locations
+ * @param ips host IP addresses
+ * @param innerVlan host inner VLAN identifier
+ * @param tpid outer TPID of a host
+ * @param configured true if configured via NetworkConfiguration
+ * @param annotations optional key/value annotations
+ */
+ public DefaultHost(ProviderId providerId, HostId id, MacAddress mac, VlanId vlan,
+ Set<HostLocation> locations, Set<IpAddress> ips, VlanId innerVlan,
+ EthType tpid, boolean configured, Annotations... annotations) {
super(providerId, id, annotations);
this.mac = mac;
this.vlan = vlan;
this.locations = new HashSet<>(locations);
this.ips = new HashSet<>(ips);
this.configured = configured;
+ this.innerVlan = innerVlan;
+ this.tpid = tpid;
}
@Override
@@ -135,6 +162,16 @@
}
@Override
+ public VlanId innerVlan() {
+ return innerVlan;
+ }
+
+ @Override
+ public EthType tpid() {
+ return tpid;
+ }
+
+ @Override
public boolean configured() {
return configured;
}
@@ -156,6 +193,8 @@
Objects.equals(this.vlan, other.vlan) &&
Objects.equals(this.locations, other.locations) &&
Objects.equals(this.ipAddresses(), other.ipAddresses()) &&
+ Objects.equals(this.innerVlan, other.innerVlan) &&
+ Objects.equals(this.tpid, other.tpid) &&
Objects.equals(this.annotations(), other.annotations());
}
return false;
@@ -171,6 +210,8 @@
.add("ipAddresses", ipAddresses())
.add("annotations", annotations())
.add("configured", configured())
+ .add("innerVlanId", innerVlan())
+ .add("outerTPID", tpid())
.toString();
}
diff --git a/core/api/src/main/java/org/onosproject/net/Host.java b/core/api/src/main/java/org/onosproject/net/Host.java
index b47f843..1c2e50a 100644
--- a/core/api/src/main/java/org/onosproject/net/Host.java
+++ b/core/api/src/main/java/org/onosproject/net/Host.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.net;
+import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
@@ -77,6 +78,24 @@
default boolean configured() {
return false;
}
+
+ /**
+ * Returns the inner VLAN ID tied to this host.
+ *
+ * @return VLAN ID value; VlanId.NONE if only one VLAN ID is tied to this host
+ */
+ default VlanId innerVlan() {
+ return VlanId.NONE;
+ }
+
+ /**
+ * Returns the TPID of the outermost VLAN associated with this host.
+ *
+ * @return TPID of the outermost VLAN header
+ */
+ default EthType tpid() {
+ return EthType.EtherType.UNKNOWN.ethType();
+ }
// TODO: explore capturing list of recent locations to aid in mobility
}
diff --git a/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java b/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
index 3879257..17abc53 100644
--- a/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/config/basics/BasicHostConfig.java
@@ -17,7 +17,9 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
@@ -25,6 +27,8 @@
import java.util.HashSet;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
* Basic configuration for network end-station hosts.
*/
@@ -32,16 +36,29 @@
private static final String IPS = "ips";
private static final String LOCATIONS = "locations";
+ private static final String INNER_VLAN = "innerVlan";
+ private static final String OUTER_TPID = "outerTpid";
private static final String DASH = "-";
@Override
public boolean isValid() {
// locations is mandatory and must have at least one
// ipAddresses can be absent, but if present must be valid
+ // innerVlan: 0 < innerVlan < VlanId.MAX_VLAN, if present
+ // outerTpid: either 0x8100 or 0x88a8, if present
+ if (!isIntegralNumber(object, INNER_VLAN, FieldPresence.OPTIONAL, 0, VlanId.MAX_VLAN)) {
+ return false;
+ }
+ checkArgument(!hasField(object, OUTER_TPID) ||
+ (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
+ EthType.EtherType.QINQ.ethType().toShort() ||
+ (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF) ==
+ EthType.EtherType.VLAN.ethType().toShort());
this.locations();
this.ipAddresses();
- return hasOnlyFields(ALLOWED, NAME, LOC_TYPE, LATITUDE, LONGITUDE, ROLES,
- GRID_X, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS);
+ return hasOnlyFields(ALLOWED, NAME, LOC_TYPE, LATITUDE, LONGITUDE,
+ GRID_Y, GRID_Y, UI_TYPE, RACK_ADDRESS, OWNER, IPS, LOCATIONS,
+ INNER_VLAN, OUTER_TPID);
}
@Override
@@ -119,4 +136,26 @@
public BasicHostConfig setIps(Set<IpAddress> ipAddresses) {
return (BasicHostConfig) setOrClear(IPS, ipAddresses);
}
-}
\ No newline at end of file
+
+ public VlanId innerVlan() {
+ String vlan = get(INNER_VLAN, null);
+ return vlan == null ? VlanId.NONE : VlanId.vlanId(Short.valueOf(vlan));
+ }
+
+ public BasicHostConfig setInnerVlan(VlanId vlanId) {
+ return (BasicHostConfig) setOrClear(INNER_VLAN, vlanId.toString());
+ }
+
+ public EthType outerTpid() {
+ short tpid = (short) (Integer.decode(get(OUTER_TPID, "0")) & 0xFFFF);
+ if (!(tpid == EthType.EtherType.VLAN.ethType().toShort() ||
+ tpid == EthType.EtherType.QINQ.ethType().toShort())) {
+ return EthType.EtherType.UNKNOWN.ethType();
+ }
+ return EthType.EtherType.lookup(tpid).ethType();
+ }
+
+ public BasicHostConfig setOuterTpid(EthType tpid) {
+ return (BasicHostConfig) setOrClear(OUTER_TPID, String.format("0x%04X", tpid.toShort()));
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java b/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
index e063c95..1992283 100644
--- a/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
@@ -20,6 +20,7 @@
import java.util.HashSet;
import java.util.Set;
+import org.onlab.packet.EthType;
import org.onosproject.net.AbstractDescription;
import org.onosproject.net.HostLocation;
import org.onosproject.net.SparseAnnotations;
@@ -42,6 +43,8 @@
private final VlanId vlan;
private final Set<HostLocation> locations;
private final Set<IpAddress> ip;
+ private final VlanId innerVlan;
+ private final EthType tpid;
private final boolean configured;
/**
@@ -135,11 +138,32 @@
Set<HostLocation> locations,
Set<IpAddress> ip, boolean configured,
SparseAnnotations... annotations) {
+ this(mac, vlan, locations, ip, VlanId.NONE, EthType.EtherType.UNKNOWN.ethType(),
+ configured, annotations);
+ }
+
+ /**
+ * Creates a host description using the supplied information.
+ *
+ * @param mac host MAC address
+ * @param vlan host VLAN identifier
+ * @param locations host locations
+ * @param ip host IP address
+ * @param innerVlan host inner VLAN identifier
+ * @param tpid outer TPID of a host
+ * @param configured true if configured via NetworkConfiguration
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultHostDescription(MacAddress mac, VlanId vlan, Set<HostLocation> locations,
+ Set<IpAddress> ip, VlanId innerVlan, EthType tpid,
+ boolean configured, SparseAnnotations... annotations) {
super(annotations);
this.mac = mac;
this.vlan = vlan;
this.locations = new HashSet<>(locations);
this.ip = new HashSet<>(ip);
+ this.innerVlan = innerVlan;
+ this.tpid = tpid;
this.configured = configured;
}
@@ -176,6 +200,16 @@
}
@Override
+ public VlanId innerVlan() {
+ return innerVlan;
+ }
+
+ @Override
+ public EthType tpid() {
+ return tpid;
+ }
+
+ @Override
public String toString() {
return toStringHelper(this)
.add("mac", mac)
@@ -183,6 +217,8 @@
.add("locations", locations)
.add("ipAddress", ip)
.add("configured", configured)
+ .add("innerVlanId", innerVlan)
+ .add("outerTPID", tpid)
.toString();
}
@@ -201,7 +237,9 @@
return Objects.equal(this.mac, that.mac)
&& Objects.equal(this.vlan, that.vlan)
&& Objects.equal(this.locations, that.locations)
- && Objects.equal(this.ip, that.ip);
+ && Objects.equal(this.ip, that.ip)
+ && Objects.equal(this.innerVlan, that.innerVlan)
+ && Objects.equal(this.tpid, that.tpid);
}
return false;
}
diff --git a/core/api/src/main/java/org/onosproject/net/host/HostDescription.java b/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
index 7994599..543836e 100644
--- a/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/host/HostDescription.java
@@ -22,6 +22,7 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+import org.onlab.packet.EthType;
/**
* Information describing host and its location.
@@ -43,6 +44,24 @@
VlanId vlan();
/**
+ * Returns the inner VLAN associated with this host.
+ *
+ * @return VLAN ID value; VlanId.NONE if only one VLAN ID is associated with this host
+ */
+ default VlanId innerVlan() {
+ return VlanId.NONE;
+ }
+
+ /**
+ * Returns the TPID of the outermost VLAN associated with this host.
+ *
+ * @return TPID of the outermost VLAN header
+ */
+ default EthType tpid() {
+ return EthType.EtherType.UNKNOWN.ethType();
+ }
+
+ /**
* Returns the most recent location of the host on the network edge.
*
* @return the most recent host location