blob: 2c62c742a9d84fa27a4c7d96f86a244eeeb0ce81 [file] [log] [blame]
alshabib9af70072015-02-09 14:34:16 -08001/*
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.openflow.drivers;
17
18import com.google.common.collect.Lists;
Saurav Dasfa2fa932015-03-03 11:29:48 -080019
alshabib9af70072015-02-09 14:34:16 -080020import org.onosproject.openflow.controller.Dpid;
alshabib9af70072015-02-09 14:34:16 -080021import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
22import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
23import org.projectfloodlight.openflow.protocol.OFFlowMod;
24import org.projectfloodlight.openflow.protocol.OFMessage;
25import org.projectfloodlight.openflow.protocol.OFType;
26import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
27import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
28import org.projectfloodlight.openflow.types.TableId;
29
Saurav Dasfa2fa932015-03-03 11:29:48 -080030import java.util.ArrayList;
alshabib9af70072015-02-09 14:34:16 -080031import java.util.Collections;
32import java.util.List;
33
34/**
35 * Corsa switch driver for BGP Router deployment.
36 */
37public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
Saurav Dasfa2fa932015-03-03 11:29:48 -080038 private static final int FIRST_TABLE = 0;
alshabib9af70072015-02-09 14:34:16 -080039 private static final int VLAN_MPLS_TABLE = 1;
40 private static final int VLAN_TABLE = 2;
41 private static final int MPLS_TABLE = 3;
42 private static final int ETHER_TABLE = 4;
43 private static final int COS_MAP_TABLE = 5;
44 private static final int FIB_TABLE = 6;
45 private static final int LOCAL_TABLE = 9;
46
alshabib9af70072015-02-09 14:34:16 -080047 OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) {
48 super(dpid);
49
50 setSwitchDescription(desc);
51 }
52
Saurav Dasfa2fa932015-03-03 11:29:48 -080053 /**
54 * Used by the default sendMsg to 'write' to the switch.
55 * This method is indirectly used by generic onos services like proxyarp
56 * to request packets from the default flow table. In a multi-table
57 * pipeline, these requests are redirected to the correct table.
58 *
59 * For the Corsa switch, the equivalent table is the LOCAL TABLE
60 *
61 */
alshabib9af70072015-02-09 14:34:16 -080062 @Override
63 public void write(OFMessage msg) {
Saurav Dasfa2fa932015-03-03 11:29:48 -080064 if (msg.getType() == OFType.FLOW_MOD) {
65 OFFlowMod flowMod = (OFFlowMod) msg;
66 OFFlowMod.Builder builder = flowMod.createBuilder();
67 builder.setTableId(TableId.of(LOCAL_TABLE));
68 channel.write(Collections.singletonList(builder.build()));
69 } else {
70 channel.write(Collections.singletonList(msg));
71 }
alshabib9af70072015-02-09 14:34:16 -080072 }
73
74 @Override
75 public void write(List<OFMessage> msgs) {
Saurav Dasfa2fa932015-03-03 11:29:48 -080076 List<OFMessage> newMsgs = new ArrayList<OFMessage>();
77 for (OFMessage msg : msgs) {
78 if (msg.getType() == OFType.FLOW_MOD) {
79 OFFlowMod flowMod = (OFFlowMod) msg;
80 OFFlowMod.Builder builder = flowMod.createBuilder();
81 builder.setTableId(TableId.of(LOCAL_TABLE));
82 newMsgs.add(builder.build());
83 } else {
84 newMsgs.add(msg);
85 }
86 }
87 channel.write(newMsgs);
alshabib9af70072015-02-09 14:34:16 -080088 }
89
90 @Override
Saurav Dasfa2fa932015-03-03 11:29:48 -080091 public void transformAndSendMsg(OFMessage msg, TableType type) {
Saurav Dasfbe25c52015-03-04 11:12:00 -080092 log.trace("Trying to send {} of TableType {}", msg, type);
alshabib9af70072015-02-09 14:34:16 -080093 if (msg.getType() == OFType.FLOW_MOD) {
94 OFFlowMod flowMod = (OFFlowMod) msg;
95 OFFlowMod.Builder builder = flowMod.createBuilder();
Saurav Dascbe6de32015-03-01 18:30:46 -080096 List<OFInstruction> instructions = flowMod.getInstructions();
alshabib9af70072015-02-09 14:34:16 -080097 List<OFInstruction> newInstructions = Lists.newArrayList();
98 for (OFInstruction i : instructions) {
99 if (i instanceof OFInstructionGotoTable) {
100 OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
101 TableType tid = TableType.values()[gotoTable.getTableId().getValue()];
102 switch (tid) {
103 case VLAN_MPLS:
104 newInstructions.add(
105 gotoTable.createBuilder()
106 .setTableId(TableId.of(VLAN_MPLS_TABLE)).build());
107 break;
108 case VLAN:
109 newInstructions.add(
110 gotoTable.createBuilder()
111 .setTableId(TableId.of(VLAN_TABLE)).build());
112 break;
113 case ETHER:
114 newInstructions.add(
115 gotoTable.createBuilder()
116 .setTableId(TableId.of(ETHER_TABLE)).build());
117 break;
118 case COS:
119 newInstructions.add(
120 gotoTable.createBuilder()
121 .setTableId(TableId.of(COS_MAP_TABLE)).build());
122 break;
123 case IP:
124 newInstructions.add(
125 gotoTable.createBuilder()
126 .setTableId(TableId.of(FIB_TABLE)).build());
127 break;
128 case MPLS:
129 newInstructions.add(
130 gotoTable.createBuilder()
131 .setTableId(TableId.of(MPLS_TABLE)).build());
132 break;
133 case ACL:
134 newInstructions.add(
135 gotoTable.createBuilder()
136 .setTableId(TableId.of(LOCAL_TABLE)).build());
137 break;
138 case NONE:
Saurav Dascbe6de32015-03-01 18:30:46 -0800139 log.error("Should never have to go to Table 0");
140 /*newInstructions.add(
alshabib9af70072015-02-09 14:34:16 -0800141 gotoTable.createBuilder()
142 .setTableId(TableId.of(0)).build());
Saurav Dascbe6de32015-03-01 18:30:46 -0800143 */
alshabib9af70072015-02-09 14:34:16 -0800144 break;
145 default:
146 log.warn("Unknown table type: {}", tid);
147 }
148
149 } else {
150 newInstructions.add(i);
151 }
152 }
153 switch (type) {
154 case VLAN_MPLS:
155 builder.setTableId(TableId.of(VLAN_MPLS_TABLE));
156 break;
157 case VLAN:
158 builder.setTableId(TableId.of(VLAN_TABLE));
159 break;
160 case ETHER:
161 builder.setTableId(TableId.of(ETHER_TABLE));
162 break;
163 case COS:
164 builder.setTableId(TableId.of(COS_MAP_TABLE));
165 break;
166 case IP:
167 builder.setTableId(TableId.of(FIB_TABLE));
168 break;
169 case MPLS:
170 builder.setTableId(TableId.of(MPLS_TABLE));
171 break;
172 case ACL:
173 builder.setTableId(TableId.of(LOCAL_TABLE));
174 break;
Saurav Dasfa2fa932015-03-03 11:29:48 -0800175 case FIRST:
176 builder.setTableId(TableId.of(FIRST_TABLE));
177 break;
alshabib9af70072015-02-09 14:34:16 -0800178 case NONE:
Saurav Dasfa2fa932015-03-03 11:29:48 -0800179 builder.setTableId(TableId.of(LOCAL_TABLE));
alshabib9af70072015-02-09 14:34:16 -0800180 break;
181 default:
182 log.warn("Unknown table type: {}", type);
183 }
alshabib10580802015-02-18 18:30:33 -0800184 builder.setInstructions(newInstructions);
Saurav Dascbe6de32015-03-01 18:30:46 -0800185 OFMessage msgnew = builder.build();
Saurav Dasfa2fa932015-03-03 11:29:48 -0800186 channel.write(Collections.singletonList(msgnew));
Saurav Dascbe6de32015-03-01 18:30:46 -0800187 log.debug("Installed {}", msgnew);
188
alshabib9af70072015-02-09 14:34:16 -0800189 } else {
Saurav Dasfa2fa932015-03-03 11:29:48 -0800190 channel.write(Collections.singletonList(msg));
191 }
192 }
193
194 @Override
195 public TableType getTableType(TableId tid) {
196 switch (tid.getValue()) {
197 case VLAN_MPLS_TABLE:
198 return TableType.VLAN_MPLS;
199 case VLAN_TABLE:
200 return TableType.VLAN;
201 case ETHER_TABLE:
202 return TableType.ETHER;
203 case COS_MAP_TABLE:
204 return TableType.COS;
205 case FIB_TABLE:
206 return TableType.IP;
207 case MPLS_TABLE:
208 return TableType.MPLS;
209 case LOCAL_TABLE:
210 return TableType.NONE;
211 case FIRST_TABLE:
212 return TableType.FIRST;
213 default:
214 log.warn("Unknown table type: {}", tid.getValue());
215 return TableType.NONE;
alshabib9af70072015-02-09 14:34:16 -0800216 }
217 }
218
219 @Override
220 public Boolean supportNxRole() {
221 return false;
222 }
223
224 @Override
225 public void startDriverHandshake() {}
226
227 @Override
228 public boolean isDriverHandshakeComplete() {
229 return true;
230 }
231
232 @Override
233 public void processDriverHandshakeMessage(OFMessage m) {}
234}