blob: 82adfaddb3e1bf2abcaf3cd07037d18b6132acf9 [file] [log] [blame]
Rusty Eddy4ae5aa82015-12-15 12:58:27 -08001/*
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 */
16package org.onosproject.pim.impl;
17
18import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.onlab.packet.Ethernet;
24import org.onlab.packet.IPv4;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080027import org.onosproject.net.flow.DefaultTrafficSelector;
28import org.onosproject.net.flow.TrafficSelector;
29import org.onosproject.net.mcast.MulticastRouteService;
30import org.onosproject.net.packet.InboundPacket;
31import org.onosproject.net.packet.PacketContext;
Jonathan Hart36fd31e2016-01-28 15:55:31 -080032import org.onosproject.net.packet.PacketPriority;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080033import org.onosproject.net.packet.PacketProcessor;
34import org.onosproject.net.packet.PacketService;
35import org.slf4j.Logger;
36
Jonathan Hart36fd31e2016-01-28 15:55:31 -080037import java.util.Optional;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080038
39import static org.slf4j.LoggerFactory.getLogger;
40
41/**
42 * The main PIM controller class.
43 */
44@Component(immediate = true)
45public class PIMApplication {
46 private final Logger log = getLogger(getClass());
47
48 // Used to get the appId
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected CoreService coreService;
51
52 // Our application ID
53 private static ApplicationId appId;
54
55 // Register to receive PIM packets, used to send packets as well
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected PacketService packetService;
58
59 // Use the MulticastRouteService to manage incoming PIM Join/Prune state as well as
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected MulticastRouteService ms;
62
63 // Create an instance of the PIM packet handler
64 protected PIMPacketHandler pimPacketHandler;
65
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080066 // Provide interfaces to the pimInterface manager as a result of Netconfig updates.
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected PIMInterfaceService pimInterfaceManager;
69
Jonathan Hart36fd31e2016-01-28 15:55:31 -080070 private final PIMPacketProcessor processor = new PIMPacketProcessor();
71
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080072 /**
73 * Activate the PIM component.
74 */
75 @Activate
76 public void activate() {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080077 // Get our application ID
78 appId = coreService.registerApplication("org.onosproject.pim");
79
80 // Build the traffic selector for PIM packets
81 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
82 selector.matchEthType(Ethernet.TYPE_IPV4);
83 selector.matchIPProtocol(IPv4.PROTOCOL_PIM);
84
85 // Use the traffic selector to tell the packet service which packets we want.
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080086 packetService.addProcessor(processor, PacketProcessor.director(5));
87
Jonathan Hart36fd31e2016-01-28 15:55:31 -080088 packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
89 appId, Optional.empty());
90
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080091 // Get a copy of the PIM Packet Handler
92 pimPacketHandler = new PIMPacketHandler();
93
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080094 log.info("Started");
95 }
96
97 /**
98 * Deactivate the PIM component.
99 */
100 @Deactivate
101 public void deactivate() {
Jonathan Hart36fd31e2016-01-28 15:55:31 -0800102 packetService.removeProcessor(processor);
103
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800104 log.info("Stopped");
105 }
106
107 /**
108 * The class that will receive PIM packets, sanitize them, determine the PIMInterface
109 * they arrived on, then forward them on to be processed by the appropriate entity.
110 */
111 public class PIMPacketProcessor implements PacketProcessor {
112 private final Logger log = getLogger(getClass());
113
114 @Override
115 public void process(PacketContext context) {
116
117 // return if this packet has already been handled
118 if (context.isHandled()) {
119 return;
120 }
121
122 // get the inbound packet
123 InboundPacket pkt = context.inPacket();
124 if (pkt == null) {
125 // problem getting the inbound pkt. Log it debug to avoid spamming log file
126 log.debug("Could not retrieve packet from context");
127 return;
128 }
129
130 // Get the ethernet header
131 Ethernet eth = pkt.parsed();
132 if (eth == null) {
133 // problem getting the ethernet pkt. Log it debug to avoid spamming log file
134 log.debug("Could not retrieve ethnernet packet from the parsed packet");
135 return;
136 }
137
138 // Get the PIM Interface the packet was received on.
139 PIMInterface pimi = pimInterfaceManager.getPIMInterface(pkt.receivedFrom());
140 if (pimi == null) {
141 log.debug("We received PIM packet from a non PIM interface: " + pkt.receivedFrom().toString());
142 return;
143 }
144
145 /*
146 * Pass the packet processing off to the PIMInterface for processing.
147 *
148 * TODO: Is it possible that PIM interface processing should move to the
149 * PIMInterfaceManager directly?
150 */
151 PIMPacketHandler ph = new PIMPacketHandler();
152 ph.processPacket(eth, pimi);
153 }
154 }
155
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800156}