alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

......@@ -5,14 +5,31 @@ 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.onos.net.Host;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.Instructions;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.packet.InboundPacket;
import org.onlab.onos.net.packet.PacketContext;
import org.onlab.onos.net.packet.PacketProcessor;
import org.onlab.onos.net.packet.PacketService;
import org.onlab.onos.net.topology.TopologyService;
import org.slf4j.Logger;
@Component
import java.util.Set;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Sample reactive forwarding application.
*/
@Component(immediate = true)
public class ReactiveForwarding {
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected TopologyService topologyService;
......@@ -22,18 +39,99 @@ public class ReactiveForwarding {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
private ReactivePacketProcessor processor;
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
@Activate
public void activate() {
processor = new ReactivePacketProcessor(topologyService, hostService);
packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
log.info("Started");
}
@Deactivate
public void deactivate() {
packetService.removeProcessor(processor);
processor = null;
log.info("Stopped");
}
/**
* Packet processor responsible for forwarding packets along their paths.
*/
private class ReactivePacketProcessor implements PacketProcessor {
@Override
public void process(PacketContext context) {
InboundPacket pkt = context.inPacket();
HostId id = HostId.hostId(pkt.parsed().getDestinationMAC());
// Do we know who this is for? If not, flood and bail.
Host dst = hostService.getHost(id);
if (dst == null) {
flood(context);
return;
}
// Are we on an edge switch that our destination is on? If so,
// simply forward out to the destination and bail.
if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) {
forward(context, dst.location().port());
return;
}
// Otherwise, get a set of paths that lead from here to the
// destination edge switch.
Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(),
context.inPacket().receivedFrom().deviceId(),
dst.location().deviceId());
if (paths.isEmpty()) {
// If there are no paths, flood and bail.
flood(context);
return;
}
// Otherwise, pick a path that does not lead back to where we
// came from; if no such path, flood and bail.
Path path = pickForwardPath(paths, pkt.receivedFrom().port());
if (path == null) {
log.warn("Doh... don't know where to go...");
flood(context);
return;
}
// Otherwise forward and be done with it.
forward(context, path.src().port());
}
}
// Selects a path from the given set that does not lead back to the
// specified port.
private Path pickForwardPath(Set<Path> paths, PortNumber notToPort) {
for (Path path : paths) {
if (!path.src().port().equals(notToPort)) {
return path;
}
}
return null;
}
// Floods the specified packet.
private void flood(PacketContext context) {
boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(),
context.inPacket().receivedFrom());
if (canBcast) {
forward(context, PortNumber.FLOOD);
} else {
context.block();
}
}
// Forwards the packet to the specified port.
private void forward(PacketContext context, PortNumber portNumber) {
context.treatmentBuilder().add(Instructions.createOutput(portNumber));
context.send();
}
}
......
package org.onlab.onos.fwd;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Set;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.Instructions;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.packet.InboundPacket;
import org.onlab.onos.net.packet.PacketContext;
import org.onlab.onos.net.packet.PacketProcessor;
import org.onlab.onos.net.topology.TopologyService;
import org.onlab.packet.VLANID;
import org.slf4j.Logger;
public class ReactivePacketProcessor implements PacketProcessor {
private final Logger log = getLogger(getClass());
private final TopologyService topologyService;
private final HostService hostService;
public ReactivePacketProcessor(TopologyService topologyService, HostService hostService) {
this.topologyService = topologyService;
this.hostService = hostService;
}
@Override
public void process(PacketContext context) {
InboundPacket pkt = context.inPacket();
HostId id = HostId.hostId(pkt.parsed().getDestinationMAC(), VLANID.vlanId((short) -1));
Host dst = hostService.getHost(id);
if (dst == null) {
flood(context);
return;
}
Set<Path> p = null;
if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) {
context.treatmentBuilder().add(Instructions.createOutput(dst.location().port()));
context.send();
return;
} else {
p = topologyService.getPaths(topologyService.currentTopology(),
context.inPacket().receivedFrom().deviceId(), dst.location().deviceId());
}
if (p.isEmpty()) {
flood(context);
} else {
Path p1 = p.iterator().next();
context.treatmentBuilder().add(Instructions.createOutput(p1.src().port()));
context.send();
}
}
private void flood(PacketContext context) {
boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(),
context.inPacket().receivedFrom());
if (canBcast) {
context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD));
context.send();
} else {
context.block();
}
}
}
/**
* Trivial application that provides simple form of reactive forwarding.
*/
package org.onlab.onos.fwd;
\ No newline at end of file
......@@ -15,6 +15,7 @@ import org.onlab.onos.net.topology.Topology;
import org.onlab.onos.net.topology.TopologyGraph;
import org.onlab.onos.net.topology.TopologyService;
import org.onlab.onos.net.topology.TopologyVertex;
import org.onlab.packet.IPAddress;
import org.onlab.rest.BaseResource;
import javax.ws.rs.GET;
......@@ -54,6 +55,7 @@ public class TopologyResource extends BaseResource {
ArrayNode vertexesNode = mapper.createArrayNode();
for (TopologyVertex vertex : graph.getVertexes()) {
vertexesNode.add(json(mapper, vertex.deviceId(), 2,
vertex.deviceId().uri().getSchemeSpecificPart(),
deviceService.isAvailable(vertex.deviceId())));
}
......@@ -70,14 +72,17 @@ public class TopologyResource extends BaseResource {
// Merge the exterior and interior vertexes and inject host links as
// the exterior edges.
for (Host host : hostService.getHosts()) {
vertexesNode.add(json(mapper, host.id(), 3, true));
Set<IPAddress> ipAddresses = host.ipAddresses();
IPAddress ipAddress = ipAddresses.isEmpty() ? null : ipAddresses.iterator().next();
String label = ipAddress != null ? ipAddress.toString() : host.mac().toString();
vertexesNode.add(json(mapper, host.id(), 3, label, true));
edgesNode.add(json(mapper, 1, host.location(), new ConnectPoint(host.id(), portNumber(-1))));
}
// Now put the vertexes and edges into a root node and ship them off
ObjectNode rootNode = mapper.createObjectNode();
rootNode.put("vertexes", vertexesNode);
rootNode.put("edges", edgesNode);
rootNode.set("vertexes", vertexesNode);
rootNode.set("edges", edgesNode);
return Response.ok(rootNode.toString()).build();
}
......@@ -126,12 +131,12 @@ public class TopologyResource extends BaseResource {
return aggLinks;
}
// Produces JSON for a graph vertex.
private ObjectNode json(ObjectMapper mapper, ElementId id, int group,
boolean isOnline) {
String label, boolean isOnline) {
return mapper.createObjectNode()
.put("name", id.uri().toString())
.put("label", label)
.put("group", group)
.put("online", isOnline);
}
......
......@@ -129,7 +129,7 @@
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
// d3.select(this).classed("fixed", d.fixed = true);
}
......@@ -147,8 +147,8 @@
}
return false;
}
node = {"id": vertex.name, "group": vertex.group,
"online": vertex.online, "stamp": stamp};
node = {"id": vertex.name, "label": vertex.label,
"group": vertex.group, "online": vertex.online, "stamp": stamp};
nodes.push(node);
topo.vertexes[vertex.name] = node;
update();
......@@ -239,6 +239,8 @@
targetNode = aux;
} else if (d3.event.keyCode == 70) {
nextPath();
} else if (d3.event.keyCode == 67 && selectedNode) {
selectedNode.fixed = !selectedNode.fixed;
}
d3.selectAll(".nodeStrokeClass").attr("fill", fillColor);
......@@ -288,7 +290,7 @@
.attr("class", "textClass")
.attr("x", 20)
.attr("y", ".31em")
.text(function (d) { return d.id; });
.text(function (d) { return d.label; });
node.exit().remove();
......
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.device.DeviceAdminService;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.host.HostAdminService;
import org.onlab.onos.net.host.HostService;
/**
* Wipes-out the entire network information base, i.e. devices, links, hosts.
*/
@Command(scope = "onos", name = "wipe-out",
description = "Wipes-out the entire network information base, i.e. devices, links, hosts")
public class WipeOutCommand extends ClustersListCommand {
@Override
protected Object doExecute() throws Exception {
DeviceAdminService deviceAdminService = get(DeviceAdminService.class);
DeviceService deviceService = get(DeviceService.class);
for (Device device : deviceService.getDevices()) {
deviceAdminService.removeDevice(device.id());
}
HostAdminService hostAdminService = get(HostAdminService.class);
HostService hostService = get(HostService.class);
for (Host host : hostService.getHosts()) {
hostAdminService.removeHost(host.id());
}
return null;
}
}
......@@ -58,11 +58,11 @@
<command>
<action class="org.onlab.onos.cli.net.HostsListCommand"/>
<completers>
<ref component-id="hostIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.WipeOutCommand"/>
</command>
</command-bundle>
<bean id="deviceIdCompleter" class="org.onlab.onos.cli.net.DeviceIdCompleter"/>
......
......@@ -42,10 +42,19 @@ public final class HostId extends ElementId {
* @param vlanId vlan identifier
* @return host identifier
*/
// FIXME: replace vlanId long with a rich data-type, e.g. VLanId or something like that
public static HostId hostId(MACAddress mac, VLANID vlanId) {
// FIXME: use more efficient means of encoding
return hostId("nic" + ":" + mac + "/" + vlanId);
}
/**
* Creates a device id using the supplied MAC and default VLAN.
*
* @param mac mac address
* @return host identifier
*/
public static HostId hostId(MACAddress mac) {
return hostId(mac, VLANID.vlanId(VLANID.UNTAGGED));
}
}
......
......@@ -4,12 +4,17 @@ import org.onlab.onos.net.DeviceId;
/**
* Service for injecting flow rules into the environment and for obtaining
* information about flow rules already in the environment.
* information about flow rules already in the environment. This implements
* semantics of a distributed authoritative flow table where the master copy
* of the flow rules lies with the controller and the devices hold only the
* 'cached' copy.
*/
public interface FlowRuleService {
/**
* Returns the collection of flow entries applied on the specified device.
* This will include flow rules which may not yet have been applied to
* the device.
*
* @param deviceId device identifier
* @return collection of flow rules
......@@ -17,7 +22,9 @@ public interface FlowRuleService {
Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
/**
* Applies the specified flow rules onto their respective devices.
* Applies the specified flow rules onto their respective devices. These
* flow rules will be retained by the system and re-applied anytime the
* device reconnects to the controller.
*
* @param flowRules one or more flow rules
* throws SomeKindOfException that indicates which ones were applied and
......@@ -26,7 +33,9 @@ public interface FlowRuleService {
void applyFlowRules(FlowRule... flowRules);
/**
* Removes the specified flow rules from their respective devices.
* Removes the specified flow rules from their respective devices. If the
* device is not presently connected to the controller, these flow will
* be removed once the device reconnects.
*
* @param flowRules one or more flow rules
* throws SomeKindOfException that indicates which ones were removed and
......@@ -34,6 +43,10 @@ public interface FlowRuleService {
*/
void removeFlowRules(FlowRule... flowRules);
// void addInitialFlowContributor(InitialFlowContributor contributor);
// void removeInitialFlowContributor(InitialFlowContributor contributor);
/**
* Adds the specified flow rule listener.
*
......
......@@ -2,7 +2,6 @@ package org.onlab.onos.net.flow;
/**
* Abstraction of a single traffic treatment step.
* @param <T> the type parameter for the instruction
*/
public interface Instruction {
......
......@@ -23,6 +23,7 @@ public final class Instructions {
return new OutputInstruction(number);
}
// TODO: Move these out into separate classes and to flow.instruction package
public static DropInstruction createDrop() {
return new DropInstruction();
}
......@@ -30,7 +31,6 @@ public final class Instructions {
// TODO: add create methods
public static final class DropInstruction implements Instruction {
@Override
public Type type() {
return Type.DROP;
......@@ -39,7 +39,6 @@ public final class Instructions {
public static final class OutputInstruction implements Instruction {
private final PortNumber port;
private OutputInstruction(PortNumber port) {
......@@ -54,8 +53,6 @@ public final class Instructions {
public Type type() {
return Type.OUTPUT;
}
}
}
......
package org.onlab.onos.net.host;
import org.onlab.onos.net.HostId;
/**
* Service for administering the inventory of end-station hosts.
*/
public interface HostAdminService {
/**
* Removes the end-station host with the specified identifier.
*
* @param hostId host identifier
*/
void removeHost(HostId hostId);
}
......@@ -43,13 +43,15 @@ public interface PacketContext {
/**
* Blocks the outbound packet from being sent from this point onward.
*
* @return whether the outbound packet is blocked.
*/
boolean block();
/**
* Check whether the outbound packet is blocked.
* @return
* Indicates whether the outbound packet is handled, i.e. sent or blocked.
*
* @return true uf the packed is handled
*/
boolean isHandled();
......
......@@ -139,8 +139,7 @@ class SimpleDeviceStore {
DeviceEvent markOffline(DeviceId deviceId) {
synchronized (this) {
Device device = devices.get(deviceId);
checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
boolean removed = availableDevices.remove(deviceId);
boolean removed = device != null && availableDevices.remove(deviceId);
return !removed ? null :
new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
}
......
......@@ -12,6 +12,7 @@ import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.host.HostAdminService;
import org.onlab.onos.net.host.HostDescription;
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostListener;
......@@ -38,7 +39,7 @@ import static org.slf4j.LoggerFactory.getLogger;
@Service
public class SimpleHostManager
extends AbstractProviderRegistry<HostProvider, HostProviderService>
implements HostService, HostProviderRegistry {
implements HostService, HostAdminService, HostProviderRegistry {
public static final String HOST_ID_NULL = "Host ID cannot be null";
private final Logger log = getLogger(getClass());
......@@ -124,6 +125,16 @@ public class SimpleHostManager
listenerRegistry.removeListener(listener);
}
@Override
public void removeHost(HostId hostId) {
checkNotNull(hostId, HOST_ID_NULL);
HostEvent event = store.removeHost(hostId);
if (event != null) {
log.info("Host {} administratively removed", hostId);
post(event);
}
}
// Personalized host provider service issued to the supplied provider.
private class InternalHostProviderService
extends AbstractProviderService<HostProvider>
......
......@@ -16,6 +16,9 @@ import org.onlab.onos.event.EventDeliveryService;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.device.DeviceEvent;
import org.onlab.onos.net.device.DeviceListener;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.link.LinkAdminService;
import org.onlab.onos.net.link.LinkDescription;
import org.onlab.onos.net.link.LinkEvent;
......@@ -49,6 +52,10 @@ public class SimpleLinkManager
listenerRegistry = new AbstractListenerRegistry<>();
private final SimpleLinkStore store = new SimpleLinkStore();
private final DeviceListener deviceListener = new InnerDeviceListener();
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EventDeliveryService eventDispatcher;
......@@ -56,12 +63,14 @@ public class SimpleLinkManager
@Activate
public void activate() {
eventDispatcher.addSink(LinkEvent.class, listenerRegistry);
deviceService.addListener(deviceListener);
log.info("Started");
}
@Deactivate
public void deactivate() {
eventDispatcher.removeSink(LinkEvent.class);
deviceService.removeListener(deviceListener);
log.info("Stopped");
}
......@@ -140,6 +149,20 @@ public class SimpleLinkManager
listenerRegistry.removeListener(listener);
}
// Auxiliary interceptor for device remove events to prune links that
// are associated with the removed device or its port.
private class InnerDeviceListener implements DeviceListener {
@Override
public void event(DeviceEvent event) {
if (event.type() == DeviceEvent.Type.DEVICE_REMOVED) {
removeLinks(event.subject().id());
} else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
removeLinks(new ConnectPoint(event.subject().id(),
event.port().number()));
}
}
}
@Override
protected LinkProviderService createProviderService(LinkProvider provider) {
return new InternalLinkProviderService(provider);
......
......@@ -25,10 +25,8 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry;
import org.onlab.onos.net.provider.AbstractProviderService;
import org.slf4j.Logger;
/**
* Provides a basic implementation of the packet SB &amp; NB APIs.
*
*/
@Component(immediate = true)
@Service
......@@ -43,7 +41,6 @@ implements PacketService, PacketProviderRegistry {
private final Map<Integer, PacketProcessor> processors = new TreeMap<>();
@Activate
public void activate() {
log.info("Started");
......@@ -62,19 +59,20 @@ implements PacketService, PacketProviderRegistry {
@Override
public void removeProcessor(PacketProcessor processor) {
checkNotNull(processor, "Processor cannot be null");
processors.values().remove(processor);
}
@Override
public void emit(OutboundPacket packet) {
checkNotNull(packet, "Packet cannot be null");
final Device device = deviceService.getDevice(packet.sendThrough());
final PacketProvider packetProvider = getProvider(device.providerId());
packetProvider.emit(packet);
}
@Override
protected PacketProviderService createProviderService(
PacketProvider provider) {
protected PacketProviderService createProviderService(PacketProvider provider) {
return new InternalPacketProviderService(provider);
}
......
......@@ -22,6 +22,7 @@ import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.event.impl.TestEventDispatcher;
import org.onlab.onos.net.trivial.device.impl.SimpleDeviceManager;
import java.util.ArrayList;
import java.util.Iterator;
......@@ -65,6 +66,7 @@ public class SimpleLinkManagerTest {
admin = mgr;
registry = mgr;
mgr.eventDispatcher = new TestEventDispatcher();
mgr.deviceService = new SimpleDeviceManager();
mgr.activate();
service.addListener(listener);
......
......@@ -39,27 +39,27 @@
<feature name="onos-rest" version="1.0.0"
description="ONOS REST API components">
<feature>onos-core</feature>
<feature>onos-api</feature>
<feature>onos-thirdparty-web</feature>
<bundle>mvn:org.onlab.onos/onos-rest/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-gui" version="1.0.0"
description="ONOS GUI console components">
<feature>onos-core</feature>
<feature>onos-api</feature>
<feature>onos-thirdparty-web</feature>
<bundle>mvn:org.onlab.onos/onos-gui/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-cli" version="1.0.0"
description="ONOS admin command console components">
<feature>onos-core</feature>
<feature>onos-api</feature>
<bundle>mvn:org.onlab.onos/onos-cli/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-openflow" version="1.0.0"
description="ONOS OpenFlow API, Controller &amp; Providers">
<feature>onos-core</feature>
<feature>onos-api</feature>
<bundle>mvn:io.netty/netty/3.9.2.Final</bundle>
<bundle>mvn:org.onlab.onos/onos-of-api/1.0.0-SNAPSHOT</bundle>
......@@ -74,14 +74,14 @@
<feature name="onos-app-tvue" version="1.0.0"
description="ONOS sample topology viewer application">
<feature>onos-core</feature>
<feature>onos-api</feature>
<feature>onos-thirdparty-web</feature>
<bundle>mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-app-fwd" version="1.0.0"
description="ONOS sample forwarding application">
<feature>onos-core</feature>
<feature>onos-api</feature>
<bundle>mvn:org.onlab.onos/onos-app-fwd/1.0.0-SNAPSHOT</bundle>
</feature>
......
......@@ -366,7 +366,7 @@
<group>
<title>Sample Applications</title>
<packages>
org.onlab.onos.tvue
org.onlab.onos.tvue:org.onlab.onos.fwd
</packages>
</group>
</groups>
......
#!/bin/bash
#-------------------------------------------------------------------------------
# Starts ONOS Apache Karaf container
#-------------------------------------------------------------------------------
cd $(dirname $0)/../apache-karaf-*/bin
./karaf "$@"
#!/bin/bash
#-------------------------------------------------------------------------------
# Packages ONOS distributable into onos.tar.gz
#-------------------------------------------------------------------------------
export M2_REPO=${M2_REPO:-~/.m2/repository}
export KARAF_ZIP=${KARAF_ZIP:-~/Downloads/apache-karaf-3.0.1.zip}
export KARAF_DIST=$(basename $KARAF_ZIP .zip)
export ONOS_VERSION=${ONOS_VERSION:-1.0.0-SNAPSHOT}
export ONOS_STAGE_ROOT=${ONOS_STAGE_ROOT:-/tmp}
export ONOS_BITS=onos-$ONOS_VERSION
export ONOS_STAGE=$ONOS_STAGE_ROOT/$ONOS_BITS
# Bail on any errors
set -e
rm -fr $ONOS_STAGE # Remove this when package script is completed
# Make sure we have the original apache karaf bits first
[ ! -d $M2_REPO ] && echo "M2 repository $M2_REPO not found" && exit 1
[ ! -f $KARAF_ZIP ] && echo "Apache Karaf bits $KARAF_ZIP not found" && exit 1
[ -d $ONOS_STAGE ] && echo "ONOS stage $ONOS_STAGE already exists" && exit 1
# Create the stage directory and warp into it
mkdir -p $ONOS_STAGE
cd $ONOS_STAGE
# Unroll the Apache Karaf bits and make the ONOS top-level directories.
unzip $KARAF_ZIP
mkdir bin
mkdir lib
# Stage the ONOS admin scripts
cp -r $ONOS_ROOT/tools/package/bin .
# Stage the ONOS bundles
mkdir -p lib/org/onlab
cp -r $M2_REPO/org/onlab lib/org
# Patch the Apache Karaf distribution file to point to the lib as maven repo
#perl -pi.old -e "s|^org.ops4j.pax.url.mvn.repositories= |org.ops4j.pax.url.mvn.repositories= \\\n file:../../lib, |" $ONOS_STAGE/$KARAF_DIST/etc/org.ops4j.pax.url.mvn.cfg
# Patch the Apache Karaf distribution file to add ONOS features repository
perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onlab.onos/onos-features/$ONOS_VERSION/xml/features|" \
$ONOS_STAGE/$KARAF_DIST/etc/org.apache.karaf.features.cfg
# Patch the Apache Karaf distribution file to load ONOS features
perl -pi.old -e 's|^(featuresBoot=.*)|\1,onos-api,onos-core,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-tvue|' \
/tmp/onos-1.0.0-SNAPSHOT/apache-karaf-3.0.1/etc/org.apache.karaf.features.cfg
# Patch the Apache Karaf distribution with ONOS branding bundle
cp $M2_REPO/org/onlab/onos/onos-branding/$ONOS_VERSION/onos-branding-*.jar \
$ONOS_STAGE/apache-karaf-*/lib
# Now package up the ONOS tar file
cd $ONOS_STAGE_ROOT
tar zcf $ONOS_BITS.tar.gz $ONOS_BITS
......@@ -3,6 +3,7 @@ package org.onlab.packet;
/**
* Representation of a VLAN ID.
*/
// FIXME: This will end-up looking like a constant; we should name it 'VlanId', 'IpAddress', 'MacAddress'.
public class VLANID {
private final short value;
......