blob: 4915cc7676fb5e83b0e25fc4056310731aa997e5 [file] [log] [blame]
Brian O'Connor8c166a72013-11-14 18:41:48 -08001package net.onrc.onos.ofcontroller.flowprogrammer;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.Map;
Brian O'Connorea1efbe2013-11-25 22:57:43 -08007
8import org.openflow.protocol.OFFlowRemoved;
9import org.openflow.protocol.OFMessage;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080010import org.openflow.protocol.OFType;
11import org.slf4j.Logger;
12import org.slf4j.LoggerFactory;
13
Brian O'Connorea1efbe2013-11-25 22:57:43 -080014import net.floodlightcontroller.core.FloodlightContext;
Brian O'Connor8c166a72013-11-14 18:41:48 -080015import net.floodlightcontroller.core.IFloodlightProviderService;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080016import net.floodlightcontroller.core.IOFMessageListener;
17import net.floodlightcontroller.core.IOFSwitch;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080018import net.floodlightcontroller.core.IOFSwitchListener;
Brian O'Connor8c166a72013-11-14 18:41:48 -080019import net.floodlightcontroller.core.module.FloodlightModuleContext;
20import net.floodlightcontroller.core.module.FloodlightModuleException;
21import net.floodlightcontroller.core.module.IFloodlightModule;
22import net.floodlightcontroller.core.module.IFloodlightService;
Naoki Shiota2a35b442013-11-26 19:17:38 -080023import net.floodlightcontroller.restserver.IRestApiService;
24import net.onrc.onos.ofcontroller.flowprogrammer.web.FlowProgrammerWebRoutable;
Brian O'Connorbae524b2013-11-26 15:00:26 -080025import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
26import net.onrc.onos.ofcontroller.util.FlowEntryId;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080027import net.onrc.onos.registry.controller.IControllerRegistryService;
Brian O'Connor8c166a72013-11-14 18:41:48 -080028
Naoki Shiotae3199732013-11-25 16:14:43 -080029/**
30 * FlowProgrammer is a module responsible to maintain flows installed to switches.
31 * FlowProgrammer consists of FlowPusher and FlowSynchronizer.
Naoki Shiotab485d412013-11-26 12:04:19 -080032 * FlowPusher manages the rate of installation, and FlowSynchronizer synchronizes
Naoki Shiotae3199732013-11-25 16:14:43 -080033 * flows between GraphDB and switches.
Naoki Shiotab485d412013-11-26 12:04:19 -080034 * FlowProgrammer also watch the event of addition/deletion of switches to
35 * start/stop synchronization. When a switch is added to network, FlowProgrammer
36 * immediately kicks synchronization to keep switch's flow table latest state.
37 * Adversely, when a switch is removed from network, FlowProgrammer immediately
38 * stops synchronization.
Naoki Shiotae3199732013-11-25 16:14:43 -080039 * @author Brian
40 *
41 */
Brian O'Connorea1efbe2013-11-25 22:57:43 -080042public class FlowProgrammer implements IFloodlightModule,
43 IOFMessageListener,
44 IOFSwitchListener {
Naoki Shiotae3199732013-11-25 16:14:43 -080045 // flag to enable FlowSynchronizer
Brian O'Connor056f8262013-12-09 18:10:49 -080046 private static final boolean enableFlowSync = true;
Naoki Shiotadf051d42014-01-20 16:12:41 -080047 protected static final Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
Brian O'Connor8c166a72013-11-14 18:41:48 -080048 protected volatile IFloodlightProviderService floodlightProvider;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080049 protected volatile IControllerRegistryService registryService;
Naoki Shiota2a35b442013-11-26 19:17:38 -080050 protected volatile IRestApiService restApi;
Brian O'Connorbae524b2013-11-26 15:00:26 -080051 protected volatile IFlowService flowManager;
Brian O'Connorea1efbe2013-11-25 22:57:43 -080052
Brian O'Connor8c166a72013-11-14 18:41:48 -080053 protected FlowPusher pusher;
54 private static final int NUM_PUSHER_THREAD = 1;
55
56 protected FlowSynchronizer synchronizer;
Naoki Shiotae3199732013-11-25 16:14:43 -080057
Brian O'Connor8c166a72013-11-14 18:41:48 -080058 public FlowProgrammer() {
59 pusher = new FlowPusher(NUM_PUSHER_THREAD);
Naoki Shiota8739faa2013-11-18 17:00:25 -080060 if (enableFlowSync) {
Brian O'Connore600f1d2013-11-25 23:09:18 -080061 synchronizer = new FlowSynchronizer();
Naoki Shiota8739faa2013-11-18 17:00:25 -080062 }
Brian O'Connor8c166a72013-11-14 18:41:48 -080063 }
64
65 @Override
66 public void init(FloodlightModuleContext context)
67 throws FloodlightModuleException {
68 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Brian O'Connorea1efbe2013-11-25 22:57:43 -080069 registryService = context.getServiceImpl(IControllerRegistryService.class);
Naoki Shiota2a35b442013-11-26 19:17:38 -080070 restApi = context.getServiceImpl(IRestApiService.class);
Brian O'Connorbae524b2013-11-26 15:00:26 -080071 flowManager = context.getServiceImpl(IFlowService.class);
Naoki Shiotac1601d32013-11-20 10:47:34 -080072 pusher.init(null, context, floodlightProvider.getOFMessageFactory(), null);
Naoki Shiota8739faa2013-11-18 17:00:25 -080073 if (enableFlowSync) {
Brian O'Connore600f1d2013-11-25 23:09:18 -080074 synchronizer.init(pusher);
Naoki Shiota8739faa2013-11-18 17:00:25 -080075 }
Brian O'Connor8c166a72013-11-14 18:41:48 -080076 }
77
78 @Override
79 public void startUp(FloodlightModuleContext context) {
Naoki Shiota2a35b442013-11-26 19:17:38 -080080 restApi.addRestletRoutable(new FlowProgrammerWebRoutable());
Brian O'Connor8c166a72013-11-14 18:41:48 -080081 pusher.start();
Brian O'Connorea1efbe2013-11-25 22:57:43 -080082 floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
83 floodlightProvider.addOFSwitchListener(this);
Brian O'Connor8c166a72013-11-14 18:41:48 -080084 }
85
86 @Override
87 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
88 Collection<Class<? extends IFloodlightService>> l =
89 new ArrayList<Class<? extends IFloodlightService>>();
90 l.add(IFlowPusherService.class);
Naoki Shiota8739faa2013-11-18 17:00:25 -080091 if (enableFlowSync) {
Brian O'Connore600f1d2013-11-25 23:09:18 -080092 l.add(IFlowSyncService.class);
Naoki Shiota8739faa2013-11-18 17:00:25 -080093 }
Brian O'Connor8c166a72013-11-14 18:41:48 -080094 return l;
95 }
96
97 @Override
98 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
99 Map<Class<? extends IFloodlightService>,
100 IFloodlightService> m =
101 new HashMap<Class<? extends IFloodlightService>,
102 IFloodlightService>();
103 m.put(IFlowPusherService.class, pusher);
Naoki Shiota8739faa2013-11-18 17:00:25 -0800104 if (enableFlowSync) {
Brian O'Connore600f1d2013-11-25 23:09:18 -0800105 m.put(IFlowSyncService.class, synchronizer);
Naoki Shiota8739faa2013-11-18 17:00:25 -0800106 }
Brian O'Connor8c166a72013-11-14 18:41:48 -0800107 return m;
108 }
109
110 @Override
111 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
112 Collection<Class<? extends IFloodlightService>> l =
113 new ArrayList<Class<? extends IFloodlightService>>();
114 l.add(IFloodlightProviderService.class);
Naoki Shiota2a35b442013-11-26 19:17:38 -0800115 l.add(IRestApiService.class);
Brian O'Connor8c166a72013-11-14 18:41:48 -0800116 return l;
117 }
Brian O'Connorea1efbe2013-11-25 22:57:43 -0800118
119 @Override
120 public String getName() {
121 // TODO Auto-generated method stub
122 return "FlowProgrammer";
123 }
124
125 @Override
126 public boolean isCallbackOrderingPrereq(OFType type, String name) {
127 // TODO Auto-generated method stub
128 return false;
129 }
130
131 @Override
132 public boolean isCallbackOrderingPostreq(OFType type, String name) {
133 // TODO Auto-generated method stub
134 return false;
135 }
136
137 @Override
138 public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
139 switch (msg.getType()) {
140 case FLOW_REMOVED:
141 OFFlowRemoved flowMsg = (OFFlowRemoved) msg;
Brian O'Connorbae524b2013-11-26 15:00:26 -0800142 FlowEntryId id = new FlowEntryId(flowMsg.getCookie());
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800143 log.debug("Got flow entry removed from {}: {}",sw.getId(), id);
Brian O'Connorbae524b2013-11-26 15:00:26 -0800144 flowManager.flowEntryOnSwitchExpired(sw, id);
Brian O'Connorea1efbe2013-11-25 22:57:43 -0800145 break;
146 default:
147 break;
148 }
149
150 return Command.CONTINUE;
151 }
152
153 @Override
154 public void addedSwitch(IOFSwitch sw) {
155 log.debug("Switch added: {}", sw.getId());
156
Naoki Shiotae2f4da72013-12-09 16:34:17 -0800157 if (enableFlowSync) {
158 if (registryService.hasControl(sw.getId())) {
159 synchronizer.synchronize(sw);
160 }
Brian O'Connorea1efbe2013-11-25 22:57:43 -0800161 }
162 }
163
164 @Override
165 public void removedSwitch(IOFSwitch sw) {
166 log.debug("Switch removed: {}", sw.getId());
167
Brian O'Connore600f1d2013-11-25 23:09:18 -0800168 if (enableFlowSync) {
169 synchronizer.interrupt(sw);
170 }
Brian O'Connorea1efbe2013-11-25 22:57:43 -0800171 }
172
173 @Override
174 public void switchPortChanged(Long switchId) {
175 // TODO Auto-generated method stub
176 }
Brian O'Connor8c166a72013-11-14 18:41:48 -0800177
Brian O'Connor8c166a72013-11-14 18:41:48 -0800178}