Showing
8 changed files
with
133 additions
and
75 deletions
... | @@ -8,49 +8,40 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector; | ... | @@ -8,49 +8,40 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector; |
8 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; | 8 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; |
9 | import org.onlab.onos.net.flow.TrafficSelector; | 9 | import org.onlab.onos.net.flow.TrafficSelector; |
10 | import org.onlab.onos.net.flow.TrafficTreatment; | 10 | import org.onlab.onos.net.flow.TrafficTreatment; |
11 | -import org.onlab.onos.net.host.HostService; | ||
12 | import org.onlab.onos.net.intent.HostToHostIntent; | 11 | import org.onlab.onos.net.intent.HostToHostIntent; |
13 | import org.onlab.onos.net.intent.IntentId; | 12 | import org.onlab.onos.net.intent.IntentId; |
14 | import org.onlab.onos.net.intent.IntentService; | 13 | import org.onlab.onos.net.intent.IntentService; |
15 | 14 | ||
16 | /** | 15 | /** |
17 | - * Lists all shortest-paths paths between the specified source and | 16 | + * Installs host-to-host connectivity intent. |
18 | - * destination devices. | ||
19 | */ | 17 | */ |
20 | -@Command(scope = "onos", name = "add-intent", | 18 | +@Command(scope = "onos", name = "add-host-intent", |
21 | - description = "Installs HostToHostIntent between the specified source and destination devices") | 19 | + description = "Installs host-to-host connectivity intent") |
22 | -public class IntentInstallCommand extends AbstractShellCommand { | 20 | +public class AddHostToHostIntentCommand extends AbstractShellCommand { |
23 | 21 | ||
24 | - @Argument(index = 0, name = "src", description = "Source device ID", | 22 | + @Argument(index = 0, name = "one", description = "One host ID", |
25 | required = true, multiValued = false) | 23 | required = true, multiValued = false) |
26 | - String src = null; | 24 | + String one = null; |
27 | 25 | ||
28 | - @Argument(index = 1, name = "dst", description = "Destination device ID", | 26 | + @Argument(index = 1, name = "two", description = "Another host ID", |
29 | required = true, multiValued = false) | 27 | required = true, multiValued = false) |
30 | - String dst = null; | 28 | + String two = null; |
31 | 29 | ||
32 | private static long id = 1; | 30 | private static long id = 1; |
33 | 31 | ||
34 | @Override | 32 | @Override |
35 | protected void execute() { | 33 | protected void execute() { |
36 | IntentService service = get(IntentService.class); | 34 | IntentService service = get(IntentService.class); |
37 | - HostService hosts = get(HostService.class); | ||
38 | 35 | ||
39 | - HostId srcId = HostId.hostId(src); | 36 | + HostId oneId = HostId.hostId(one); |
40 | - HostId dstId = HostId.hostId(dst); | 37 | + HostId twoId = HostId.hostId(two); |
41 | 38 | ||
42 | - TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); | 39 | + TrafficSelector selector = DefaultTrafficSelector.builder().build(); |
43 | - builder.matchEthSrc(hosts.getHost(srcId).mac()) | 40 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); |
44 | - .matchEthDst(hosts.getHost(dstId).mac()); | ||
45 | - | ||
46 | - TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | ||
47 | 41 | ||
48 | HostToHostIntent intent = | 42 | HostToHostIntent intent = |
49 | - new HostToHostIntent(new IntentId(id++), srcId, dstId, | 43 | + new HostToHostIntent(new IntentId(id++), oneId, twoId, |
50 | - builder.build(), treat.build()); | 44 | + selector, treatment); |
51 | - | ||
52 | - log.info("Adding intent {}", intent); | ||
53 | - | ||
54 | service.submit(intent); | 45 | service.submit(intent); |
55 | } | 46 | } |
56 | 47 | ... | ... |
1 | +package org.onlab.onos.cli.net; | ||
2 | + | ||
3 | +import org.apache.karaf.shell.commands.Command; | ||
4 | +import org.onlab.onos.cli.AbstractShellCommand; | ||
5 | +import org.onlab.onos.net.intent.Intent; | ||
6 | +import org.onlab.onos.net.intent.IntentService; | ||
7 | + | ||
8 | +/** | ||
9 | + * Lists the inventory of intents and their states. | ||
10 | + */ | ||
11 | +@Command(scope = "onos", name = "intents", | ||
12 | + description = "Lists the inventory of intents and their states") | ||
13 | +public class IntentsListCommand extends AbstractShellCommand { | ||
14 | + | ||
15 | + @Override | ||
16 | + protected void execute() { | ||
17 | + IntentService service = get(IntentService.class); | ||
18 | + for (Intent intent : service.getIntents()) { | ||
19 | + print("%s", intent); | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | +} |
... | @@ -56,12 +56,16 @@ | ... | @@ -56,12 +56,16 @@ |
56 | <ref component-id="deviceIdCompleter"/> | 56 | <ref component-id="deviceIdCompleter"/> |
57 | </completers> | 57 | </completers> |
58 | </command> | 58 | </command> |
59 | + | ||
59 | <command> | 60 | <command> |
60 | - <action class="org.onlab.onos.cli.net.IntentInstallCommand"/> | 61 | + <action class="org.onlab.onos.cli.net.AddHostToHostIntentCommand"/> |
61 | <completers> | 62 | <completers> |
62 | <ref component-id="hostIdCompleter"/> | 63 | <ref component-id="hostIdCompleter"/> |
63 | </completers> | 64 | </completers> |
64 | </command> | 65 | </command> |
66 | + <command> | ||
67 | + <action class="org.onlab.onos.cli.net.IntentsListCommand"/> | ||
68 | + </command> | ||
65 | 69 | ||
66 | <command> | 70 | <command> |
67 | <action class="org.onlab.onos.cli.net.ClustersListCommand"/> | 71 | <action class="org.onlab.onos.cli.net.ClustersListCommand"/> | ... | ... |
... | @@ -47,7 +47,23 @@ public class ConnectPoint { | ... | @@ -47,7 +47,23 @@ public class ConnectPoint { |
47 | return (DeviceId) elementId; | 47 | return (DeviceId) elementId; |
48 | } | 48 | } |
49 | throw new IllegalStateException("Connection point not associated " + | 49 | throw new IllegalStateException("Connection point not associated " + |
50 | - "with an infrastructure device"); | 50 | + "with an infrastructure device"); |
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Returns the identifier of the infrastructure device if the connection | ||
55 | + * point belongs to a network element which is indeed an end-station host. | ||
56 | + * | ||
57 | + * @return network element identifier as a host identifier | ||
58 | + * @throws java.lang.IllegalStateException if connection point is not | ||
59 | + * associated with a host | ||
60 | + */ | ||
61 | + public HostId hostId() { | ||
62 | + if (elementId instanceof HostId) { | ||
63 | + return (HostId) elementId; | ||
64 | + } | ||
65 | + throw new IllegalStateException("Connection point not associated " + | ||
66 | + "with an end-station host"); | ||
51 | } | 67 | } |
52 | 68 | ||
53 | /** | 69 | /** | ... | ... |
... | @@ -10,47 +10,49 @@ import java.util.Objects; | ... | @@ -10,47 +10,49 @@ import java.util.Objects; |
10 | import static com.google.common.base.Preconditions.checkNotNull; | 10 | import static com.google.common.base.Preconditions.checkNotNull; |
11 | 11 | ||
12 | /** | 12 | /** |
13 | - * Abstraction of end-station to end-station connectivity. | 13 | + * Abstraction of end-station to end-station bidirectional connectivity. |
14 | */ | 14 | */ |
15 | public class HostToHostIntent extends ConnectivityIntent { | 15 | public class HostToHostIntent extends ConnectivityIntent { |
16 | 16 | ||
17 | - private final HostId src; | 17 | + private final HostId one; |
18 | - private final HostId dst; | 18 | + private final HostId two; |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * Creates a new point-to-point intent with the supplied ingress/egress | 21 | * Creates a new point-to-point intent with the supplied ingress/egress |
22 | * ports. | 22 | * ports. |
23 | * | 23 | * |
24 | * @param intentId intent identifier | 24 | * @param intentId intent identifier |
25 | + * @param one first host | ||
26 | + * @param two second host | ||
25 | * @param selector action | 27 | * @param selector action |
26 | * @param treatment ingress port | 28 | * @param treatment ingress port |
27 | * @throws NullPointerException if {@code ingressPort} or {@code egressPort} | 29 | * @throws NullPointerException if {@code ingressPort} or {@code egressPort} |
28 | * is null. | 30 | * is null. |
29 | */ | 31 | */ |
30 | - public HostToHostIntent(IntentId intentId, HostId src, HostId dst, | 32 | + public HostToHostIntent(IntentId intentId, HostId one, HostId two, |
31 | - TrafficSelector selector, TrafficTreatment treatment) { | 33 | + TrafficSelector selector, |
34 | + TrafficTreatment treatment) { | ||
32 | super(intentId, selector, treatment); | 35 | super(intentId, selector, treatment); |
33 | - this.src = checkNotNull(src); | 36 | + this.one = checkNotNull(one); |
34 | - this.dst = checkNotNull(dst); | 37 | + this.two = checkNotNull(two); |
35 | } | 38 | } |
36 | 39 | ||
37 | /** | 40 | /** |
38 | - * Returns the port on which the ingress traffic should be connected to the | 41 | + * Returns identifier of the first host. |
39 | - * egress. | ||
40 | * | 42 | * |
41 | - * @return ingress port | 43 | + * @return first host identifier |
42 | */ | 44 | */ |
43 | - public HostId getSrc() { | 45 | + public HostId one() { |
44 | - return src; | 46 | + return one; |
45 | } | 47 | } |
46 | 48 | ||
47 | /** | 49 | /** |
48 | - * Returns the port on which the traffic should egress. | 50 | + * Returns identifier of the second host. |
49 | * | 51 | * |
50 | - * @return egress port | 52 | + * @return second host identifier |
51 | */ | 53 | */ |
52 | - public HostId getDst() { | 54 | + public HostId two() { |
53 | - return dst; | 55 | + return two; |
54 | } | 56 | } |
55 | 57 | ||
56 | @Override | 58 | @Override |
... | @@ -66,13 +68,13 @@ public class HostToHostIntent extends ConnectivityIntent { | ... | @@ -66,13 +68,13 @@ public class HostToHostIntent extends ConnectivityIntent { |
66 | } | 68 | } |
67 | 69 | ||
68 | HostToHostIntent that = (HostToHostIntent) o; | 70 | HostToHostIntent that = (HostToHostIntent) o; |
69 | - return Objects.equals(this.src, that.src) | 71 | + return Objects.equals(this.one, that.one) |
70 | - && Objects.equals(this.dst, that.dst); | 72 | + && Objects.equals(this.two, that.two); |
71 | } | 73 | } |
72 | 74 | ||
73 | @Override | 75 | @Override |
74 | public int hashCode() { | 76 | public int hashCode() { |
75 | - return Objects.hash(super.hashCode(), src, dst); | 77 | + return Objects.hash(super.hashCode(), one, two); |
76 | } | 78 | } |
77 | 79 | ||
78 | @Override | 80 | @Override |
... | @@ -80,9 +82,9 @@ public class HostToHostIntent extends ConnectivityIntent { | ... | @@ -80,9 +82,9 @@ public class HostToHostIntent extends ConnectivityIntent { |
80 | return MoreObjects.toStringHelper(getClass()) | 82 | return MoreObjects.toStringHelper(getClass()) |
81 | .add("id", getId()) | 83 | .add("id", getId()) |
82 | .add("selector", getTrafficSelector()) | 84 | .add("selector", getTrafficSelector()) |
83 | - .add("treatmetn", getTrafficTreatment()) | 85 | + .add("treatment", getTrafficTreatment()) |
84 | - .add("src", src) | 86 | + .add("one", one) |
85 | - .add("dst", dst) | 87 | + .add("two", two) |
86 | .toString(); | 88 | .toString(); |
87 | } | 89 | } |
88 | 90 | ... | ... |
1 | package org.onlab.onos.net.intent.impl; | 1 | package org.onlab.onos.net.intent.impl; |
2 | 2 | ||
3 | -import java.util.Arrays; | ||
4 | -import java.util.List; | ||
5 | -import java.util.Set; | ||
6 | - | ||
7 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
9 | import org.apache.felix.scr.annotations.Deactivate; | 5 | import org.apache.felix.scr.annotations.Deactivate; |
10 | import org.apache.felix.scr.annotations.Reference; | 6 | import org.apache.felix.scr.annotations.Reference; |
11 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 7 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
12 | -import org.onlab.onos.net.ConnectPoint; | 8 | +import org.onlab.onos.net.Host; |
9 | +import org.onlab.onos.net.HostId; | ||
13 | import org.onlab.onos.net.Path; | 10 | import org.onlab.onos.net.Path; |
14 | -import org.onlab.onos.net.PortNumber; | 11 | +import org.onlab.onos.net.flow.TrafficSelector; |
12 | +import org.onlab.onos.net.host.HostService; | ||
15 | import org.onlab.onos.net.intent.HostToHostIntent; | 13 | import org.onlab.onos.net.intent.HostToHostIntent; |
16 | import org.onlab.onos.net.intent.IdGenerator; | 14 | import org.onlab.onos.net.intent.IdGenerator; |
17 | import org.onlab.onos.net.intent.Intent; | 15 | import org.onlab.onos.net.intent.Intent; |
... | @@ -21,6 +19,12 @@ import org.onlab.onos.net.intent.IntentId; | ... | @@ -21,6 +19,12 @@ import org.onlab.onos.net.intent.IntentId; |
21 | import org.onlab.onos.net.intent.PathIntent; | 19 | import org.onlab.onos.net.intent.PathIntent; |
22 | import org.onlab.onos.net.topology.PathService; | 20 | import org.onlab.onos.net.topology.PathService; |
23 | 21 | ||
22 | +import java.util.Arrays; | ||
23 | +import java.util.List; | ||
24 | +import java.util.Set; | ||
25 | + | ||
26 | +import static org.onlab.onos.net.flow.DefaultTrafficSelector.builder; | ||
27 | + | ||
24 | /** | 28 | /** |
25 | * A intent compiler for {@link HostToHostIntent}. | 29 | * A intent compiler for {@link HostToHostIntent}. |
26 | */ | 30 | */ |
... | @@ -34,6 +38,9 @@ public class HostToHostIntentCompiler | ... | @@ -34,6 +38,9 @@ public class HostToHostIntentCompiler |
34 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 38 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
35 | protected PathService pathService; | 39 | protected PathService pathService; |
36 | 40 | ||
41 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
42 | + protected HostService hostService; | ||
43 | + | ||
37 | private IdGenerator<IntentId> intentIdGenerator; | 44 | private IdGenerator<IntentId> intentIdGenerator; |
38 | 45 | ||
39 | @Activate | 46 | @Activate |
... | @@ -50,18 +57,34 @@ public class HostToHostIntentCompiler | ... | @@ -50,18 +57,34 @@ public class HostToHostIntentCompiler |
50 | 57 | ||
51 | @Override | 58 | @Override |
52 | public List<Intent> compile(HostToHostIntent intent) { | 59 | public List<Intent> compile(HostToHostIntent intent) { |
53 | - Set<Path> paths = pathService.getPaths(intent.getSrc(), intent.getDst()); | 60 | + Path pathOne = getPath(intent.one(), intent.two()); |
61 | + Path pathTwo = getPath(intent.two(), intent.one()); | ||
62 | + | ||
63 | + Host one = hostService.getHost(intent.one()); | ||
64 | + Host two = hostService.getHost(intent.two()); | ||
65 | + | ||
66 | + return Arrays.asList(createPathIntent(pathOne, one, two, intent), | ||
67 | + createPathIntent(pathTwo, two, one, intent)); | ||
68 | + } | ||
69 | + | ||
70 | + // Creates a path intent from the specified path and original connectivity intent. | ||
71 | + private Intent createPathIntent(Path path, Host src, Host dst, | ||
72 | + HostToHostIntent intent) { | ||
73 | + | ||
74 | + TrafficSelector selector = builder(intent.getTrafficSelector()) | ||
75 | + .matchEthSrc(src.mac()).matchEthDst(dst.mac()).build(); | ||
76 | + | ||
77 | + return new PathIntent(intentIdGenerator.getNewId(), | ||
78 | + selector, intent.getTrafficTreatment(), | ||
79 | + path.src(), path.dst(), path); | ||
80 | + } | ||
81 | + | ||
82 | + private Path getPath(HostId one, HostId two) { | ||
83 | + Set<Path> paths = pathService.getPaths(one, two); | ||
54 | if (paths.isEmpty()) { | 84 | if (paths.isEmpty()) { |
55 | - throw new PathNotFoundException(); | 85 | + throw new PathNotFoundException("No path from host " + one + " to " + two); |
56 | } | 86 | } |
57 | - Path path = paths.iterator().next(); | 87 | + // TODO: let's be more intelligent about this eventually |
58 | - | 88 | + return paths.iterator().next(); |
59 | - return Arrays.asList((Intent) new PathIntent( | ||
60 | - intentIdGenerator.getNewId(), | ||
61 | - intent.getTrafficSelector(), | ||
62 | - intent.getTrafficTreatment(), | ||
63 | - new ConnectPoint(intent.getSrc(), PortNumber.ALL), | ||
64 | - new ConnectPoint(intent.getDst(), PortNumber.ALL), | ||
65 | - path)); | ||
66 | } | 89 | } |
67 | } | 90 | } | ... | ... |
... | @@ -355,8 +355,8 @@ public class IntentManager | ... | @@ -355,8 +355,8 @@ public class IntentManager |
355 | private class InternalStoreDelegate implements IntentStoreDelegate { | 355 | private class InternalStoreDelegate implements IntentStoreDelegate { |
356 | @Override | 356 | @Override |
357 | public void notify(IntentEvent event) { | 357 | public void notify(IntentEvent event) { |
358 | - processStoreEvent(event); | ||
359 | eventDispatcher.post(event); | 358 | eventDispatcher.post(event); |
359 | + processStoreEvent(event); | ||
360 | } | 360 | } |
361 | } | 361 | } |
362 | 362 | ... | ... |
1 | package org.onlab.onos.net.intent.impl; | 1 | package org.onlab.onos.net.intent.impl; |
2 | 2 | ||
3 | -import java.util.Iterator; | ||
4 | - | ||
5 | import org.apache.felix.scr.annotations.Activate; | 3 | import org.apache.felix.scr.annotations.Activate; |
6 | import org.apache.felix.scr.annotations.Component; | 4 | import org.apache.felix.scr.annotations.Component; |
7 | import org.apache.felix.scr.annotations.Deactivate; | 5 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -12,7 +10,6 @@ import org.onlab.onos.net.ConnectPoint; | ... | @@ -12,7 +10,6 @@ import org.onlab.onos.net.ConnectPoint; |
12 | import org.onlab.onos.net.Link; | 10 | import org.onlab.onos.net.Link; |
13 | import org.onlab.onos.net.flow.DefaultFlowRule; | 11 | import org.onlab.onos.net.flow.DefaultFlowRule; |
14 | import org.onlab.onos.net.flow.DefaultTrafficSelector; | 12 | import org.onlab.onos.net.flow.DefaultTrafficSelector; |
15 | -import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
16 | import org.onlab.onos.net.flow.FlowRule; | 13 | import org.onlab.onos.net.flow.FlowRule; |
17 | import org.onlab.onos.net.flow.FlowRuleService; | 14 | import org.onlab.onos.net.flow.FlowRuleService; |
18 | import org.onlab.onos.net.flow.TrafficSelector; | 15 | import org.onlab.onos.net.flow.TrafficSelector; |
... | @@ -21,6 +18,10 @@ import org.onlab.onos.net.intent.IntentExtensionService; | ... | @@ -21,6 +18,10 @@ import org.onlab.onos.net.intent.IntentExtensionService; |
21 | import org.onlab.onos.net.intent.IntentInstaller; | 18 | import org.onlab.onos.net.intent.IntentInstaller; |
22 | import org.onlab.onos.net.intent.PathIntent; | 19 | import org.onlab.onos.net.intent.PathIntent; |
23 | 20 | ||
21 | +import java.util.Iterator; | ||
22 | + | ||
23 | +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder; | ||
24 | + | ||
24 | /** | 25 | /** |
25 | * Installer for {@link PathIntent path connectivity intents}. | 26 | * Installer for {@link PathIntent path connectivity intents}. |
26 | */ | 27 | */ |
... | @@ -51,18 +52,16 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { | ... | @@ -51,18 +52,16 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> { |
51 | DefaultTrafficSelector.builder(intent.getTrafficSelector()); | 52 | DefaultTrafficSelector.builder(intent.getTrafficSelector()); |
52 | Iterator<Link> links = intent.getPath().links().iterator(); | 53 | Iterator<Link> links = intent.getPath().links().iterator(); |
53 | ConnectPoint prev = links.next().dst(); | 54 | ConnectPoint prev = links.next().dst(); |
55 | + | ||
54 | while (links.hasNext()) { | 56 | while (links.hasNext()) { |
55 | builder.matchInport(prev.port()); | 57 | builder.matchInport(prev.port()); |
56 | Link link = links.next(); | 58 | Link link = links.next(); |
57 | - | 59 | + TrafficTreatment treatment = builder() |
58 | - TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | 60 | + .setOutput(link.src().port()).build(); |
59 | - treat.setOutput(link.src().port()); | ||
60 | - | ||
61 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), | 61 | FlowRule rule = new DefaultFlowRule(link.src().deviceId(), |
62 | - builder.build(), treat.build(), | 62 | + builder.build(), treatment, |
63 | - 10, appId, 30); | 63 | + 123, appId, 600); |
64 | flowRuleService.applyFlowRules(rule); | 64 | flowRuleService.applyFlowRules(rule); |
65 | - | ||
66 | prev = link.dst(); | 65 | prev = link.dst(); |
67 | } | 66 | } |
68 | 67 | ... | ... |
-
Please register or login to post a comment