Committed by
Gerrit Code Review
support addition and removal of mcast sinks
vlan mcast rules are now optional Change-Id: Icb7022089a6e139970040d8cdea97df0cdc8dc7c
Showing
6 changed files
with
156 additions
and
47 deletions
... | @@ -28,10 +28,8 @@ import org.apache.felix.scr.annotations.Property; | ... | @@ -28,10 +28,8 @@ import org.apache.felix.scr.annotations.Property; |
28 | import org.apache.felix.scr.annotations.Reference; | 28 | import org.apache.felix.scr.annotations.Reference; |
29 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 29 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
30 | import org.onlab.packet.Ethernet; | 30 | import org.onlab.packet.Ethernet; |
31 | -import org.onlab.packet.IPv4; | ||
32 | import org.onlab.packet.IpAddress; | 31 | import org.onlab.packet.IpAddress; |
33 | import org.onlab.packet.VlanId; | 32 | import org.onlab.packet.VlanId; |
34 | -import org.onlab.util.Tools; | ||
35 | import org.onosproject.cfg.ComponentConfigService; | 33 | import org.onosproject.cfg.ComponentConfigService; |
36 | import org.onosproject.codec.CodecService; | 34 | import org.onosproject.codec.CodecService; |
37 | import org.onosproject.core.ApplicationId; | 35 | import org.onosproject.core.ApplicationId; |
... | @@ -60,10 +58,13 @@ import org.slf4j.Logger; | ... | @@ -60,10 +58,13 @@ import org.slf4j.Logger; |
60 | 58 | ||
61 | import java.util.Dictionary; | 59 | import java.util.Dictionary; |
62 | import java.util.Map; | 60 | import java.util.Map; |
61 | +import java.util.Properties; | ||
63 | import java.util.concurrent.atomic.AtomicBoolean; | 62 | import java.util.concurrent.atomic.AtomicBoolean; |
64 | import java.util.concurrent.atomic.AtomicInteger; | 63 | import java.util.concurrent.atomic.AtomicInteger; |
65 | 64 | ||
65 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
66 | import static com.google.common.net.MediaType.JSON_UTF_8; | 66 | import static com.google.common.net.MediaType.JSON_UTF_8; |
67 | +import static org.onlab.util.Tools.get; | ||
67 | import static org.slf4j.LoggerFactory.getLogger; | 68 | import static org.slf4j.LoggerFactory.getLogger; |
68 | 69 | ||
69 | /** | 70 | /** |
... | @@ -76,6 +77,10 @@ public class CordMcast { | ... | @@ -76,6 +77,10 @@ public class CordMcast { |
76 | 77 | ||
77 | private static final int DEFAULT_PRIORITY = 1000; | 78 | private static final int DEFAULT_PRIORITY = 1000; |
78 | private static final short DEFAULT_MCAST_VLAN = 4000; | 79 | private static final short DEFAULT_MCAST_VLAN = 4000; |
80 | + private static final String DEFAULT_SYNC_HOST = "10.90.0.8:8181"; | ||
81 | + private static final String DEFAULT_USER = "karaf"; | ||
82 | + private static final String DEFAULT_PASSWORD = "karaf"; | ||
83 | + | ||
79 | private final Logger log = getLogger(getClass()); | 84 | private final Logger log = getLogger(getClass()); |
80 | 85 | ||
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 86 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
... | @@ -96,11 +101,8 @@ public class CordMcast { | ... | @@ -96,11 +101,8 @@ public class CordMcast { |
96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 101 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
97 | protected ComponentConfigService componentConfigService; | 102 | protected ComponentConfigService componentConfigService; |
98 | 103 | ||
99 | - | ||
100 | protected McastListener listener = new InternalMulticastListener(); | 104 | protected McastListener listener = new InternalMulticastListener(); |
101 | 105 | ||
102 | - | ||
103 | - | ||
104 | //TODO: move this to a ec map | 106 | //TODO: move this to a ec map |
105 | private Map<IpAddress, Integer> groups = Maps.newConcurrentMap(); | 107 | private Map<IpAddress, Integer> groups = Maps.newConcurrentMap(); |
106 | 108 | ||
... | @@ -109,18 +111,21 @@ public class CordMcast { | ... | @@ -109,18 +111,21 @@ public class CordMcast { |
109 | 111 | ||
110 | private ApplicationId appId; | 112 | private ApplicationId appId; |
111 | 113 | ||
112 | - //TODO: network config this | 114 | + @Property(name = "mcastVlan", intValue = DEFAULT_MCAST_VLAN, |
113 | - private short mcastVlan = DEFAULT_MCAST_VLAN; | 115 | + label = "VLAN for multicast traffic") |
116 | + private int mcastVlan = DEFAULT_MCAST_VLAN; | ||
114 | 117 | ||
115 | - // TODO component config this | 118 | + @Property(name = "vlanEnabled", boolValue = false, |
116 | - private int priority = DEFAULT_PRIORITY; | 119 | + label = "Use vlan for multicast traffic") |
120 | + private boolean vlanEnabled = false; | ||
117 | 121 | ||
118 | - private static final String DEFAULT_USER = "karaf"; | 122 | + @Property(name = "priority", intValue = DEFAULT_PRIORITY, |
119 | - private static final String DEFAULT_PASSWORD = "karaf"; | 123 | + label = "Priority for multicast rules") |
124 | + private int priority = DEFAULT_PRIORITY; | ||
120 | 125 | ||
121 | - @Property(name = "syncHost", value = "", | 126 | + @Property(name = "syncHost", value = DEFAULT_SYNC_HOST, |
122 | label = "host:port to synchronize routes to") | 127 | label = "host:port to synchronize routes to") |
123 | - private String syncHost = "10.90.0.8:8181"; | 128 | + private String syncHost = DEFAULT_SYNC_HOST; |
124 | 129 | ||
125 | @Property(name = "username", value = DEFAULT_USER, | 130 | @Property(name = "username", value = DEFAULT_USER, |
126 | label = "Username for REST password authentication") | 131 | label = "Username for REST password authentication") |
... | @@ -153,10 +158,37 @@ public class CordMcast { | ... | @@ -153,10 +158,37 @@ public class CordMcast { |
153 | 158 | ||
154 | @Modified | 159 | @Modified |
155 | public void modified(ComponentContext context) { | 160 | public void modified(ComponentContext context) { |
156 | - Dictionary<?, ?> properties = context.getProperties(); | 161 | + Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); |
157 | - user = Tools.get(properties, "username"); | 162 | + |
158 | - password = Tools.get(properties, "password"); | 163 | + |
159 | - syncHost = Tools.get(properties, "syncHost"); | 164 | + try { |
165 | + String s = get(properties, "username"); | ||
166 | + user = isNullOrEmpty(s) ? DEFAULT_USER : s.trim(); | ||
167 | + | ||
168 | + s = get(properties, "password"); | ||
169 | + password = isNullOrEmpty(s) ? DEFAULT_PASSWORD : s.trim(); | ||
170 | + | ||
171 | + s = get(properties, "mcastVlan"); | ||
172 | + mcastVlan = isNullOrEmpty(s) ? DEFAULT_MCAST_VLAN : Short.parseShort(s.trim()); | ||
173 | + | ||
174 | + s = get(properties, "vlanEnabled"); | ||
175 | + vlanEnabled = isNullOrEmpty(s) || Boolean.parseBoolean(s.trim()); | ||
176 | + | ||
177 | + s = get(properties, "priority"); | ||
178 | + priority = isNullOrEmpty(s) ? DEFAULT_PRIORITY : Integer.parseInt(s.trim()); | ||
179 | + | ||
180 | + s = get(properties, syncHost); | ||
181 | + syncHost = isNullOrEmpty(s) ? DEFAULT_SYNC_HOST : s.trim(); | ||
182 | + } catch (Exception e) { | ||
183 | + user = DEFAULT_USER; | ||
184 | + password = DEFAULT_PASSWORD; | ||
185 | + syncHost = DEFAULT_SYNC_HOST; | ||
186 | + mcastVlan = DEFAULT_MCAST_VLAN; | ||
187 | + vlanEnabled = false; | ||
188 | + priority = DEFAULT_PRIORITY; | ||
189 | + } | ||
190 | + | ||
191 | + | ||
160 | } | 192 | } |
161 | 193 | ||
162 | private class InternalMulticastListener implements McastListener { | 194 | private class InternalMulticastListener implements McastListener { |
... | @@ -173,6 +205,7 @@ public class CordMcast { | ... | @@ -173,6 +205,7 @@ public class CordMcast { |
173 | provisionGroup(event.subject()); | 205 | provisionGroup(event.subject()); |
174 | break; | 206 | break; |
175 | case SINK_REMOVED: | 207 | case SINK_REMOVED: |
208 | + unprovisionGroup(event.subject()); | ||
176 | break; | 209 | break; |
177 | default: | 210 | default: |
178 | log.warn("Unknown mcast event {}", event.type()); | 211 | log.warn("Unknown mcast event {}", event.type()); |
... | @@ -180,6 +213,39 @@ public class CordMcast { | ... | @@ -180,6 +213,39 @@ public class CordMcast { |
180 | } | 213 | } |
181 | } | 214 | } |
182 | 215 | ||
216 | + private void unprovisionGroup(McastRouteInfo info) { | ||
217 | + if (!info.sink().isPresent()) { | ||
218 | + log.warn("No sink given after sink removed event: {}", info); | ||
219 | + return; | ||
220 | + } | ||
221 | + ConnectPoint loc = info.sink().get(); | ||
222 | + | ||
223 | + NextObjective next = DefaultNextObjective.builder() | ||
224 | + .fromApp(appId) | ||
225 | + .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build()) | ||
226 | + .withType(NextObjective.Type.BROADCAST) | ||
227 | + .withId(groups.get(info.route().group())) | ||
228 | + .removeFromExisting(new ObjectiveContext() { | ||
229 | + @Override | ||
230 | + public void onSuccess(Objective objective) { | ||
231 | + //TODO: change to debug | ||
232 | + log.info("Next Objective {} installed", objective.id()); | ||
233 | + } | ||
234 | + | ||
235 | + @Override | ||
236 | + public void onError(Objective objective, ObjectiveError error) { | ||
237 | + //TODO: change to debug | ||
238 | + log.info("Next Objective {} failed, because {}", | ||
239 | + objective.id(), | ||
240 | + error); | ||
241 | + } | ||
242 | + }); | ||
243 | + | ||
244 | + flowObjectiveService.next(loc.deviceId(), next); | ||
245 | + | ||
246 | + | ||
247 | + } | ||
248 | + | ||
183 | private void provisionGroup(McastRouteInfo info) { | 249 | private void provisionGroup(McastRouteInfo info) { |
184 | if (!info.sink().isPresent()) { | 250 | if (!info.sink().isPresent()) { |
185 | log.warn("No sink given after sink added event: {}", info); | 251 | log.warn("No sink given after sink added event: {}", info); |
... | @@ -192,12 +258,37 @@ public class CordMcast { | ... | @@ -192,12 +258,37 @@ public class CordMcast { |
192 | Integer nextId = groups.computeIfAbsent(info.route().group(), (g) -> { | 258 | Integer nextId = groups.computeIfAbsent(info.route().group(), (g) -> { |
193 | Integer id = allocateId(); | 259 | Integer id = allocateId(); |
194 | 260 | ||
195 | - TrafficSelector mcast = DefaultTrafficSelector.builder() | 261 | + NextObjective next = DefaultNextObjective.builder() |
196 | - .matchVlanId(VlanId.vlanId(mcastVlan)) | 262 | + .fromApp(appId) |
263 | + .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build()) | ||
264 | + .withType(NextObjective.Type.BROADCAST) | ||
265 | + .withId(id) | ||
266 | + .add(new ObjectiveContext() { | ||
267 | + @Override | ||
268 | + public void onSuccess(Objective objective) { | ||
269 | + //TODO: change to debug | ||
270 | + log.info("Next Objective {} installed", objective.id()); | ||
271 | + } | ||
272 | + | ||
273 | + @Override | ||
274 | + public void onError(Objective objective, ObjectiveError error) { | ||
275 | + //TODO: change to debug | ||
276 | + log.info("Next Objective {} failed, because {}", | ||
277 | + objective.id(), | ||
278 | + error); | ||
279 | + } | ||
280 | + }); | ||
281 | + | ||
282 | + flowObjectiveService.next(loc.deviceId(), next); | ||
283 | + | ||
284 | + TrafficSelector.Builder mcast = DefaultTrafficSelector.builder() | ||
197 | .matchEthType(Ethernet.TYPE_IPV4) | 285 | .matchEthType(Ethernet.TYPE_IPV4) |
198 | - .matchIPProtocol(IPv4.PROTOCOL_IGMP) | 286 | + .matchIPDst(g.toIpPrefix()); |
199 | - .matchIPDst(g.toIpPrefix()) | 287 | + |
200 | - .build(); | 288 | + |
289 | + if (vlanEnabled) { | ||
290 | + mcast.matchVlanId(VlanId.vlanId((short) mcastVlan)); | ||
291 | + } | ||
201 | 292 | ||
202 | 293 | ||
203 | ForwardingObjective fwd = DefaultForwardingObjective.builder() | 294 | ForwardingObjective fwd = DefaultForwardingObjective.builder() |
... | @@ -206,7 +297,7 @@ public class CordMcast { | ... | @@ -206,7 +297,7 @@ public class CordMcast { |
206 | .makePermanent() | 297 | .makePermanent() |
207 | .withFlag(ForwardingObjective.Flag.VERSATILE) | 298 | .withFlag(ForwardingObjective.Flag.VERSATILE) |
208 | .withPriority(priority) | 299 | .withPriority(priority) |
209 | - .withSelector(mcast) | 300 | + .withSelector(mcast.build()) |
210 | .add(new ObjectiveContext() { | 301 | .add(new ObjectiveContext() { |
211 | @Override | 302 | @Override |
212 | public void onSuccess(Objective objective) { | 303 | public void onSuccess(Objective objective) { |
... | @@ -228,6 +319,7 @@ public class CordMcast { | ... | @@ -228,6 +319,7 @@ public class CordMcast { |
228 | return id; | 319 | return id; |
229 | }); | 320 | }); |
230 | 321 | ||
322 | + if (!sync.get()) { | ||
231 | NextObjective next = DefaultNextObjective.builder() | 323 | NextObjective next = DefaultNextObjective.builder() |
232 | .fromApp(appId) | 324 | .fromApp(appId) |
233 | .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build()) | 325 | .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build()) |
... | @@ -250,6 +342,7 @@ public class CordMcast { | ... | @@ -250,6 +342,7 @@ public class CordMcast { |
250 | }); | 342 | }); |
251 | 343 | ||
252 | flowObjectiveService.next(loc.deviceId(), next); | 344 | flowObjectiveService.next(loc.deviceId(), next); |
345 | + } | ||
253 | 346 | ||
254 | if (sync.get()) { | 347 | if (sync.get()) { |
255 | syncRoute(info); | 348 | syncRoute(info); | ... | ... |
... | @@ -246,7 +246,7 @@ public class IgmpSnoop { | ... | @@ -246,7 +246,7 @@ public class IgmpSnoop { |
246 | .withMeta(DefaultTrafficTreatment.builder() | 246 | .withMeta(DefaultTrafficTreatment.builder() |
247 | .setOutput(PortNumber.CONTROLLER).build()) | 247 | .setOutput(PortNumber.CONTROLLER).build()) |
248 | .fromApp(appId) | 248 | .fromApp(appId) |
249 | - .withPriority(1000) | 249 | + .withPriority(10000) |
250 | .add(new ObjectiveContext() { | 250 | .add(new ObjectiveContext() { |
251 | @Override | 251 | @Override |
252 | public void onSuccess(Objective objective) { | 252 | public void onSuccess(Objective objective) { |
... | @@ -417,6 +417,7 @@ public class IgmpSnoop { | ... | @@ -417,6 +417,7 @@ public class IgmpSnoop { |
417 | private class InternalDeviceListener implements DeviceListener { | 417 | private class InternalDeviceListener implements DeviceListener { |
418 | @Override | 418 | @Override |
419 | public void event(DeviceEvent event) { | 419 | public void event(DeviceEvent event) { |
420 | + DeviceId devId = event.subject().id(); | ||
420 | switch (event.type()) { | 421 | switch (event.type()) { |
421 | 422 | ||
422 | case DEVICE_ADDED: | 423 | case DEVICE_ADDED: |
... | @@ -427,11 +428,15 @@ public class IgmpSnoop { | ... | @@ -427,11 +428,15 @@ public class IgmpSnoop { |
427 | case PORT_STATS_UPDATED: | 428 | case PORT_STATS_UPDATED: |
428 | break; | 429 | break; |
429 | case PORT_ADDED: | 430 | case PORT_ADDED: |
430 | - if (event.port().isEnabled()) { | 431 | + if (!oltData.get(devId).uplink().equals(event.port().number()) && |
432 | + event.port().isEnabled()) { | ||
431 | processFilterObjective(event.subject().id(), event.port(), false); | 433 | processFilterObjective(event.subject().id(), event.port(), false); |
432 | } | 434 | } |
433 | break; | 435 | break; |
434 | case PORT_UPDATED: | 436 | case PORT_UPDATED: |
437 | + if (oltData.get(devId).uplink().equals(event.port().number())) { | ||
438 | + break; | ||
439 | + } | ||
435 | if (event.port().isEnabled()) { | 440 | if (event.port().isEnabled()) { |
436 | processFilterObjective(event.subject().id(), event.port(), false); | 441 | processFilterObjective(event.subject().id(), event.port(), false); |
437 | } else { | 442 | } else { | ... | ... |
... | @@ -15,13 +15,10 @@ | ... | @@ -15,13 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.store.serializers; | 16 | package org.onosproject.store.serializers; |
17 | 17 | ||
18 | -import com.esotericsoftware.kryo.serializers.JavaSerializer; | ||
19 | import com.google.common.collect.ImmutableList; | 18 | import com.google.common.collect.ImmutableList; |
20 | import com.google.common.collect.ImmutableMap; | 19 | import com.google.common.collect.ImmutableMap; |
21 | import com.google.common.collect.ImmutableSet; | 20 | import com.google.common.collect.ImmutableSet; |
22 | import com.google.common.collect.Maps; | 21 | import com.google.common.collect.Maps; |
23 | -import com.google.common.collect.Sets; | ||
24 | - | ||
25 | import org.onlab.packet.ChassisId; | 22 | import org.onlab.packet.ChassisId; |
26 | import org.onlab.packet.EthType; | 23 | import org.onlab.packet.EthType; |
27 | import org.onlab.packet.Ip4Address; | 24 | import org.onlab.packet.Ip4Address; |
... | @@ -90,8 +87,8 @@ import org.onosproject.net.device.DefaultPortDescription; | ... | @@ -90,8 +87,8 @@ import org.onosproject.net.device.DefaultPortDescription; |
90 | import org.onosproject.net.device.DefaultPortStatistics; | 87 | import org.onosproject.net.device.DefaultPortStatistics; |
91 | import org.onosproject.net.device.OchPortDescription; | 88 | import org.onosproject.net.device.OchPortDescription; |
92 | import org.onosproject.net.device.OduCltPortDescription; | 89 | import org.onosproject.net.device.OduCltPortDescription; |
93 | -import org.onosproject.net.device.OtuPortDescription; | ||
94 | import org.onosproject.net.device.OmsPortDescription; | 90 | import org.onosproject.net.device.OmsPortDescription; |
91 | +import org.onosproject.net.device.OtuPortDescription; | ||
95 | import org.onosproject.net.device.PortStatistics; | 92 | import org.onosproject.net.device.PortStatistics; |
96 | import org.onosproject.net.flow.CompletedBatchOperation; | 93 | import org.onosproject.net.flow.CompletedBatchOperation; |
97 | import org.onosproject.net.flow.DefaultFlowEntry; | 94 | import org.onosproject.net.flow.DefaultFlowEntry; |
... | @@ -257,7 +254,6 @@ public final class KryoNamespaces { | ... | @@ -257,7 +254,6 @@ public final class KryoNamespaces { |
257 | .register(HashMap.class) | 254 | .register(HashMap.class) |
258 | .register(ConcurrentHashMap.class) | 255 | .register(ConcurrentHashMap.class) |
259 | .register(CopyOnWriteArraySet.class) | 256 | .register(CopyOnWriteArraySet.class) |
260 | - .register(new JavaSerializer(), Sets.newConcurrentHashSet().getClass()) | ||
261 | .register(ArrayList.class, | 257 | .register(ArrayList.class, |
262 | LinkedList.class, | 258 | LinkedList.class, |
263 | HashSet.class, | 259 | HashSet.class, |
... | @@ -541,5 +537,6 @@ public final class KryoNamespaces { | ... | @@ -541,5 +537,6 @@ public final class KryoNamespaces { |
541 | 537 | ||
542 | 538 | ||
543 | // not to be instantiated | 539 | // not to be instantiated |
544 | - private KryoNamespaces() {} | 540 | + private KryoNamespaces() { |
541 | + } | ||
545 | } | 542 | } | ... | ... |
... | @@ -25,6 +25,7 @@ import org.apache.commons.lang3.tuple.Pair; | ... | @@ -25,6 +25,7 @@ import org.apache.commons.lang3.tuple.Pair; |
25 | import org.onlab.osgi.ServiceDirectory; | 25 | import org.onlab.osgi.ServiceDirectory; |
26 | import org.onlab.packet.EthType; | 26 | import org.onlab.packet.EthType; |
27 | import org.onlab.packet.IPv4; | 27 | import org.onlab.packet.IPv4; |
28 | +import org.onlab.packet.IpPrefix; | ||
28 | import org.onlab.packet.VlanId; | 29 | import org.onlab.packet.VlanId; |
29 | import org.onlab.util.KryoNamespace; | 30 | import org.onlab.util.KryoNamespace; |
30 | import org.onosproject.core.ApplicationId; | 31 | import org.onosproject.core.ApplicationId; |
... | @@ -47,6 +48,7 @@ import org.onosproject.net.flow.TrafficTreatment; | ... | @@ -47,6 +48,7 @@ import org.onosproject.net.flow.TrafficTreatment; |
47 | import org.onosproject.net.flow.criteria.Criteria; | 48 | import org.onosproject.net.flow.criteria.Criteria; |
48 | import org.onosproject.net.flow.criteria.Criterion; | 49 | import org.onosproject.net.flow.criteria.Criterion; |
49 | import org.onosproject.net.flow.criteria.EthTypeCriterion; | 50 | import org.onosproject.net.flow.criteria.EthTypeCriterion; |
51 | +import org.onosproject.net.flow.criteria.IPCriterion; | ||
50 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; | 52 | import org.onosproject.net.flow.criteria.IPProtocolCriterion; |
51 | import org.onosproject.net.flow.criteria.PortCriterion; | 53 | import org.onosproject.net.flow.criteria.PortCriterion; |
52 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 54 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
... | @@ -99,6 +101,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -99,6 +101,7 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
99 | 101 | ||
100 | private DeviceId deviceId; | 102 | private DeviceId deviceId; |
101 | private ApplicationId appId; | 103 | private ApplicationId appId; |
104 | + private IpPrefix mcastPrefix = IpPrefix.valueOf("224.0.0.0/4"); | ||
102 | 105 | ||
103 | protected FlowObjectiveStore flowObjectiveStore; | 106 | protected FlowObjectiveStore flowObjectiveStore; |
104 | 107 | ||
... | @@ -253,6 +256,12 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -253,6 +256,12 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
253 | GroupBucket bucket = DefaultGroupBucket.createAllGroupBucket(treatment); | 256 | GroupBucket bucket = DefaultGroupBucket.createAllGroupBucket(treatment); |
254 | GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); | 257 | GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); |
255 | 258 | ||
259 | + | ||
260 | + | ||
261 | + pendingGroups.put(key, nextObjective); | ||
262 | + | ||
263 | + switch (nextObjective.op()) { | ||
264 | + case ADD: | ||
256 | GroupDescription groupDesc = | 265 | GroupDescription groupDesc = |
257 | new DefaultGroupDescription(deviceId, | 266 | new DefaultGroupDescription(deviceId, |
258 | GroupDescription.Type.ALL, | 267 | GroupDescription.Type.ALL, |
... | @@ -260,19 +269,20 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -260,19 +269,20 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
260 | key, | 269 | key, |
261 | null, | 270 | null, |
262 | nextObjective.appId()); | 271 | nextObjective.appId()); |
263 | - | ||
264 | - pendingGroups.put(key, nextObjective); | ||
265 | - | ||
266 | - switch (nextObjective.op()) { | ||
267 | - case ADD: | ||
268 | groupService.addGroup(groupDesc); | 272 | groupService.addGroup(groupDesc); |
269 | break; | 273 | break; |
270 | case REMOVE: | 274 | case REMOVE: |
271 | groupService.removeGroup(deviceId, key, nextObjective.appId()); | 275 | groupService.removeGroup(deviceId, key, nextObjective.appId()); |
272 | break; | 276 | break; |
273 | case ADD_TO_EXISTING: | 277 | case ADD_TO_EXISTING: |
278 | + groupService.addBucketsToGroup(deviceId, key, | ||
279 | + new GroupBuckets(Collections.singletonList(bucket)), | ||
280 | + key, nextObjective.appId()); | ||
281 | + break; | ||
274 | case REMOVE_FROM_EXISTING: | 282 | case REMOVE_FROM_EXISTING: |
275 | - //TODO: handle addition to group when caller signals it. | 283 | + groupService.removeBucketsFromGroup(deviceId, key, |
284 | + new GroupBuckets(Collections.singletonList(bucket)), | ||
285 | + key, nextObjective.appId()); | ||
276 | break; | 286 | break; |
277 | default: | 287 | default: |
278 | log.warn("Unknown next objective operation: {}", nextObjective.op()); | 288 | log.warn("Unknown next objective operation: {}", nextObjective.op()); |
... | @@ -287,14 +297,14 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -287,14 +297,14 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
287 | fail(fwd, ObjectiveError.BADPARAMS); | 297 | fail(fwd, ObjectiveError.BADPARAMS); |
288 | } | 298 | } |
289 | 299 | ||
290 | - OLTPipelineGroup next = getGroupForNextObjective(fwd.nextId()); | 300 | + GroupKey key = getGroupForNextObjective(fwd.nextId()); |
291 | 301 | ||
292 | - if (next == null) { | 302 | + if (key == null) { |
293 | log.error("Group for forwarding objective missing: {}", fwd); | 303 | log.error("Group for forwarding objective missing: {}", fwd); |
294 | fail(fwd, ObjectiveError.GROUPMISSING); | 304 | fail(fwd, ObjectiveError.GROUPMISSING); |
295 | } | 305 | } |
296 | 306 | ||
297 | - Group group = groupService.getGroup(deviceId, next.key()); | 307 | + Group group = groupService.getGroup(deviceId, key); |
298 | TrafficTreatment treatment = | 308 | TrafficTreatment treatment = |
299 | buildTreatment(Instructions.createGroup(group.id())); | 309 | buildTreatment(Instructions.createGroup(group.id())); |
300 | 310 | ||
... | @@ -330,16 +340,20 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { | ... | @@ -330,16 +340,20 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
330 | 340 | ||
331 | private boolean checkForMulticast(ForwardingObjective fwd) { | 341 | private boolean checkForMulticast(ForwardingObjective fwd) { |
332 | 342 | ||
333 | - VlanIdCriterion vlan = (VlanIdCriterion) filterForCriterion(fwd.selector().criteria(), | 343 | + IPCriterion ip = (IPCriterion) filterForCriterion(fwd.selector().criteria(), |
334 | - Criterion.Type.VLAN_VID); | 344 | + Criterion.Type.IPV4_DST); |
345 | + | ||
346 | + if (ip == null) { | ||
347 | + return false; | ||
348 | + } | ||
335 | 349 | ||
336 | - return (vlan != null && vlan.vlanId().equals(VlanId.vlanId(MCAST_VLAN))); | 350 | + return mcastPrefix.contains(ip.ip()); |
337 | 351 | ||
338 | } | 352 | } |
339 | 353 | ||
340 | - private OLTPipelineGroup getGroupForNextObjective(Integer nextId) { | 354 | + private GroupKey getGroupForNextObjective(Integer nextId) { |
341 | NextGroup next = flowObjectiveStore.getNextGroup(nextId); | 355 | NextGroup next = flowObjectiveStore.getNextGroup(nextId); |
342 | - return (OLTPipelineGroup) appKryo.deserialize(next.data()); | 356 | + return appKryo.deserialize(next.data()); |
343 | 357 | ||
344 | } | 358 | } |
345 | 359 | ... | ... |
... | @@ -66,9 +66,9 @@ public final class MulticastData { | ... | @@ -66,9 +66,9 @@ public final class MulticastData { |
66 | sinks.put(sink, true); | 66 | sinks.put(sink, true); |
67 | } | 67 | } |
68 | 68 | ||
69 | - public boolean removeSink(ConnectPoint sink) { | 69 | + public void removeSink(ConnectPoint sink) { |
70 | checkNotNull(sink); | 70 | checkNotNull(sink); |
71 | - return sinks.remove(sink); | 71 | + sinks.remove(sink); |
72 | } | 72 | } |
73 | 73 | ||
74 | public boolean isEmpty() { | 74 | public boolean isEmpty() { | ... | ... |
-
Please register or login to post a comment