blob: 38ba59b1c3a5006de2cc84b32b07e41d7d87bf06 [file] [log] [blame]
alshabib1cc04f72014-09-16 16:09:58 -07001package org.onlab.onos.provider.of.flow.impl;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
alshabib35edb1a2014-09-16 17:44:44 -07005import java.util.Collections;
6import java.util.LinkedList;
7import java.util.List;
8
alshabib1cc04f72014-09-16 16:09:58 -07009import org.apache.felix.scr.annotations.Activate;
10import org.apache.felix.scr.annotations.Component;
11import org.apache.felix.scr.annotations.Deactivate;
12import org.apache.felix.scr.annotations.Reference;
13import org.apache.felix.scr.annotations.ReferenceCardinality;
14import org.onlab.onos.net.DeviceId;
15import org.onlab.onos.net.flow.FlowEntry;
16import org.onlab.onos.net.flow.FlowRule;
17import org.onlab.onos.net.flow.FlowRuleProvider;
18import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
19import org.onlab.onos.net.flow.FlowRuleProviderService;
alshabib35edb1a2014-09-16 17:44:44 -070020import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
21import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
22import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
23import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
24import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
25import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
26import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
27import org.onlab.onos.net.flow.criteria.Criterion;
28import org.onlab.onos.net.flow.instructions.Instruction;
alshabib7b2748f2014-09-16 20:21:11 -070029import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
alshabib35edb1a2014-09-16 17:44:44 -070030import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
33import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
34import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
35import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
alshabib1cc04f72014-09-16 16:09:58 -070036import org.onlab.onos.net.provider.AbstractProvider;
37import org.onlab.onos.net.provider.ProviderId;
38import org.onlab.onos.net.topology.TopologyService;
alshabib35edb1a2014-09-16 17:44:44 -070039import org.onlab.onos.of.controller.Dpid;
alshabib1cc04f72014-09-16 16:09:58 -070040import org.onlab.onos.of.controller.OpenFlowController;
alshabib35edb1a2014-09-16 17:44:44 -070041import org.onlab.onos.of.controller.OpenFlowSwitch;
42import org.projectfloodlight.openflow.protocol.OFFactory;
43import org.projectfloodlight.openflow.protocol.OFFlowMod;
44import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
45import org.projectfloodlight.openflow.protocol.action.OFAction;
46import org.projectfloodlight.openflow.protocol.match.Match;
47import org.projectfloodlight.openflow.protocol.match.MatchField;
48import org.projectfloodlight.openflow.types.EthType;
49import org.projectfloodlight.openflow.types.IPv4Address;
50import org.projectfloodlight.openflow.types.IpProtocol;
51import org.projectfloodlight.openflow.types.MacAddress;
alshabibf1cd8792014-09-16 18:04:18 -070052import org.projectfloodlight.openflow.types.OFBufferId;
alshabib35edb1a2014-09-16 17:44:44 -070053import org.projectfloodlight.openflow.types.OFPort;
54import org.projectfloodlight.openflow.types.OFVlanVidMatch;
55import org.projectfloodlight.openflow.types.VlanPcp;
56import org.projectfloodlight.openflow.types.VlanVid;
alshabib1cc04f72014-09-16 16:09:58 -070057import org.slf4j.Logger;
58
59/**
60 * Provider which uses an OpenFlow controller to detect network
61 * end-station hosts.
62 */
63@Component(immediate = true)
64public class OpenFlowRuleProvider extends AbstractProvider implements FlowRuleProvider {
65
66 private final Logger log = getLogger(getClass());
67
68 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 protected FlowRuleProviderRegistry providerRegistry;
70
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected OpenFlowController controller;
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected TopologyService topologyService;
76
77 private FlowRuleProviderService providerService;
78
79 /**
80 * Creates an OpenFlow host provider.
81 */
82 public OpenFlowRuleProvider() {
83 super(new ProviderId("org.onlab.onos.provider.openflow"));
84 }
85
86 @Activate
87 public void activate() {
88 providerService = providerRegistry.register(this);
89 log.info("Started");
90 }
91
92 @Deactivate
93 public void deactivate() {
94 providerRegistry.unregister(this);
95 providerService = null;
96
97 log.info("Stopped");
98 }
99 @Override
100 public void applyFlowRule(FlowRule... flowRules) {
alshabib35edb1a2014-09-16 17:44:44 -0700101 for (int i = 0; i < flowRules.length; i++) {
102 applyRule(flowRules[i]);
103 }
alshabib1cc04f72014-09-16 16:09:58 -0700104 }
105
alshabib35edb1a2014-09-16 17:44:44 -0700106 private void applyRule(FlowRule flowRule) {
107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
108 Match match = buildMatch(flowRule.selector().criteria(), sw.factory());
109 List<OFAction> actions =
110 buildActions(flowRule.treatment().instructions(), sw.factory());
111
112 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
113 OFFlowMod fm = sw.factory().buildFlowModify()
alshabibf1cd8792014-09-16 18:04:18 -0700114 .setBufferId(OFBufferId.NO_BUFFER)
alshabib35edb1a2014-09-16 17:44:44 -0700115 .setActions(actions)
116 .setMatch(match)
117 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
118 .setIdleTimeout(10)
119 .setHardTimeout(10)
120 .setPriority(flowRule.priority())
121 .build();
alshabib35edb1a2014-09-16 17:44:44 -0700122 sw.sendMsg(fm);
alshabib35edb1a2014-09-16 17:44:44 -0700123 }
124
125 private List<OFAction> buildActions(List<Instruction> instructions, OFFactory factory) {
126 List<OFAction> acts = new LinkedList<>();
127 for (Instruction i : instructions) {
128 switch (i.type()) {
129 case DROP:
130 log.warn("Saw drop action; assigning drop action");
alshabibf1cd8792014-09-16 18:04:18 -0700131 return new LinkedList<>();
alshabib35edb1a2014-09-16 17:44:44 -0700132 case L2MODIFICATION:
133 acts.add(buildL2Modification(i, factory));
134 case L3MODIFICATION:
135 acts.add(buildL3Modification(i, factory));
136 case OUTPUT:
alshabib7b2748f2014-09-16 20:21:11 -0700137 OutputInstruction out = (OutputInstruction) i;
138 acts.add(factory.actions().buildOutput().setPort(
139 OFPort.of((int) out.port().toLong())).build());
alshabib35edb1a2014-09-16 17:44:44 -0700140 break;
141 case GROUP:
142 default:
143 log.warn("Instruction type {} not yet implemented.", i.type());
144 }
145 }
146
147 return acts;
148 }
149
150 private OFAction buildL3Modification(Instruction i, OFFactory factory) {
151 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
152 ModIPInstruction ip;
153 switch (l3m.subtype()) {
154 case L3_DST:
155 ip = (ModIPInstruction) i;
156 return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
157 case L3_SRC:
158 ip = (ModIPInstruction) i;
159 return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
160 default:
161 log.warn("Unimplemented action type {}.", l3m.subtype());
162 break;
163 }
164 return null;
165 }
166
167 private OFAction buildL2Modification(Instruction i, OFFactory factory) {
168 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
169 ModEtherInstruction eth;
170 switch (l2m.subtype()) {
171 case L2_DST:
172 eth = (ModEtherInstruction) l2m;
173 return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
174 case L2_SRC:
175 eth = (ModEtherInstruction) l2m;
176 return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
177 case VLAN_ID:
178 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
179 return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
180 case VLAN_PCP:
181 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
182 return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
183 default:
184 log.warn("Unimplemented action type {}.", l2m.subtype());
185 break;
186 }
187 return null;
188 }
189
190 private Match buildMatch(List<Criterion> criteria, OFFactory factory) {
191 Match.Builder mBuilder = factory.buildMatch();
192 EthCriterion eth;
193 IPCriterion ip;
194 for (Criterion c : criteria) {
195 switch (c.type()) {
196 case IN_PORT:
197 PortCriterion inport = (PortCriterion) c;
198 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
199 break;
200 case ETH_SRC:
201 eth = (EthCriterion) c;
202 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
203 break;
204 case ETH_DST:
205 eth = (EthCriterion) c;
206 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
207 break;
208 case ETH_TYPE:
209 EthTypeCriterion ethType = (EthTypeCriterion) c;
210 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
alshabib7b2748f2014-09-16 20:21:11 -0700211 break;
alshabib35edb1a2014-09-16 17:44:44 -0700212 case IPV4_DST:
213 ip = (IPCriterion) c;
alshabib64231f62014-09-16 17:58:36 -0700214 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
alshabib35edb1a2014-09-16 17:44:44 -0700215 break;
216 case IPV4_SRC:
217 ip = (IPCriterion) c;
alshabib64231f62014-09-16 17:58:36 -0700218 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
alshabib35edb1a2014-09-16 17:44:44 -0700219 break;
220 case IP_PROTO:
221 IPProtocolCriterion p = (IPProtocolCriterion) c;
222 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
223 break;
224 case VLAN_PCP:
225 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
226 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
227 break;
228 case VLAN_VID:
229 VlanIdCriterion vid = (VlanIdCriterion) c;
230 mBuilder.setExact(MatchField.VLAN_VID,
231 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
232 break;
233 case ARP_OP:
234 case ARP_SHA:
235 case ARP_SPA:
236 case ARP_THA:
237 case ARP_TPA:
238 case ICMPV4_CODE:
239 case ICMPV4_TYPE:
240 case ICMPV6_CODE:
241 case ICMPV6_TYPE:
242 case IN_PHY_PORT:
243 case IPV6_DST:
244 case IPV6_EXTHDR:
245 case IPV6_FLABEL:
246 case IPV6_ND_SLL:
247 case IPV6_ND_TARGET:
248 case IPV6_ND_TLL:
249 case IPV6_SRC:
250 case IP_DSCP:
251 case IP_ECN:
252 case METADATA:
253 case MPLS_BOS:
254 case MPLS_LABEL:
255 case MPLS_TC:
256 case PBB_ISID:
257 case SCTP_DST:
258 case SCTP_SRC:
259 case TCP_DST:
260 case TCP_SRC:
261 case TUNNEL_ID:
262 case UDP_DST:
263 case UDP_SRC:
264 default:
265 log.warn("Action type {} not yet implemented.", c.type());
266 }
267 }
268 return mBuilder.build();
269 }
270
alshabib1cc04f72014-09-16 16:09:58 -0700271 @Override
272 public void removeFlowRule(FlowRule... flowRules) {
273 // TODO Auto-generated method stub
274
275 }
276
277 @Override
278 public Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId) {
279 // TODO Auto-generated method stub
280 return null;
281 }
282
283
284 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
285 // possibly barriers as well. May not be internal at all...
286
287
288}