alshabib

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

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