blob: 75bb9d4a254af23debc55ecc550c81462936e6cc [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) {
alshabib9af70072015-02-09 14:34:16 -080092 if (msg.getType() == OFType.FLOW_MOD) {
93 OFFlowMod flowMod = (OFFlowMod) msg;
94 OFFlowMod.Builder builder = flowMod.createBuilder();
Saurav Dascbe6de32015-03-01 18:30:46 -080095 List<OFInstruction> instructions = flowMod.getInstructions();
alshabib9af70072015-02-09 14:34:16 -080096 List<OFInstruction> newInstructions = Lists.newArrayList();
97 for (OFInstruction i : instructions) {
98 if (i instanceof OFInstructionGotoTable) {
99 OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
100 TableType tid = TableType.values()[gotoTable.getTableId().getValue()];
101 switch (tid) {
102 case VLAN_MPLS:
103 newInstructions.add(
104 gotoTable.createBuilder()
105 .setTableId(TableId.of(VLAN_MPLS_TABLE)).build());
106 break;
107 case VLAN:
108 newInstructions.add(
109 gotoTable.createBuilder()
110 .setTableId(TableId.of(VLAN_TABLE)).build());
111 break;
112 case ETHER:
113 newInstructions.add(
114 gotoTable.createBuilder()
115 .setTableId(TableId.of(ETHER_TABLE)).build());
116 break;
117 case COS:
118 newInstructions.add(
119 gotoTable.createBuilder()
120 .setTableId(TableId.of(COS_MAP_TABLE)).build());
121 break;
122 case IP:
123 newInstructions.add(
124 gotoTable.createBuilder()
125 .setTableId(TableId.of(FIB_TABLE)).build());
126 break;
127 case MPLS:
128 newInstructions.add(
129 gotoTable.createBuilder()
130 .setTableId(TableId.of(MPLS_TABLE)).build());
131 break;
132 case ACL:
133 newInstructions.add(
134 gotoTable.createBuilder()
135 .setTableId(TableId.of(LOCAL_TABLE)).build());
136 break;
137 case NONE:
Saurav Dascbe6de32015-03-01 18:30:46 -0800138 log.error("Should never have to go to Table 0");
139 /*newInstructions.add(
alshabib9af70072015-02-09 14:34:16 -0800140 gotoTable.createBuilder()
141 .setTableId(TableId.of(0)).build());
Saurav Dascbe6de32015-03-01 18:30:46 -0800142 */
alshabib9af70072015-02-09 14:34:16 -0800143 break;
144 default:
145 log.warn("Unknown table type: {}", tid);
146 }
147
148 } else {
149 newInstructions.add(i);
150 }
151 }
152 switch (type) {
153 case VLAN_MPLS:
154 builder.setTableId(TableId.of(VLAN_MPLS_TABLE));
155 break;
156 case VLAN:
157 builder.setTableId(TableId.of(VLAN_TABLE));
158 break;
159 case ETHER:
160 builder.setTableId(TableId.of(ETHER_TABLE));
161 break;
162 case COS:
163 builder.setTableId(TableId.of(COS_MAP_TABLE));
164 break;
165 case IP:
166 builder.setTableId(TableId.of(FIB_TABLE));
167 break;
168 case MPLS:
169 builder.setTableId(TableId.of(MPLS_TABLE));
170 break;
171 case ACL:
172 builder.setTableId(TableId.of(LOCAL_TABLE));
173 break;
Saurav Dasfa2fa932015-03-03 11:29:48 -0800174 case FIRST:
175 builder.setTableId(TableId.of(FIRST_TABLE));
176 break;
alshabib9af70072015-02-09 14:34:16 -0800177 case NONE:
Saurav Dasfa2fa932015-03-03 11:29:48 -0800178 builder.setTableId(TableId.of(LOCAL_TABLE));
alshabib9af70072015-02-09 14:34:16 -0800179 break;
180 default:
181 log.warn("Unknown table type: {}", type);
182 }
alshabib10580802015-02-18 18:30:33 -0800183 builder.setInstructions(newInstructions);
Saurav Dascbe6de32015-03-01 18:30:46 -0800184 OFMessage msgnew = builder.build();
Saurav Dasfa2fa932015-03-03 11:29:48 -0800185 channel.write(Collections.singletonList(msgnew));
Saurav Dascbe6de32015-03-01 18:30:46 -0800186 log.debug("Installed {}", msgnew);
187
alshabib9af70072015-02-09 14:34:16 -0800188 } else {
Saurav Dasfa2fa932015-03-03 11:29:48 -0800189 channel.write(Collections.singletonList(msg));
190 }
191 }
192
193 @Override
194 public TableType getTableType(TableId tid) {
195 switch (tid.getValue()) {
196 case VLAN_MPLS_TABLE:
197 return TableType.VLAN_MPLS;
198 case VLAN_TABLE:
199 return TableType.VLAN;
200 case ETHER_TABLE:
201 return TableType.ETHER;
202 case COS_MAP_TABLE:
203 return TableType.COS;
204 case FIB_TABLE:
205 return TableType.IP;
206 case MPLS_TABLE:
207 return TableType.MPLS;
208 case LOCAL_TABLE:
209 return TableType.NONE;
210 case FIRST_TABLE:
211 return TableType.FIRST;
212 default:
213 log.warn("Unknown table type: {}", tid.getValue());
214 return TableType.NONE;
alshabib9af70072015-02-09 14:34:16 -0800215 }
216 }
217
218 @Override
219 public Boolean supportNxRole() {
220 return false;
221 }
222
223 @Override
224 public void startDriverHandshake() {}
225
226 @Override
227 public boolean isDriverHandshakeComplete() {
228 return true;
229 }
230
231 @Override
232 public void processDriverHandshakeMessage(OFMessage m) {}
233}