alshabib
Committed by Gerrit Code Review

Initial implementation of cord multicast application

Change-Id: I36a007b0ffaac8c3a4ad1dc39ad9822b8d7e5878
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2014 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<project xmlns="http://maven.apache.org/POM/4.0.0"
18 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20 + <modelVersion>4.0.0</modelVersion>
21 +
22 + <parent>
23 + <groupId>org.onosproject</groupId>
24 + <artifactId>onos-apps</artifactId>
25 + <version>1.5.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-cord-mcast</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>CORD Multicast application</description>
33 +
34 + <properties>
35 + <onos.app.name>org.onosproject.cordmcast</onos.app.name>
36 + </properties>
37 +
38 + <dependencies>
39 + <dependency>
40 + <groupId>org.onosproject</groupId>
41 + <artifactId>onos-cli</artifactId>
42 + <version>${project.version}</version>
43 + </dependency>
44 + <dependency>
45 + <groupId>org.apache.karaf.shell</groupId>
46 + <artifactId>org.apache.karaf.shell.console</artifactId>
47 + </dependency>
48 + <dependency>
49 + <groupId>com.google.guava</groupId>
50 + <artifactId>guava</artifactId>
51 + </dependency>
52 + <dependency>
53 + <groupId>org.onosproject</groupId>
54 + <artifactId>onlab-misc</artifactId>
55 + </dependency>
56 + <dependency>
57 + <groupId>org.apache.felix</groupId>
58 + <artifactId>org.apache.felix.scr</artifactId>
59 + <version>1.8.2</version>
60 + </dependency>
61 + <dependency>
62 + <groupId>org.osgi</groupId>
63 + <artifactId>org.osgi.compendium</artifactId>
64 + <version>5.0.0</version>
65 + </dependency>
66 + </dependencies>
67 +</project>
1 +/*
2 + * Copyright 2015-2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.cordmcast;
17 +
18 +import com.google.common.collect.Maps;
19 +import org.apache.felix.scr.annotations.Activate;
20 +import org.apache.felix.scr.annotations.Component;
21 +import org.apache.felix.scr.annotations.Deactivate;
22 +import org.apache.felix.scr.annotations.Reference;
23 +import org.apache.felix.scr.annotations.ReferenceCardinality;
24 +import org.onlab.packet.Ethernet;
25 +import org.onlab.packet.IPv4;
26 +import org.onlab.packet.IpAddress;
27 +import org.onlab.packet.VlanId;
28 +import org.onosproject.core.ApplicationId;
29 +import org.onosproject.core.CoreService;
30 +import org.onosproject.net.ConnectPoint;
31 +import org.onosproject.net.flow.DefaultTrafficSelector;
32 +import org.onosproject.net.flow.DefaultTrafficTreatment;
33 +import org.onosproject.net.flow.TrafficSelector;
34 +import org.onosproject.net.flowobjective.DefaultForwardingObjective;
35 +import org.onosproject.net.flowobjective.DefaultNextObjective;
36 +import org.onosproject.net.flowobjective.FlowObjectiveService;
37 +import org.onosproject.net.flowobjective.ForwardingObjective;
38 +import org.onosproject.net.flowobjective.NextObjective;
39 +import org.onosproject.net.flowobjective.Objective;
40 +import org.onosproject.net.flowobjective.ObjectiveContext;
41 +import org.onosproject.net.flowobjective.ObjectiveError;
42 +import org.onosproject.net.group.GroupService;
43 +import org.onosproject.net.mcast.McastEvent;
44 +import org.onosproject.net.mcast.McastListener;
45 +import org.onosproject.net.mcast.McastRouteInfo;
46 +import org.onosproject.net.mcast.MulticastRouteService;
47 +import org.slf4j.Logger;
48 +
49 +import java.util.Map;
50 +import java.util.concurrent.atomic.AtomicInteger;
51 +
52 +import static org.slf4j.LoggerFactory.getLogger;
53 +
54 +/**
55 + * CORD multicast provisoning application. Operates by listening to
56 + * events on the multicast rib and provsioning groups to program multicast
57 + * flows on the dataplane.
58 + */
59 +@Component(immediate = true)
60 +public class CordMcast {
61 +
62 + private static final int DEFAULT_PRIORITY = 1000;
63 + private static final short DEFAULT_MCAST_VLAN = 4000;
64 + private final Logger log = getLogger(getClass());
65 +
66 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 + protected MulticastRouteService mcastService;
68 +
69 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 + protected GroupService groupService;
71 +
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected FlowObjectiveService flowObjectiveService;
74 +
75 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 + protected CoreService coreService;
77 +
78 + protected McastListener listener = new InternalMulticastListener();
79 +
80 +
81 +
82 + //TODO: move this to a ec map
83 + private Map<IpAddress, Integer> groups = Maps.newConcurrentMap();
84 +
85 + //TODO: move this to distributed atomic long
86 + private AtomicInteger channels = new AtomicInteger(0);
87 +
88 + private ApplicationId appId;
89 +
90 + //TODO: network config this
91 + private short mcastVlan = DEFAULT_MCAST_VLAN;
92 +
93 + // TODO component config this
94 + private int priority = DEFAULT_PRIORITY;
95 +
96 + @Activate
97 + public void activate() {
98 + appId = coreService.registerApplication("org.onosproject.cordmcast");
99 + mcastService.addListener(listener);
100 + //TODO: obtain all existing mcast routes
101 + log.info("Started");
102 + }
103 +
104 + @Deactivate
105 + public void deactivate() {
106 + mcastService.removeListener(listener);
107 + log.info("Stopped");
108 + }
109 +
110 + private class InternalMulticastListener implements McastListener {
111 + @Override
112 + public void event(McastEvent event) {
113 + switch (event.type()) {
114 + case ROUTE_ADDED:
115 + break;
116 + case ROUTE_REMOVED:
117 + break;
118 + case SOURCE_ADDED:
119 + break;
120 + case SINK_ADDED:
121 + provisionGroup(event.subject());
122 + break;
123 + case SINK_REMOVED:
124 + break;
125 + default:
126 + log.warn("Unknown mcast event {}", event.type());
127 + }
128 + }
129 + }
130 +
131 + private void provisionGroup(McastRouteInfo info) {
132 + if (!info.sink().isPresent()) {
133 + log.warn("No sink given after sink added event: {}", info);
134 + return;
135 + }
136 + ConnectPoint loc = info.sink().get();
137 +
138 +
139 + Integer nextId = groups.computeIfAbsent(info.route().group(), (g) -> {
140 + Integer id = allocateId(g);
141 +
142 + TrafficSelector mcast = DefaultTrafficSelector.builder()
143 + .matchVlanId(VlanId.vlanId(mcastVlan))
144 + .matchEthType(Ethernet.TYPE_IPV4)
145 + .matchIPProtocol(IPv4.PROTOCOL_IGMP)
146 + .matchIPDst(g.toIpPrefix())
147 + .build();
148 +
149 +
150 + ForwardingObjective fwd = DefaultForwardingObjective.builder()
151 + .fromApp(appId)
152 + .nextStep(id)
153 + .makePermanent()
154 + .withFlag(ForwardingObjective.Flag.VERSATILE)
155 + .withPriority(priority)
156 + .withSelector(mcast)
157 + .add(new ObjectiveContext() {
158 + @Override
159 + public void onSuccess(Objective objective) {
160 + //TODO: change to debug
161 + log.info("Forwarding objective installed {}", objective);
162 + }
163 +
164 + @Override
165 + public void onError(Objective objective, ObjectiveError error) {
166 + //TODO: change to debug
167 + log.info("Forwarding objective failed {}", objective);
168 + }
169 + });
170 +
171 + flowObjectiveService.forward(loc.deviceId(), fwd);
172 +
173 + return id;
174 + });
175 +
176 + NextObjective next = DefaultNextObjective.builder()
177 + .fromApp(appId)
178 + .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build())
179 + .withType(NextObjective.Type.BROADCAST)
180 + .withId(nextId)
181 + .addToExisting(new ObjectiveContext() {
182 + @Override
183 + public void onSuccess(Objective objective) {
184 + //TODO: change to debug
185 + log.info("Next Objective {} installed", objective.id());
186 + }
187 +
188 + @Override
189 + public void onError(Objective objective, ObjectiveError error) {
190 + //TODO: change to debug
191 + log.info("Next Objective {} failed, because {}",
192 + objective.id(),
193 + error);
194 + }
195 + });
196 +
197 + flowObjectiveService.next(loc.deviceId(), next);
198 + }
199 +
200 + private Integer allocateId(IpAddress group) {
201 + Integer channel = groups.putIfAbsent(group, channels.getAndIncrement());
202 + return channel == null ? groups.get(group) : channel;
203 + }
204 +}
1 +/*
2 + * Copyright 2015-16 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * Application for provisioning multicast streams in the context of cord.
19 + */
20 +package org.onosproject.cordmcast;
...\ No newline at end of file ...\ No newline at end of file
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
66 <module>events</module> 66 <module>events</module>
67 <module>vrouter</module> 67 <module>vrouter</module>
68 <module>openstackrouting</module> 68 <module>openstackrouting</module>
69 + <module>cordmcast</module>
69 </modules> 70 </modules>
70 71
71 <properties> 72 <properties>
......