blob: ff2ef9bd9730a469e853316ea14fd0773adb5afc [file] [log] [blame]
lucac0afcf92014-08-16 20:51:53 -07001package net.onrc.onos.apps.defaultrules;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.List;
6import java.util.Map;
7
8import net.floodlightcontroller.core.IFloodlightProviderService;
9import net.floodlightcontroller.core.IOFSwitch;
10import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
11import net.floodlightcontroller.core.IOFSwitchListener;
12import net.floodlightcontroller.core.module.FloodlightModuleContext;
13import net.floodlightcontroller.core.module.FloodlightModuleException;
14import net.floodlightcontroller.core.module.IFloodlightModule;
15import net.floodlightcontroller.core.module.IFloodlightService;
16import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
17import net.onrc.onos.core.util.Dpid;
18
19import org.projectfloodlight.openflow.protocol.OFFactory;
20import org.projectfloodlight.openflow.protocol.OFFlowMod;
21import org.projectfloodlight.openflow.protocol.OFMessage;
22import org.projectfloodlight.openflow.protocol.OFPortDesc;
23import org.projectfloodlight.openflow.protocol.action.OFAction;
24import org.projectfloodlight.openflow.protocol.match.Match;
25import org.projectfloodlight.openflow.protocol.match.MatchField;
26import org.projectfloodlight.openflow.types.EthType;
27import org.projectfloodlight.openflow.types.MacAddress;
28import org.projectfloodlight.openflow.types.OFBufferId;
29import org.projectfloodlight.openflow.types.OFPort;
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33/**
34 * Pushing default flows for SDN IP.
35 * <p/>
36 * The module is a temporary solution to push default flows
37 * upon switch connection. Specifically, when a switch connects
38 * is pushed a default drop flow, a flow that allow ARP and a flow
39 * that allow LLDP.
40 * The module is not synchronized with other potential applications
41 * sending different flows.
42 * TODO: The module should talk to the Intent or MatchAction framework
43 * to synchronize its behavior with the rest of the system.
44 */
45public class DefaultRules implements IFloodlightModule, IOFSwitchListener {
46
47 private IFloodlightProviderService floodlightProvider;
48 private IFlowPusherService flowPusher;
49 private static final Logger log = LoggerFactory.getLogger(DefaultRules.class);
50 private static final String APP_NAME = "DefaultRules";
51
52 private static final short IDLE_TIMEOUT = 0;
53 private static final short HARD_TIMEOUT = 0;
54 private static final short DROP_RULE_PRIORITY = 1;
55 private static final short DEFAULT_RULE_PRIORITY = 2;
56 private static final MacAddress LLDP_MAC_ADDRESS =
57 MacAddress.of("01:80:c2:00:00:0e");
58
59 @Override
60 public String getName() {
61 return DefaultRules.APP_NAME;
62 }
63
64 @Override
65 public void switchActivatedMaster(long swId) {
66 // Install default drop rule sending a FlowMod
67 this.writeDefaultDrop(swId);
68 // Permit standard LLDP and ARP
69 this.permitStdLLDP(swId);
70 this.permitARP(swId);
71 }
72
73 /**
74 * Installs a default FlowMod on the switch to DROP by default all packet-ins.
75 *
76 * @param swId The switch ID
77 */
78 private void writeDefaultDrop(long swId) {
79 IOFSwitch sw = floodlightProvider.getMasterSwitch(swId);
80 OFFactory factory = sw.getFactory();
81 OFFlowMod.Builder builder = factory.buildFlowAdd();
82 Match match = factory.buildMatch().build();
83 List<OFAction> actionList = new ArrayList<OFAction>();
84 builder.setMatch(match)
85 .setActions(actionList)
86 .setIdleTimeout(IDLE_TIMEOUT)
87 .setHardTimeout(HARD_TIMEOUT)
88 .setBufferId(OFBufferId.NO_BUFFER)
89 .setPriority(DROP_RULE_PRIORITY);
90 OFMessage ofMessage = builder.build();
91 log.debug("Sending 'default drop' OF messsage to switch {}.", swId);
92 flowPusher.add(new Dpid(swId), ofMessage);
93 }
94
95 /**
96 * Installs a default FlowMod on the switch to allow LLDP traffic.
97 * LLDP flows have an higher priority than the DROP ones.
98 *
99 * @param swId The switch ID
100 */
101 private void permitStdLLDP(long swId) {
102 IOFSwitch sw = floodlightProvider.getMasterSwitch(swId);
103 OFFactory factory = sw.getFactory();
104 OFFlowMod.Builder builder = factory.buildFlowAdd();
105 Match match = factory.buildMatch()
106 .setExact(MatchField.ETH_TYPE, EthType.LLDP)
107 .setExact(MatchField.ETH_DST, LLDP_MAC_ADDRESS)
108 .build();
109 List<OFAction> actionList = new ArrayList<OFAction>();
110 OFAction action = factory.actions().output(OFPort.CONTROLLER, Short.MAX_VALUE);
111 actionList.add(action);
112 builder.setMatch(match)
113 .setActions(actionList)
114 .setIdleTimeout(IDLE_TIMEOUT)
115 .setHardTimeout(HARD_TIMEOUT)
116 .setBufferId(OFBufferId.NO_BUFFER)
117 .setPriority(DEFAULT_RULE_PRIORITY);
118 OFMessage ofMessage = builder.build();
119 log.debug("Sending 'LLDP permit' OF message to switch {}.", swId);
120 flowPusher.add(new Dpid(swId), ofMessage);
121 }
122
123 /**
124 * The method installs a default FlowMod on the switch to allow ARP traffic.
125 * ARP flows have an higher priority than the DROP ones
126 *
127 * @param swId The switch ID
128 */
129 private void permitARP(long swId) {
130 IOFSwitch sw = floodlightProvider.getMasterSwitch(swId);
131 OFFactory factory = sw.getFactory();
132 OFFlowMod.Builder builder = factory.buildFlowAdd();
133 Match match = factory.buildMatch()
134 .setExact(MatchField.ETH_TYPE, EthType.ARP)
135 .build();
136 List<OFAction> actionList = new ArrayList<OFAction>();
137 OFAction action = factory.actions().output(OFPort.CONTROLLER, Short.MAX_VALUE);
138 actionList.add(action);
139 builder.setMatch(match)
140 .setActions(actionList)
141 .setIdleTimeout(IDLE_TIMEOUT)
142 .setHardTimeout(HARD_TIMEOUT)
143 .setBufferId(OFBufferId.NO_BUFFER)
144 .setPriority(DEFAULT_RULE_PRIORITY);
145 OFMessage ofMessage = builder.build();
146 log.debug("Sending 'ARP permit' OF message to the switch {}.", swId);
147 flowPusher.add(new Dpid(swId), ofMessage);
148 }
149
150 @Override
151 public void switchActivatedEqual(long swId) {
152 }
153
154 @Override
155 public void switchMasterToEqual(long swId) {
156 }
157
158 @Override
159 public void switchEqualToMaster(long swId) {
160 }
161
162 @Override
163 public void switchDisconnected(long swId) {
164 }
165
166 @Override
167 public void switchPortChanged(long swId, OFPortDesc port, PortChangeType changeType) {
168 }
169
170 @Override
171 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
172 return null;
173 }
174
175 @Override
176 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
177 return null;
178 }
179
180 @Override
181 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
182 List<Class<? extends IFloodlightService>> dependencies =
183 new ArrayList<Class<? extends IFloodlightService>>();
184 dependencies.add(IFloodlightProviderService.class);
185 dependencies.add(IFlowPusherService.class);
186 return dependencies;
187 }
188
189 @Override
190 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
191 this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
192 this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
193 }
194
195 @Override
196 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
197 floodlightProvider.addOFSwitchListener(this);
198 }
199}