blob: 8d76e313f90890cac2fbed7161610b2288793267 [file] [log] [blame]
Rusty Eddy4ae5aa82015-12-15 12:58:27 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Rusty Eddy4ae5aa82015-12-15 12:58:27 -08003 *
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
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import org.osgi.service.component.annotations.Activate;
19import org.osgi.service.component.annotations.Component;
20import org.osgi.service.component.annotations.Deactivate;
21import org.osgi.service.component.annotations.Reference;
22import org.osgi.service.component.annotations.ReferenceCardinality;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080023import 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)
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070045public class PimApplication {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080046 private final Logger log = getLogger(getClass());
47
48 // Used to get the appId
Ray Milkeyd84f89b2018-08-17 14:54:17 -070049 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080050 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
Ray Milkeyd84f89b2018-08-17 14:54:17 -070056 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080057 protected PacketService packetService;
58
59 // Use the MulticastRouteService to manage incoming PIM Join/Prune state as well as
Ray Milkeyd84f89b2018-08-17 14:54:17 -070060 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080061 protected MulticastRouteService ms;
62
63 // Create an instance of the PIM packet handler
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070064 protected PimPacketHandler pimPacketHandler;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080065
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080066 // Provide interfaces to the pimInterface manager as a result of Netconfig updates.
Ray Milkeyd84f89b2018-08-17 14:54:17 -070067 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070068 protected PimInterfaceService pimInterfaceManager;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080069
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070070 private final PimPacketProcessor processor = new PimPacketProcessor();
Jonathan Hart36fd31e2016-01-28 15:55:31 -080071
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
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070092 pimPacketHandler = new PimPacketHandler();
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080093
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 */
Jonathan Hartfbfe2a82016-03-29 11:36:33 -0700111 public class PimPacketProcessor implements PacketProcessor {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800112
113 @Override
114 public void process(PacketContext context) {
115
116 // return if this packet has already been handled
117 if (context.isHandled()) {
118 return;
119 }
120
121 // get the inbound packet
122 InboundPacket pkt = context.inPacket();
123 if (pkt == null) {
124 // problem getting the inbound pkt. Log it debug to avoid spamming log file
125 log.debug("Could not retrieve packet from context");
126 return;
127 }
128
129 // Get the ethernet header
130 Ethernet eth = pkt.parsed();
131 if (eth == null) {
132 // problem getting the ethernet pkt. Log it debug to avoid spamming log file
Jonathan Hart7f4bc522016-02-20 11:32:43 -0800133 log.debug("Could not retrieve ethernet packet from the parsed packet");
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800134 return;
135 }
136
137 // Get the PIM Interface the packet was received on.
Jonathan Hartfbfe2a82016-03-29 11:36:33 -0700138 PimInterface pimi = pimInterfaceManager.getPimInterface(pkt.receivedFrom());
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800139 if (pimi == null) {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800140 return;
141 }
142
143 /*
144 * Pass the packet processing off to the PIMInterface for processing.
145 *
146 * TODO: Is it possible that PIM interface processing should move to the
147 * PIMInterfaceManager directly?
148 */
Jonathan Hart7f4bc522016-02-20 11:32:43 -0800149 pimPacketHandler.processPacket(eth, pimi);
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800150 }
151 }
152
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800153}