blob: 640cea85db1897ab986c7e1701f3f33768c38126 [file] [log] [blame]
tom9c94c5b2014-09-17 13:14:42 -07001package org.onlab.onos.openflow.drivers.impl;
tom7ef8ff92014-09-17 13:08:06 -07002
3
4
5import java.util.Collections;
6import java.util.List;
7
tom9c94c5b2014-09-17 13:14:42 -07008import org.onlab.onos.openflow.controller.Dpid;
alshabib6eb438a2014-10-01 16:39:37 -07009import org.onlab.onos.openflow.controller.RoleState;
tom9c94c5b2014-09-17 13:14:42 -070010import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
11import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
12import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriverFactory;
tom7ef8ff92014-09-17 13:08:06 -070013import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
14import org.projectfloodlight.openflow.protocol.OFMessage;
15import org.projectfloodlight.openflow.protocol.OFPortDesc;
16import org.projectfloodlight.openflow.protocol.OFVersion;
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20/**
21 * A simple implementation of a driver manager that differentiates between
22 * connected switches using the OF Description Statistics Reply message.
23 */
24public final class DriverManager implements OpenFlowSwitchDriverFactory {
25
26 private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
27
28 // Whether to use an OF 1.3 configured TTP, or to use an OF 1.0-style
29 // single table with packet-ins.
30 private static boolean cpqdUsePipeline13 = false;
31
32 /**
33 * Return an IOFSwitch object based on switch's manufacturer description
34 * from OFDescStatsReply.
35 *
36 * @param desc DescriptionStatistics reply from the switch
37 * @return A IOFSwitch instance if the driver found an implementation for
38 * the given description. Otherwise it returns OFSwitchImplBase
39 */
40 @Override
41 public OpenFlowSwitchDriver getOFSwitchImpl(Dpid dpid,
42 OFDescStatsReply desc, OFVersion ofv) {
43 String vendor = desc.getMfrDesc();
44 String hw = desc.getHwDesc();
45 if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
46 &&
47 hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
48 return new OFSwitchImplCPqD13(dpid, desc, cpqdUsePipeline13);
49 }
50
51 if (vendor.startsWith("Nicira") &&
52 hw.startsWith("Open vSwitch")) {
53 if (ofv == OFVersion.OF_10) {
54 return new OFSwitchImplOVS10(dpid, desc);
55 } else if (ofv == OFVersion.OF_13) {
56 return new OFSwitchImplOVS13(dpid, desc);
57 }
58 }
59
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070060 String sw = desc.getSwDesc();
61 if (sw.startsWith("LINC-OE")) {
Yuta HIGUCHIbccb6be2014-10-09 17:20:29 -070062 log.debug("Optical Emulator LINC-OE with DPID:{} found..", dpid);
63 return new OFOpticalSwitchImplLINC13(dpid, desc);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070064 }
65
tom7ef8ff92014-09-17 13:08:06 -070066 log.warn("DriverManager could not identify switch desc: {}. "
67 + "Assigning AbstractOpenFlowSwich", desc);
68 return new AbstractOpenFlowSwitch(dpid, desc) {
69
70 @Override
alshabib6eb438a2014-10-01 16:39:37 -070071 public void setRole(RoleState state) {
72 this.role = RoleState.MASTER;
73 }
74
75 @Override
tom7ef8ff92014-09-17 13:08:06 -070076 public void write(List<OFMessage> msgs) {
77 channel.write(msgs);
78 }
79
80 @Override
81 public void write(OFMessage msg) {
82 channel.write(Collections.singletonList(msg));
83
84 }
85
86 @Override
87 public Boolean supportNxRole() {
88 return false;
89 }
90
91 @Override
92 public void startDriverHandshake() {}
93
94 @Override
95 public void processDriverHandshakeMessage(OFMessage m) {}
96
97 @Override
98 public boolean isDriverHandshakeComplete() {
99 return true;
100 }
101
102 @Override
103 public List<OFPortDesc> getPorts() {
104 if (this.factory().getVersion() == OFVersion.OF_10) {
105 return Collections.unmodifiableList(features.getPorts());
106 } else {
107 return Collections.unmodifiableList(ports.getEntries());
108 }
109 }
110 };
111 }
112
113 /**
114 * Private constructor to avoid instantiation.
115 */
116 private DriverManager() {
117 }
118
119 /**
120 * Sets the configuration parameter which determines how the CPqD switch
121 * is set up. If usePipeline13 is true, a 1.3 pipeline will be set up on
122 * the switch. Otherwise, the switch will be set up in a 1.0 style with
123 * a single table where missed packets are sent to the controller.
124 *
125 * @param usePipeline13 whether to use a 1.3 pipeline or not
126 */
127 public static void setConfigForCpqd(boolean usePipeline13) {
128 cpqdUsePipeline13 = usePipeline13;
129 }
130
131 public static OpenFlowSwitchDriver getSwitch(Dpid dpid,
132 OFDescStatsReply desc, OFVersion ofv) {
133 return new DriverManager().getOFSwitchImpl(dpid, desc, ofv);
134 }
135
136}