blob: defdf08f4e470ab73846dd730b4505fca086bf21 [file] [log] [blame]
toma9a77c22014-10-03 17:05:20 -07001package org.onlab.onos.ifwd;
2
3import org.apache.felix.scr.annotations.Activate;
4import org.apache.felix.scr.annotations.Component;
5import org.apache.felix.scr.annotations.Deactivate;
6import org.apache.felix.scr.annotations.Reference;
7import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskab97cf282014-10-20 23:31:12 -07008import org.onlab.onos.ApplicationId;
9import org.onlab.onos.CoreService;
toma9a77c22014-10-03 17:05:20 -070010import org.onlab.onos.net.Host;
11import org.onlab.onos.net.HostId;
12import org.onlab.onos.net.PortNumber;
13import org.onlab.onos.net.flow.DefaultTrafficSelector;
14import org.onlab.onos.net.flow.DefaultTrafficTreatment;
15import org.onlab.onos.net.flow.TrafficSelector;
16import org.onlab.onos.net.flow.TrafficTreatment;
17import org.onlab.onos.net.host.HostService;
18import org.onlab.onos.net.intent.HostToHostIntent;
toma9a77c22014-10-03 17:05:20 -070019import org.onlab.onos.net.intent.IntentService;
Brian O'Connor958d3812014-10-03 19:46:23 -070020import org.onlab.onos.net.packet.DefaultOutboundPacket;
toma9a77c22014-10-03 17:05:20 -070021import org.onlab.onos.net.packet.InboundPacket;
Brian O'Connor958d3812014-10-03 19:46:23 -070022import org.onlab.onos.net.packet.OutboundPacket;
toma9a77c22014-10-03 17:05:20 -070023import org.onlab.onos.net.packet.PacketContext;
24import org.onlab.onos.net.packet.PacketProcessor;
25import org.onlab.onos.net.packet.PacketService;
26import org.onlab.onos.net.topology.TopologyService;
27import org.onlab.packet.Ethernet;
28import org.slf4j.Logger;
29
Thomas Vachuskab97cf282014-10-20 23:31:12 -070030import static org.slf4j.LoggerFactory.getLogger;
31
toma9a77c22014-10-03 17:05:20 -070032/**
33 * WORK-IN-PROGRESS: Sample reactive forwarding application using intent framework.
34 */
35@Component(immediate = true)
36public class IntentReactiveForwarding {
37
toma9a77c22014-10-03 17:05:20 -070038 private final Logger log = getLogger(getClass());
39
40 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Thomas Vachuskab97cf282014-10-20 23:31:12 -070041 protected CoreService coreService;
42
43 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
toma9a77c22014-10-03 17:05:20 -070044 protected TopologyService topologyService;
45
46 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
47 protected PacketService packetService;
48
49 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected IntentService intentService;
51
52 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
53 protected HostService hostService;
54
55 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
Thomas Vachuskab97cf282014-10-20 23:31:12 -070056 private ApplicationId appId;
toma9a77c22014-10-03 17:05:20 -070057
58 @Activate
59 public void activate() {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070060 appId = coreService.registerApplication("org.onlab.onos.ifwd");
toma9a77c22014-10-03 17:05:20 -070061 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
tom0511a522014-10-04 12:06:02 -070062 log.info("Started");
toma9a77c22014-10-03 17:05:20 -070063 }
64
65 @Deactivate
66 public void deactivate() {
67 packetService.removeProcessor(processor);
68 processor = null;
69 log.info("Stopped");
70 }
71
toma9a77c22014-10-03 17:05:20 -070072 /**
73 * Packet processor responsible for forwarding packets along their paths.
74 */
75 private class ReactivePacketProcessor implements PacketProcessor {
76
77 @Override
78 public void process(PacketContext context) {
79 // Stop processing if the packet has been handled, since we
80 // can't do any more to it.
81 if (context.isHandled()) {
82 return;
83 }
84
85 InboundPacket pkt = context.inPacket();
86 Ethernet ethPkt = pkt.parsed();
87
88 HostId srcId = HostId.hostId(ethPkt.getSourceMAC());
89 HostId dstId = HostId.hostId(ethPkt.getDestinationMAC());
90
91 // Do we know who this is for? If not, flood and bail.
92 Host dst = hostService.getHost(dstId);
93 if (dst == null) {
94 flood(context);
95 return;
96 }
97
98 // Otherwise forward and be done with it.
99 setUpConnectivity(context, srcId, dstId);
Brian O'Connor958d3812014-10-03 19:46:23 -0700100 forwardPacketToDst(context, dst);
toma9a77c22014-10-03 17:05:20 -0700101 }
102 }
103
104 // Floods the specified packet if permissible.
105 private void flood(PacketContext context) {
106 if (topologyService.isBroadcastPoint(topologyService.currentTopology(),
107 context.inPacket().receivedFrom())) {
108 packetOut(context, PortNumber.FLOOD);
109 } else {
110 context.block();
111 }
112 }
113
114 // Sends a packet out the specified port.
115 private void packetOut(PacketContext context, PortNumber portNumber) {
116 context.treatmentBuilder().setOutput(portNumber);
117 context.send();
118 }
119
Brian O'Connor958d3812014-10-03 19:46:23 -0700120 private void forwardPacketToDst(PacketContext context, Host dst) {
121 TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(dst.location().port()).build();
122 OutboundPacket packet = new DefaultOutboundPacket(dst.location().deviceId(),
tom0511a522014-10-04 12:06:02 -0700123 treatment, context.inPacket().unparsed());
Brian O'Connor958d3812014-10-03 19:46:23 -0700124 packetService.emit(packet);
125 log.info("sending packet: {}", packet);
126 }
127
toma9a77c22014-10-03 17:05:20 -0700128 // Install a rule forwarding the packet to the specified port.
129 private void setUpConnectivity(PacketContext context, HostId srcId, HostId dstId) {
130 TrafficSelector selector = DefaultTrafficSelector.builder().build();
131 TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
132
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700133 HostToHostIntent intent = new HostToHostIntent(appId, srcId, dstId,
134 selector, treatment);
toma9a77c22014-10-03 17:05:20 -0700135
136 intentService.submit(intent);
137 }
138
139}