diff --git a/cli/src/main/java/org/onosproject/cli/net/HostsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/HostsListCommand.java index fa125f7b94..683ab26160 100644 --- a/cli/src/main/java/org/onosproject/cli/net/HostsListCommand.java +++ b/cli/src/main/java/org/onosproject/cli/net/HostsListCommand.java @@ -38,7 +38,8 @@ import static com.google.common.collect.Lists.newArrayList; public class HostsListCommand extends AbstractShellCommand { private static final String FMT = - "id=%s, mac=%s, locations=%s, vlan=%s, ip(s)=%s%s, provider=%s:%s, configured=%s"; + "id=%s, mac=%s, locations=%s, vlan=%s, ip(s)=%s%s, innerVlan=%s, outerTPID=%s, " + + "provider=%s:%s, configured=%s"; private static final String FMT_SHORT = "id=%s, mac=%s, locations=%s, vlan=%s, ip(s)=%s"; @@ -94,6 +95,7 @@ public class HostsListCommand extends AbstractShellCommand { print(FMT, host.id(), host.mac(), host.locations(), host.vlan(), host.ipAddresses(), annotations(host.annotations()), + host.innerVlan(), host.tpid().toString(), host.providerId().scheme(), host.providerId().id(), host.configured()); } 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 b430020840..ec0d9b5602 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 @@ public class DefaultHost extends AbstractElement implements Host { private final VlanId vlan; private final Set locations; private final Set 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 @@ public class DefaultHost extends AbstractElement implements Host { /** * 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 locations, Set 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 locations, Set 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 @@ -134,6 +161,16 @@ public class DefaultHost extends AbstractElement implements Host { return vlan; } + @Override + public VlanId innerVlan() { + return innerVlan; + } + + @Override + public EthType tpid() { + return tpid; + } + @Override public boolean configured() { return configured; @@ -156,6 +193,8 @@ public class DefaultHost extends AbstractElement implements Host { 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 @@ public class DefaultHost extends AbstractElement implements Host { .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 b47f843e53..1c2e50ad0c 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 @@ public interface Host extends Element { 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 38792570f9..17abc53e0f 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 @@ package org.onosproject.net.config.basics; 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 org.onosproject.net.HostLocation; 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 @@ public final class BasicHostConfig extends BasicElementConfig { 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 final class BasicHostConfig extends BasicElementConfig { public BasicHostConfig setIps(Set 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 e063c95265..19922839ee 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.Comparator; 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 @@ public class DefaultHostDescription extends AbstractDescription private final VlanId vlan; private final Set locations; private final Set ip; + private final VlanId innerVlan; + private final EthType tpid; private final boolean configured; /** @@ -135,11 +138,32 @@ public class DefaultHostDescription extends AbstractDescription Set locations, Set 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 locations, + Set 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; } @@ -175,6 +199,16 @@ public class DefaultHostDescription extends AbstractDescription return configured; } + @Override + public VlanId innerVlan() { + return innerVlan; + } + + @Override + public EthType tpid() { + return tpid; + } + @Override public String toString() { return toStringHelper(this) @@ -183,6 +217,8 @@ public class DefaultHostDescription extends AbstractDescription .add("locations", locations) .add("ipAddress", ip) .add("configured", configured) + .add("innerVlanId", innerVlan) + .add("outerTPID", tpid) .toString(); } @@ -201,7 +237,9 @@ public class DefaultHostDescription extends AbstractDescription 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 7994599406..543836e5bf 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.onosproject.net.HostLocation; 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. @@ -42,6 +43,24 @@ public interface HostDescription extends Description { */ 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. * diff --git a/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java b/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java index 6721cc74be..dab2c9dc65 100644 --- a/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java +++ b/core/api/src/test/java/org/onosproject/net/config/basics/BasicHostConfigTest.java @@ -20,7 +20,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.google.common.collect.ImmutableSet; import org.junit.Test; +import org.onlab.packet.EthType; import org.onlab.packet.IpAddress; +import org.onlab.packet.VlanId; import org.onosproject.net.HostId; import org.onosproject.net.HostLocation; import org.onosproject.net.NetTestTools; @@ -36,7 +38,7 @@ import static org.hamcrest.Matchers.is; public class BasicHostConfigTest { /** - * Tests construction, setters and getters of a BasicLinkConfig object. + * Tests construction, setters and getters of a BasicHostConfig object. */ @Test public void testConstruction() { @@ -53,11 +55,15 @@ public class BasicHostConfigTest { HostLocation loc2 = new HostLocation( NetTestTools.connectPoint("d2", 2), System.currentTimeMillis()); Set locs = ImmutableSet.of(loc1, loc2); + VlanId vlanId = VlanId.vlanId((short) 10); + EthType ethType = EthType.EtherType.lookup((short) 0x88a8).ethType(); config.init(hostId, "KEY", JsonNodeFactory.instance.objectNode(), mapper, delegate); config.setIps(ips) - .setLocations(locs); + .setLocations(locs) + .setInnerVlan(vlanId) + .setOuterTpid(ethType); assertThat(config.isValid(), is(true)); assertThat(config.name(), is("-")); @@ -65,6 +71,8 @@ public class BasicHostConfigTest { assertThat(config.ipAddresses(), hasItems(ip1, ip2, ip3)); assertThat(config.locations(), hasSize(2)); assertThat(config.locations(), hasItems(loc1, loc2)); + assertThat(config.innerVlan(), is(vlanId)); + assertThat(config.outerTpid(), is(ethType)); } } \ No newline at end of file diff --git a/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java index b82be46901..5f8ca9d6a1 100644 --- a/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java +++ b/core/common/src/main/java/org/onosproject/codec/impl/HostCodec.java @@ -40,6 +40,8 @@ public final class HostCodec extends AnnotatedCodec { .put("id", host.id().toString()) .put("mac", host.mac().toString()) .put("vlan", host.vlan().toString()) + .put("innerVlan", host.innerVlan().toString()) + .put("outerTpid", host.tpid().toString()) .put("configured", host.configured()); final ArrayNode jsonIpAddresses = result.putArray("ipAddresses"); diff --git a/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java b/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java index 976e324eec..b19673703b 100644 --- a/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java +++ b/core/net/src/main/java/org/onosproject/net/host/impl/BasicHostOperator.java @@ -69,8 +69,8 @@ public final class BasicHostOperator extends BasicElementOperator { SparseAnnotations sa = combine(cfg, descr.annotations()); return new DefaultHostDescription(descr.hwAddress(), descr.vlan(), - locations, ipAddresses, - descr.configured(), sa); + locations, ipAddresses, descr.innerVlan(), + descr.tpid(), descr.configured(), sa); } /** diff --git a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java index bc7f197602..8dc1613c96 100644 --- a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java +++ b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java @@ -218,6 +218,8 @@ public class DistributedHostStore if (!Objects.equals(existingHost.providerId(), providerId) || !Objects.equals(existingHost.mac(), hostDescription.hwAddress()) || !Objects.equals(existingHost.vlan(), hostDescription.vlan()) || + !Objects.equals(existingHost.innerVlan(), hostDescription.innerVlan()) || + !Objects.equals(existingHost.tpid(), hostDescription.tpid()) || !Objects.equals(existingHost.locations(), hostDescription.locations())) { return true; } @@ -275,6 +277,8 @@ public class DistributedHostStore hostDescription.vlan(), hostDescription.locations(), addresses, + hostDescription.innerVlan(), + hostDescription.tpid(), hostDescription.configured(), annotations); }); diff --git a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java index 0633d12f37..45ed92de4c 100644 --- a/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java +++ b/providers/host/src/main/java/org/onosproject/provider/host/impl/HostLocationProvider.java @@ -28,6 +28,7 @@ import org.onlab.packet.ARP; import org.onlab.packet.BasePacket; import org.onlab.packet.DHCP; import org.onlab.packet.DHCP6; +import org.onlab.packet.EthType; import org.onlab.packet.Ethernet; import org.onlab.packet.ICMP6; import org.onlab.packet.IPacket; @@ -441,15 +442,17 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid * Create or update host information. * Will not update IP if IP is null, all zero or self-assigned. * - * @param hid host ID - * @param mac source Mac address - * @param vlan VLAN ID - * @param hloc host location - * @param ip source IP address or null if not updating + * @param hid host ID + * @param mac source Mac address + * @param vlan VLAN ID + * @param innerVlan inner VLAN ID + * @param outerTpid outer TPID + * @param hloc host location + * @param ip source IP address or null if not updating */ - private void createOrUpdateHost(HostId hid, MacAddress mac, - VlanId vlan, HostLocation hloc, - IpAddress ip) { + private void createOrUpdateHost(HostId hid, MacAddress mac, VlanId vlan, + VlanId innerVlan, EthType outerTpid, + HostLocation hloc, IpAddress ip) { Set newLocations = Sets.newHashSet(hloc); if (multihomingEnabled) { @@ -473,8 +476,10 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid } HostDescription desc = ip == null || ip.isZero() || ip.isSelfAssigned() ? - new DefaultHostDescription(mac, vlan, newLocations, Sets.newHashSet(), false) : - new DefaultHostDescription(mac, vlan, newLocations, Sets.newHashSet(ip), false); + new DefaultHostDescription(mac, vlan, newLocations, Sets.newHashSet(), + innerVlan, outerTpid, false) : + new DefaultHostDescription(mac, vlan, newLocations, Sets.newHashSet(ip), + innerVlan, outerTpid, false); try { providerService.hostDetected(hid, desc, false); } catch (IllegalStateException e) { @@ -521,6 +526,15 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid } VlanId vlan = VlanId.vlanId(eth.getVlanID()); + VlanId outerVlan = VlanId.vlanId(eth.getQinQVID()); + VlanId innerVlan = VlanId.NONE; + EthType outerTpid = EthType.EtherType.UNKNOWN.ethType(); + // Set up values for double-tagged hosts + if (outerVlan.toShort() != Ethernet.VLAN_UNTAGGED) { + innerVlan = vlan; + vlan = outerVlan; + outerTpid = EthType.EtherType.lookup(eth.getQinQTPID()).ethType(); + } ConnectPoint heardOn = context.inPacket().receivedFrom(); // If this arrived on control port, bail out. @@ -550,12 +564,12 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid ARP arp = (ARP) eth.getPayload(); IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, arp.getSenderProtocolAddress()); - createOrUpdateHost(hid, srcMac, vlan, hloc, ip); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, ip); // IPv4: update location only } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) { // Update host location - createOrUpdateHost(hid, srcMac, vlan, hloc, null); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, null); if (useDhcp) { DHCP dhcp = findDhcp(eth).orElse(null); // DHCP ACK: additionally update IP of DHCP client @@ -586,7 +600,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid // DHCPv6 protocol DHCP6 dhcp6 = findDhcp6(pkt).orElse(null); if (dhcp6 != null && useDhcp6) { - createOrUpdateHost(hid, srcMac, vlan, hloc, null); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, null); handleDhcp6(dhcp6, vlan); return; } @@ -605,13 +619,13 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid return; } // NeighborSolicitation, NeighborAdvertisement - createOrUpdateHost(hid, srcMac, vlan, hloc, ip); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, ip); // Also learn from the target address of NeighborAdvertisement if (pkt instanceof NeighborAdvertisement) { NeighborAdvertisement na = (NeighborAdvertisement) pkt; Ip6Address targetAddr = Ip6Address.valueOf(na.getTargetAddress()); - createOrUpdateHost(hid, srcMac, vlan, hloc, targetAddr); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, targetAddr); } return; } @@ -624,7 +638,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid } // normal IPv6 packets - createOrUpdateHost(hid, srcMac, vlan, hloc, null); + createOrUpdateHost(hid, srcMac, vlan, innerVlan, outerTpid, hloc, null); } } diff --git a/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java b/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java index 42278d3c78..a0be2d9f00 100644 --- a/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java +++ b/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java @@ -21,6 +21,7 @@ import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.packet.EthType; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; @@ -119,6 +120,28 @@ public class NetworkConfigHostProvider extends AbstractProvider implements HostP providerService.hostDetected(hid, desc, true); } + /** + * Adds host information. + * IP information will be appended if host exists. + * + * @param mac MAC address of the host + * @param vlan VLAN ID of the host + * @param locations Location of the host + * @param ips Set of IP addresses of the host + * @param innerVlan host inner VLAN identifier + * @param outerTpid outer TPID of a host + */ + protected void addHost(MacAddress mac, VlanId vlan, Set locations, Set ips, + VlanId innerVlan, EthType outerTpid) { + HostId hid = HostId.hostId(mac, vlan); + HostDescription desc = (ips != null) ? + new DefaultHostDescription(mac, vlan, locations, ips, + innerVlan, outerTpid, true) : + new DefaultHostDescription(mac, vlan, locations, Collections.emptySet(), + innerVlan, outerTpid, true); + providerService.hostDetected(hid, desc, true); + } + /** * Updates host information. * IP information will be replaced if host exists. @@ -134,6 +157,25 @@ public class NetworkConfigHostProvider extends AbstractProvider implements HostP providerService.hostDetected(hid, desc, true); } + /** + * Updates host information. + * IP information will be replaced if host exists. + * + * @param mac MAC address of the host + * @param vlan VLAN ID of the host + * @param locations Location of the host + * @param ips Set of IP addresses of the host + * @param innerVlan host inner VLAN identifier + * @param outerTpid outer TPID of a host + */ + protected void updateHost(MacAddress mac, VlanId vlan, Set locations, Set ips, + VlanId innerVlan, EthType outerTpid) { + HostId hid = HostId.hostId(mac, vlan); + HostDescription desc = new DefaultHostDescription(mac, vlan, locations, ips, + innerVlan, outerTpid, true); + providerService.hostDetected(hid, desc, true); + } + /** * Removes host information. * @@ -155,7 +197,9 @@ public class NetworkConfigHostProvider extends AbstractProvider implements HostP Set locations = hostConfig.locations().stream() .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis())) .collect(Collectors.toSet()); - addHost(mac, vlan, locations, ipAddresses); + VlanId innerVlan = hostConfig.innerVlan(); + EthType outerTpid = hostConfig.outerTpid(); + addHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid); }); } @@ -175,6 +219,8 @@ public class NetworkConfigHostProvider extends AbstractProvider implements HostP BasicHostConfig hostConfig = networkConfigRegistry.getConfig(hostId, BasicHostConfig.class); Set ipAddresses = null; Set locations = null; + VlanId innerVlan = VlanId.NONE; + EthType outerTpid = EthType.EtherType.UNKNOWN.ethType(); // Note: There will be no config presented in the CONFIG_REMOVE case if (hostConfig != null) { @@ -187,14 +233,16 @@ public class NetworkConfigHostProvider extends AbstractProvider implements HostP locations = locations.stream() .map(hostLocation -> new HostLocation(hostLocation, System.currentTimeMillis())) .collect(Collectors.toSet()); + innerVlan = hostConfig.innerVlan(); + outerTpid = hostConfig.outerTpid(); } switch (event.type()) { case CONFIG_ADDED: - addHost(mac, vlan, locations, ipAddresses); + addHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid); break; case CONFIG_UPDATED: - updateHost(mac, vlan, locations, ipAddresses); + updateHost(mac, vlan, locations, ipAddresses, innerVlan, outerTpid); break; case CONFIG_REMOVED: removeHost(mac, vlan); diff --git a/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java b/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java index 36ad76d535..36de211684 100644 --- a/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java +++ b/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java @@ -19,6 +19,7 @@ package org.onosproject.provider.netcfghost; import com.google.common.collect.Sets; import org.junit.Before; import org.junit.Test; +import org.onlab.packet.EthType; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; @@ -54,6 +55,8 @@ public class NetworkConfigHostProviderTest { private Set ips = new HashSet<>(); private HostId hostId = HostId.hostId(mac, vlan); private HostDescription hostDescription; + private VlanId innerVlan = VlanId.vlanId((short) 20); + private EthType outerTpid = EthType.EtherType.lookup((short) 0x88a8).ethType(); @Before public void setUp() { @@ -62,12 +65,13 @@ public class NetworkConfigHostProviderTest { // Initialize test variables ips.add(IpAddress.valueOf("10.0.0.1")); ips.add(IpAddress.valueOf("192.168.0.1")); - hostDescription = new DefaultHostDescription(mac, vlan, locations, ips, true); + hostDescription = new DefaultHostDescription(mac, vlan, locations, ips, + innerVlan, outerTpid, true); } @Test public void testAddHost() throws Exception { - provider.addHost(mac, vlan, locations, ips); + provider.addHost(mac, vlan, locations, ips, innerVlan, outerTpid); assertThat(providerService.hostId, is(hostId)); assertThat(providerService.hostDescription, is(hostDescription)); assertThat(providerService.event, is("hostDetected")); @@ -76,7 +80,7 @@ public class NetworkConfigHostProviderTest { @Test public void testUpdateHost() throws Exception { - provider.updateHost(mac, vlan, locations, ips); + provider.updateHost(mac, vlan, locations, ips, innerVlan, outerTpid); assertThat(providerService.hostId, is(hostId)); assertThat(providerService.hostDescription, is(hostDescription)); assertThat(providerService.event, is("hostDetected")); diff --git a/web/api/src/test/java/org/onosproject/rest/resources/HostResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/HostResourceTest.java index 4bb9523c91..5ab26140c4 100644 --- a/web/api/src/test/java/org/onosproject/rest/resources/HostResourceTest.java +++ b/web/api/src/test/java/org/onosproject/rest/resources/HostResourceTest.java @@ -217,7 +217,7 @@ public class HostResourceTest extends ResourceTest { @Override public boolean matchesSafely(JsonArray json) { boolean hostFound = false; - final int expectedAttributes = 6; + final int expectedAttributes = 8; for (int jsonHostIndex = 0; jsonHostIndex < json.size(); jsonHostIndex++) {