blob: 4a817bf33eef85b29e90b52e7e97ab01fc036b94 [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
18import java.util.ArrayList;
19import java.util.Collection;
20import java.util.Collections;
21import java.util.List;
22
23import org.onlab.packet.Ethernet;
24import org.onlab.packet.MacAddress;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.net.behaviour.NextGroup;
27import org.onosproject.net.flow.DefaultFlowRule;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.FlowRule;
31import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
33import org.onosproject.net.flow.criteria.Criterion;
34import org.onosproject.net.flow.criteria.EthCriterion;
35import org.onosproject.net.flow.criteria.EthTypeCriterion;
36import org.onosproject.net.flow.criteria.IPCriterion;
37import org.onosproject.net.flow.criteria.MplsCriterion;
38import org.onosproject.net.flow.instructions.Instruction;
39import org.onosproject.net.flowobjective.FilteringObjective;
40import org.onosproject.net.flowobjective.ForwardingObjective;
41import org.onosproject.net.flowobjective.ObjectiveError;
42import org.onosproject.net.group.Group;
43import org.onosproject.net.group.GroupKey;
44
45/**
46 * Spring-open driver implementation for Dell hardware switches.
47 */
48public class SpringOpenTTPDell extends SpringOpenTTP {
49
50 /* Table IDs to be used for Dell Open Segment Routers*/
51 private static final int DELL_TABLE_VLAN = 17;
52 private static final int DELL_TABLE_TMAC = 18;
53 private static final int DELL_TABLE_IPV4_UNICAST = 30;
54 private static final int DELL_TABLE_MPLS = 25;
55 private static final int DELL_TABLE_ACL = 40;
56
57 //TODO: Store this info in the distributed store.
58 private MacAddress deviceTMac = null;
59
60 public SpringOpenTTPDell() {
61 super();
62 vlanTableId = DELL_TABLE_VLAN;
63 tmacTableId = DELL_TABLE_TMAC;
64 ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST;
65 mplsTableId = DELL_TABLE_MPLS;
66 aclTableId = DELL_TABLE_ACL;
67 }
68
69 @Override
70 protected void setTableMissEntries() {
71 // No need to set table-miss-entries in Dell switches
72 return;
73 }
74
75 @Override
76 //Dell switches need ETH_DST based match condition in all IP table entries.
77 //So this method overrides the default spring-open behavior and adds
78 //ETH_DST match condition while pushing IP table flow rules
79 protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
80 log.debug("Processing specific");
81 TrafficSelector selector = fwd.selector();
82 EthTypeCriterion ethType = (EthTypeCriterion) selector
83 .getCriterion(Criterion.Type.ETH_TYPE);
84 if ((ethType == null) ||
85 ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) &&
86 (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) {
87 log.debug("processSpecific: Unsupported "
88 + "forwarding objective criteraia");
89 fail(fwd, ObjectiveError.UNSUPPORTED);
90 return Collections.emptySet();
91 }
92
93 TrafficSelector.Builder filteredSelectorBuilder =
94 DefaultTrafficSelector.builder();
95 int forTableId = -1;
96 if (((short) ethType.ethType()) == Ethernet.TYPE_IPV4) {
97 if (deviceTMac == null) {
98 log.debug("processSpecific: ETH_DST filtering "
99 + "objective is not set which is required "
100 + "before sending a IPv4 forwarding objective");
101 //TODO: Map the error to more appropriate error code.
102 fail(fwd, ObjectiveError.DEVICEMISSING);
103 return Collections.emptySet();
104 }
105 filteredSelectorBuilder = filteredSelectorBuilder
106 .matchEthType(Ethernet.TYPE_IPV4)
107 .matchEthDst(deviceTMac)
108 .matchIPDst(((IPCriterion) selector
109 .getCriterion(Criterion.Type.IPV4_DST))
110 .ip());
111 forTableId = ipv4UnicastTableId;
112 log.debug("processing IPv4 specific forwarding objective");
113 } else {
114 filteredSelectorBuilder = filteredSelectorBuilder
115 .matchEthType(Ethernet.MPLS_UNICAST)
116 .matchMplsLabel(((MplsCriterion)
117 selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
118 //TODO: Add Match for BoS
119 //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) {
120 //}
121 forTableId = mplsTableId;
122 log.debug("processing MPLS specific forwarding objective");
123 }
124
125 TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
126 .builder();
127 if (fwd.treatment() != null) {
128 for (Instruction i : fwd.treatment().allInstructions()) {
129 treatmentBuilder.add(i);
130 }
131 }
132
133 if (fwd.nextId() != null) {
134 NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
135
136 if (next != null) {
137 GroupKey key = appKryo.deserialize(next.data());
138
139 Group group = groupService.getGroup(deviceId, key);
140
141 if (group == null) {
142 log.warn("The group left!");
143 fail(fwd, ObjectiveError.GROUPMISSING);
144 return Collections.emptySet();
145 }
146 treatmentBuilder.group(group.id());
147 log.debug("Adding OUTGROUP action");
148 }
149 }
150
151 TrafficSelector filteredSelector = filteredSelectorBuilder.build();
152 TrafficTreatment treatment = treatmentBuilder.transition(aclTableId)
153 .build();
154
155 FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
156 .fromApp(fwd.appId()).withPriority(fwd.priority())
157 .forDevice(deviceId).withSelector(filteredSelector)
158 .withTreatment(treatment);
159
160 if (fwd.permanent()) {
161 ruleBuilder.makePermanent();
162 } else {
163 ruleBuilder.makeTemporary(fwd.timeout());
164 }
165
166 ruleBuilder.forTable(forTableId);
167 return Collections.singletonList(ruleBuilder.build());
168
169 }
170
171 @Override
172 //Dell switches need ETH_DST based match condition in all IP table entries.
173 //So while processing the ETH_DST based filtering objective, store
174 //the device MAC to be used locally to use it while pushing the IP rules.
175 protected List<FlowRule> processEthDstFilter(Criterion c,
176 FilteringObjective filt,
177 ApplicationId applicationId) {
178 List<FlowRule> rules = new ArrayList<FlowRule>();
179 EthCriterion e = (EthCriterion) c;
180 TrafficSelector.Builder selectorIp = DefaultTrafficSelector
181 .builder();
182 TrafficTreatment.Builder treatmentIp = DefaultTrafficTreatment
183 .builder();
184
185 // Store device termination Mac to be used in IP flow entries
186 deviceTMac = e.mac();
187
188 selectorIp.matchEthDst(e.mac());
189 selectorIp.matchEthType(Ethernet.TYPE_IPV4);
190 treatmentIp.transition(ipv4UnicastTableId);
191 FlowRule ruleIp = DefaultFlowRule.builder().forDevice(deviceId)
192 .withSelector(selectorIp.build())
193 .withTreatment(treatmentIp.build())
194 .withPriority(filt.priority()).fromApp(applicationId)
195 .makePermanent().forTable(tmacTableId).build();
196 log.debug("adding IP ETH rule for MAC: {}", e.mac());
197 rules.add(ruleIp);
198
199 TrafficSelector.Builder selectorMpls = DefaultTrafficSelector
200 .builder();
201 TrafficTreatment.Builder treatmentMpls = DefaultTrafficTreatment
202 .builder();
203 selectorMpls.matchEthDst(e.mac());
204 selectorMpls.matchEthType(Ethernet.MPLS_UNICAST);
205 treatmentMpls.transition(mplsTableId);
206 FlowRule ruleMpls = DefaultFlowRule.builder()
207 .forDevice(deviceId).withSelector(selectorMpls.build())
208 .withTreatment(treatmentMpls.build())
209 .withPriority(filt.priority()).fromApp(applicationId)
210 .makePermanent().forTable(tmacTableId).build();
211 log.debug("adding MPLS ETH rule for MAC: {}", e.mac());
212 rules.add(ruleMpls);
213
214 return rules;
215 }
216
217}