alshabib
Committed by Gerrit Code Review

Adding mfwd, igmp and mfwd apps

Change-Id: Ie7187716db36b754e4cd687a8f9de004e27c7825

adding mfwd, pim, igmp apps

Change-Id: Iddd2dcee24dc905d5ff0efe1d1d798fc83a7c736
Showing 32 changed files with 2742 additions and 0 deletions
...@@ -331,6 +331,7 @@ public class DhcpManagerTest { ...@@ -331,6 +331,7 @@ public class DhcpManagerTest {
331 331
332 @Override 332 @Override
333 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) { 333 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
334 +
334 } 335 }
335 336
336 @Override 337 @Override
......
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/xsd/maven-4.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.4.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-igmp</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>Internet Group Message Protocol</description>
33 +
34 + <properties>
35 + <onos.app.name>org.onosproject.igmp</onos.app.name>
36 + </properties>
37 +
38 + <dependencies>
39 + <dependency>
40 + <groupId>org.onosproject</groupId>
41 + <artifactId>onos-api</artifactId>
42 + <version>${project.version}</version>
43 + </dependency>
44 +
45 + <dependency>
46 + <groupId>org.onosproject</groupId>
47 + <artifactId>onos-cli</artifactId>
48 + <version>${project.version}</version>
49 + </dependency>
50 +
51 +
52 + <dependency>
53 + <groupId>org.onosproject</groupId>
54 + <artifactId>onlab-osgi</artifactId>
55 + <version>${project.version}</version>
56 + </dependency>
57 +
58 + <dependency>
59 + <groupId>org.onosproject</groupId>
60 + <artifactId>onlab-junit</artifactId>
61 + <scope>test</scope>
62 + </dependency>
63 +
64 + <!-- This is needed by ComponentContext, used for tunable configuration -->
65 + <dependency>
66 + <groupId>org.osgi</groupId>
67 + <artifactId>org.osgi.compendium</artifactId>
68 + </dependency>
69 +
70 + <dependency>
71 + <groupId>org.apache.felix</groupId>
72 + <artifactId>org.apache.felix.scr.annotations</artifactId>
73 + <version>1.9.8</version>
74 + <scope>provided</scope>
75 + </dependency>
76 +
77 + </dependencies>
78 +
79 + <build>
80 + <plugins>
81 + <plugin>
82 + <groupId>org.apache.felix</groupId>
83 + <artifactId>maven-bundle-plugin</artifactId>
84 + <extensions>true</extensions>
85 + <configuration>
86 + <instructions>
87 + <Bundle-SymbolicName>
88 + ${project.groupId}.${project.artifactId}
89 + </Bundle-SymbolicName>
90 + <Import-Package>
91 + org.slf4j,
92 + org.osgi.framework,
93 + org.apache.commons.lang.math.*,
94 + com.google.common.*,
95 + org.onlab.packet.*,
96 + org.onlab.rest.*,
97 + org.onosproject.*,
98 + org.onosproject.mfwd.impl.*;
99 + org.onlab.util.*,
100 + org.jboss.netty.util.*
101 + </Import-Package>
102 + </instructions>
103 + </configuration>
104 + </plugin>
105 + <plugin>
106 + <groupId>org.apache.maven.plugins</groupId>
107 + <artifactId>maven-compiler-plugin</artifactId>
108 + <version>2.5.1</version>
109 + <configuration>
110 + <source>1.8</source>
111 + <target>1.8</target>
112 + </configuration>
113 + </plugin>
114 + </plugins>
115 + </build>
116 +
117 +</project>
1 +/*
2 + * Copyright 2015 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.igmp.impl;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import org.apache.felix.scr.annotations.Activate;
21 +import org.apache.felix.scr.annotations.Component;
22 +import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.IPv4;
27 +import org.onlab.packet.Ip4Address;
28 +import org.onlab.packet.IpAddress;
29 +import org.onlab.packet.IpPrefix;
30 +import org.onlab.packet.IGMP;
31 +import org.onosproject.core.ApplicationId;
32 +import org.onosproject.core.CoreService;
33 +import org.onosproject.net.flow.DefaultTrafficSelector;
34 +import org.onosproject.net.flow.TrafficSelector;
35 +import org.onosproject.net.packet.InboundPacket;
36 +import org.onosproject.net.packet.PacketContext;
37 +import org.onosproject.net.packet.PacketPriority;
38 +import org.onosproject.net.packet.PacketProcessor;
39 +import org.onosproject.net.packet.PacketService;
40 +import org.slf4j.Logger;
41 +
42 +/**
43 + * Internet Group Management Protocol.
44 + */
45 +@Component(immediate = true)
46 +public class IGMPComponent {
47 + private final Logger log = getLogger(getClass());
48 +
49 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 + protected PacketService packetService;
51 +
52 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 + protected CoreService coreService;
54 +
55 + private IGMPPacketProcessor processor = new IGMPPacketProcessor();
56 + private static ApplicationId appId;
57 +
58 + @Activate
59 + public void activate() {
60 + appId = coreService.registerApplication("org.onosproject.igmp");
61 +
62 + packetService.addProcessor(processor, PacketProcessor.director(1));
63 +
64 + // Build a traffic selector for all multicast traffic
65 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
66 + selector.matchEthType(Ethernet.TYPE_IPV4);
67 + selector.matchIPProtocol(IPv4.PROTOCOL_IGMP);
68 + packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
69 +
70 + log.info("Started");
71 + }
72 +
73 + @Deactivate
74 + public void deactivate() {
75 + packetService.removeProcessor(processor);
76 + processor = null;
77 + log.info("Stopped");
78 + }
79 +
80 + /**
81 + * Packet processor responsible for handling IGMP packets.
82 + */
83 + private class IGMPPacketProcessor implements PacketProcessor {
84 +
85 + @Override
86 + public void process(PacketContext context) {
87 + // Stop processing if the packet has been handled, since we
88 + // can't do any more to it.
89 + if (context.isHandled()) {
90 + return;
91 + }
92 +
93 + InboundPacket pkt = context.inPacket();
94 + Ethernet ethPkt = pkt.parsed();
95 + if (ethPkt == null) {
96 + return;
97 + }
98 +
99 + /*
100 + * IPv6 MLD packets are handled by ICMP6. We'll only deal
101 + * with IPv4.
102 + */
103 + if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
104 + return;
105 + }
106 +
107 + IPv4 ip = (IPv4) ethPkt.getPayload();
108 + IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
109 + IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
110 + log.debug("Packet (" + saddr.toString() + ", " + gaddr.toString() +
111 + "\tingress port: " + context.inPacket().receivedFrom().toString());
112 +
113 + if (ip.getProtocol() != IPv4.PROTOCOL_IGMP) {
114 + log.error("IGMP Picked up a non IGMP packet.");
115 + return;
116 + }
117 +
118 + IpPrefix mcast = IpPrefix.valueOf("224.0.0.0/4");
119 + if (!mcast.contains(gaddr)) {
120 + log.error("IGMP Picked up a non multicast packet.");
121 + return;
122 + }
123 +
124 + if (mcast.contains(saddr)) {
125 + log.error("IGMP Picked up a packet with a multicast source address.");
126 + return;
127 + }
128 + IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
129 + IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
130 +
131 + IGMP igmp = (IGMP) ip.getPayload();
132 + switch (igmp.getIgmpType()) {
133 +
134 + case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT:
135 + IGMPProcessMembership.processMembership(igmp, pkt.receivedFrom());
136 + break;
137 +
138 + case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY:
139 + IGMPProcessQuery.processQuery(igmp, pkt.receivedFrom());
140 + break;
141 +
142 + case IGMP.TYPE_IGMPV1_MEMBERSHIP_REPORT:
143 + case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT:
144 + case IGMP.TYPE_IGMPV2_LEAVE_GROUP:
145 + log.debug("IGMP version 1 & 2 message types are not currently supported. Message type: " +
146 + igmp.getIgmpType());
147 + break;
148 +
149 + default:
150 + log.debug("Unkown IGMP message type: " + igmp.getIgmpType());
151 + break;
152 + }
153 + }
154 + }
155 +}
1 +/*
2 + * Copyright 2015 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.igmp.impl;
17 +
18 +import org.onlab.packet.IGMP;
19 +import org.onosproject.net.ConnectPoint;
20 +
21 +/**
22 + * Process an IGMP Membership Report.
23 + */
24 +public final class IGMPProcessMembership {
25 +
26 + // Hide the default constructor.
27 + private IGMPProcessMembership() {
28 + }
29 +
30 + /**
31 + * Process the IGMP Membership report.
32 + *
33 + * @param igmp the deserialized IGMP message.
34 + */
35 + public static void processMembership(IGMP igmp, ConnectPoint recievedFrom) {
36 + }
37 +
38 +}
1 +/*
2 + * Copyright 2015 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.igmp.impl;
17 +
18 +import org.onlab.packet.IGMP;
19 +import org.onosproject.net.ConnectPoint;
20 +
21 +/**
22 + * Process IGMP Query messages.
23 + */
24 +public final class IGMPProcessQuery {
25 +
26 + // Hide the default constructor.
27 + private IGMPProcessQuery() {
28 + }
29 +
30 + /**
31 + * Process the IGMP Membership Query message.
32 + *
33 + * @param igmp The deserialzed IGMP message
34 + */
35 + public static void processQuery(IGMP igmp, ConnectPoint receivedFrom) {
36 + }
37 +
38 +}
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.4.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-mfwd</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>Multicast forwarding application</description>
33 +
34 + <properties>
35 + <onos.app.name>org.onosproject.mfwd</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>io.netty</groupId>
46 + <artifactId>netty</artifactId>
47 + <version>3.9.0.Final</version>
48 + </dependency>
49 +
50 + <dependency>
51 + <groupId>org.osgi</groupId>
52 + <artifactId>org.osgi.compendium</artifactId>
53 + </dependency>
54 +
55 + <dependency>
56 + <groupId>org.apache.karaf.shell</groupId>
57 + <artifactId>org.apache.karaf.shell.console</artifactId>
58 + </dependency>
59 +
60 + <dependency>
61 + <groupId>org.osgi</groupId>
62 + <artifactId>org.osgi.core</artifactId>
63 + </dependency>
64 +
65 + <dependency>
66 + <groupId>org.onosproject</groupId>
67 + <artifactId>onlab-rest</artifactId>
68 + <version>${project.version}</version>
69 + </dependency>
70 + <dependency>
71 + <groupId>org.onosproject</groupId>
72 + <artifactId>onos-rest</artifactId>
73 + <version>${project.version}</version>
74 + </dependency>
75 + <dependency>
76 + <groupId>com.sun.jersey</groupId>
77 + <artifactId>jersey-servlet</artifactId>
78 + </dependency>
79 + <dependency>
80 + <groupId>com.fasterxml.jackson.core</groupId>
81 + <artifactId>jackson-databind</artifactId>
82 + </dependency>
83 + <dependency>
84 + <groupId>com.fasterxml.jackson.core</groupId>
85 + <artifactId>jackson-annotations</artifactId>
86 + </dependency>
87 +
88 + <dependency>
89 + <groupId>org.onosproject</groupId>
90 + <artifactId>onlab-junit</artifactId>
91 + <scope>test</scope>
92 + </dependency>
93 +
94 + <dependency>
95 + <groupId>org.easymock</groupId>
96 + <artifactId>easymock</artifactId>
97 + <scope>test</scope>
98 + </dependency>
99 +
100 + </dependencies>
101 +
102 +
103 + <build>
104 + <plugins>
105 + <plugin>
106 + <groupId>org.apache.felix</groupId>
107 + <artifactId>maven-bundle-plugin</artifactId>
108 + <extensions>true</extensions>
109 + <configuration>
110 + <instructions>
111 + <_wab>src/main/webapp/</_wab>
112 + <Bundle-SymbolicName>
113 + ${project.groupId}.${project.artifactId}
114 + </Bundle-SymbolicName>
115 + <Import-Package>
116 + org.slf4j,
117 + org.osgi.framework,
118 + javax.ws.rs,javax.ws.rs.core,
119 + com.sun.jersey.api.core,
120 + com.sun.jersey.spi.container.servlet,
121 + com.sun.jersey.server.impl.container.servlet,
122 + com.fasterxml.jackson.databind,
123 + com.fasterxml.jackson.databind.node,
124 + org.apache.commons.lang.math.*,
125 + com.google.common.*,
126 + org.onlab.packet.*,
127 + org.onlab.rest.*,
128 + org.onosproject.*,
129 + org.onlab.util.*,
130 + org.jboss.netty.util.*
131 + </Import-Package>
132 + <Web-ContextPath>${web.context}</Web-ContextPath>
133 + </instructions>
134 + </configuration>
135 + </plugin>
136 + </plugins>
137 + </build>
138 +
139 +</project>
140 +
1 +/*
2 + * Copyright 2014-2015 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.mfwd.cli;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onosproject.cli.AbstractShellCommand;
21 +
22 +import org.onosproject.mfwd.impl.McastRouteTable;
23 +
24 +/**
25 + * Delete a multicast route.
26 + */
27 +@Command(scope = "onos", name = "mcast-delete",
28 + description = "Delete a multicast route flow")
29 +public class McastDeleteCommand extends AbstractShellCommand {
30 +
31 + @Argument(index = 0, name = "sAddr",
32 + description = "IP Address of the multicast source. '*' can be used for any source (*, G) entry",
33 + required = true, multiValued = false)
34 + String sAddr = null;
35 +
36 + @Argument(index = 1, name = "gAddr",
37 + description = "IP Address of the multicast group",
38 + required = true, multiValued = false)
39 + String gAddr = null;
40 +
41 + @Override
42 + protected void execute() {
43 + McastRouteTable mrib = McastRouteTable.getInstance();
44 + mrib.removeRoute(sAddr, gAddr);
45 + }
46 +}
47 +
1 +/*
2 + * Copyright 2014-2015 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.mfwd.cli;
17 +
18 +import org.apache.karaf.shell.commands.Argument;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onlab.packet.IpPrefix;
21 +import org.onosproject.cli.AbstractShellCommand;
22 +
23 +import org.onosproject.mfwd.impl.McastRouteBase;
24 +import org.onosproject.mfwd.impl.McastRouteTable;
25 +
26 +/**
27 + * Installs a source, multicast group flow.
28 + */
29 +@Command(scope = "onos", name = "mcast-join",
30 + description = "Installs a source, multicast group flow")
31 +public class McastJoinCommand extends AbstractShellCommand {
32 +
33 + @Argument(index = 0, name = "sAddr",
34 + description = "IP Address of the multicast source. '*' can be used for any source (*, G) entry",
35 + required = true, multiValued = false)
36 + String sAddr = null;
37 +
38 + @Argument(index = 1, name = "gAddr",
39 + description = "IP Address of the multicast group",
40 + required = true, multiValued = false)
41 + String gAddr = null;
42 +
43 + @Argument(index = 2, name = "ingressPort",
44 + description = "Ingress port and Egress ports",
45 + required = false, multiValued = false)
46 + String ingressPort = null;
47 +
48 + @Argument(index = 3, name = "ports",
49 + description = "Ingress port and Egress ports",
50 + required = false, multiValued = true)
51 + String[] ports = null;
52 +
53 + @Override
54 + protected void execute() {
55 + McastRouteTable mrib = McastRouteTable.getInstance();
56 + IpPrefix mcast = IpPrefix.valueOf("224.0.0.0/4");
57 + IpPrefix saddr = IpPrefix.valueOf(sAddr);
58 + if (mcast.contains(saddr)) {
59 + print("Error: the source address " + sAddr + " must be an IPv4 unicast address");
60 + return;
61 + }
62 +
63 + IpPrefix gaddr = IpPrefix.valueOf(gAddr);
64 + if (!mcast.contains(gaddr)) {
65 + print("Error: " + gAddr + " must be a multicast group address");
66 + return;
67 + }
68 +
69 + McastRouteBase mr = mrib.addRoute(sAddr, gAddr);
70 + if (mr == null) {
71 + print("Error: unable to save the multicast state");
72 + return;
73 + }
74 +
75 + // Port format "of:0000000000000023/4"
76 + if (ingressPort != null) {
77 + String inCP = ingressPort;
78 + log.debug("Ingress port provided: " + inCP);
79 + String [] cp = inCP.split("/");
80 + mr.addIngressPoint(cp[0], Long.parseLong(cp[1]));
81 + } else {
82 + return;
83 + }
84 +
85 + if (ports == null) {
86 + return;
87 + }
88 +
89 + for (int i = 0; i < ports.length; i++) {
90 + String egCP = ports[i];
91 + log.debug("Egress port provided: " + egCP);
92 + String [] cp = egCP.split("/");
93 + mr.addEgressPoint(cp[0], Long.parseLong(cp[1]));
94 + }
95 + print("Added the mcast route");
96 + }
97 +}
1 +/*
2 + * Copyright 2014-2015 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.mfwd.cli;
17 +
18 +import org.apache.karaf.shell.commands.Command;
19 +import org.onosproject.cli.AbstractShellCommand;
20 +import org.onosproject.net.ConnectPoint;
21 +import org.onlab.packet.IpPrefix;
22 +
23 +import java.util.Map;
24 +import java.util.Set;
25 +
26 +import org.slf4j.Logger;
27 +import org.onosproject.mfwd.impl.McastRouteTable;
28 +import org.onosproject.mfwd.impl.McastRouteGroup;
29 +
30 +import com.fasterxml.jackson.databind.JsonNode;
31 +import com.fasterxml.jackson.databind.ObjectMapper;
32 +import com.fasterxml.jackson.databind.node.ArrayNode;
33 +
34 +import static org.slf4j.LoggerFactory.getLogger;
35 +
36 +/**
37 + * Displays the source, multicast group flows entries.
38 + */
39 +@Command(scope = "onos", name = "mcast-show", description = "Displays the source, multicast group flows")
40 +public class McastShowCommand extends AbstractShellCommand {
41 +
42 + private final Logger log = getLogger(getClass());
43 +
44 + @Override
45 + protected void execute() {
46 + McastRouteTable mrt = McastRouteTable.getInstance();
47 + if (outputJson()) {
48 + print("%s", json(mrt));
49 + } else {
50 + printMrib4(mrt);
51 + }
52 + }
53 +
54 + public JsonNode json(McastRouteTable mrt) {
55 + ObjectMapper mapper = new ObjectMapper();
56 + ArrayNode result = mapper.createArrayNode();
57 + Map<IpPrefix, McastRouteGroup> mrib4 = mrt.getMrib4();
58 + for (McastRouteGroup mg : mrib4.values()) {
59 + String sAddr = "";
60 + String gAddr = "";
61 + String inPort = "";
62 + String outPorts = "";
63 + if (mg.getSaddr() != null) {
64 + sAddr = mg.getSaddr().toString();
65 + log.info("Multicast Source: " + sAddr);
66 + }
67 + if (mg.getGaddr() != null) {
68 + gAddr = mg.getGaddr().toString();
69 + log.info("Multicast Group: " + gAddr);
70 + }
71 + if (mg.getIngressPoint() != null) {
72 + inPort = mg.getIngressPoint().toString();
73 + log.info("Multicast Ingress: " + inPort);
74 + }
75 + Set<ConnectPoint> eps = mg.getEgressPoints();
76 + if (eps != null && !eps.isEmpty()) {
77 + outPorts = eps.toString();
78 + }
79 + result.add(mapper.createObjectNode()
80 + .put("src", sAddr)
81 + .put("grp", gAddr)
82 + .put("inPort", inPort)
83 + .put("outPorts", outPorts));
84 + }
85 + return result;
86 + }
87 +
88 + /**
89 + * Displays multicast route table entries.
90 + *
91 + * @param mrt route table
92 + */
93 + protected void printMrib4(McastRouteTable mrt) {
94 + print(mrt.printMcastRouteTable());
95 + }
96 +}
1 +/**
2 + * Sample Multicast forwarding framework using intents.
3 + */
4 +package org.onosproject.mfwd.cli;
5 +
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import org.apache.felix.scr.annotations.Activate;
21 +import org.apache.felix.scr.annotations.Component;
22 +import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +
26 +import org.onlab.packet.Ethernet;
27 +import org.onlab.packet.IpPrefix;
28 +import org.onlab.packet.IpAddress;
29 +import org.onlab.packet.Ip4Address;
30 +import org.onlab.packet.IPv4;
31 +import org.onosproject.core.ApplicationId;
32 +import org.onosproject.core.CoreService;
33 +import org.onosproject.net.ConnectPoint;
34 +import org.onosproject.net.flow.DefaultTrafficSelector;
35 +import org.onosproject.net.flow.DefaultTrafficTreatment;
36 +import org.onosproject.net.flow.TrafficSelector;
37 +import org.onosproject.net.flow.TrafficTreatment;
38 +import org.onosproject.net.packet.DefaultOutboundPacket;
39 +import org.onosproject.net.packet.InboundPacket;
40 +import org.onosproject.net.packet.OutboundPacket;
41 +import org.onosproject.net.packet.PacketContext;
42 +import org.onosproject.net.packet.PacketPriority;
43 +import org.onosproject.net.packet.PacketProcessor;
44 +import org.onosproject.net.packet.PacketService;
45 +import org.slf4j.Logger;
46 +
47 +/**
48 + * WORK-IN-PROGRESS: The multicast forwarding application using intent framework.
49 + */
50 +@Component(immediate = true)
51 +public class McastForwarding {
52 +
53 + private final Logger log = getLogger(getClass());
54 + private final IpPrefix mcast = IpPrefix.valueOf("224.0.0.0/4");
55 +
56 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 + protected PacketService packetService;
58 +
59 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 + protected CoreService coreService;
61 +
62 + private ReactivePacketProcessor processor = new ReactivePacketProcessor();
63 + private McastRouteTable mrib;
64 + private static ApplicationId appId;
65 +
66 + /**
67 + * Active MulticastForwardingIntent.
68 + */
69 + @Activate
70 + public void activate() {
71 + appId = coreService.registerApplication("org.onosproject.mfwd");
72 +
73 + packetService.addProcessor(processor, PacketProcessor.director(2));
74 +
75 + // Build a traffic selector for all multicast traffic
76 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
77 + selector.matchEthType(Ethernet.TYPE_IPV4);
78 + selector.matchIPDst(mcast);
79 + packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
80 +
81 + mrib = McastRouteTable.getInstance();
82 + log.info("Started");
83 + }
84 +
85 + /**
86 + * Deactivate Multicast Forwarding Intent.
87 + */
88 + @Deactivate
89 + public void deactivate() {
90 + packetService.removeProcessor(processor);
91 + processor = null;
92 + log.info("Stopped");
93 + }
94 +
95 + /**
96 + * Get the application ID, used by the McastIntentManager.
97 + *
98 + * @return the application ID
99 + */
100 + public static ApplicationId getAppId() {
101 + return appId;
102 + }
103 +
104 + /**
105 + * Packet processor responsible for forwarding packets along their paths.
106 + */
107 + private class ReactivePacketProcessor implements PacketProcessor {
108 +
109 + /**
110 + * Process incoming packets.
111 + *
112 + * @param context packet processing context
113 + */
114 + @Override
115 + public void process(PacketContext context) {
116 + // Stop processing if the packet has been handled, since we
117 + // can't do any more to it.
118 + if (context.isHandled()) {
119 + return;
120 + }
121 +
122 + InboundPacket pkt = context.inPacket();
123 + Ethernet ethPkt = pkt.parsed();
124 +
125 + if (ethPkt == null) {
126 + return;
127 + }
128 +
129 + if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4 &&
130 + ethPkt.getEtherType() != Ethernet.TYPE_IPV6) {
131 + return;
132 + }
133 +
134 + if (ethPkt.getEtherType() == Ethernet.TYPE_IPV6) {
135 + // Ignore ipv6 at the moment.
136 + return;
137 + }
138 +
139 + IPv4 ip = (IPv4) ethPkt.getPayload();
140 + IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
141 + IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
142 +
143 + log.debug("Packet ({}, {}) has been punted\n" +
144 + "\tingress port: {}\n",
145 + saddr.toString(),
146 + gaddr.toString(),
147 + context.inPacket().receivedFrom().toString());
148 +
149 + if (!mcast.contains(gaddr)) {
150 + // Yikes, this is a bad group address
151 + return;
152 + }
153 +
154 + if (mcast.contains(saddr)) {
155 + // Yikes, the source address is multicast
156 + return;
157 + }
158 +
159 + IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
160 + IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
161 +
162 + /*
163 + * Do a best match lookup on the (s, g) of the packet. If an entry does
164 + * not exist create one and store it's incoming connect point.
165 + *
166 + * The connect point is deviceId / portId that the packet entered
167 + * the SDN network. This differs from traditional mcast where the
168 + * ingress port would be a specific device.
169 + */
170 + McastRoute entry = mrib.findBestMatch(spfx, gpfx);
171 + if (entry == null || entry.getSaddr().equals(IPv4.fromIPv4Address(0))) {
172 +
173 + /*
174 + * Create an entry that we can fast drop.
175 + */
176 + entry = mrib.addRoute(spfx, gpfx);
177 + entry.addIngressPoint(context.inPacket().receivedFrom());
178 + }
179 +
180 + /*
181 + * TODO: If we do not have an ingress or any egress connect points we
182 + * should set up a fast drop entry.
183 + */
184 + if (entry.getIngressPoint() == null) {
185 + return;
186 + }
187 +
188 + if (entry.getEgressPoints().isEmpty()) {
189 + return;
190 + }
191 +
192 + /*
193 + * This is odd, we should not have received a punted packet if an
194 + * intent was installed unless the intent was not installed
195 + * correctly. However, we are seeing packets get punted after
196 + * the intent has been installed.
197 + *
198 + * Therefore we are going to forward the packets even if they
199 + * should have already been forwarded by the intent fabric.
200 + */
201 + if (entry.getIntentKey() != null) {
202 + return;
203 + }
204 +
205 + entry.setIntent();
206 + McastIntentManager im = McastIntentManager.getInstance();
207 + im.setIntent(entry);
208 +
209 + entry.incrementPuntCount();
210 +
211 + // Send the pack out each of the egress devices & port
212 + forwardPacketToDst(context, entry);
213 + }
214 + }
215 +
216 + /**
217 + * Forward the packet to it's multicast destinations.
218 + *
219 + * @param context The packet context
220 + * @param entry The multicast route entry matching this packet
221 + */
222 + private void forwardPacketToDst(PacketContext context, McastRoute entry) {
223 +
224 + // Send the pack out each of the respective egress ports
225 + for (ConnectPoint egress : entry.getEgressPoints()) {
226 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
227 + .setOutput(egress.port()).build();
228 +
229 + OutboundPacket packet = new DefaultOutboundPacket(
230 + egress.deviceId(),
231 + treatment,
232 + context.inPacket().unparsed());
233 +
234 + packetService.emit(packet);
235 + }
236 + }
237 +}
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import org.apache.felix.scr.annotations.Activate;
19 +import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Service;
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.onosproject.net.intent.Intent;
26 +import org.onosproject.net.intent.SinglePointToMultiPointIntent;
27 +import org.onosproject.net.intent.IntentService;
28 +import org.onosproject.net.flow.DefaultTrafficSelector;
29 +import org.onosproject.net.flow.DefaultTrafficTreatment;
30 +import org.onosproject.net.flow.TrafficSelector;
31 +import org.onosproject.net.flow.TrafficTreatment;
32 +
33 +@Component(immediate = true)
34 +@Service(value = org.onosproject.mfwd.impl.McastIntentManager.class)
35 +public class McastIntentManager {
36 +
37 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
38 + protected IntentService intentService;
39 +
40 + private static McastIntentManager instance;
41 +
42 + public McastIntentManager() {
43 + instance = this;
44 + }
45 +
46 + /**
47 + * Active this component.
48 + */
49 + @Activate
50 + public void activate() { }
51 +
52 + /**
53 + * Deactivate this component.
54 + */
55 + @Deactivate
56 + public void deactivate() {
57 + withdrawAllIntents();
58 + }
59 +
60 + /**
61 + * Get instance of this intentManager.
62 + *
63 + * @return the instance of this intent manager.
64 + */
65 + public static McastIntentManager getInstance() {
66 + if (instance == null) {
67 + instance = new McastIntentManager();
68 + }
69 + return instance;
70 + }
71 +
72 + /**
73 + * Install the PointToMultipoint forwarding intent.
74 + *
75 + * @param mroute multicast route entry
76 + * @return the intent that has been set or null otherwise
77 + */
78 + public SinglePointToMultiPointIntent setIntent(McastRoute mroute) {
79 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
80 + TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
81 +
82 + if (mroute.getIngressPoint() == null ||
83 + mroute.getEgressPoints().isEmpty()) {
84 + return null;
85 + }
86 +
87 + /*
88 + * Match the group AND source addresses. We will also check ether type to
89 + * determine if we are doing ipv4 or ipv6.
90 + *
91 + * If we really wanted to be pendantic we could put in a
92 + * condition to make sure the ethernet MAC address was also
93 + * mcast.
94 + */
95 + selector.matchEthType(Ethernet.TYPE_IPV4)
96 + .matchIPDst(mroute.getGaddr())
97 + .matchIPSrc(mroute.getSaddr());
98 +
99 + SinglePointToMultiPointIntent intent =
100 + SinglePointToMultiPointIntent.builder()
101 + .appId(McastForwarding.getAppId())
102 + .selector(selector.build())
103 + .treatment(treatment)
104 + .ingressPoint(mroute.getIngressPoint())
105 + .egressPoints(mroute.getEgressPoints()).
106 + build();
107 +
108 + intentService.submit(intent);
109 + return intent;
110 + }
111 +
112 + /**
113 + * Withdraw the intent represented by this route.
114 + *
115 + * @param mroute the mcast route whose intent we want to remove
116 + */
117 + public void withdrawIntent(McastRouteBase mroute) {
118 + Intent intent = intentService.getIntent(mroute.getIntentKey());
119 + intentService.withdraw(intent);
120 + }
121 +
122 + /**
123 + * Withdraw all intents.
124 + *
125 + * This will be called from the deactivate method so we don't leave
126 + * a mess behind us after we leave.
127 + */
128 + public void withdrawAllIntents() {
129 + for (Intent intent : intentService.getIntents()) {
130 + intentService.withdraw(intent);
131 + }
132 + }
133 +}
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import org.onlab.packet.IpPrefix;
19 +import org.onosproject.net.ConnectPoint;
20 +import org.onosproject.net.intent.Key;
21 +import org.onosproject.net.intent.SinglePointToMultiPointIntent;
22 +
23 +import java.util.Set;
24 +
25 +/**
26 + * This McastRouteBase interface is implemented by the McastRouteBase class which
27 + * in turn acts as the base class for both the McastRouteGroup and McastRouteSource.
28 + */
29 +interface McastRoute {
30 +
31 + /**
32 + * Gets the group addresses.
33 + *
34 + * @return group address
35 + */
36 + public IpPrefix getGaddr();
37 +
38 + /**
39 + * Gets the source address.
40 + *
41 + * @return the source address
42 + */
43 + public IpPrefix getSaddr();
44 +
45 + /**
46 + * Determines if this is an IPv4 multicast route.
47 + *
48 + * @return true if it is an IPv4 route
49 + */
50 + public boolean isIp4();
51 +
52 + /**
53 + * Determines if this is an IPv6 multicast route.
54 + *
55 + * @return true if it is an IPv6 route
56 + */
57 + public boolean isIp6();
58 +
59 + /**
60 + * Add the ingress ConnectPoint with a ConnectPoint.
61 + *
62 + * @param ingress ingress point
63 + */
64 + public void addIngressPoint(ConnectPoint ingress);
65 +
66 + /**
67 + * Add the ingress Connect Point using. ..
68 + *
69 + * @param deviceId device ID
70 + * @param portNum port number
71 + */
72 + public void addIngressPoint(String deviceId, long portNum);
73 +
74 + /**
75 + * Get the ingress connect point.
76 + *
77 + * @return the ingress connect point
78 + */
79 + public ConnectPoint getIngressPoint();
80 +
81 + /**
82 + * Add an egress connect point.
83 + *
84 + * @param member the egress ConnectPoint to be added
85 + */
86 + public void addEgressPoint(ConnectPoint member);
87 +
88 + /**
89 + * Add an egress connect point.
90 + *
91 + * @param deviceId the device ID of the connect point
92 + * @param portNum the port number of the connect point
93 + */
94 + public void addEgressPoint(String deviceId, long portNum);
95 +
96 + /**
97 + * Get the egress connect points.
98 + *
99 + * @return a set of egress connect points
100 + */
101 + public Set<ConnectPoint> getEgressPoints();
102 +
103 + /**
104 + * Increment the punt count.
105 + */
106 + public void incrementPuntCount();
107 +
108 + /**
109 + * Get the punt count.
110 + *
111 + * @return the punt count
112 + */
113 + public int getPuntCount();
114 +
115 + /**
116 + * Have the McastIntentManager create an intent, attempt to
117 + * install the intent and then save the key.
118 + */
119 + public void setIntent();
120 +
121 + /**
122 + * Set the Intent key.
123 + *
124 + * @param intent intent
125 + */
126 + public void setIntent(SinglePointToMultiPointIntent intent);
127 +
128 + /**
129 + * Withdraw the intent if it has been installed.
130 + */
131 + public void withdrawIntent();
132 +
133 + /**
134 + * Get the intent key.
135 + *
136 + * @return the intentKey
137 + */
138 + public Key getIntentKey();
139 +
140 + /**
141 + * Pretty print the the route.
142 + *
143 + * @return a pretty string
144 + */
145 + public String toString();
146 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import org.onlab.packet.IpPrefix;
21 +import org.onosproject.net.ConnectPoint;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.PortNumber;
24 +import org.onosproject.net.intent.SinglePointToMultiPointIntent;
25 +import org.onosproject.net.intent.Key;
26 +
27 +import java.util.Set;
28 +import java.util.HashSet;
29 +
30 +/**
31 + * McastRouteBase base class for McastRouteGroup and McastRouteSource.
32 + */
33 +public class McastRouteBase implements McastRoute {
34 + protected final IpPrefix gaddr;
35 + protected final IpPrefix saddr;
36 +
37 + protected ConnectPoint ingressPoint;
38 + protected Set<ConnectPoint> egressPoints;
39 +
40 + protected boolean isGroup = false;
41 +
42 + /**
43 + * How may times has this packet been punted.
44 + */
45 + private int puntCount = 0;
46 +
47 + /**
48 + * If the intentKey is null that means no intent has
49 + * been installed.
50 + */
51 + protected Key intentKey = null;
52 +
53 + /**
54 + * Create a multicast route. This is the parent class for both the Group
55 + * and the source.
56 + *
57 + * @param saddr source address
58 + * @param gaddr multicast group address
59 + */
60 + public McastRouteBase(String saddr, String gaddr) {
61 + this.gaddr = IpPrefix.valueOf(checkNotNull(gaddr));
62 + if (saddr == null || saddr.equals("*")) {
63 + this.saddr = IpPrefix.valueOf(0, 0);
64 + } else {
65 + this.saddr = IpPrefix.valueOf(checkNotNull(gaddr));
66 + }
67 + this.init();
68 + }
69 +
70 + /**
71 + * Create a multicast group table entry.
72 + * @param gaddr multicast group address
73 + */
74 + public McastRouteBase(String gaddr) {
75 + this("*", gaddr);
76 + }
77 +
78 + /**
79 + * Set the source and group address value of a (*, G) group.
80 + *
81 + * @param gpfx the group prefix address
82 + */
83 + public McastRouteBase(IpPrefix gpfx) {
84 + this(IpPrefix.valueOf(0, 0), gpfx);
85 + }
86 +
87 + /**
88 + * Create a multicast route constructor.
89 + *
90 + * @param saddr source address
91 + * @param gaddr group address
92 + */
93 + public McastRouteBase(IpPrefix saddr, IpPrefix gaddr) {
94 + this.saddr = checkNotNull(saddr);
95 + this.gaddr = checkNotNull(gaddr);
96 +
97 + this.init();
98 + }
99 +
100 + private void init() {
101 + this.isGroup = (this.saddr.prefixLength() == 0);
102 + this.ingressPoint = null;
103 + this.egressPoints = new HashSet();
104 + }
105 +
106 + /**
107 + * Get the multicast group address.
108 + *
109 + * @return the multicast group address
110 + */
111 + @Override
112 + public IpPrefix getGaddr() {
113 + return gaddr;
114 + }
115 +
116 + /**
117 + * Get the multicast source address.
118 + *
119 + * @return the multicast source address
120 + */
121 + @Override
122 + public IpPrefix getSaddr() {
123 + return saddr;
124 + }
125 +
126 + /**
127 + * Is this an IPv4 multicast route.
128 + *
129 + * @return true if it is an IPv4 route
130 + */
131 + @Override
132 + public boolean isIp4() {
133 + return gaddr.isIp4();
134 + }
135 +
136 + /**
137 + * Is this an IPv6 multicast route.
138 + *
139 + * @return true if it is an IPv6 route
140 + */
141 + @Override
142 + public boolean isIp6() {
143 + return gaddr.isIp6();
144 + }
145 +
146 + /**
147 + * Is this a multicast group route?
148 + *
149 + * @return true if it is a multicast group route.
150 + */
151 + public boolean isGroup() {
152 + return isGroup;
153 + }
154 +
155 + /**
156 + * @return true if this is (S, G) false if it (*, G).
157 + */
158 + public boolean isSource() {
159 + return (!isGroup);
160 + }
161 +
162 + /**
163 + * Add an ingress point to this route.
164 + *
165 + * @param ingress incoming connect point
166 + */
167 + @Override
168 + public void addIngressPoint(ConnectPoint ingress) {
169 + ingressPoint = checkNotNull(ingress);
170 + }
171 +
172 + /**
173 + * Add or modify the ingress connect point.
174 + *
175 + * @param deviceId the switch device Id
176 + * @param portNum the ingress port number
177 + */
178 + @Override
179 + public void addIngressPoint(String deviceId, long portNum) {
180 + ingressPoint = new ConnectPoint(
181 + DeviceId.deviceId(deviceId),
182 + PortNumber.portNumber(portNum));
183 + }
184 +
185 + /**
186 + * Get the ingress ConnectPoint.
187 + *
188 + * @return the ingress ConnectPoint
189 + */
190 + @Override
191 + public ConnectPoint getIngressPoint() {
192 + return this.ingressPoint;
193 + }
194 +
195 + /**
196 + * Add an egress ConnectPoint.
197 + *
198 + * @param member member egress connect point
199 + */
200 + @Override
201 + public void addEgressPoint(ConnectPoint member) {
202 + egressPoints.add(checkNotNull(member));
203 + }
204 +
205 + /**
206 + * Add an egress ConnectPoint.
207 + *
208 + * @param deviceId deviceId of the connect point
209 + * @param portNum portNum of the connect point
210 + */
211 + @Override
212 + public void addEgressPoint(String deviceId, long portNum) {
213 + ConnectPoint cp = new ConnectPoint(DeviceId.deviceId(deviceId), PortNumber.portNumber(portNum));
214 + this.egressPoints.add(cp);
215 + }
216 +
217 + /**
218 + * Get egress connect points for the route.
219 + *
220 + * @return Set of egress connect points
221 + */
222 + @Override
223 + public Set<ConnectPoint> getEgressPoints() {
224 + return egressPoints;
225 + }
226 +
227 + /**
228 + * Get the number of times the packet has been punted.
229 + *
230 + * @return the punt count
231 + */
232 + @Override
233 + public int getPuntCount() {
234 + return puntCount;
235 + }
236 +
237 + /**
238 + * Increment the punt count.
239 + *
240 + * TODO: we need to handle wrapping.
241 + */
242 + @Override
243 + public void incrementPuntCount() {
244 + puntCount++;
245 + }
246 +
247 + /**
248 + * Have the McastIntentManager create and set the intent, then save the intent key.
249 + *
250 + * If we already have an intent, we will first withdraw the existing intent and
251 + * replace it with a new one. This will support the case where the ingress connectPoint
252 + * or group of egress connectPoints change.
253 + */
254 + @Override
255 + public void setIntent() {
256 + if (this.intentKey != null) {
257 + this.withdrawIntent();
258 + }
259 + McastIntentManager im = McastIntentManager.getInstance();
260 + SinglePointToMultiPointIntent intent = im.setIntent(this);
261 + this.intentKey = intent.key();
262 + }
263 +
264 + /**
265 + * Set the Intent key.
266 + *
267 + * @param intent intent
268 + */
269 + @Override
270 + public void setIntent(SinglePointToMultiPointIntent intent) {
271 + intentKey = intent.key();
272 + }
273 +
274 + /**
275 + * Get the intent key represented by this route.
276 + *
277 + * @return intentKey
278 + */
279 + @Override
280 + public Key getIntentKey() {
281 + return this.intentKey;
282 + }
283 +
284 +
285 + /**
286 + * Withdraw the intent and set the key to null.
287 + */
288 + @Override
289 + public void withdrawIntent() {
290 + if (intentKey == null) {
291 + // nothing to withdraw
292 + return;
293 + }
294 + McastIntentManager im = McastIntentManager.getInstance();
295 + im.withdrawIntent(this);
296 + this.intentKey = null;
297 + }
298 +
299 + /**
300 + * Pretty Print this Multicast Route. Works for McastRouteSource and McastRouteGroup.
301 + *
302 + * @return pretty string of the multicast route
303 + */
304 + @Override
305 + public String toString() {
306 + String out = String.format("(%s, %s)\n\t",
307 + saddr.toString(), gaddr.toString());
308 +
309 + out += "intent: ";
310 + out += (intentKey == null) ? "not installed" : this.intentKey.toString();
311 + out += "\n\tingress: ";
312 + out += (ingressPoint == null) ? "NULL" : ingressPoint.toString();
313 + out += "\n\tegress: {\n";
314 + if (egressPoints != null && !egressPoints.isEmpty()) {
315 + for (ConnectPoint eg : egressPoints) {
316 + out += "\t\t" + eg.toString() + "\n";
317 + }
318 + }
319 + out += ("\t}\n");
320 + out += ("\tpunted: " + this.getPuntCount() + "\n");
321 + return out;
322 + }
323 +}
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import java.util.HashMap;
20 +import org.onlab.packet.IpPrefix;
21 +
22 +/**
23 + * The McastRouteGroup extends the McastRouteBase class and serves two purposes:
24 + * first it represents a (*, G) multicast route entry. Second it serves
25 + * as a container for all (S, G) multicast route entries that belong
26 + * to the same group address.
27 + */
28 +public class McastRouteGroup extends McastRouteBase {
29 + private HashMap<IpPrefix, McastRouteSource> sources;
30 +
31 + /**
32 + * Class constructor.
33 + *
34 + * @param gaddr - String representation of group address.
35 + */
36 + public McastRouteGroup(String gaddr) {
37 + super(checkNotNull(gaddr));
38 + this.init();
39 + }
40 +
41 + /**
42 + * Create a multicast group.
43 + *
44 + * @param gpfx - Group address
45 + */
46 + public McastRouteGroup(IpPrefix gpfx) {
47 + super(checkNotNull(gpfx));
48 + this.init();
49 + }
50 +
51 + /**
52 + * Common initialization used by constructors.
53 + */
54 + private void init() {
55 + this.sources = new HashMap();
56 + super.isGroup = true;
57 + }
58 +
59 + /**
60 + * Find a specific multicast source address for this group.
61 + *
62 + * @param saddr the source address
63 + * @return the multicast source route or null if it does not exist
64 + */
65 + public McastRouteSource findSource(IpPrefix saddr) {
66 + return this.sources.get(checkNotNull(saddr));
67 + }
68 +
69 + /**
70 + * Return the entire set of multicast sources for this group.
71 + *
72 + * @return the set of multicast sources
73 + */
74 + public HashMap<IpPrefix, McastRouteSource> getSources() {
75 + return this.sources;
76 + }
77 +
78 + /**
79 + * Add a new McastRouteSource to this group.
80 + *
81 + * @param src the multicast source
82 + */
83 + public void addSource(McastRouteSource src) {
84 + checkNotNull(src);
85 + this.sources.put(src.getSaddr(), src);
86 + }
87 +
88 + /**
89 + * Remove the source with this specific IpPrefix from this group entry.
90 + *
91 + * @param spfx IP Prefix of the source to be removed
92 + * @return the source route that was just removed
93 + */
94 + public McastRouteSource removeSource(IpPrefix spfx) {
95 + McastRouteSource src = this.sources.remove(spfx);
96 + src.withdrawIntent();
97 + return src;
98 + }
99 +
100 + /**
101 + * Remove all sources from this.
102 + */
103 + public void removeSources() {
104 + for (McastRouteSource src : this.sources.values()) {
105 + src.withdrawIntent();
106 + this.sources.remove(src.getSaddr());
107 + }
108 + }
109 +
110 +}
1 +/*
2 + * Copyright 2015 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.mfwd.impl;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import org.onlab.packet.IpPrefix;
20 +
21 +/**
22 + * This class represents and specific multicast senders source address. Objects from
23 + * this class will belong to the sources collection of the multicast group.
24 + */
25 +public class McastRouteSource extends McastRouteBase {
26 +
27 + // A reference to our parent group
28 + private McastRouteGroup group;
29 +
30 + /**
31 + * Create a multicast source with IpPrefixes.
32 + *
33 + * @param source the source address
34 + * @param group the group address
35 + */
36 + public McastRouteSource(IpPrefix source, IpPrefix group) {
37 + super(checkNotNull(source), checkNotNull(group));
38 + }
39 +
40 + /**
41 + * Set our parent multicast group.
42 + *
43 + * @param group the group this source belongs to
44 + */
45 + public void setGroup(McastRouteGroup group) {
46 + this.group = group;
47 + }
48 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/**
2 + * Sample Multicast forwarding framework using intents.
3 + */
4 +package org.onosproject.mfwd.impl;
1 +/*
2 + * Copyright 2015 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.mfwd.rest;
17 +
18 +import com.fasterxml.jackson.databind.JsonNode;
19 +import com.fasterxml.jackson.databind.ObjectMapper;
20 +
21 +import java.io.IOException;
22 +import java.io.InputStream;
23 +import java.util.Map;
24 +
25 +import javax.ws.rs.Consumes;
26 +import javax.ws.rs.GET;
27 +import javax.ws.rs.POST;
28 +import javax.ws.rs.Path;
29 +import javax.ws.rs.Produces;
30 +import javax.ws.rs.core.MediaType;
31 +import javax.ws.rs.core.Response;
32 +
33 +import org.onlab.packet.IpPrefix;
34 +import org.onlab.rest.BaseResource;
35 +import org.onosproject.mfwd.impl.McastRouteGroup;
36 +import org.onosproject.mfwd.impl.McastRouteTable;
37 +
38 +/**
39 + * Rest API for Multicast Forwarding.
40 + */
41 +@Path("mcast")
42 +public class McastResource extends BaseResource {
43 +
44 + /**
45 + * Retrieve the multicast route table.
46 + * @return the multicast route table.
47 + * @throws IOException if an error occurs
48 + */
49 + @GET
50 + @Produces(MediaType.APPLICATION_JSON)
51 + public Response showAll() throws IOException {
52 + ObjectMapper mapper = new ObjectMapper();
53 + McastRouteTable mcastRouteTable = McastRouteTable.getInstance();
54 + Map<IpPrefix, McastRouteGroup> map = mcastRouteTable.getMrib4();
55 + return Response.ok(mapper.createObjectNode().toString()).build();
56 + }
57 +
58 + /**
59 + * Static join of a multicast flow.
60 + * @param input source, group, ingress connectPoint egress connectPoints
61 + * @return status of static join
62 + * @throws IOException if an error occurs
63 + */
64 + @POST
65 + @Consumes(MediaType.APPLICATION_JSON)
66 + @Produces(MediaType.APPLICATION_JSON)
67 + public Response join(InputStream input) throws IOException {
68 + ObjectMapper mapper = new ObjectMapper();
69 + JsonNode cfg = mapper.readTree(input);
70 + return null;
71 + }
72 +}
1 +<!--
2 + ~ Copyright 2014 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 +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
17 +
18 + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
19 + <command>
20 + <action class="org.onosproject.mfwd.cli.McastJoinCommand"/>
21 + </command>
22 + <command>
23 + <action class="org.onosproject.mfwd.cli.McastDeleteCommand"/>
24 + </command>
25 + <command>
26 + <action class="org.onosproject.mfwd.cli.McastShowCommand"/>
27 + </command>
28 + </command-bundle>
29 +
30 +</blueprint>
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 +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
18 + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 + id="ONOS" version="2.5">
21 + <display-name>ONOS APP MFWD</display-name>
22 +
23 + <servlet>
24 + <servlet-name>JAX-RS Service</servlet-name>
25 + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
26 + <init-param>
27 + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
28 + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
29 + </init-param>
30 + <init-param>
31 + <param-name>com.sun.jersey.config.property.classnames</param-name>
32 + <param-value>
33 + org.onosproject.mfwd.rest.McastResource
34 + </param-value>
35 + </init-param>
36 + <load-on-startup>1</load-on-startup>
37 + </servlet>
38 +
39 + <servlet-mapping>
40 + <servlet-name>JAX-RS Service</servlet-name>
41 + <url-pattern>/*</url-pattern>
42 + </servlet-mapping>
43 +
44 +</web-app>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 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/xsd/maven-4.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.4.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-pim</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>Protocol Independent Multicast Emulation</description>
33 +
34 + <properties>
35 + <onos.app.name>org.onosproject.pim</onos.app.name>
36 + </properties>
37 +
38 + <dependencies>
39 + <dependency>
40 + <groupId>org.onosproject</groupId>
41 + <artifactId>onos-api</artifactId>
42 + <version>${project.version}</version>
43 + </dependency>
44 +
45 + <dependency>
46 + <groupId>org.onosproject</groupId>
47 + <artifactId>onos-cli</artifactId>
48 + <version>${project.version}</version>
49 + </dependency>
50 +
51 +
52 + <dependency>
53 + <groupId>org.onosproject</groupId>
54 + <artifactId>onlab-osgi</artifactId>
55 + <version>${project.version}</version>
56 + </dependency>
57 +
58 + <dependency>
59 + <groupId>org.onosproject</groupId>
60 + <artifactId>onlab-junit</artifactId>
61 + <scope>test</scope>
62 + </dependency>
63 +
64 + <!-- This is needed by ComponentContext, used for tunable configuration -->
65 + <dependency>
66 + <groupId>org.osgi</groupId>
67 + <artifactId>org.osgi.compendium</artifactId>
68 + </dependency>
69 +
70 + <dependency>
71 + <groupId>org.apache.karaf.shell</groupId>
72 + <artifactId>org.apache.karaf.shell.console</artifactId>
73 + </dependency>
74 +
75 + <dependency>
76 + <groupId>org.apache.felix</groupId>
77 + <artifactId>org.apache.felix.scr.annotations</artifactId>
78 + <version>1.9.8</version>
79 + <scope>provided</scope>
80 + </dependency>
81 + </dependencies>
82 +
83 + <build>
84 + <plugins>
85 + <plugin>
86 + <groupId>org.apache.felix</groupId>
87 + <artifactId>maven-bundle-plugin</artifactId>
88 + <extensions>true</extensions>
89 + <configuration>
90 + <instructions>
91 + <Bundle-SymbolicName>
92 + ${project.groupId}.${project.artifactId}
93 + </Bundle-SymbolicName>
94 + <Import-Package>
95 + org.slf4j,
96 + org.osgi.framework,
97 + org.apache.commons.lang.math.*,
98 + com.google.common.*,
99 + org.onlab.packet.*,
100 + org.onlab.rest.*,
101 + org.onosproject.*,
102 + org.onosproject.mfwd.impl.*;
103 + org.onlab.util.*,
104 + org.jboss.netty.util.*
105 + </Import-Package>
106 + </instructions>
107 + </configuration>
108 + </plugin>
109 + <plugin>
110 + <groupId>org.apache.maven.plugins</groupId>
111 + <artifactId>maven-compiler-plugin</artifactId>
112 + <version>2.5.1</version>
113 + <configuration>
114 + <source>1.8</source>
115 + <target>1.8</target>
116 + </configuration>
117 + </plugin>
118 + </plugins>
119 + </build>
120 +</project>
1 +/*
2 + * Copyright 2014-2015 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.pim.cli;
17 +
18 +import com.fasterxml.jackson.databind.JsonNode;
19 +import org.apache.karaf.shell.commands.Command;
20 +import org.onosproject.cli.AbstractShellCommand;
21 +import org.onosproject.net.ConnectPoint;
22 +import org.onosproject.pim.impl.PIMNeighbors;
23 +import org.onosproject.pim.impl.PIMNeighborsCodec;
24 +
25 +import java.util.HashMap;
26 +
27 +@Command(scope = "onos", name = "pim-show", description = "Displays the pim neighbors")
28 +public class PIMShowCommand extends AbstractShellCommand {
29 +
30 + // prints either the json or cli version of the hash map connect point
31 + // neighbors from the PIMNeighbors class.
32 + @Override
33 + protected void execute() {
34 + // grab connect point neighbors hash map to send in to json encoder.
35 + HashMap<ConnectPoint, PIMNeighbors> pimNbrs = PIMNeighbors.getConnectPointNeighbors();
36 + if (outputJson()) {
37 + print("%s", json(pimNbrs));
38 + } else {
39 + print(PIMNeighbors.printPimNeighbors());
40 + }
41 + }
42 +
43 + private JsonNode json(HashMap<ConnectPoint, PIMNeighbors> pimNbrs) {
44 + return new PIMNeighborsCodec().encode(pimNbrs, this);
45 + }
46 +
47 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/**
2 + * PIM Multicast forwarding framework using intents.
3 + */
4 +package org.onosproject.pim.cli;
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2015 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.pim.impl;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import org.apache.felix.scr.annotations.Activate;
21 +import org.apache.felix.scr.annotations.Component;
22 +import org.apache.felix.scr.annotations.Deactivate;
23 +import org.apache.felix.scr.annotations.Reference;
24 +import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.IPv4;
27 +import org.onlab.packet.Ip4Address;
28 +import org.onlab.packet.IpAddress;
29 +import org.onlab.packet.IpPrefix;
30 +import org.onlab.packet.PIM;
31 +import org.onosproject.core.ApplicationId;
32 +import org.onosproject.core.CoreService;
33 +import org.onosproject.net.flow.DefaultTrafficSelector;
34 +import org.onosproject.net.flow.TrafficSelector;
35 +import org.onosproject.net.packet.InboundPacket;
36 +import org.onosproject.net.packet.PacketContext;
37 +import org.onosproject.net.packet.PacketPriority;
38 +import org.onosproject.net.packet.PacketProcessor;
39 +import org.onosproject.net.packet.PacketService;
40 +import org.slf4j.Logger;
41 +
42 +/**
43 + * Protocol Independent Multicast Emulation.
44 + */
45 +@Component(immediate = true)
46 +public class PIMComponent {
47 + private final Logger log = getLogger(getClass());
48 +
49 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 + protected PacketService packetService;
51 +
52 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 + protected CoreService coreService;
54 +
55 + private PIMPacketProcessor processor = new PIMPacketProcessor();
56 + private static ApplicationId appId;
57 +
58 + @Activate
59 + public void activate() {
60 + appId = coreService.registerApplication("org.onosproject.pim");
61 +
62 + packetService.addProcessor(processor, PacketProcessor.director(1));
63 +
64 + // Build a traffic selector for all multicast traffic
65 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
66 + selector.matchEthType(Ethernet.TYPE_IPV4);
67 + selector.matchIPProtocol(IPv4.PROTOCOL_PIM);
68 + packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
69 +
70 + log.info("Started");
71 + }
72 +
73 + @Deactivate
74 + public void deactivate() {
75 + packetService.removeProcessor(processor);
76 + processor = null;
77 + log.info("Stopped");
78 + }
79 +
80 + /**
81 + * Packet processor responsible for handling IGMP packets.
82 + */
83 + private class PIMPacketProcessor implements PacketProcessor {
84 +
85 + @Override
86 + public void process(PacketContext context) {
87 + // Stop processing if the packet has been handled, since we
88 + // can't do any more to it.
89 + if (context.isHandled()) {
90 + return;
91 + }
92 +
93 + InboundPacket pkt = context.inPacket();
94 + if (pkt == null) {
95 + return;
96 + }
97 +
98 + Ethernet ethPkt = pkt.parsed();
99 + if (ethPkt == null) {
100 + return;
101 + }
102 +
103 + /*
104 + * IPv6 MLD packets are handled by ICMP6. We'll only deal
105 + * with IPv4.
106 + */
107 + if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
108 + return;
109 + }
110 +
111 + IPv4 ip = (IPv4) ethPkt.getPayload();
112 + IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
113 + IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
114 + log.debug("Packet (" + saddr.toString() + ", " + gaddr.toString() +
115 + "\tingress port: " + context.inPacket().receivedFrom().toString());
116 +
117 + if (ip.getProtocol() != IPv4.PROTOCOL_PIM) {
118 + log.debug("PIM Picked up a non PIM packet: IP protocol: " + ip.getProtocol());
119 + return;
120 + }
121 +
122 + // TODO: check incoming to be PIM.PIM_ADDRESS or "Our" address.
123 + IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
124 + IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
125 +
126 + PIM pim = (PIM) ip.getPayload();
127 + switch (pim.getPimMsgType()) {
128 +
129 + case PIM.TYPE_HELLO:
130 + PIMNeighbors.processHello(ethPkt, context.inPacket().receivedFrom());
131 + break;
132 +
133 + case PIM.TYPE_JOIN_PRUNE_REQUEST:
134 + // Create the function
135 + break;
136 +
137 + case PIM.TYPE_ASSERT:
138 + case PIM.TYPE_BOOTSTRAP:
139 + case PIM.TYPE_CANDIDATE_RP_ADV:
140 + case PIM.TYPE_GRAFT:
141 + case PIM.TYPE_GRAFT_ACK:
142 + case PIM.TYPE_REGISTER:
143 + case PIM.TYPE_REGISTER_STOP:
144 + log.debug("Unsupported PIM message type: " + pim.getPimMsgType());
145 + break;
146 +
147 + default:
148 + log.debug("Unkown PIM message type: " + pim.getPimMsgType());
149 + break;
150 + }
151 + }
152 + }
153 +}
1 +/*
2 + * Copyright 2014-2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in reliance 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.pim.impl;
17 +
18 +import org.jboss.netty.util.Timeout;
19 +import org.jboss.netty.util.TimerTask;
20 +import org.onlab.packet.IpAddress;
21 +import org.onlab.packet.MacAddress;
22 +import org.onlab.packet.pim.PIMHello;
23 +import org.onlab.packet.pim.PIMHelloOption;
24 +import org.onosproject.net.ConnectPoint;
25 +import org.slf4j.Logger;
26 +
27 +import java.nio.ByteBuffer;
28 +import java.util.concurrent.TimeUnit;
29 +
30 +import static com.google.common.base.Preconditions.checkNotNull;
31 +import static org.slf4j.LoggerFactory.getLogger;
32 +
33 +/**
34 + * PIMNeighbor represents all the PIM routers that have sent us
35 + * hello messages, or that possibly have been statically configured.
36 + */
37 +public class PIMNeighbor {
38 + private final Logger log = getLogger(getClass());
39 +
40 + // The primary address of this PIM neighbor
41 + private IpAddress primaryAddr;
42 +
43 + // The MacAddress of this neighbor
44 + private MacAddress macAddress;
45 +
46 + // The ConnectPoint this PIM neighbor is connected to.
47 + private ConnectPoint connectPoint;
48 +
49 + // Is this neighbor us?
50 + private boolean isThisUs = false;
51 +
52 + // The option values this neighbor has sent us.
53 + private int priority = 0;
54 + private int genId = 0;
55 + private short holdtime = 0;
56 +
57 + // Is this pim neighbor the DR?
58 + private boolean isDr = false;
59 +
60 + // Timeout for this neighbor
61 + private volatile Timeout timeout;
62 +
63 + private boolean reelect = false;
64 +
65 + // A back pointer the neighbors list this neighbor belongs to.
66 + private PIMNeighbors neighbors;
67 +
68 + /**
69 + * Construct this neighbor from the address and connect point.
70 + *
71 + * @param ipaddr IP Address of neighbor
72 + * @param macaddr MAC Address of the neighbor
73 + * @param cp The ConnectPoint of this neighbor
74 + */
75 + public PIMNeighbor(IpAddress ipaddr, MacAddress macaddr, ConnectPoint cp) {
76 + this.macAddress = macaddr;
77 + this.primaryAddr = ipaddr;
78 + this.connectPoint = cp;
79 + this.resetTimeout();
80 + }
81 +
82 + /**
83 + * Get the primary address of this neighbor.
84 + *
85 + * @return the primary IP address.
86 + */
87 + public IpAddress getPrimaryAddr() {
88 + return primaryAddr;
89 + }
90 +
91 + /**
92 + * Set the primary address of this neighbor.
93 + *
94 + * @param primaryAddr the address we'll use when sending hello messages
95 + */
96 + public void setPrimaryAddr(IpAddress primaryAddr) {
97 + this.primaryAddr = primaryAddr;
98 + }
99 +
100 + /**
101 + * Get the priority this neighbor has advertised to us.
102 + *
103 + * @return the priority
104 + */
105 + public int getPriority() {
106 + return priority;
107 + }
108 +
109 + /**
110 + * Set the priority for this neighbor.
111 + *
112 + * @param priority This neighbors priority.
113 + */
114 + public void setPriority(int priority) {
115 + this.priority = priority;
116 + }
117 +
118 + /**
119 + * Get the generation ID.
120 + *
121 + * @return the generation ID.
122 + */
123 + public int getGenId() {
124 + return genId;
125 + }
126 +
127 + /**
128 + * Set the generation ID.
129 + *
130 + * @param genId the generation ID.
131 + */
132 + public void setGenId(int genId) {
133 + this.genId = genId;
134 + }
135 +
136 + /**
137 + * Get the holdtime for this neighbor.
138 + *
139 + * @return the holdtime
140 + */
141 + public short getHoldtime() {
142 + return holdtime;
143 + }
144 +
145 + /**
146 + * Set the holdtime for this neighbor.
147 + *
148 + * @param holdtime the holdtime.
149 + */
150 + public void setholdtime(short holdtime) {
151 + this.holdtime = holdtime;
152 + }
153 +
154 + /**
155 + * Is this neighbor the designated router on this connect point?
156 + *
157 + * @return true if so, false if not.
158 + */
159 + public boolean isDr() {
160 + return isDr;
161 + }
162 +
163 + /**
164 + * Set this router as the designated router on this connect point.
165 + *
166 + * @param isDr True is this neighbor is the DR false otherwise
167 + */
168 + public void setIsDr(boolean isDr) {
169 + this.isDr = isDr;
170 + }
171 +
172 + /**
173 + * The ConnectPoint this neighbor is connected to.
174 + *
175 + * @return the ConnectPoint
176 + */
177 + public ConnectPoint getConnectPoint() {
178 + return connectPoint;
179 + }
180 +
181 + /**
182 + * Set the ConnectPoint this router is connected to.
183 + *
184 + * @param connectPoint the ConnectPoint this router is connected to.
185 + */
186 + public void setConnectPoint(ConnectPoint connectPoint) {
187 + this.connectPoint = connectPoint;
188 + }
189 +
190 + /**
191 + * Set a back pointer to the neighbors list this neighbor is a member of.
192 + *
193 + * @param neighbors the neighbor list this neighbor belongs to
194 + */
195 + public void setNeighbors(PIMNeighbors neighbors) {
196 + this.neighbors = neighbors;
197 + }
198 +
199 + /**
200 + * We have received a fresh hello from a neighbor, now we need to process it.
201 + * Depending on the values received in the the hello options may force a
202 + * re-election process.
203 + *
204 + * We will also refresh the timeout for this neighbor.
205 + *
206 + * @param hello copy of the hello we'll be able to extract options from.
207 + */
208 + public void refresh(PIMHello hello) {
209 + checkNotNull(hello);
210 +
211 + for (PIMHelloOption opt : hello.getOptions().values()) {
212 +
213 + int len = opt.getOptLength();
214 + byte [] value = new byte[len];
215 + ByteBuffer bb = ByteBuffer.wrap(value);
216 +
217 + switch (opt.getOptType()) {
218 + case PIMHelloOption.OPT_GENID:
219 + int newid = bb.getInt();
220 + if (this.genId != newid) {
221 + // TODO: we have a newly rebooted neighbor. Send them our joins.
222 + this.genId = newid;
223 + }
224 + break;
225 +
226 + case PIMHelloOption.OPT_PRIORITY:
227 + int newpri = bb.getInt();
228 + if (this.priority != newpri) {
229 +
230 + // The priorities have changed. We may need to re-elect a new DR?
231 + if (this.isDr || this.neighbors.getDesignatedRouter().getPriority() < priority) {
232 + reelect = true;
233 + }
234 + this.priority = newpri;
235 + }
236 + break;
237 +
238 + case PIMHelloOption.OPT_HOLDTIME:
239 + short holdtime = bb.getShort();
240 + if (this.holdtime != holdtime) {
241 + this.holdtime = holdtime;
242 + if (holdtime == 0) {
243 + // We have a neighbor going down. We can remove all joins
244 + // we have learned from them.
245 + // TODO: What else do we need to do when a neighbor goes down?
246 +
247 + log.debug("PIM Neighbor has timed out: {}", this.primaryAddr.toString());
248 + return;
249 + }
250 + }
251 + break;
252 +
253 + case PIMHelloOption.OPT_PRUNEDELAY:
254 + case PIMHelloOption.OPT_ADDRLIST:
255 + // TODO: implement prune delay and addr list. Fall through for now.
256 +
257 + default:
258 + log.debug("PIM Hello option type: {} not yet supported or unknown.", opt.getOptType());
259 + break;
260 + }
261 + }
262 +
263 + if (reelect) {
264 + this.neighbors.electDR(this);
265 + }
266 +
267 + // Reset the next timeout timer
268 + this.resetTimeout();
269 + }
270 +
271 + /* --------------------------------------- Timer functions -------------------------- */
272 +
273 + /**
274 + * Restart the timeout task for this neighbor.
275 + */
276 + private void resetTimeout() {
277 +
278 + if (this.holdtime == 0) {
279 +
280 + // Prepare to die.
281 + log.debug("shutting down timer for nbr {}", this.primaryAddr.toString());
282 + if (this.timeout != null) {
283 + this.timeout.cancel();
284 + this.timeout = null;
285 + }
286 + return;
287 + }
288 +
289 + // Cancel the existing timeout and start a fresh new one.
290 + if (this.timeout != null) {
291 + this.timeout.cancel();
292 + }
293 +
294 + this.timeout = PIMTimer.getTimer().newTimeout(new NeighborTimeoutTask(this), holdtime, TimeUnit.SECONDS);
295 + }
296 +
297 + /**
298 + * The task to run when a neighbor timeout expires.
299 + */
300 + private final class NeighborTimeoutTask implements TimerTask {
301 + PIMNeighbor nbr;
302 +
303 + NeighborTimeoutTask(PIMNeighbor nbr) {
304 + this.nbr = nbr;
305 + }
306 +
307 + @Override
308 + public void run(Timeout timeout) throws Exception {
309 +
310 + // TODO: log.debug;
311 + PIMNeighbors neighbors = nbr.neighbors;
312 + neighbors.removeNeighbor(nbr.getPrimaryAddr());
313 + }
314 + }
315 +
316 + /**
317 + * Stop the timeout timer.
318 + *
319 + * This happens when we remove the neighbor.
320 + */
321 + private final void stopTimeout() {
322 + this.timeout.cancel();
323 + this.timeout = null;
324 + }
325 +
326 + @Override
327 + public String toString() {
328 + String out = "";
329 + if (this.isDr) {
330 + out += "*NBR:";
331 + } else {
332 + out += "NBR:";
333 + }
334 + out += "\tIP: " + this.primaryAddr.toString();
335 + out += "\tPr: " + String.valueOf(this.priority);
336 + out += "\tHoldTime: " + String.valueOf(this.holdtime);
337 + out += "\tGenID: " + String.valueOf(this.genId) + "\n";
338 + return out;
339 + }
340 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2015 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.pim.impl;
17 +
18 +import com.fasterxml.jackson.databind.node.ArrayNode;
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +import org.onosproject.codec.CodecContext;
21 +import org.onosproject.codec.JsonCodec;
22 +import org.onosproject.net.ConnectPoint;
23 +
24 +import java.util.HashMap;
25 +
26 +import static com.google.common.base.Preconditions.checkNotNull;
27 +
28 +/**
29 + * PIM neighbors Codec.
30 + */
31 +public class PIMNeighborsCodec extends JsonCodec<HashMap<ConnectPoint, PIMNeighbors>> {
32 + // JSON field names
33 + //Return Name
34 + private static final String CPNBRLIST = "connect_point_list";
35 +
36 + // PIM Neightbors Fields
37 + private static final String IP = "ip";
38 + private static final String PRIORITY = "priority";
39 + private static final String NBRLIST = "neighbor_list";
40 +
41 + // PIM neighbor Files
42 + private static final String DR = "designated";
43 + private static final String NBR_IP = "ip";
44 + private static final String PR = "priority";
45 + private static final String HOLDTIME = "hold_time";
46 +
47 + /**
48 + * Encode the PIM Neighbors.
49 + *
50 + * @param cpn ConnectPoint neighbors
51 + * @param context encoding context
52 + *
53 + * @return Encoded neighbors used by CLI and REST
54 + */
55 + @Override
56 + public ObjectNode encode(HashMap<ConnectPoint, PIMNeighbors> cpn, CodecContext context) {
57 + checkNotNull(cpn, "Pim Neighbors cannot be null");
58 +
59 + ObjectNode pimNbrJsonCodec = context.mapper().createObjectNode();
60 + ArrayNode cpnList = context.mapper().createArrayNode();
61 +
62 + for (PIMNeighbors pn: cpn.values()) {
63 + // get the PimNeighbors Obj, contains Neighbors list
64 + // create the json object for a single Entry in the Neighbors list
65 + ObjectNode cp = context.mapper().createObjectNode();
66 + cp.put(IP, pn.getOurIpAddress().toString());
67 + cp.put(PRIORITY, String.valueOf(pn.getOurPriority()));
68 +
69 + // create the array for the neighbors list
70 + ArrayNode nbrsList = context.mapper().createArrayNode();
71 + for (PIMNeighbor nbr : pn.getOurNeighborsList().values()) {
72 + nbrsList.add(neighbor(nbr, context));
73 + }
74 + // adds pim neighbor to list
75 + cp.set(NBRLIST, nbrsList);
76 + // adds to arraynode which will represent the connect point neighbors hash map.
77 + cpnList.add(cp);
78 + }
79 + pimNbrJsonCodec.set(CPNBRLIST, cpnList);
80 + return pimNbrJsonCodec;
81 + }
82 +
83 + /**
84 + * Encode a single PIM Neighbor.
85 + *
86 + * @param nbr the neighbor to be encoded
87 + * @param context encoding context
88 + * @return the encoded neighbor
89 + */
90 + private ObjectNode neighbor(PIMNeighbor nbr, CodecContext context) {
91 + return context.mapper().createObjectNode()
92 + .put(DR, Boolean.toString(nbr.isDr()))
93 + .put(NBR_IP, nbr.getPrimaryAddr().toString())
94 + .put(PR, String.valueOf(nbr.getPriority()))
95 + .put(HOLDTIME, String.valueOf(nbr.getHoldtime()));
96 + }
97 +}
1 +/*
2 + * Copyright 2015 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.pim.impl;
17 +
18 +import org.jboss.netty.util.HashedWheelTimer;
19 +
20 +/**
21 + * PIM Timer used for PIM Neighbors.
22 + */
23 +public final class PIMTimer {
24 +
25 + private static volatile HashedWheelTimer timer;
26 +
27 + // Ban public construction
28 + private PIMTimer() {
29 + }
30 +
31 + /**
32 + * Returns the singleton hashed-wheel timer.
33 + *
34 + * @return hashed-wheel timer
35 + */
36 + public static HashedWheelTimer getTimer() {
37 + if (PIMTimer.timer == null) {
38 + initTimer();
39 + }
40 + return PIMTimer.timer;
41 + }
42 +
43 + // Start the PIM timer.
44 + private static synchronized void initTimer() {
45 + if (PIMTimer.timer == null) {
46 +
47 + // Create and start a new hashed wheel timer, if it does not exist.
48 + HashedWheelTimer hwTimer = new HashedWheelTimer();
49 + hwTimer.start();
50 + PIMTimer.timer = hwTimer;
51 + }
52 + }
53 +}
1 +/*
2 + * Copyright 2015 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 + * PIM Emulation speak hello messages and listen to Join/Prunes.
19 + */
20 +package org.onosproject.pim.impl;
1 +<!--
2 + ~ Copyright 2015 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 +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
17 +
18 + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
19 + <command>
20 + <action class="org.onosproject.pim.cli.PIMShowCommand"/>
21 + </command>
22 + </command-bundle>
23 +
24 +</blueprint>
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
58 <module>vtnweb</module> 58 <module>vtnweb</module>
59 <module>dhcp</module> 59 <module>dhcp</module>
60 <module>cordvtn</module> 60 <module>cordvtn</module>
61 + <module>mfwd</module>
62 + <module>igmp</module>
63 + <module>pim</module>
61 </modules> 64 </modules>
62 65
63 <properties> 66 <properties>
......