blob: b59d1ab7aac7ade692a46d687b729ee770194018 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
toma9a77c22014-10-03 17:05:20 -070019package org.onlab.onos.ifwd;
20
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070026import org.onlab.onos.core.ApplicationId;
27import org.onlab.onos.core.CoreService;
toma9a77c22014-10-03 17:05:20 -070028import org.onlab.onos.net.Host;
29import org.onlab.onos.net.HostId;
30import org.onlab.onos.net.PortNumber;
31import org.onlab.onos.net.flow.DefaultTrafficSelector;
32import org.onlab.onos.net.flow.DefaultTrafficTreatment;
33import org.onlab.onos.net.flow.TrafficSelector;
34import org.onlab.onos.net.flow.TrafficTreatment;
35import org.onlab.onos.net.host.HostService;
36import org.onlab.onos.net.intent.HostToHostIntent;
toma9a77c22014-10-03 17:05:20 -070037import org.onlab.onos.net.intent.IntentService;
Brian O'Connor958d3812014-10-03 19:46:23 -070038import org.onlab.onos.net.packet.DefaultOutboundPacket;
toma9a77c22014-10-03 17:05:20 -070039import org.onlab.onos.net.packet.InboundPacket;
Brian O'Connor958d3812014-10-03 19:46:23 -070040import org.onlab.onos.net.packet.OutboundPacket;
toma9a77c22014-10-03 17:05:20 -070041import org.onlab.onos.net.packet.PacketContext;
42import org.onlab.onos.net.packet.PacketProcessor;
43import org.onlab.onos.net.packet.PacketService;
44import org.onlab.onos.net.topology.TopologyService;
45import org.onlab.packet.Ethernet;
46import org.slf4j.Logger;
47
Thomas Vachuskab97cf282014-10-20 23:31:12 -070048import static org.slf4j.LoggerFactory.getLogger;
49
toma9a77c22014-10-03 17:05:20 -070050/**
51 * WORK-IN-PROGRESS: Sample reactive forwarding application using intent framework.
52 */
53@Component(immediate = true)
54public class IntentReactiveForwarding {
55
toma9a77c22014-10-03 17:05:20 -070056 private final Logger log = getLogger(getClass());
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Thomas Vachuskab97cf282014-10-20 23:31:12 -070059 protected CoreService coreService;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
toma9a77c22014-10-03 17:05:20 -070062 protected TopologyService topologyService;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected PacketService packetService;
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected IntentService intentService;
69
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected HostService hostService;
72
73 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
Thomas Vachuskab97cf282014-10-20 23:31:12 -070074 private ApplicationId appId;
toma9a77c22014-10-03 17:05:20 -070075
76 @Activate
77 public void activate() {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070078 appId = coreService.registerApplication("org.onlab.onos.ifwd");
toma9a77c22014-10-03 17:05:20 -070079 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
tom0511a522014-10-04 12:06:02 -070080 log.info("Started");
toma9a77c22014-10-03 17:05:20 -070081 }
82
83 @Deactivate
84 public void deactivate() {
85 packetService.removeProcessor(processor);
86 processor = null;
87 log.info("Stopped");
88 }
89
toma9a77c22014-10-03 17:05:20 -070090 /**
91 * Packet processor responsible for forwarding packets along their paths.
92 */
93 private class ReactivePacketProcessor implements PacketProcessor {
94
95 @Override
96 public void process(PacketContext context) {
97 // Stop processing if the packet has been handled, since we
98 // can't do any more to it.
99 if (context.isHandled()) {
100 return;
101 }
102
103 InboundPacket pkt = context.inPacket();
104 Ethernet ethPkt = pkt.parsed();
105
106 HostId srcId = HostId.hostId(ethPkt.getSourceMAC());
107 HostId dstId = HostId.hostId(ethPkt.getDestinationMAC());
108
109 // Do we know who this is for? If not, flood and bail.
110 Host dst = hostService.getHost(dstId);
111 if (dst == null) {
112 flood(context);
113 return;
114 }
115
116 // Otherwise forward and be done with it.
117 setUpConnectivity(context, srcId, dstId);
Brian O'Connor958d3812014-10-03 19:46:23 -0700118 forwardPacketToDst(context, dst);
toma9a77c22014-10-03 17:05:20 -0700119 }
120 }
121
122 // Floods the specified packet if permissible.
123 private void flood(PacketContext context) {
124 if (topologyService.isBroadcastPoint(topologyService.currentTopology(),
125 context.inPacket().receivedFrom())) {
126 packetOut(context, PortNumber.FLOOD);
127 } else {
128 context.block();
129 }
130 }
131
132 // Sends a packet out the specified port.
133 private void packetOut(PacketContext context, PortNumber portNumber) {
134 context.treatmentBuilder().setOutput(portNumber);
135 context.send();
136 }
137
Brian O'Connor958d3812014-10-03 19:46:23 -0700138 private void forwardPacketToDst(PacketContext context, Host dst) {
139 TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(dst.location().port()).build();
140 OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(),
tom0511a522014-10-04 12:06:02 -0700141 treatment, context.inPacket().unparsed());
Brian O'Connor958d3812014-10-03 19:46:23 -0700142 packetService.emit(packet);
143 log.info("sending packet: {}", packet);
144 }
145
toma9a77c22014-10-03 17:05:20 -0700146 // Install a rule forwarding the packet to the specified port.
147 private void setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) {
148 TrafficSelector selector = DefaultTrafficSelector.builder().build();
149 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
150
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700151 HostToHostIntent intent = new HostToHostIntent(appId, srcId, dstId,
152 selector, treatment);
toma9a77c22014-10-03 17:05:20 -0700153
154 intentService.submit(intent);
155 }
156
157}