Jonathan Hart

Change the way 1.3 flow mods are built to support rewrite actions.

Change-Id: I9c1c3059822b19d0665702162dee9904f95127d8
...@@ -201,7 +201,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -201,7 +201,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
201 @Override 201 @Override
202 public TrafficTreatment build() { 202 public TrafficTreatment build() {
203 203
204 - //If we are dropping should we just return an emptry list? 204 + //If we are dropping should we just return an empty list?
205 List<Instruction> instructions = new LinkedList<Instruction>(); 205 List<Instruction> instructions = new LinkedList<Instruction>();
206 instructions.addAll(modifications); 206 instructions.addAll(modifications);
207 instructions.addAll(groups); 207 instructions.addAll(groups);
......
...@@ -33,7 +33,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc; ...@@ -33,7 +33,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
33 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp; 33 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
34 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid; 34 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
35 import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; 35 import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
36 -import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; 36 +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions;
37 import org.projectfloodlight.openflow.protocol.match.Match; 37 import org.projectfloodlight.openflow.protocol.match.Match;
38 import org.projectfloodlight.openflow.protocol.match.MatchField; 38 import org.projectfloodlight.openflow.protocol.match.MatchField;
39 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic; 39 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
...@@ -104,8 +104,8 @@ public class FlowEntryBuilder { ...@@ -104,8 +104,8 @@ public class FlowEntryBuilder {
104 case OF_13: 104 case OF_13:
105 List<OFInstruction> ins = entry.getInstructions(); 105 List<OFInstruction> ins = entry.getInstructions();
106 for (OFInstruction in : ins) { 106 for (OFInstruction in : ins) {
107 - if (in.getType().equals(OFInstructionType.APPLY_ACTIONS)) { 107 + if (in.getType().equals(OFInstructionType.WRITE_ACTIONS)) {
108 - OFInstructionApplyActions apply = (OFInstructionApplyActions) in; 108 + OFInstructionWriteActions apply = (OFInstructionWriteActions) in;
109 return apply.getActions(); 109 return apply.getActions();
110 } 110 }
111 } 111 }
......
...@@ -2,14 +2,8 @@ package org.onlab.onos.provider.of.flow.impl; ...@@ -2,14 +2,8 @@ package org.onlab.onos.provider.of.flow.impl;
2 2
3 import static org.slf4j.LoggerFactory.getLogger; 3 import static org.slf4j.LoggerFactory.getLogger;
4 4
5 -import java.util.Collections;
6 -import java.util.LinkedList;
7 -import java.util.List;
8 -
9 -import org.onlab.onos.net.flow.FlowId;
10 import org.onlab.onos.net.flow.FlowRule; 5 import org.onlab.onos.net.flow.FlowRule;
11 import org.onlab.onos.net.flow.TrafficSelector; 6 import org.onlab.onos.net.flow.TrafficSelector;
12 -import org.onlab.onos.net.flow.TrafficTreatment;
13 import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; 7 import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
14 import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; 8 import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
15 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; 9 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
...@@ -20,22 +14,10 @@ import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion; ...@@ -20,22 +14,10 @@ import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
20 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; 14 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
21 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; 15 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
22 import org.onlab.onos.net.flow.criteria.Criterion; 16 import org.onlab.onos.net.flow.criteria.Criterion;
23 -import org.onlab.onos.net.flow.instructions.Instruction;
24 -import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
25 -import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
26 -import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
27 -import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
28 -import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
29 -import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
30 -import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
31 -import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
32 -import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
33 import org.projectfloodlight.openflow.protocol.OFFactory; 17 import org.projectfloodlight.openflow.protocol.OFFactory;
34 import org.projectfloodlight.openflow.protocol.OFFlowAdd; 18 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
35 import org.projectfloodlight.openflow.protocol.OFFlowDelete; 19 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
36 import org.projectfloodlight.openflow.protocol.OFFlowMod; 20 import org.projectfloodlight.openflow.protocol.OFFlowMod;
37 -import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
38 -import org.projectfloodlight.openflow.protocol.action.OFAction;
39 import org.projectfloodlight.openflow.protocol.match.Match; 21 import org.projectfloodlight.openflow.protocol.match.Match;
40 import org.projectfloodlight.openflow.protocol.match.MatchField; 22 import org.projectfloodlight.openflow.protocol.match.MatchField;
41 import org.projectfloodlight.openflow.types.CircuitSignalID; 23 import org.projectfloodlight.openflow.types.CircuitSignalID;
...@@ -44,181 +26,82 @@ import org.projectfloodlight.openflow.types.IPv4Address; ...@@ -44,181 +26,82 @@ import org.projectfloodlight.openflow.types.IPv4Address;
44 import org.projectfloodlight.openflow.types.IpProtocol; 26 import org.projectfloodlight.openflow.types.IpProtocol;
45 import org.projectfloodlight.openflow.types.MacAddress; 27 import org.projectfloodlight.openflow.types.MacAddress;
46 import org.projectfloodlight.openflow.types.Masked; 28 import org.projectfloodlight.openflow.types.Masked;
47 -import org.projectfloodlight.openflow.types.OFBufferId;
48 import org.projectfloodlight.openflow.types.OFPort; 29 import org.projectfloodlight.openflow.types.OFPort;
49 import org.projectfloodlight.openflow.types.OFVlanVidMatch; 30 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
50 import org.projectfloodlight.openflow.types.TransportPort; 31 import org.projectfloodlight.openflow.types.TransportPort;
51 -import org.projectfloodlight.openflow.types.U64;
52 import org.projectfloodlight.openflow.types.VlanPcp; 32 import org.projectfloodlight.openflow.types.VlanPcp;
53 import org.projectfloodlight.openflow.types.VlanVid; 33 import org.projectfloodlight.openflow.types.VlanVid;
54 import org.slf4j.Logger; 34 import org.slf4j.Logger;
55 35
56 - 36 +/**
57 -public class FlowModBuilder { 37 + * Builder for OpenFlow flow mods based on FlowRules.
38 + */
39 +public abstract class FlowModBuilder {
58 40
59 private final Logger log = getLogger(getClass()); 41 private final Logger log = getLogger(getClass());
60 42
61 private final OFFactory factory; 43 private final OFFactory factory;
62 - private final TrafficTreatment treatment; 44 + private final FlowRule flowRule;
63 private final TrafficSelector selector; 45 private final TrafficSelector selector;
64 46
65 - private final int priority; 47 + /**
66 - 48 + * Creates a new flow mod builder.
67 - private final FlowId cookie; 49 + *
68 - 50 + * @param flowRule the flow rule to transform into a flow mod
69 - 51 + * @param factory the OpenFlow factory to use to build the flow mod
70 - 52 + * @return the new flow mod builder
71 - public FlowModBuilder(FlowRule flowRule, OFFactory factory) { 53 + */
72 - this.factory = factory; 54 + public static FlowModBuilder builder(FlowRule flowRule, OFFactory factory) {
73 - this.treatment = flowRule.treatment(); 55 + switch (factory.getVersion()) {
74 - this.selector = flowRule.selector(); 56 + case OF_10:
75 - this.priority = flowRule.priority(); 57 + return new FlowModBuilderVer10(flowRule, factory);
76 - this.cookie = flowRule.id(); 58 + case OF_13:
77 - } 59 + return new FlowModBuilderVer13(flowRule, factory);
78 -
79 - public OFFlowAdd buildFlowAdd() {
80 - Match match = buildMatch();
81 - List<OFAction> actions = buildActions();
82 -
83 - //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
84 - OFFlowAdd fm = factory.buildFlowAdd()
85 - .setXid(cookie.value())
86 - .setCookie(U64.of(cookie.value()))
87 - .setBufferId(OFBufferId.NO_BUFFER)
88 - .setActions(actions)
89 - .setMatch(match)
90 - .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
91 - .setPriority(priority)
92 - .build();
93 -
94 - return fm;
95 -
96 - }
97 -
98 - public OFFlowMod buildFlowMod() {
99 - Match match = buildMatch();
100 - List<OFAction> actions = buildActions();
101 -
102 - //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
103 - OFFlowMod fm = factory.buildFlowModify()
104 - .setXid(cookie.value())
105 - .setCookie(U64.of(cookie.value()))
106 - .setBufferId(OFBufferId.NO_BUFFER)
107 - .setActions(actions)
108 - .setMatch(match)
109 - .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
110 - .setPriority(priority)
111 - .build();
112 -
113 - return fm;
114 -
115 - }
116 -
117 - public OFFlowDelete buildFlowDel() {
118 - Match match = buildMatch();
119 - List<OFAction> actions = buildActions();
120 -
121 - OFFlowDelete fm = factory.buildFlowDelete()
122 - .setXid(cookie.value())
123 - .setCookie(U64.of(cookie.value()))
124 - .setBufferId(OFBufferId.NO_BUFFER)
125 - .setActions(actions)
126 - .setMatch(match)
127 - .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
128 - .setPriority(priority)
129 - .build();
130 -
131 - return fm;
132 - }
133 -
134 - private List<OFAction> buildActions() {
135 - List<OFAction> acts = new LinkedList<>();
136 - if (treatment == null) {
137 - return acts;
138 - }
139 - for (Instruction i : treatment.instructions()) {
140 - switch (i.type()) {
141 - case DROP:
142 - log.warn("Saw drop action; assigning drop action");
143 - return new LinkedList<>();
144 - case L0MODIFICATION:
145 - acts.add(buildL0Modification(i));
146 - break;
147 - case L2MODIFICATION:
148 - acts.add(buildL2Modification(i));
149 - break;
150 - case L3MODIFICATION:
151 - acts.add(buildL3Modification(i));
152 - break;
153 - case OUTPUT:
154 - OutputInstruction out = (OutputInstruction) i;
155 - acts.add(factory.actions().buildOutput().setPort(
156 - OFPort.of((int) out.port().toLong())).build());
157 - break;
158 - case GROUP:
159 default: 60 default:
160 - log.warn("Instruction type {} not yet implemented.", i.type()); 61 + throw new UnsupportedOperationException(
62 + "No flow mod builder for protocol version " + factory.getVersion());
161 } 63 }
162 } 64 }
163 65
164 - return acts; 66 + /**
165 - } 67 + * Constructs a flow mod builder.
166 - 68 + *
167 - private OFAction buildL0Modification(Instruction i) { 69 + * @param flowRule the flow rule to transform into a flow mod
168 - L0ModificationInstruction l0m = (L0ModificationInstruction) i; 70 + * @param factory the OpenFlow factory to use to build the flow mod
169 - switch (l0m.subtype()) { 71 + */
170 - case LAMBDA: 72 + protected FlowModBuilder(FlowRule flowRule, OFFactory factory) {
171 - ModLambdaInstruction ml = (ModLambdaInstruction) i; 73 + this.factory = factory;
172 - return factory.actions().circuit(factory.oxms().ochSigidBasic( 74 + this.flowRule = flowRule;
173 - new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1))); 75 + this.selector = flowRule.selector();
174 - default:
175 - log.warn("Unimplemented action type {}.", l0m.subtype());
176 - break;
177 - }
178 - return null;
179 - }
180 -
181 - private OFAction buildL3Modification(Instruction i) {
182 - L3ModificationInstruction l3m = (L3ModificationInstruction) i;
183 - ModIPInstruction ip;
184 - switch (l3m.subtype()) {
185 - case IP_DST:
186 - ip = (ModIPInstruction) i;
187 - return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
188 - case IP_SRC:
189 - ip = (ModIPInstruction) i;
190 - return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
191 - default:
192 - log.warn("Unimplemented action type {}.", l3m.subtype());
193 - break;
194 - }
195 - return null;
196 - }
197 -
198 - private OFAction buildL2Modification(Instruction i) {
199 - L2ModificationInstruction l2m = (L2ModificationInstruction) i;
200 - ModEtherInstruction eth;
201 - switch (l2m.subtype()) {
202 - case ETH_DST:
203 - eth = (ModEtherInstruction) l2m;
204 - return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
205 - case ETH_SRC:
206 - eth = (ModEtherInstruction) l2m;
207 - return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
208 - case VLAN_ID:
209 - ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
210 - return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
211 - case VLAN_PCP:
212 - ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
213 - return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
214 - default:
215 - log.warn("Unimplemented action type {}.", l2m.subtype());
216 - break;
217 - }
218 - return null;
219 } 76 }
220 77
221 - private Match buildMatch() { 78 + /**
79 + * Builds an ADD flow mod.
80 + *
81 + * @return the flow mod
82 + */
83 + public abstract OFFlowAdd buildFlowAdd();
84 +
85 + /**
86 + * Builds a MODIFY flow mod.
87 + *
88 + * @return the flow mod
89 + */
90 + public abstract OFFlowMod buildFlowMod();
91 +
92 + /**
93 + * Builds a DELETE flow mod.
94 + *
95 + * @return the flow mod
96 + */
97 + public abstract OFFlowDelete buildFlowDel();
98 +
99 + /**
100 + * Builds the match for the flow mod.
101 + *
102 + * @return the match
103 + */
104 + protected Match buildMatch() {
222 Match.Builder mBuilder = factory.buildMatch(); 105 Match.Builder mBuilder = factory.buildMatch();
223 EthCriterion eth; 106 EthCriterion eth;
224 IPCriterion ip; 107 IPCriterion ip;
...@@ -323,6 +206,22 @@ public class FlowModBuilder { ...@@ -323,6 +206,22 @@ public class FlowModBuilder {
323 return mBuilder.build(); 206 return mBuilder.build();
324 } 207 }
325 208
209 + /**
210 + * Returns the flow rule for this builder.
211 + *
212 + * @return the flow rule
213 + */
214 + protected FlowRule flowRule() {
215 + return flowRule;
216 + }
326 217
218 + /**
219 + * Returns the factory used for building OpenFlow constructs.
220 + *
221 + * @return the factory
222 + */
223 + protected OFFactory factory() {
224 + return factory;
225 + }
327 226
328 } 227 }
......
1 +package org.onlab.onos.provider.of.flow.impl;
2 +
3 +import java.util.Collections;
4 +import java.util.LinkedList;
5 +import java.util.List;
6 +
7 +import org.onlab.onos.net.flow.FlowRule;
8 +import org.onlab.onos.net.flow.TrafficTreatment;
9 +import org.onlab.onos.net.flow.instructions.Instruction;
10 +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
11 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
12 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
13 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
14 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
15 +import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
16 +import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
17 +import org.projectfloodlight.openflow.protocol.OFFactory;
18 +import org.projectfloodlight.openflow.protocol.OFFlowAdd;
19 +import org.projectfloodlight.openflow.protocol.OFFlowDelete;
20 +import org.projectfloodlight.openflow.protocol.OFFlowMod;
21 +import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
22 +import org.projectfloodlight.openflow.protocol.action.OFAction;
23 +import org.projectfloodlight.openflow.protocol.match.Match;
24 +import org.projectfloodlight.openflow.types.IPv4Address;
25 +import org.projectfloodlight.openflow.types.MacAddress;
26 +import org.projectfloodlight.openflow.types.OFBufferId;
27 +import org.projectfloodlight.openflow.types.OFPort;
28 +import org.projectfloodlight.openflow.types.U64;
29 +import org.projectfloodlight.openflow.types.VlanPcp;
30 +import org.projectfloodlight.openflow.types.VlanVid;
31 +import org.slf4j.Logger;
32 +import org.slf4j.LoggerFactory;
33 +
34 +/**
35 + * Flow mod builder for OpenFlow 1.0.
36 + */
37 +public class FlowModBuilderVer10 extends FlowModBuilder {
38 +
39 + private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
40 +
41 + private final TrafficTreatment treatment;
42 +
43 + /**
44 + * Constructor for a flow mod builder for OpenFlow 1.0.
45 + *
46 + * @param flowRule the flow rule to transform into a flow mod
47 + * @param factory the OpenFlow factory to use to build the flow mod
48 + */
49 + protected FlowModBuilderVer10(FlowRule flowRule, OFFactory factory) {
50 + super(flowRule, factory);
51 +
52 + this.treatment = flowRule.treatment();
53 + }
54 +
55 + @Override
56 + public OFFlowAdd buildFlowAdd() {
57 + Match match = buildMatch();
58 + List<OFAction> actions = buildActions();
59 +
60 + long cookie = flowRule().id().value();
61 +
62 + //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
63 + OFFlowAdd fm = factory().buildFlowAdd()
64 + .setXid(cookie)
65 + .setCookie(U64.of(cookie))
66 + .setBufferId(OFBufferId.NO_BUFFER)
67 + .setActions(actions)
68 + .setMatch(match)
69 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
70 + .setPriority(flowRule().priority())
71 + .build();
72 +
73 + return fm;
74 + }
75 +
76 + @Override
77 + public OFFlowMod buildFlowMod() {
78 + Match match = buildMatch();
79 + List<OFAction> actions = buildActions();
80 +
81 + long cookie = flowRule().id().value();
82 +
83 + //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
84 + OFFlowMod fm = factory().buildFlowModify()
85 + .setXid(cookie)
86 + .setCookie(U64.of(cookie))
87 + .setBufferId(OFBufferId.NO_BUFFER)
88 + .setActions(actions)
89 + .setMatch(match)
90 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
91 + .setPriority(flowRule().priority())
92 + .build();
93 +
94 + return fm;
95 + }
96 +
97 + @Override
98 + public OFFlowDelete buildFlowDel() {
99 + Match match = buildMatch();
100 + List<OFAction> actions = buildActions();
101 +
102 + long cookie = flowRule().id().value();
103 +
104 + OFFlowDelete fm = factory().buildFlowDelete()
105 + .setXid(cookie)
106 + .setCookie(U64.of(cookie))
107 + .setBufferId(OFBufferId.NO_BUFFER)
108 + .setActions(actions)
109 + .setMatch(match)
110 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
111 + .setPriority(flowRule().priority())
112 + .build();
113 +
114 + return fm;
115 + }
116 +
117 + private List<OFAction> buildActions() {
118 + List<OFAction> acts = new LinkedList<>();
119 + if (treatment == null) {
120 + return acts;
121 + }
122 + for (Instruction i : treatment.instructions()) {
123 + switch (i.type()) {
124 + case DROP:
125 + log.warn("Saw drop action; assigning drop action");
126 + return new LinkedList<>();
127 + case L2MODIFICATION:
128 + acts.add(buildL2Modification(i));
129 + break;
130 + case L3MODIFICATION:
131 + acts.add(buildL3Modification(i));
132 + break;
133 + case OUTPUT:
134 + OutputInstruction out = (OutputInstruction) i;
135 + acts.add(factory().actions().buildOutput().setPort(
136 + OFPort.of((int) out.port().toLong())).build());
137 + break;
138 + case L0MODIFICATION:
139 + case GROUP:
140 + log.warn("Instruction type {} not supported with protocol version {}",
141 + i.type(), factory().getVersion());
142 + break;
143 + default:
144 + log.warn("Instruction type {} not yet implemented.", i.type());
145 + }
146 + }
147 +
148 + return acts;
149 + }
150 +
151 + private OFAction buildL3Modification(Instruction i) {
152 + L3ModificationInstruction l3m = (L3ModificationInstruction) i;
153 + ModIPInstruction ip;
154 + switch (l3m.subtype()) {
155 + case IP_DST:
156 + ip = (ModIPInstruction) i;
157 + return factory().actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
158 + case IP_SRC:
159 + ip = (ModIPInstruction) i;
160 + return factory().actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
161 + default:
162 + log.warn("Unimplemented action type {}.", l3m.subtype());
163 + break;
164 + }
165 + return null;
166 + }
167 +
168 + private OFAction buildL2Modification(Instruction i) {
169 + L2ModificationInstruction l2m = (L2ModificationInstruction) i;
170 + ModEtherInstruction eth;
171 + switch (l2m.subtype()) {
172 + case ETH_DST:
173 + eth = (ModEtherInstruction) l2m;
174 + return factory().actions().setDlDst(MacAddress.of(eth.mac().toLong()));
175 + case ETH_SRC:
176 + eth = (ModEtherInstruction) l2m;
177 + return factory().actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
178 + case VLAN_ID:
179 + ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
180 + return factory().actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
181 + case VLAN_PCP:
182 + ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
183 + return factory().actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
184 + default:
185 + log.warn("Unimplemented action type {}.", l2m.subtype());
186 + break;
187 + }
188 + return null;
189 + }
190 +
191 +}
1 +package org.onlab.onos.provider.of.flow.impl;
2 +
3 +import java.util.Collections;
4 +import java.util.LinkedList;
5 +import java.util.List;
6 +
7 +import org.onlab.onos.net.flow.FlowRule;
8 +import org.onlab.onos.net.flow.TrafficTreatment;
9 +import org.onlab.onos.net.flow.instructions.Instruction;
10 +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
11 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
12 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
13 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
14 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
15 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
16 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
17 +import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
18 +import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
19 +import org.projectfloodlight.openflow.protocol.OFFactory;
20 +import org.projectfloodlight.openflow.protocol.OFFlowAdd;
21 +import org.projectfloodlight.openflow.protocol.OFFlowDelete;
22 +import org.projectfloodlight.openflow.protocol.OFFlowMod;
23 +import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
24 +import org.projectfloodlight.openflow.protocol.action.OFAction;
25 +import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
26 +import org.projectfloodlight.openflow.protocol.match.Match;
27 +import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
28 +import org.projectfloodlight.openflow.types.CircuitSignalID;
29 +import org.projectfloodlight.openflow.types.IPv4Address;
30 +import org.projectfloodlight.openflow.types.MacAddress;
31 +import org.projectfloodlight.openflow.types.OFBufferId;
32 +import org.projectfloodlight.openflow.types.OFPort;
33 +import org.projectfloodlight.openflow.types.OFVlanVidMatch;
34 +import org.projectfloodlight.openflow.types.U64;
35 +import org.projectfloodlight.openflow.types.VlanPcp;
36 +import org.slf4j.Logger;
37 +import org.slf4j.LoggerFactory;
38 +
39 +/**
40 + * Flow mod builder for OpenFlow 1.3+.
41 + */
42 +public class FlowModBuilderVer13 extends FlowModBuilder {
43 +
44 + private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
45 +
46 + private final TrafficTreatment treatment;
47 +
48 + /**
49 + * Constructor for a flow mod builder for OpenFlow 1.3.
50 + *
51 + * @param flowRule the flow rule to transform into a flow mod
52 + * @param factory the OpenFlow factory to use to build the flow mod
53 + */
54 + protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory) {
55 + super(flowRule, factory);
56 +
57 + this.treatment = flowRule.treatment();
58 + }
59 +
60 + @Override
61 + public OFFlowAdd buildFlowAdd() {
62 + Match match = buildMatch();
63 + OFInstruction writeActions =
64 + factory().instructions().writeActions(buildActions());
65 +
66 + long cookie = flowRule().id().value();
67 +
68 + //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
69 + OFFlowAdd fm = factory().buildFlowAdd()
70 + .setXid(cookie)
71 + .setCookie(U64.of(cookie))
72 + .setBufferId(OFBufferId.NO_BUFFER)
73 + .setInstructions(Collections.singletonList(writeActions))
74 + .setMatch(match)
75 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
76 + .setPriority(flowRule().priority())
77 + .build();
78 +
79 + return fm;
80 + }
81 +
82 + @Override
83 + public OFFlowMod buildFlowMod() {
84 + Match match = buildMatch();
85 + OFInstruction writeActions =
86 + factory().instructions().writeActions(buildActions());
87 +
88 + long cookie = flowRule().id().value();
89 +
90 + //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
91 + OFFlowMod fm = factory().buildFlowModify()
92 + .setXid(cookie)
93 + .setCookie(U64.of(cookie))
94 + .setBufferId(OFBufferId.NO_BUFFER)
95 + .setInstructions(Collections.singletonList(writeActions))
96 + .setMatch(match)
97 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
98 + .setPriority(flowRule().priority())
99 + .build();
100 +
101 + return fm;
102 + }
103 +
104 + @Override
105 + public OFFlowDelete buildFlowDel() {
106 + Match match = buildMatch();
107 + OFInstruction writeActions =
108 + factory().instructions().writeActions(buildActions());
109 +
110 + long cookie = flowRule().id().value();
111 +
112 + OFFlowDelete fm = factory().buildFlowDelete()
113 + .setXid(cookie)
114 + .setCookie(U64.of(cookie))
115 + .setBufferId(OFBufferId.NO_BUFFER)
116 + .setInstructions(Collections.singletonList(writeActions))
117 + .setMatch(match)
118 + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
119 + .setPriority(flowRule().priority())
120 + .build();
121 +
122 + return fm;
123 + }
124 +
125 + private List<OFAction> buildActions() {
126 + List<OFAction> actions = new LinkedList<>();
127 + if (treatment == null) {
128 + return actions;
129 + }
130 + for (Instruction i : treatment.instructions()) {
131 + switch (i.type()) {
132 + case DROP:
133 + log.warn("Saw drop action; assigning drop action");
134 + return new LinkedList<>();
135 + case L0MODIFICATION:
136 + actions.add(buildL0Modification(i));
137 + break;
138 + case L2MODIFICATION:
139 + actions.add(buildL2Modification(i));
140 + break;
141 + case L3MODIFICATION:
142 + actions.add(buildL3Modification(i));
143 + break;
144 + case OUTPUT:
145 + OutputInstruction out = (OutputInstruction) i;
146 + actions.add(factory().actions().buildOutput().setPort(
147 + OFPort.of((int) out.port().toLong())).build());
148 + break;
149 + case GROUP:
150 + default:
151 + log.warn("Instruction type {} not yet implemented.", i.type());
152 + }
153 + }
154 +
155 + return actions;
156 + }
157 +
158 + private OFAction buildL0Modification(Instruction i) {
159 + L0ModificationInstruction l0m = (L0ModificationInstruction) i;
160 + switch (l0m.subtype()) {
161 + case LAMBDA:
162 + ModLambdaInstruction ml = (ModLambdaInstruction) i;
163 + return factory().actions().circuit(factory().oxms().ochSigidBasic(
164 + new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
165 + default:
166 + log.warn("Unimplemented action type {}.", l0m.subtype());
167 + break;
168 + }
169 + return null;
170 + }
171 +
172 + private OFAction buildL2Modification(Instruction i) {
173 + L2ModificationInstruction l2m = (L2ModificationInstruction) i;
174 + ModEtherInstruction eth;
175 + OFOxm<?> oxm = null;
176 + switch (l2m.subtype()) {
177 + case ETH_DST:
178 + eth = (ModEtherInstruction) l2m;
179 + oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
180 + break;
181 + case ETH_SRC:
182 + eth = (ModEtherInstruction) l2m;
183 + oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
184 + break;
185 + case VLAN_ID:
186 + ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
187 + oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId.toShort()));
188 + break;
189 + case VLAN_PCP:
190 + ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
191 + oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp));
192 + break;
193 + default:
194 + log.warn("Unimplemented action type {}.", l2m.subtype());
195 + break;
196 + }
197 +
198 + if (oxm != null) {
199 + return factory().actions().buildSetField().setField(oxm).build();
200 + }
201 + return null;
202 + }
203 +
204 + private OFAction buildL3Modification(Instruction i) {
205 + L3ModificationInstruction l3m = (L3ModificationInstruction) i;
206 + ModIPInstruction ip;
207 + OFOxm<?> oxm = null;
208 + switch (l3m.subtype()) {
209 + case IP_DST:
210 + ip = (ModIPInstruction) i;
211 + oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip.ip().toInt()));
212 + case IP_SRC:
213 + ip = (ModIPInstruction) i;
214 + oxm = factory().oxms().ipv4Src(IPv4Address.of(ip.ip().toInt()));
215 + default:
216 + log.warn("Unimplemented action type {}.", l3m.subtype());
217 + break;
218 + }
219 +
220 + if (oxm != null) {
221 + return factory().actions().buildSetField().setField(oxm).build();
222 + }
223 + return null;
224 + }
225 +
226 +}
...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Reference; ...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Reference;
22 import org.apache.felix.scr.annotations.ReferenceCardinality; 22 import org.apache.felix.scr.annotations.ReferenceCardinality;
23 import org.onlab.onos.ApplicationId; 23 import org.onlab.onos.ApplicationId;
24 import org.onlab.onos.net.DeviceId; 24 import org.onlab.onos.net.DeviceId;
25 +import org.onlab.onos.net.flow.BatchOperation;
25 import org.onlab.onos.net.flow.CompletedBatchOperation; 26 import org.onlab.onos.net.flow.CompletedBatchOperation;
26 import org.onlab.onos.net.flow.DefaultFlowEntry; 27 import org.onlab.onos.net.flow.DefaultFlowEntry;
27 import org.onlab.onos.net.flow.FlowEntry; 28 import org.onlab.onos.net.flow.FlowEntry;
...@@ -31,7 +32,6 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation; ...@@ -31,7 +32,6 @@ import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
31 import org.onlab.onos.net.flow.FlowRuleProvider; 32 import org.onlab.onos.net.flow.FlowRuleProvider;
32 import org.onlab.onos.net.flow.FlowRuleProviderRegistry; 33 import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
33 import org.onlab.onos.net.flow.FlowRuleProviderService; 34 import org.onlab.onos.net.flow.FlowRuleProviderService;
34 -import org.onlab.onos.net.flow.BatchOperation;
35 import org.onlab.onos.net.provider.AbstractProvider; 35 import org.onlab.onos.net.provider.AbstractProvider;
36 import org.onlab.onos.net.provider.ProviderId; 36 import org.onlab.onos.net.provider.ProviderId;
37 import org.onlab.onos.net.topology.TopologyService; 37 import org.onlab.onos.net.topology.TopologyService;
...@@ -148,7 +148,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -148,7 +148,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
148 148
149 private void applyRule(FlowRule flowRule) { 149 private void applyRule(FlowRule flowRule) {
150 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri())); 150 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
151 - sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowAdd()); 151 + sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory()).buildFlowAdd());
152 } 152 }
153 153
154 154
...@@ -163,7 +163,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -163,7 +163,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
163 163
164 private void removeRule(FlowRule flowRule) { 164 private void removeRule(FlowRule flowRule) {
165 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri())); 165 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
166 - sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel()); 166 + sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory()).buildFlowDel());
167 } 167 }
168 168
169 @Override 169 @Override
...@@ -192,7 +192,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -192,7 +192,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
192 return failed; 192 return failed;
193 } 193 }
194 sws.add(new Dpid(sw.getId())); 194 sws.add(new Dpid(sw.getId()));
195 - FlowModBuilder builder = new FlowModBuilder(flowRule, sw.factory()); 195 + FlowModBuilder builder = FlowModBuilder.builder(flowRule, sw.factory());
196 switch (fbe.getOperator()) { 196 switch (fbe.getOperator()) {
197 case ADD: 197 case ADD:
198 mod = builder.buildFlowAdd(); 198 mod = builder.buildFlowAdd();
......