Showing
9 changed files
with
121 additions
and
34 deletions
... | @@ -14,6 +14,7 @@ import org.onlab.onos.net.flow.TrafficSelector; | ... | @@ -14,6 +14,7 @@ import org.onlab.onos.net.flow.TrafficSelector; |
14 | import org.onlab.onos.net.flow.TrafficTreatment; | 14 | import org.onlab.onos.net.flow.TrafficTreatment; |
15 | import org.onlab.onos.net.host.HostService; | 15 | import org.onlab.onos.net.host.HostService; |
16 | import org.onlab.onos.net.intent.HostToHostIntent; | 16 | import org.onlab.onos.net.intent.HostToHostIntent; |
17 | +import org.onlab.onos.net.intent.Intent; | ||
17 | import org.onlab.onos.net.intent.IntentId; | 18 | import org.onlab.onos.net.intent.IntentId; |
18 | import org.onlab.onos.net.intent.IntentService; | 19 | import org.onlab.onos.net.intent.IntentService; |
19 | import org.onlab.onos.net.packet.DefaultOutboundPacket; | 20 | import org.onlab.onos.net.packet.DefaultOutboundPacket; |
... | @@ -26,6 +27,9 @@ import org.onlab.onos.net.topology.TopologyService; | ... | @@ -26,6 +27,9 @@ import org.onlab.onos.net.topology.TopologyService; |
26 | import org.onlab.packet.Ethernet; | 27 | import org.onlab.packet.Ethernet; |
27 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
28 | 29 | ||
30 | +import java.util.Map; | ||
31 | +import java.util.concurrent.ConcurrentHashMap; | ||
32 | + | ||
29 | import static org.slf4j.LoggerFactory.getLogger; | 33 | import static org.slf4j.LoggerFactory.getLogger; |
30 | 34 | ||
31 | /** | 35 | /** |
... | @@ -52,6 +56,8 @@ public class IntentReactiveForwarding { | ... | @@ -52,6 +56,8 @@ public class IntentReactiveForwarding { |
52 | 56 | ||
53 | private static long intentId = 1; | 57 | private static long intentId = 1; |
54 | 58 | ||
59 | + private Map<HostIdPair, IntentId> intents = new ConcurrentHashMap<>(); | ||
60 | + | ||
55 | @Activate | 61 | @Activate |
56 | public void activate() { | 62 | public void activate() { |
57 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); | 63 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); |
... | @@ -91,8 +97,12 @@ public class IntentReactiveForwarding { | ... | @@ -91,8 +97,12 @@ public class IntentReactiveForwarding { |
91 | return; | 97 | return; |
92 | } | 98 | } |
93 | 99 | ||
94 | - // Otherwise forward and be done with it. | 100 | + // Install a new intent only if we have not installed one already |
95 | - setUpConnectivity(context, srcId, dstId); | 101 | + HostIdPair key = new HostIdPair(srcId, dstId); |
102 | + if (!intents.containsKey(key)) { | ||
103 | + // Otherwise forward and be done with it. | ||
104 | + intents.put(key, setUpConnectivity(context, srcId, dstId).getId()); | ||
105 | + } | ||
96 | forwardPacketToDst(context, dst); | 106 | forwardPacketToDst(context, dst); |
97 | } | 107 | } |
98 | } | 108 | } |
... | @@ -122,15 +132,26 @@ public class IntentReactiveForwarding { | ... | @@ -122,15 +132,26 @@ public class IntentReactiveForwarding { |
122 | } | 132 | } |
123 | 133 | ||
124 | // Install a rule forwarding the packet to the specified port. | 134 | // Install a rule forwarding the packet to the specified port. |
125 | - private void setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) { | 135 | + private Intent setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) { |
126 | TrafficSelector selector = DefaultTrafficSelector.builder().build(); | 136 | TrafficSelector selector = DefaultTrafficSelector.builder().build(); |
127 | TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); | 137 | TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); |
128 | 138 | ||
129 | HostToHostIntent intent = | 139 | HostToHostIntent intent = |
130 | new HostToHostIntent(new IntentId(intentId++), srcId, dstId, | 140 | new HostToHostIntent(new IntentId(intentId++), srcId, dstId, |
131 | selector, treatment); | 141 | selector, treatment); |
132 | - | ||
133 | intentService.submit(intent); | 142 | intentService.submit(intent); |
143 | + return intent; | ||
134 | } | 144 | } |
135 | 145 | ||
146 | + | ||
147 | + private class HostIdPair { | ||
148 | + HostId one; | ||
149 | + HostId two; | ||
150 | + | ||
151 | + HostIdPair(HostId one, HostId two) { | ||
152 | + boolean oneFirst = one.hashCode() < two.hashCode(); | ||
153 | + this.one = oneFirst ? one : two; | ||
154 | + this.two = oneFirst ? two : one; | ||
155 | + } | ||
156 | + } | ||
136 | } | 157 | } | ... | ... |
1 | +package org.onlab.onos.cli; | ||
2 | + | ||
3 | +import org.apache.karaf.shell.commands.Command; | ||
4 | +import org.onlab.onos.cluster.ClusterService; | ||
5 | +import org.onlab.onos.net.device.DeviceService; | ||
6 | +import org.onlab.onos.net.flow.FlowRuleService; | ||
7 | +import org.onlab.onos.net.host.HostService; | ||
8 | +import org.onlab.onos.net.intent.IntentService; | ||
9 | +import org.onlab.onos.net.link.LinkService; | ||
10 | +import org.onlab.onos.net.topology.TopologyService; | ||
11 | + | ||
12 | +/** | ||
13 | + * Provides summary of ONOS model. | ||
14 | + */ | ||
15 | +@Command(scope = "onos", name = "summary", | ||
16 | + description = "Provides summary of ONOS model") | ||
17 | +public class SummaryCommand extends AbstractShellCommand { | ||
18 | + | ||
19 | + @Override | ||
20 | + protected void execute() { | ||
21 | + TopologyService topologyService = get(TopologyService.class); | ||
22 | + print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, flows=%d, intents=%d", | ||
23 | + get(ClusterService.class).getNodes().size(), | ||
24 | + get(DeviceService.class).getDeviceCount(), | ||
25 | + get(LinkService.class).getLinkCount(), | ||
26 | + get(HostService.class).getHostCount(), | ||
27 | + topologyService.getClusters(topologyService.currentTopology()).size(), | ||
28 | + get(FlowRuleService.class).getFlowRuleCount(), | ||
29 | + get(IntentService.class).getIntentCount()); | ||
30 | + } | ||
31 | + | ||
32 | +} |
... | @@ -2,6 +2,9 @@ | ... | @@ -2,6 +2,9 @@ |
2 | 2 | ||
3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | 3 | <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> |
4 | <command> | 4 | <command> |
5 | + <action class="org.onlab.onos.cli.SummaryCommand"/> | ||
6 | + </command> | ||
7 | + <command> | ||
5 | <action class="org.onlab.onos.cli.NodesListCommand"/> | 8 | <action class="org.onlab.onos.cli.NodesListCommand"/> |
6 | </command> | 9 | </command> |
7 | <command> | 10 | <command> | ... | ... |
... | @@ -13,6 +13,13 @@ import org.onlab.onos.net.DeviceId; | ... | @@ -13,6 +13,13 @@ import org.onlab.onos.net.DeviceId; |
13 | public interface FlowRuleService { | 13 | public interface FlowRuleService { |
14 | 14 | ||
15 | /** | 15 | /** |
16 | + * Returns the number of flow rules in the system. | ||
17 | + * | ||
18 | + * @return flow rule count | ||
19 | + */ | ||
20 | + int getFlowRuleCount(); | ||
21 | + | ||
22 | + /** | ||
16 | * Returns the collection of flow entries applied on the specified device. | 23 | * Returns the collection of flow entries applied on the specified device. |
17 | * This will include flow rules which may not yet have been applied to | 24 | * This will include flow rules which may not yet have been applied to |
18 | * the device. | 25 | * the device. |
... | @@ -72,7 +79,4 @@ public interface FlowRuleService { | ... | @@ -72,7 +79,4 @@ public interface FlowRuleService { |
72 | * @param listener flow rule listener | 79 | * @param listener flow rule listener |
73 | */ | 80 | */ |
74 | void removeListener(FlowRuleListener listener); | 81 | void removeListener(FlowRuleListener listener); |
75 | - | ||
76 | - | ||
77 | - | ||
78 | } | 82 | } | ... | ... |
... | @@ -10,7 +10,15 @@ import org.onlab.onos.store.Store; | ... | @@ -10,7 +10,15 @@ import org.onlab.onos.store.Store; |
10 | public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { | 10 | public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> { |
11 | 11 | ||
12 | /** | 12 | /** |
13 | + * Returns the number of flow rule in the store. | ||
14 | + * | ||
15 | + * @return number of flow rules | ||
16 | + */ | ||
17 | + int getFlowRuleCount(); | ||
18 | + | ||
19 | + /** | ||
13 | * Returns the stored flow. | 20 | * Returns the stored flow. |
21 | + * | ||
14 | * @param rule the rule to look for | 22 | * @param rule the rule to look for |
15 | * @return a flow rule | 23 | * @return a flow rule |
16 | */ | 24 | */ |
... | @@ -60,5 +68,4 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat | ... | @@ -60,5 +68,4 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat |
60 | * @return flow_removed event, or null if nothing removed | 68 | * @return flow_removed event, or null if nothing removed |
61 | */ | 69 | */ |
62 | FlowRuleEvent removeFlowRule(FlowEntry rule); | 70 | FlowRuleEvent removeFlowRule(FlowEntry rule); |
63 | - | ||
64 | } | 71 | } | ... | ... |
... | @@ -40,14 +40,14 @@ import com.google.common.collect.Lists; | ... | @@ -40,14 +40,14 @@ import com.google.common.collect.Lists; |
40 | @Component(immediate = true) | 40 | @Component(immediate = true) |
41 | @Service | 41 | @Service |
42 | public class FlowRuleManager | 42 | public class FlowRuleManager |
43 | -extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> | 43 | + extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService> |
44 | -implements FlowRuleService, FlowRuleProviderRegistry { | 44 | + implements FlowRuleService, FlowRuleProviderRegistry { |
45 | 45 | ||
46 | public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; | 46 | public static final String FLOW_RULE_NULL = "FlowRule cannot be null"; |
47 | private final Logger log = getLogger(getClass()); | 47 | private final Logger log = getLogger(getClass()); |
48 | 48 | ||
49 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> | 49 | private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener> |
50 | - listenerRegistry = new AbstractListenerRegistry<>(); | 50 | + listenerRegistry = new AbstractListenerRegistry<>(); |
51 | 51 | ||
52 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); | 52 | private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate(); |
53 | 53 | ||
... | @@ -75,6 +75,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -75,6 +75,11 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
75 | } | 75 | } |
76 | 76 | ||
77 | @Override | 77 | @Override |
78 | + public int getFlowRuleCount() { | ||
79 | + return store.getFlowRuleCount(); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
78 | public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { | 83 | public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { |
79 | return store.getFlowEntries(deviceId); | 84 | return store.getFlowEntries(deviceId); |
80 | } | 85 | } |
... | @@ -106,7 +111,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -106,7 +111,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
106 | 111 | ||
107 | @Override | 112 | @Override |
108 | public void removeFlowRulesById(ApplicationId id) { | 113 | public void removeFlowRulesById(ApplicationId id) { |
109 | - Iterable<FlowRule> rules = getFlowRulesById(id); | 114 | + Iterable<FlowRule> rules = getFlowRulesById(id); |
110 | FlowRuleProvider frp; | 115 | FlowRuleProvider frp; |
111 | Device device; | 116 | Device device; |
112 | 117 | ||
... | @@ -140,8 +145,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -140,8 +145,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
140 | } | 145 | } |
141 | 146 | ||
142 | private class InternalFlowRuleProviderService | 147 | private class InternalFlowRuleProviderService |
143 | - extends AbstractProviderService<FlowRuleProvider> | 148 | + extends AbstractProviderService<FlowRuleProvider> |
144 | - implements FlowRuleProviderService { | 149 | + implements FlowRuleProviderService { |
145 | 150 | ||
146 | protected InternalFlowRuleProviderService(FlowRuleProvider provider) { | 151 | protected InternalFlowRuleProviderService(FlowRuleProvider provider) { |
147 | super(provider); | 152 | super(provider); |
... | @@ -160,16 +165,16 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -160,16 +165,16 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
160 | FlowRuleProvider frp = getProvider(device.providerId()); | 165 | FlowRuleProvider frp = getProvider(device.providerId()); |
161 | FlowRuleEvent event = null; | 166 | FlowRuleEvent event = null; |
162 | switch (stored.state()) { | 167 | switch (stored.state()) { |
163 | - case ADDED: | 168 | + case ADDED: |
164 | - case PENDING_ADD: | 169 | + case PENDING_ADD: |
165 | frp.applyFlowRule(stored); | 170 | frp.applyFlowRule(stored); |
166 | - break; | 171 | + break; |
167 | - case PENDING_REMOVE: | 172 | + case PENDING_REMOVE: |
168 | - case REMOVED: | 173 | + case REMOVED: |
169 | - event = store.removeFlowRule(stored); | 174 | + event = store.removeFlowRule(stored); |
170 | - break; | 175 | + break; |
171 | - default: | 176 | + default: |
172 | - break; | 177 | + break; |
173 | 178 | ||
174 | } | 179 | } |
175 | if (event != null) { | 180 | if (event != null) { |
... | @@ -186,17 +191,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -186,17 +191,17 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
186 | FlowRuleProvider frp = getProvider(device.providerId()); | 191 | FlowRuleProvider frp = getProvider(device.providerId()); |
187 | FlowRuleEvent event = null; | 192 | FlowRuleEvent event = null; |
188 | switch (flowRule.state()) { | 193 | switch (flowRule.state()) { |
189 | - case PENDING_REMOVE: | 194 | + case PENDING_REMOVE: |
190 | - case REMOVED: | 195 | + case REMOVED: |
191 | - event = store.removeFlowRule(flowRule); | 196 | + event = store.removeFlowRule(flowRule); |
192 | - frp.removeFlowRule(flowRule); | 197 | + frp.removeFlowRule(flowRule); |
193 | - break; | 198 | + break; |
194 | - case ADDED: | 199 | + case ADDED: |
195 | - case PENDING_ADD: | 200 | + case PENDING_ADD: |
196 | - frp.applyFlowRule(flowRule); | 201 | + frp.applyFlowRule(flowRule); |
197 | - break; | 202 | + break; |
198 | - default: | 203 | + default: |
199 | - log.debug("Flow {} has not been installed.", flowRule); | 204 | + log.debug("Flow {} has not been installed.", flowRule); |
200 | } | 205 | } |
201 | 206 | ||
202 | if (event != null) { | 207 | if (event != null) { | ... | ... |
... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore | ... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore |
58 | 58 | ||
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | + public int getFlowRuleCount() { | ||
62 | + return flowEntries.size(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
61 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 66 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
62 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 67 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
63 | if (f.equals(rule)) { | 68 | if (f.equals(rule)) { | ... | ... |
... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore | ... | @@ -58,6 +58,11 @@ public class DistributedFlowRuleStore |
58 | 58 | ||
59 | 59 | ||
60 | @Override | 60 | @Override |
61 | + public int getFlowRuleCount() { | ||
62 | + return flowEntries.size(); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
61 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 66 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
62 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 67 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
63 | if (f.equals(rule)) { | 68 | if (f.equals(rule)) { | ... | ... |
... | @@ -57,6 +57,11 @@ public class SimpleFlowRuleStore | ... | @@ -57,6 +57,11 @@ public class SimpleFlowRuleStore |
57 | 57 | ||
58 | 58 | ||
59 | @Override | 59 | @Override |
60 | + public int getFlowRuleCount() { | ||
61 | + return flowEntries.size(); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
60 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { | 65 | public synchronized FlowEntry getFlowEntry(FlowRule rule) { |
61 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { | 66 | for (FlowEntry f : flowEntries.get(rule.deviceId())) { |
62 | if (f.equals(rule)) { | 67 | if (f.equals(rule)) { | ... | ... |
-
Please register or login to post a comment