Committed by
Gerrit Code Review
updated mcastforwarding to handle new events
Change-Id: I8b3e9acc147e1f25f19ac25e579f65353cf0c72e
Showing
1 changed file
with
119 additions
and
31 deletions
| ... | @@ -32,7 +32,13 @@ import org.onosproject.net.flow.DefaultTrafficSelector; | ... | @@ -32,7 +32,13 @@ import org.onosproject.net.flow.DefaultTrafficSelector; |
| 32 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 32 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 33 | import org.onosproject.net.flow.TrafficSelector; | 33 | import org.onosproject.net.flow.TrafficSelector; |
| 34 | import org.onosproject.net.flow.TrafficTreatment; | 34 | import org.onosproject.net.flow.TrafficTreatment; |
| 35 | +import org.onosproject.net.intent.Intent; | ||
| 36 | +import org.onosproject.net.intent.IntentService; | ||
| 37 | +import org.onosproject.net.intent.Key; | ||
| 38 | +import org.onosproject.net.intent.SinglePointToMultiPointIntent; | ||
| 35 | import org.onosproject.net.mcast.McastRoute; | 39 | import org.onosproject.net.mcast.McastRoute; |
| 40 | +import org.onosproject.net.mcast.McastListener; | ||
| 41 | +import org.onosproject.net.mcast.McastEvent; | ||
| 36 | import org.onosproject.net.mcast.MulticastRouteService; | 42 | import org.onosproject.net.mcast.MulticastRouteService; |
| 37 | import org.onosproject.net.packet.DefaultOutboundPacket; | 43 | import org.onosproject.net.packet.DefaultOutboundPacket; |
| 38 | import org.onosproject.net.packet.InboundPacket; | 44 | import org.onosproject.net.packet.InboundPacket; |
| ... | @@ -44,6 +50,10 @@ import org.onosproject.net.packet.PacketService; | ... | @@ -44,6 +50,10 @@ import org.onosproject.net.packet.PacketService; |
| 44 | import org.slf4j.Logger; | 50 | import org.slf4j.Logger; |
| 45 | 51 | ||
| 46 | import java.util.ArrayList; | 52 | import java.util.ArrayList; |
| 53 | +import java.util.HashMap; | ||
| 54 | +import java.util.HashSet; | ||
| 55 | +import java.util.Map; | ||
| 56 | +import java.util.Set; | ||
| 47 | 57 | ||
| 48 | import static com.google.common.base.Preconditions.checkNotNull; | 58 | import static com.google.common.base.Preconditions.checkNotNull; |
| 49 | import static org.slf4j.LoggerFactory.getLogger; | 59 | import static org.slf4j.LoggerFactory.getLogger; |
| ... | @@ -66,9 +76,12 @@ public class McastForwarding { | ... | @@ -66,9 +76,12 @@ public class McastForwarding { |
| 66 | protected CoreService coreService; | 76 | protected CoreService coreService; |
| 67 | 77 | ||
| 68 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 78 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 69 | - protected MulticastRouteService mcastRouteManager; | 79 | + private IntentService intentService; |
| 70 | 80 | ||
| 81 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 82 | + protected MulticastRouteService mcastRouteManager; | ||
| 71 | 83 | ||
| 84 | + protected McastIntentManager mcastIntentManager; | ||
| 72 | 85 | ||
| 73 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); | 86 | private ReactivePacketProcessor processor = new ReactivePacketProcessor(); |
| 74 | private static ApplicationId appId; | 87 | private static ApplicationId appId; |
| ... | @@ -80,6 +93,9 @@ public class McastForwarding { | ... | @@ -80,6 +93,9 @@ public class McastForwarding { |
| 80 | public void activate() { | 93 | public void activate() { |
| 81 | appId = coreService.registerApplication("org.onosproject.mfwd"); | 94 | appId = coreService.registerApplication("org.onosproject.mfwd"); |
| 82 | 95 | ||
| 96 | + mcastIntentManager = new McastIntentManager(); | ||
| 97 | + mcastRouteManager.addListener(mcastIntentManager); | ||
| 98 | + | ||
| 83 | packetService.addProcessor(processor, PacketProcessor.director(2)); | 99 | packetService.addProcessor(processor, PacketProcessor.director(2)); |
| 84 | 100 | ||
| 85 | // Build a traffic selector for all multicast traffic | 101 | // Build a traffic selector for all multicast traffic |
| ... | @@ -98,6 +114,8 @@ public class McastForwarding { | ... | @@ -98,6 +114,8 @@ public class McastForwarding { |
| 98 | @Deactivate | 114 | @Deactivate |
| 99 | public void deactivate() { | 115 | public void deactivate() { |
| 100 | packetService.removeProcessor(processor); | 116 | packetService.removeProcessor(processor); |
| 117 | + mcastRouteManager.removeListener(mcastIntentManager); | ||
| 118 | + mcastIntentManager.withdrawAllIntents(); | ||
| 101 | processor = null; | 119 | processor = null; |
| 102 | log.info("Stopped"); | 120 | log.info("Stopped"); |
| 103 | } | 121 | } |
| ... | @@ -112,10 +130,47 @@ public class McastForwarding { | ... | @@ -112,10 +130,47 @@ public class McastForwarding { |
| 112 | } | 130 | } |
| 113 | 131 | ||
| 114 | /** | 132 | /** |
| 133 | + * Forward the packet to it's multicast destinations. | ||
| 134 | + * | ||
| 135 | + * @param context The packet context | ||
| 136 | + * @param egressList The list of egress ports which the multicast packet is intended for. | ||
| 137 | + */ | ||
| 138 | + private void forwardPacketToDst(PacketContext context, ArrayList<ConnectPoint> egressList) { | ||
| 139 | + | ||
| 140 | + // Send the pack out each of the respective egress ports | ||
| 141 | + for (ConnectPoint egress : egressList) { | ||
| 142 | + TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
| 143 | + .setOutput(egress.port()).build(); | ||
| 144 | + | ||
| 145 | + OutboundPacket packet = new DefaultOutboundPacket( | ||
| 146 | + egress.deviceId(), | ||
| 147 | + treatment, | ||
| 148 | + context.inPacket().unparsed()); | ||
| 149 | + | ||
| 150 | + packetService.emit(packet); | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + public static McastRoute createStaticRoute(String source, String group) { | ||
| 155 | + checkNotNull(source, "Must provide a source"); | ||
| 156 | + checkNotNull(group, "Must provide a group"); | ||
| 157 | + IpAddress ipSource = IpAddress.valueOf(source); | ||
| 158 | + IpAddress ipGroup = IpAddress.valueOf(group); | ||
| 159 | + return createStaticcreateRoute(ipSource, ipGroup); | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + public static McastRoute createStaticcreateRoute(IpAddress source, IpAddress group) { | ||
| 163 | + checkNotNull(source, "Must provide a source"); | ||
| 164 | + checkNotNull(group, "Must provide a group"); | ||
| 165 | + McastRoute.Type type = McastRoute.Type.STATIC; | ||
| 166 | + return new McastRoute(source, group, type); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + /** | ||
| 115 | * Packet processor responsible for forwarding packets along their paths. | 170 | * Packet processor responsible for forwarding packets along their paths. |
| 116 | */ | 171 | */ |
| 117 | - private class ReactivePacketProcessor implements PacketProcessor { | ||
| 118 | 172 | ||
| 173 | + private class ReactivePacketProcessor implements PacketProcessor { | ||
| 119 | /** | 174 | /** |
| 120 | * Process incoming packets. | 175 | * Process incoming packets. |
| 121 | * | 176 | * |
| ... | @@ -188,42 +243,75 @@ public class McastForwarding { | ... | @@ -188,42 +243,75 @@ public class McastForwarding { |
| 188 | // Send the pack out each of the egress devices & port | 243 | // Send the pack out each of the egress devices & port |
| 189 | forwardPacketToDst(context, egressList); | 244 | forwardPacketToDst(context, egressList); |
| 190 | } | 245 | } |
| 246 | + | ||
| 191 | } | 247 | } |
| 192 | 248 | ||
| 193 | - /** | 249 | + private class McastIntentManager implements McastListener { |
| 194 | - * Forward the packet to it's multicast destinations. | ||
| 195 | - * | ||
| 196 | - * @param context The packet context | ||
| 197 | - * @param egressList The list of egress ports which the multicast packet is intended for. | ||
| 198 | - */ | ||
| 199 | - private void forwardPacketToDst(PacketContext context, ArrayList<ConnectPoint> egressList) { | ||
| 200 | 250 | ||
| 201 | - // Send the pack out each of the respective egress ports | 251 | + private Map<McastRoute, Key> intentHashMap; |
| 202 | - for (ConnectPoint egress : egressList) { | ||
| 203 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
| 204 | - .setOutput(egress.port()).build(); | ||
| 205 | 252 | ||
| 206 | - OutboundPacket packet = new DefaultOutboundPacket( | 253 | + public McastIntentManager() { |
| 207 | - egress.deviceId(), | 254 | + intentHashMap = new HashMap<>(); |
| 208 | - treatment, | 255 | + } |
| 209 | - context.inPacket().unparsed()); | ||
| 210 | 256 | ||
| 211 | - packetService.emit(packet); | 257 | + @Override |
| 258 | + public void event(McastEvent event) { | ||
| 259 | + McastRoute route = event.subject().route(); | ||
| 260 | + if (intentHashMap.containsKey(route)) { | ||
| 261 | + withdrawIntent(intentHashMap.get(route)); | ||
| 262 | + } | ||
| 263 | + Key routeKey = setIntent(route); | ||
| 264 | + intentHashMap.put(route, routeKey); | ||
| 212 | } | 265 | } |
| 213 | - } | ||
| 214 | 266 | ||
| 215 | - public static McastRoute createStaticRoute(String source, String group) { | 267 | + private Key setIntent(McastRoute route) { |
| 216 | - checkNotNull(source, "Must provide a source"); | ||
| 217 | - checkNotNull(group, "Must provide a group"); | ||
| 218 | - IpAddress ipSource = IpAddress.valueOf(source); | ||
| 219 | - IpAddress ipGroup = IpAddress.valueOf(group); | ||
| 220 | - return createStaticcreateRoute(ipSource, ipGroup); | ||
| 221 | - } | ||
| 222 | 268 | ||
| 223 | - public static McastRoute createStaticcreateRoute(IpAddress source, IpAddress group) { | 269 | + ConnectPoint ingressPoint = mcastRouteManager.fetchSource(route); |
| 224 | - checkNotNull(source, "Must provide a source"); | 270 | + Set<ConnectPoint> egressPoints = new HashSet<>(mcastRouteManager.fetchSinks(route)); |
| 225 | - checkNotNull(group, "Must provide a group"); | 271 | + |
| 226 | - McastRoute.Type type = McastRoute.Type.STATIC; | 272 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 227 | - return new McastRoute(source, group, type); | 273 | + TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); |
| 274 | + | ||
| 275 | + if (ingressPoint == null) { | ||
| 276 | + log.warn("Can't set intent without an ingress or egress connect points"); | ||
| 277 | + return null; | ||
| 278 | + } | ||
| 279 | + | ||
| 280 | + selector.matchEthType(Ethernet.TYPE_IPV4) | ||
| 281 | + .matchIPDst(route.group().toIpPrefix()) | ||
| 282 | + .matchIPSrc(route.source().toIpPrefix()); | ||
| 283 | + | ||
| 284 | + SinglePointToMultiPointIntent.Builder builder = SinglePointToMultiPointIntent.builder() | ||
| 285 | + .appId(appId) | ||
| 286 | + .selector(selector.build()) | ||
| 287 | + .treatment(treatment) | ||
| 288 | + .ingressPoint(ingressPoint); | ||
| 289 | + | ||
| 290 | + // allowing intent to be pushed without egress points means we can drop packets. | ||
| 291 | + if (!egressPoints.isEmpty()) { | ||
| 292 | + builder.egressPoints(egressPoints); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + SinglePointToMultiPointIntent intent = builder.build(); | ||
| 296 | + intentService.submit(intent); | ||
| 297 | + | ||
| 298 | + return intent.key(); | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + public void withdrawAllIntents() { | ||
| 302 | + for (Map.Entry<McastRoute, Key> entry : intentHashMap.entrySet()) { | ||
| 303 | + withdrawIntent(entry.getValue()); | ||
| 304 | + } | ||
| 305 | + intentHashMap.clear(); | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + public void withdrawIntent(Key key) { | ||
| 309 | + if (key == null) { | ||
| 310 | + // nothing to withdraw | ||
| 311 | + return; | ||
| 312 | + } | ||
| 313 | + Intent intent = intentService.getIntent(key); | ||
| 314 | + intentService.withdraw(intent); | ||
| 315 | + } | ||
| 228 | } | 316 | } |
| 229 | } | 317 | } | ... | ... |
-
Please register or login to post a comment