blob: 3267d55044a3b1e64d38f769c1ec4aa9c213ddc0 [file] [log] [blame]
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.driver.pipeline;
17
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070018import java.util.Collection;
19import java.util.Collections;
20import java.util.List;
21
22import org.onlab.packet.Ethernet;
23import org.onlab.packet.MacAddress;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.net.behaviour.NextGroup;
26import org.onosproject.net.flow.DefaultFlowRule;
27import org.onosproject.net.flow.DefaultTrafficSelector;
28import org.onosproject.net.flow.DefaultTrafficTreatment;
29import org.onosproject.net.flow.FlowRule;
30import org.onosproject.net.flow.TrafficSelector;
31import org.onosproject.net.flow.TrafficTreatment;
32import org.onosproject.net.flow.criteria.Criterion;
33import org.onosproject.net.flow.criteria.EthCriterion;
34import org.onosproject.net.flow.criteria.EthTypeCriterion;
35import org.onosproject.net.flow.criteria.IPCriterion;
36import org.onosproject.net.flow.criteria.MplsCriterion;
37import org.onosproject.net.flow.instructions.Instruction;
38import org.onosproject.net.flowobjective.FilteringObjective;
39import org.onosproject.net.flowobjective.ForwardingObjective;
40import org.onosproject.net.flowobjective.ObjectiveError;
41import org.onosproject.net.group.Group;
42import org.onosproject.net.group.GroupKey;
43
44/**
45 * Spring-open driver implementation for Dell hardware switches.
46 */
47public class SpringOpenTTPDell extends SpringOpenTTP {
48
49 /* Table IDs to be used for Dell Open Segment Routers*/
50 private static final int DELL_TABLE_VLAN = 17;
51 private static final int DELL_TABLE_TMAC = 18;
52 private static final int DELL_TABLE_IPV4_UNICAST = 30;
53 private static final int DELL_TABLE_MPLS = 25;
54 private static final int DELL_TABLE_ACL = 40;
55
56 //TODO: Store this info in the distributed store.
57 private MacAddress deviceTMac = null;
58
59 public SpringOpenTTPDell() {
60 super();
61 vlanTableId = DELL_TABLE_VLAN;
62 tmacTableId = DELL_TABLE_TMAC;
63 ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST;
64 mplsTableId = DELL_TABLE_MPLS;
65 aclTableId = DELL_TABLE_ACL;
66 }
67
68 @Override
69 protected void setTableMissEntries() {
70 // No need to set table-miss-entries in Dell switches
71 return;
72 }
73
74 @Override
75 //Dell switches need ETH_DST based match condition in all IP table entries.
76 //So this method overrides the default spring-open behavior and adds
77 //ETH_DST match condition while pushing IP table flow rules
78 protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
79 log.debug("Processing specific");
80 TrafficSelector selector = fwd.selector();
81 EthTypeCriterion ethType = (EthTypeCriterion) selector
82 .getCriterion(Criterion.Type.ETH_TYPE);
83 if ((ethType == null) ||
alshabibcaf1ca22015-06-25 15:18:16 -070084 (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) &&
85 (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070086 log.debug("processSpecific: Unsupported "
87 + "forwarding objective criteraia");
88 fail(fwd, ObjectiveError.UNSUPPORTED);
89 return Collections.emptySet();
90 }
91
92 TrafficSelector.Builder filteredSelectorBuilder =
93 DefaultTrafficSelector.builder();
94 int forTableId = -1;
alshabibcaf1ca22015-06-25 15:18:16 -070095 if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070096 if (deviceTMac == null) {
97 log.debug("processSpecific: ETH_DST filtering "
98 + "objective is not set which is required "
99 + "before sending a IPv4 forwarding objective");
100 //TODO: Map the error to more appropriate error code.
101 fail(fwd, ObjectiveError.DEVICEMISSING);
102 return Collections.emptySet();
103 }
104 filteredSelectorBuilder = filteredSelectorBuilder
105 .matchEthType(Ethernet.TYPE_IPV4)
106 .matchEthDst(deviceTMac)
107 .matchIPDst(((IPCriterion) selector
108 .getCriterion(Criterion.Type.IPV4_DST))
109 .ip());
110 forTableId = ipv4UnicastTableId;
111 log.debug("processing IPv4 specific forwarding objective");
112 } else {
113 filteredSelectorBuilder = filteredSelectorBuilder
114 .matchEthType(Ethernet.MPLS_UNICAST)
115 .matchMplsLabel(((MplsCriterion)
116 selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
117 //TODO: Add Match for BoS
118 //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) {
119 //}
120 forTableId = mplsTableId;
121 log.debug("processing MPLS specific forwarding objective");
122 }
123
124 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
125 .builder();
126 if (fwd.treatment() != null) {
127 for (Instruction i : fwd.treatment().allInstructions()) {
128 treatmentBuilder.add(i);
129 }
130 }
131
132 if (fwd.nextId() != null) {
133 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
134
135 if (next != null) {
136 GroupKey key = appKryo.deserialize(next.data());
137
138 Group group = groupService.getGroup(deviceId, key);
139
140 if (group == null) {
141 log.warn("The group left!");
142 fail(fwd, ObjectiveError.GROUPMISSING);
143 return Collections.emptySet();
144 }
145 treatmentBuilder.group(group.id());
146 log.debug("Adding OUTGROUP action");
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700147 } else {
148 log.warn("processSpecific: No associated next objective object");
149 fail(fwd, ObjectiveError.GROUPMISSING);
150 return Collections.emptySet();
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700151 }
152 }
153
154 TrafficSelector filteredSelector = filteredSelectorBuilder.build();
155 TrafficTreatment treatment = treatmentBuilder.transition(aclTableId)
156 .build();
157
158 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
159 .fromApp(fwd.appId()).withPriority(fwd.priority())
160 .forDevice(deviceId).withSelector(filteredSelector)
161 .withTreatment(treatment);
162
163 if (fwd.permanent()) {
164 ruleBuilder.makePermanent();
165 } else {
166 ruleBuilder.makeTemporary(fwd.timeout());
167 }
168
169 ruleBuilder.forTable(forTableId);
170 return Collections.singletonList(ruleBuilder.build());
171
172 }
173
174 @Override
175 //Dell switches need ETH_DST based match condition in all IP table entries.
176 //So while processing the ETH_DST based filtering objective, store
177 //the device MAC to be used locally to use it while pushing the IP rules.
178 protected List<FlowRule> processEthDstFilter(Criterion c,
179 FilteringObjective filt,
180 ApplicationId applicationId) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700181 // Store device termination Mac to be used in IP flow entries
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700182 EthCriterion e = (EthCriterion) c;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700183 deviceTMac = e.mac();
184
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700185 log.debug("For now not adding any TMAC rules "
186 + "into Dell switches as it is ignoring");
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700187
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700188 return Collections.emptyList();
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700189 }
190
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700191 @Override
192 protected List<FlowRule> processVlanIdFilter(Criterion c,
193 FilteringObjective filt,
194 ApplicationId applicationId) {
195 log.debug("For now not adding any VLAN rules "
196 + "into Dell switches as it is ignoring");
197
198 return Collections.emptyList();
199 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700200}