blob: 2e7634cc1a0e898a3e6f5df7cc6e95d3e30f2d08 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.ifwd;
toma9a77c22014-10-03 17:05:20 -070017
Jonathan Harte8600eb2015-01-12 10:30:45 -080018import static org.slf4j.LoggerFactory.getLogger;
19
toma9a77c22014-10-03 17:05:20 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
23import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Jonathan Harte8600eb2015-01-12 10:30:45 -080025import org.onlab.packet.Ethernet;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.net.Host;
29import org.onosproject.net.HostId;
30import org.onosproject.net.PortNumber;
31import org.onosproject.net.flow.DefaultTrafficSelector;
32import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hart06ae79d2015-01-13 18:56:33 -080033import org.onosproject.net.flow.FlowRuleService;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.flow.TrafficSelector;
35import org.onosproject.net.flow.TrafficTreatment;
36import org.onosproject.net.host.HostService;
37import org.onosproject.net.intent.HostToHostIntent;
38import org.onosproject.net.intent.IntentService;
39import org.onosproject.net.packet.DefaultOutboundPacket;
40import org.onosproject.net.packet.InboundPacket;
41import org.onosproject.net.packet.OutboundPacket;
42import org.onosproject.net.packet.PacketContext;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080043import org.onosproject.net.packet.PacketPriority;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.packet.PacketProcessor;
45import org.onosproject.net.packet.PacketService;
46import org.onosproject.net.topology.TopologyService;
toma9a77c22014-10-03 17:05:20 -070047import org.slf4j.Logger;
48
toma9a77c22014-10-03 17:05:20 -070049/**
50 * WORK-IN-PROGRESS: Sample reactive forwarding application using intent framework.
51 */
52@Component(immediate = true)
53public class IntentReactiveForwarding {
54
toma9a77c22014-10-03 17:05:20 -070055 private final Logger log = getLogger(getClass());
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Thomas Vachuskab97cf282014-10-20 23:31:12 -070058 protected CoreService coreService;
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
toma9a77c22014-10-03 17:05:20 -070061 protected TopologyService topologyService;
62
63 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 protected PacketService packetService;
65
66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 protected IntentService intentService;
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected HostService hostService;
71
Jonathan Hart06ae79d2015-01-13 18:56:33 -080072 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected FlowRuleService flowRuleService;
74
toma9a77c22014-10-03 17:05:20 -070075 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
Thomas Vachuskab97cf282014-10-20 23:31:12 -070076 private ApplicationId appId;
toma9a77c22014-10-03 17:05:20 -070077
78 @Activate
79 public void activate() {
Brian O'Connorabafb502014-12-02 22:26:20 -080080 appId = coreService.registerApplication("org.onosproject.ifwd");
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080081
toma9a77c22014-10-03 17:05:20 -070082 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080083
84 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
85 selector.matchEthType(Ethernet.TYPE_IPV4);
86 packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
87
tom0511a522014-10-04 12:06:02 -070088 log.info("Started");
toma9a77c22014-10-03 17:05:20 -070089 }
90
91 @Deactivate
92 public void deactivate() {
93 packetService.removeProcessor(processor);
94 processor = null;
95 log.info("Stopped");
96 }
97
toma9a77c22014-10-03 17:05:20 -070098 /**
99 * Packet processor responsible for forwarding packets along their paths.
100 */
101 private class ReactivePacketProcessor implements PacketProcessor {
102
103 @Override
104 public void process(PacketContext context) {
105 // Stop processing if the packet has been handled, since we
106 // can't do any more to it.
107 if (context.isHandled()) {
108 return;
109 }
110
111 InboundPacket pkt = context.inPacket();
112 Ethernet ethPkt = pkt.parsed();
113
Jonathan Harte8600eb2015-01-12 10:30:45 -0800114 if (ethPkt == null) {
115 return;
116 }
117
toma9a77c22014-10-03 17:05:20 -0700118 HostId srcId = HostId.hostId(ethPkt.getSourceMAC());
119 HostId dstId = HostId.hostId(ethPkt.getDestinationMAC());
120
121 // Do we know who this is for? If not, flood and bail.
122 Host dst = hostService.getHost(dstId);
123 if (dst == null) {
124 flood(context);
125 return;
126 }
127
128 // Otherwise forward and be done with it.
129 setUpConnectivity(context, srcId, dstId);
Brian O'Connor958d3812014-10-03 19:46:23 -0700130 forwardPacketToDst(context, dst);
toma9a77c22014-10-03 17:05:20 -0700131 }
132 }
133
134 // Floods the specified packet if permissible.
135 private void flood(PacketContext context) {
136 if (topologyService.isBroadcastPoint(topologyService.currentTopology(),
137 context.inPacket().receivedFrom())) {
138 packetOut(context, PortNumber.FLOOD);
139 } else {
140 context.block();
141 }
142 }
143
144 // Sends a packet out the specified port.
145 private void packetOut(PacketContext context, PortNumber portNumber) {
146 context.treatmentBuilder().setOutput(portNumber);
147 context.send();
148 }
149
Brian O'Connor958d3812014-10-03 19:46:23 -0700150 private void forwardPacketToDst(PacketContext context, Host dst) {
151 TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(dst.location().port()).build();
152 OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(),
tom0511a522014-10-04 12:06:02 -0700153 treatment, context.inPacket().unparsed());
Brian O'Connor958d3812014-10-03 19:46:23 -0700154 packetService.emit(packet);
155 log.info("sending packet: {}", packet);
156 }
157
toma9a77c22014-10-03 17:05:20 -0700158 // Install a rule forwarding the packet to the specified port.
159 private void setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) {
160 TrafficSelector selector = DefaultTrafficSelector.builder().build();
161 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
162
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700163 HostToHostIntent intent = new HostToHostIntent(appId, srcId, dstId,
164 selector, treatment);
toma9a77c22014-10-03 17:05:20 -0700165
166 intentService.submit(intent);
167 }
168
169}