blob: 36948c14e18a188bbde5173bef575ea6cd034039 [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
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080052 // Register to receive PIM packets, used to send packets as well
Ray Milkeyd84f89b2018-08-17 14:54:17 -070053 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080054 protected PacketService packetService;
55
56 // Use the MulticastRouteService to manage incoming PIM Join/Prune state as well as
Ray Milkeyd84f89b2018-08-17 14:54:17 -070057 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080058 protected MulticastRouteService ms;
59
60 // Create an instance of the PIM packet handler
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070061 protected PimPacketHandler pimPacketHandler;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080062
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080063 // Provide interfaces to the pimInterface manager as a result of Netconfig updates.
Ray Milkeyd84f89b2018-08-17 14:54:17 -070064 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070065 protected PimInterfaceService pimInterfaceManager;
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080066
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070067 private final PimPacketProcessor processor = new PimPacketProcessor();
Jonathan Hart36fd31e2016-01-28 15:55:31 -080068
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080069 /**
70 * Activate the PIM component.
71 */
72 @Activate
73 public void activate() {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080074 // Get our application ID
Ray Milkeyfe6afd82018-11-26 14:03:20 -080075 ApplicationId appId = coreService.registerApplication("org.onosproject.pim");
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080076
77 // Build the traffic selector for PIM packets
78 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
79 selector.matchEthType(Ethernet.TYPE_IPV4);
80 selector.matchIPProtocol(IPv4.PROTOCOL_PIM);
81
82 // Use the traffic selector to tell the packet service which packets we want.
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080083 packetService.addProcessor(processor, PacketProcessor.director(5));
84
Jonathan Hart36fd31e2016-01-28 15:55:31 -080085 packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
86 appId, Optional.empty());
87
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080088 // Get a copy of the PIM Packet Handler
Jonathan Hartfbfe2a82016-03-29 11:36:33 -070089 pimPacketHandler = new PimPacketHandler();
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080090
Rusty Eddy4ae5aa82015-12-15 12:58:27 -080091 log.info("Started");
92 }
93
94 /**
95 * Deactivate the PIM component.
96 */
97 @Deactivate
98 public void deactivate() {
Jonathan Hart36fd31e2016-01-28 15:55:31 -080099 packetService.removeProcessor(processor);
100
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800101 log.info("Stopped");
102 }
103
104 /**
105 * The class that will receive PIM packets, sanitize them, determine the PIMInterface
106 * they arrived on, then forward them on to be processed by the appropriate entity.
107 */
Jonathan Hartfbfe2a82016-03-29 11:36:33 -0700108 public class PimPacketProcessor implements PacketProcessor {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800109
110 @Override
111 public void process(PacketContext context) {
112
113 // return if this packet has already been handled
114 if (context.isHandled()) {
115 return;
116 }
117
118 // get the inbound packet
119 InboundPacket pkt = context.inPacket();
120 if (pkt == null) {
121 // problem getting the inbound pkt. Log it debug to avoid spamming log file
122 log.debug("Could not retrieve packet from context");
123 return;
124 }
125
126 // Get the ethernet header
127 Ethernet eth = pkt.parsed();
128 if (eth == null) {
129 // problem getting the ethernet pkt. Log it debug to avoid spamming log file
Jonathan Hart7f4bc522016-02-20 11:32:43 -0800130 log.debug("Could not retrieve ethernet packet from the parsed packet");
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800131 return;
132 }
133
134 // Get the PIM Interface the packet was received on.
Jonathan Hartfbfe2a82016-03-29 11:36:33 -0700135 PimInterface pimi = pimInterfaceManager.getPimInterface(pkt.receivedFrom());
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800136 if (pimi == null) {
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800137 return;
138 }
139
140 /*
141 * Pass the packet processing off to the PIMInterface for processing.
142 *
143 * TODO: Is it possible that PIM interface processing should move to the
144 * PIMInterfaceManager directly?
145 */
Jonathan Hart7f4bc522016-02-20 11:32:43 -0800146 pimPacketHandler.processPacket(eth, pimi);
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800147 }
148 }
149
Rusty Eddy4ae5aa82015-12-15 12:58:27 -0800150}