Committed by
Ray Milkey
Additional configuration parameters in onos-app-fwd
Additional configuration parameters that can be configured in the configuration file (org.onosproject.fwd.ReactiveForwarding.cfg), that determine application behavior: - packetOutOfppTable - application will use OFPP_TABLE port in PacketOut message, sending packet back to the OpenFlow pipeline, instead of using switch port - flowTimeout - configuring reactively installed flow timeout - flowPriority - configuring reactively installed flow priority - matchDstMacOnly - reactively installed flows will match only destination MAC address - behavior as legacy L2 switches. This options overrides all other options below. - matchVlanId - reactively installed flows will match default condition with additionally with VLAN ID field - matchIpv4Address - reactively installed flows will match default conditions, plus IPv4 address and Protocol field - matchIpv4Dscp - reactively installed flows will match default condition, IPv4 + with IPv4 DSCP and ECN fields (need matchIPv4Address enabled) - matchIpv6Address - reactively installed flows will match default condition with IPv6 address and NextHeader field - matchIpv6FlowLabel - reactively installed flows will match default condition with IPv6 address and IPv6 Flow Label (need matchIPv6Address enabled) - matchTcpUdpPorts - reactively installed flows will match default condition with IPv4 or IPv6 address and TCP/UDP ports (need matchIPv4Address or matchIPv6Address enabled) - matchIcmpFields - reactively installed flows will match default condition with IPv4 or IPv6 address and ICMP type and code fields (need matchIPv4Address or matchIPv6Address enabled) Change-Id: Ieef67a1a12f6341d4de3b07e1226affec66d361a
Showing
2 changed files
with
368 additions
and
18 deletions
... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -19,6 +19,7 @@ import static org.slf4j.LoggerFactory.getLogger; |
19 | 19 | ||
20 | import java.util.Dictionary; | 20 | import java.util.Dictionary; |
21 | import java.util.Set; | 21 | import java.util.Set; |
22 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
22 | 23 | ||
23 | import org.apache.felix.scr.annotations.Activate; | 24 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 25 | import org.apache.felix.scr.annotations.Component; |
... | @@ -28,6 +29,15 @@ import org.apache.felix.scr.annotations.Property; | ... | @@ -28,6 +29,15 @@ import org.apache.felix.scr.annotations.Property; |
28 | import org.apache.felix.scr.annotations.Reference; | 29 | import org.apache.felix.scr.annotations.Reference; |
29 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 30 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
30 | import org.onlab.packet.Ethernet; | 31 | import org.onlab.packet.Ethernet; |
32 | +import org.onlab.packet.IPv4; | ||
33 | +import org.onlab.packet.IPv6; | ||
34 | +import org.onlab.packet.TCP; | ||
35 | +import org.onlab.packet.UDP; | ||
36 | +import org.onlab.packet.ICMP; | ||
37 | +import org.onlab.packet.ICMP6; | ||
38 | +import org.onlab.packet.Ip4Prefix; | ||
39 | +import org.onlab.packet.Ip6Prefix; | ||
40 | +import org.onlab.packet.VlanId; | ||
31 | import org.onosproject.core.ApplicationId; | 41 | import org.onosproject.core.ApplicationId; |
32 | import org.onosproject.core.CoreService; | 42 | import org.onosproject.core.CoreService; |
33 | import org.onosproject.net.Host; | 43 | import org.onosproject.net.Host; |
... | @@ -57,8 +67,8 @@ import org.slf4j.Logger; | ... | @@ -57,8 +67,8 @@ import org.slf4j.Logger; |
57 | @Component(immediate = true) | 67 | @Component(immediate = true) |
58 | public class ReactiveForwarding { | 68 | public class ReactiveForwarding { |
59 | 69 | ||
60 | - private static final int TIMEOUT = 10; | 70 | + private static final int DEFAULT_TIMEOUT = 10; |
61 | - private static final int PRIORITY = 10; | 71 | + private static final int DEFAULT_PRIORITY = 10; |
62 | 72 | ||
63 | private final Logger log = getLogger(getClass()); | 73 | private final Logger log = getLogger(getClass()); |
64 | 74 | ||
... | @@ -85,10 +95,59 @@ public class ReactiveForwarding { | ... | @@ -85,10 +95,59 @@ public class ReactiveForwarding { |
85 | label = "Enable packet-out only forwarding; default is false") | 95 | label = "Enable packet-out only forwarding; default is false") |
86 | private boolean packetOutOnly = false; | 96 | private boolean packetOutOnly = false; |
87 | 97 | ||
98 | + @Property(name = "packetOutOfppTable", boolValue = false, | ||
99 | + label = "Enable first packet forwarding using OFPP_TABLE port " + | ||
100 | + "instead of PacketOut with actual port; default is false") | ||
101 | + private boolean packetOutOfppTable = false; | ||
102 | + | ||
103 | + @Property(name = "flowTimeout", intValue = DEFAULT_TIMEOUT, | ||
104 | + label = "Configure Flow Timeout for installed flow rules; " + | ||
105 | + "default is 10 sec") | ||
106 | + private int flowTimeout = DEFAULT_TIMEOUT; | ||
107 | + | ||
108 | + @Property(name = "flowPriority", intValue = DEFAULT_PRIORITY, | ||
109 | + label = "Configure Flow Priority for installed flow rules; " + | ||
110 | + "default is 10") | ||
111 | + private int flowPriority = DEFAULT_PRIORITY; | ||
112 | + | ||
88 | @Property(name = "ipv6Forwarding", boolValue = false, | 113 | @Property(name = "ipv6Forwarding", boolValue = false, |
89 | label = "Enable IPv6 forwarding; default is false") | 114 | label = "Enable IPv6 forwarding; default is false") |
90 | private boolean ipv6Forwarding = false; | 115 | private boolean ipv6Forwarding = false; |
91 | 116 | ||
117 | + @Property(name = "matchDstMacOnly", boolValue = false, | ||
118 | + label = "Enable matching Dst Mac Only; default is false") | ||
119 | + private boolean matchDstMacOnly = false; | ||
120 | + | ||
121 | + @Property(name = "matchVlanId", boolValue = false, | ||
122 | + label = "Enable matching Vlan ID; default is false") | ||
123 | + private boolean matchVlanId = false; | ||
124 | + | ||
125 | + @Property(name = "matchIpv4Address", boolValue = false, | ||
126 | + label = "Enable matching IPv4 Addresses; default is false") | ||
127 | + private boolean matchIpv4Address = false; | ||
128 | + | ||
129 | + @Property(name = "matchIpv4Dscp", boolValue = false, | ||
130 | + label = "Enable matching IPv4 DSCP and ECN; default is false") | ||
131 | + private boolean matchIpv4Dscp = false; | ||
132 | + | ||
133 | + @Property(name = "matchIpv6Address", boolValue = false, | ||
134 | + label = "Enable matching IPv6 Addresses; default is false") | ||
135 | + private boolean matchIpv6Address = false; | ||
136 | + | ||
137 | + @Property(name = "matchIpv6FlowLabel", boolValue = false, | ||
138 | + label = "Enable matching IPv6 FlowLabel; default is false") | ||
139 | + private boolean matchIpv6FlowLabel = false; | ||
140 | + | ||
141 | + @Property(name = "matchTcpUdpPorts", boolValue = false, | ||
142 | + label = "Enable matching TCP/UDP ports; default is false") | ||
143 | + private boolean matchTcpUdpPorts = false; | ||
144 | + | ||
145 | + @Property(name = "matchIcmpFields", boolValue = false, | ||
146 | + label = "Enable matching ICMPv4 and ICMPv6 fields; " + | ||
147 | + "default is false") | ||
148 | + private boolean matchIcmpFields = false; | ||
149 | + | ||
150 | + | ||
92 | @Activate | 151 | @Activate |
93 | public void activate(ComponentContext context) { | 152 | public void activate(ComponentContext context) { |
94 | appId = coreService.registerApplication("org.onosproject.fwd"); | 153 | appId = coreService.registerApplication("org.onosproject.fwd"); |
... | @@ -98,7 +157,17 @@ public class ReactiveForwarding { | ... | @@ -98,7 +157,17 @@ public class ReactiveForwarding { |
98 | 157 | ||
99 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 158 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
100 | selector.matchEthType(Ethernet.TYPE_IPV4); | 159 | selector.matchEthType(Ethernet.TYPE_IPV4); |
101 | - packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId); | 160 | + packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, |
161 | + appId); | ||
162 | + selector.matchEthType(Ethernet.TYPE_ARP); | ||
163 | + packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, | ||
164 | + appId); | ||
165 | + | ||
166 | + if (ipv6Forwarding) { | ||
167 | + selector.matchEthType(Ethernet.TYPE_IPV6); | ||
168 | + packetService.requestPackets(selector.build(), | ||
169 | + PacketPriority.REACTIVE, appId); | ||
170 | + } | ||
102 | 171 | ||
103 | log.info("Started with Application ID {}", appId.id()); | 172 | log.info("Started with Application ID {}", appId.id()); |
104 | } | 173 | } |
... | @@ -123,18 +192,123 @@ public class ReactiveForwarding { | ... | @@ -123,18 +192,123 @@ public class ReactiveForwarding { |
123 | */ | 192 | */ |
124 | private void readComponentConfiguration(ComponentContext context) { | 193 | private void readComponentConfiguration(ComponentContext context) { |
125 | Dictionary<?, ?> properties = context.getProperties(); | 194 | Dictionary<?, ?> properties = context.getProperties(); |
126 | - boolean packetOutOnlyEnabled = isPropertyEnabled(properties, "packetOutOnly"); | 195 | + boolean packetOutOnlyEnabled = |
196 | + isPropertyEnabled(properties, "packetOutOnly"); | ||
127 | if (packetOutOnly != packetOutOnlyEnabled) { | 197 | if (packetOutOnly != packetOutOnlyEnabled) { |
128 | packetOutOnly = packetOutOnlyEnabled; | 198 | packetOutOnly = packetOutOnlyEnabled; |
129 | log.info("Configured. Packet-out only forwarding is {}", | 199 | log.info("Configured. Packet-out only forwarding is {}", |
130 | packetOutOnly ? "enabled" : "disabled"); | 200 | packetOutOnly ? "enabled" : "disabled"); |
131 | } | 201 | } |
132 | - boolean ipv6ForwardingEnabled = isPropertyEnabled(properties, "ipv6Forwarding"); | 202 | + boolean packetOutOfppTableEnabled = |
203 | + isPropertyEnabled(properties, "packetOutOfppTable"); | ||
204 | + if (packetOutOfppTable != packetOutOfppTableEnabled) { | ||
205 | + packetOutOfppTable = packetOutOfppTableEnabled; | ||
206 | + log.info("Configured. Forwarding using OFPP_TABLE port is {}", | ||
207 | + packetOutOfppTable ? "enabled" : "disabled"); | ||
208 | + } | ||
209 | + boolean ipv6ForwardingEnabled = | ||
210 | + isPropertyEnabled(properties, "ipv6Forwarding"); | ||
133 | if (ipv6Forwarding != ipv6ForwardingEnabled) { | 211 | if (ipv6Forwarding != ipv6ForwardingEnabled) { |
134 | ipv6Forwarding = ipv6ForwardingEnabled; | 212 | ipv6Forwarding = ipv6ForwardingEnabled; |
135 | log.info("Configured. IPv6 forwarding is {}", | 213 | log.info("Configured. IPv6 forwarding is {}", |
136 | ipv6Forwarding ? "enabled" : "disabled"); | 214 | ipv6Forwarding ? "enabled" : "disabled"); |
137 | } | 215 | } |
216 | + boolean matchDstMacOnlyEnabled = | ||
217 | + isPropertyEnabled(properties, "matchDstMacOnly"); | ||
218 | + if (matchDstMacOnly != matchDstMacOnlyEnabled) { | ||
219 | + matchDstMacOnly = matchDstMacOnlyEnabled; | ||
220 | + log.info("Configured. Match Dst MAC Only is {}", | ||
221 | + matchDstMacOnly ? "enabled" : "disabled"); | ||
222 | + } | ||
223 | + boolean matchVlanIdEnabled = | ||
224 | + isPropertyEnabled(properties, "matchVlanId"); | ||
225 | + if (matchVlanId != matchVlanIdEnabled) { | ||
226 | + matchVlanId = matchVlanIdEnabled; | ||
227 | + log.info("Configured. Matching Vlan ID is {}", | ||
228 | + matchVlanId ? "enabled" : "disabled"); | ||
229 | + } | ||
230 | + boolean matchIpv4AddressEnabled = | ||
231 | + isPropertyEnabled(properties, "matchIpv4Address"); | ||
232 | + if (matchIpv4Address != matchIpv4AddressEnabled) { | ||
233 | + matchIpv4Address = matchIpv4AddressEnabled; | ||
234 | + log.info("Configured. Matching IPv4 Addresses is {}", | ||
235 | + matchIpv4Address ? "enabled" : "disabled"); | ||
236 | + } | ||
237 | + boolean matchIpv4DscpEnabled = | ||
238 | + isPropertyEnabled(properties, "matchIpv4Dscp"); | ||
239 | + if (matchIpv4Dscp != matchIpv4DscpEnabled) { | ||
240 | + matchIpv4Dscp = matchIpv4DscpEnabled; | ||
241 | + log.info("Configured. Matching IPv4 DSCP and ECN is {}", | ||
242 | + matchIpv4Dscp ? "enabled" : "disabled"); | ||
243 | + } | ||
244 | + boolean matchIpv6AddressEnabled = | ||
245 | + isPropertyEnabled(properties, "matchIpv6Address"); | ||
246 | + if (matchIpv6Address != matchIpv6AddressEnabled) { | ||
247 | + matchIpv6Address = matchIpv6AddressEnabled; | ||
248 | + log.info("Configured. Matching IPv6 Addresses is {}", | ||
249 | + matchIpv6Address ? "enabled" : "disabled"); | ||
250 | + } | ||
251 | + boolean matchIpv6FlowLabelEnabled = | ||
252 | + isPropertyEnabled(properties, "matchIpv6FlowLabel"); | ||
253 | + if (matchIpv6FlowLabel != matchIpv6FlowLabelEnabled) { | ||
254 | + matchIpv6FlowLabel = matchIpv6FlowLabelEnabled; | ||
255 | + log.info("Configured. Matching IPv6 FlowLabel is {}", | ||
256 | + matchIpv6FlowLabel ? "enabled" : "disabled"); | ||
257 | + } | ||
258 | + boolean matchTcpUdpPortsEnabled = | ||
259 | + isPropertyEnabled(properties, "matchTcpUdpPorts"); | ||
260 | + if (matchTcpUdpPorts != matchTcpUdpPortsEnabled) { | ||
261 | + matchTcpUdpPorts = matchTcpUdpPortsEnabled; | ||
262 | + log.info("Configured. Matching TCP/UDP fields is {}", | ||
263 | + matchTcpUdpPorts ? "enabled" : "disabled"); | ||
264 | + } | ||
265 | + boolean matchIcmpFieldsEnabled = | ||
266 | + isPropertyEnabled(properties, "matchIcmpFields"); | ||
267 | + if (matchIcmpFields != matchIcmpFieldsEnabled) { | ||
268 | + matchIcmpFields = matchIcmpFieldsEnabled; | ||
269 | + log.info("Configured. Matching ICMP (v4 and v6) fields is {}", | ||
270 | + matchIcmpFields ? "enabled" : "disabled"); | ||
271 | + } | ||
272 | + Integer flowTimeoutConfigured = | ||
273 | + getIntegerProperty(properties, "flowTimeout"); | ||
274 | + if (flowTimeoutConfigured == null) { | ||
275 | + log.info("Flow Timeout is not configured, default value is {}", | ||
276 | + flowTimeout); | ||
277 | + } else { | ||
278 | + flowTimeout = flowTimeoutConfigured; | ||
279 | + log.info("Configured. Flow Timeout is configured to {}", | ||
280 | + flowTimeout, " seconds"); | ||
281 | + } | ||
282 | + Integer flowPriorityConfigured = | ||
283 | + getIntegerProperty(properties, "flowPriority"); | ||
284 | + if (flowPriorityConfigured == null) { | ||
285 | + log.info("Flow Priority is not configured, default value is {}", | ||
286 | + flowPriority); | ||
287 | + } else { | ||
288 | + flowPriority = flowPriorityConfigured; | ||
289 | + log.info("Configured. Flow Priority is configured to {}", | ||
290 | + flowPriority); | ||
291 | + } | ||
292 | + } | ||
293 | + | ||
294 | + /** | ||
295 | + * Get Integer property from the propertyName | ||
296 | + * Return null if propertyName is not found. | ||
297 | + * | ||
298 | + * @param properties properties to be looked up | ||
299 | + * @param propertyName the name of the property to look up | ||
300 | + * @return value when the propertyName is defined or return null | ||
301 | + */ | ||
302 | + private static Integer getIntegerProperty(Dictionary<?, ?> properties, | ||
303 | + String propertyName) { | ||
304 | + Integer value = null; | ||
305 | + try { | ||
306 | + String s = (String) properties.get(propertyName); | ||
307 | + value = isNullOrEmpty(s) ? value : Integer.parseInt(s.trim()); | ||
308 | + } catch (NumberFormatException e) { | ||
309 | + value = null; | ||
310 | + } | ||
311 | + return value; | ||
138 | } | 312 | } |
139 | 313 | ||
140 | /** | 314 | /** |
... | @@ -144,7 +318,8 @@ public class ReactiveForwarding { | ... | @@ -144,7 +318,8 @@ public class ReactiveForwarding { |
144 | * @param propertyName the name of the property to look up | 318 | * @param propertyName the name of the property to look up |
145 | * @return true when the propertyName is defined and set to true | 319 | * @return true when the propertyName is defined and set to true |
146 | */ | 320 | */ |
147 | - private static boolean isPropertyEnabled(Dictionary<?, ?> properties, String propertyName) { | 321 | + private static boolean isPropertyEnabled(Dictionary<?, ?> properties, |
322 | + String propertyName) { | ||
148 | boolean enabled = false; | 323 | boolean enabled = false; |
149 | try { | 324 | try { |
150 | String flag = (String) properties.get(propertyName); | 325 | String flag = (String) properties.get(propertyName); |
... | @@ -213,7 +388,8 @@ public class ReactiveForwarding { | ... | @@ -213,7 +388,8 @@ public class ReactiveForwarding { |
213 | 388 | ||
214 | // Otherwise, get a set of paths that lead from here to the | 389 | // Otherwise, get a set of paths that lead from here to the |
215 | // destination edge switch. | 390 | // destination edge switch. |
216 | - Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(), | 391 | + Set<Path> paths = |
392 | + topologyService.getPaths(topologyService.currentTopology(), | ||
217 | pkt.receivedFrom().deviceId(), | 393 | pkt.receivedFrom().deviceId(), |
218 | dst.location().deviceId()); | 394 | dst.location().deviceId()); |
219 | if (paths.isEmpty()) { | 395 | if (paths.isEmpty()) { |
... | @@ -279,27 +455,137 @@ public class ReactiveForwarding { | ... | @@ -279,27 +455,137 @@ public class ReactiveForwarding { |
279 | 455 | ||
280 | // Install a rule forwarding the packet to the specified port. | 456 | // Install a rule forwarding the packet to the specified port. |
281 | private void installRule(PacketContext context, PortNumber portNumber) { | 457 | private void installRule(PacketContext context, PortNumber portNumber) { |
282 | - // We don't yet support bufferids in the flowservice so packet out first. | 458 | + // |
283 | - packetOut(context, portNumber); | 459 | + // We don't support (yet) buffer IDs in the Flow Service so |
284 | - if (!packetOutOnly) { | 460 | + // packet out first. |
285 | - // Install the flow rule to handle this type of message from now on. | 461 | + // |
286 | Ethernet inPkt = context.inPacket().parsed(); | 462 | Ethernet inPkt = context.inPacket().parsed(); |
287 | TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); | 463 | TrafficSelector.Builder builder = DefaultTrafficSelector.builder(); |
288 | - builder.matchEthType(inPkt.getEtherType()) | 464 | + |
465 | + // If PacketOutOnly or ARP packet than forward directly to output port | ||
466 | + if (packetOutOnly || inPkt.getEtherType() == Ethernet.TYPE_ARP) { | ||
467 | + packetOut(context, portNumber); | ||
468 | + return; | ||
469 | + } | ||
470 | + | ||
471 | + // | ||
472 | + // If matchDstMacOnly | ||
473 | + // Create flows matching dstMac only | ||
474 | + // Else | ||
475 | + // Create flows with default matching and include configured fields | ||
476 | + // | ||
477 | + if (matchDstMacOnly) { | ||
478 | + builder.matchEthDst(inPkt.getDestinationMAC()); | ||
479 | + } else { | ||
480 | + builder.matchInPort(context.inPacket().receivedFrom().port()) | ||
289 | .matchEthSrc(inPkt.getSourceMAC()) | 481 | .matchEthSrc(inPkt.getSourceMAC()) |
290 | .matchEthDst(inPkt.getDestinationMAC()) | 482 | .matchEthDst(inPkt.getDestinationMAC()) |
291 | - .matchInPort(context.inPacket().receivedFrom().port()); | 483 | + .matchEthType(inPkt.getEtherType()); |
484 | + | ||
485 | + // If configured Match Vlan ID | ||
486 | + if (matchVlanId && inPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) { | ||
487 | + builder.matchVlanId(VlanId.vlanId(inPkt.getVlanID())); | ||
488 | + } | ||
489 | + | ||
490 | + // | ||
491 | + // If configured and EtherType is IPv4 - Match IPv4 and | ||
492 | + // TCP/UDP/ICMP fields | ||
493 | + // | ||
494 | + if (matchIpv4Address && inPkt.getEtherType() == Ethernet.TYPE_IPV4) { | ||
495 | + IPv4 ipv4Packet = (IPv4) inPkt.getPayload(); | ||
496 | + byte ipv4Protocol = ipv4Packet.getProtocol(); | ||
497 | + Ip4Prefix matchIp4SrcPrefix = | ||
498 | + Ip4Prefix.valueOf(ipv4Packet.getSourceAddress(), | ||
499 | + Ip4Prefix.MAX_MASK_LENGTH); | ||
500 | + Ip4Prefix matchIp4DstPrefix = | ||
501 | + Ip4Prefix.valueOf(ipv4Packet.getDestinationAddress(), | ||
502 | + Ip4Prefix.MAX_MASK_LENGTH); | ||
503 | + builder.matchIPSrc(matchIp4SrcPrefix) | ||
504 | + .matchIPDst(matchIp4DstPrefix) | ||
505 | + .matchIPProtocol(ipv4Protocol); | ||
506 | + | ||
507 | + if (matchIpv4Dscp) { | ||
508 | + int dscp = ipv4Packet.getDiffServ() >>> 2; | ||
509 | + int ecn = ipv4Packet.getDiffServ() % 4; | ||
510 | + builder.matchIPDscp((byte) (dscp)) | ||
511 | + .matchIPEcn((byte) (ecn)); | ||
512 | + } | ||
513 | + | ||
514 | + if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_TCP) { | ||
515 | + TCP tcpPacket = (TCP) ipv4Packet.getPayload(); | ||
516 | + builder.matchTcpSrc(tcpPacket.getSourcePort()) | ||
517 | + .matchTcpDst(tcpPacket.getDestinationPort()); | ||
518 | + } | ||
519 | + if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_UDP) { | ||
520 | + UDP udpPacket = (UDP) ipv4Packet.getPayload(); | ||
521 | + builder.matchUdpSrc(udpPacket.getSourcePort()) | ||
522 | + .matchUdpDst(udpPacket.getDestinationPort()); | ||
523 | + } | ||
524 | + if (matchIcmpFields && ipv4Protocol == IPv4.PROTOCOL_ICMP) { | ||
525 | + ICMP icmpPacket = (ICMP) ipv4Packet.getPayload(); | ||
526 | + builder.matchIcmpType(icmpPacket.getIcmpType()) | ||
527 | + .matchIcmpCode(icmpPacket.getIcmpCode()); | ||
528 | + } | ||
529 | + } | ||
530 | + | ||
531 | + // | ||
532 | + // If configured and EtherType is IPv6 - Match IPv6 and | ||
533 | + // TCP/UDP/ICMP fields | ||
534 | + // | ||
535 | + if (matchIpv6Address && inPkt.getEtherType() == Ethernet.TYPE_IPV6) { | ||
536 | + IPv6 ipv6Packet = (IPv6) inPkt.getPayload(); | ||
537 | + byte ipv6NextHeader = ipv6Packet.getNextHeader(); | ||
538 | + Ip6Prefix matchIp6SrcPrefix = | ||
539 | + Ip6Prefix.valueOf(ipv6Packet.getSourceAddress(), | ||
540 | + Ip6Prefix.MAX_MASK_LENGTH); | ||
541 | + Ip6Prefix matchIp6DstPrefix = | ||
542 | + Ip6Prefix.valueOf(ipv6Packet.getDestinationAddress(), | ||
543 | + Ip6Prefix.MAX_MASK_LENGTH); | ||
544 | + builder.matchIPv6Src(matchIp6SrcPrefix) | ||
545 | + .matchIPv6Dst(matchIp6DstPrefix) | ||
546 | + .matchIPProtocol(ipv6NextHeader); | ||
547 | + | ||
548 | + if (matchIpv6FlowLabel) { | ||
549 | + builder.matchIPv6FlowLabel(ipv6Packet.getFlowLabel()); | ||
550 | + } | ||
292 | 551 | ||
552 | + if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_TCP) { | ||
553 | + TCP tcpPacket = (TCP) ipv6Packet.getPayload(); | ||
554 | + builder.matchTcpSrc(tcpPacket.getSourcePort()) | ||
555 | + .matchTcpDst(tcpPacket.getDestinationPort()); | ||
556 | + } | ||
557 | + if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_UDP) { | ||
558 | + UDP udpPacket = (UDP) ipv6Packet.getPayload(); | ||
559 | + builder.matchUdpSrc(udpPacket.getSourcePort()) | ||
560 | + .matchUdpDst(udpPacket.getDestinationPort()); | ||
561 | + } | ||
562 | + if (matchIcmpFields && ipv6NextHeader == IPv6.PROTOCOL_ICMP6) { | ||
563 | + ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload(); | ||
564 | + builder.matchIcmpv6Type(icmp6Packet.getIcmpType()) | ||
565 | + .matchIcmpv6Code(icmp6Packet.getIcmpCode()); | ||
566 | + } | ||
567 | + } | ||
568 | + } | ||
293 | TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | 569 | TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); |
294 | treat.setOutput(portNumber); | 570 | treat.setOutput(portNumber); |
295 | 571 | ||
296 | - FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), | 572 | + FlowRule f = |
297 | - builder.build(), treat.build(), PRIORITY, appId, TIMEOUT, false); | 573 | + new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), |
574 | + builder.build(), treat.build(), flowPriority, | ||
575 | + appId, flowTimeout, false); | ||
298 | 576 | ||
299 | flowRuleService.applyFlowRules(f); | 577 | flowRuleService.applyFlowRules(f); |
578 | + | ||
579 | + // | ||
580 | + // If packetOutOfppTable | ||
581 | + // Send packet back to the OpenFlow pipeline to match installed flow | ||
582 | + // Else | ||
583 | + // Send packet direction on the appropriate port | ||
584 | + // | ||
585 | + if (packetOutOfppTable) { | ||
586 | + packetOut(context, PortNumber.TABLE); | ||
587 | + } else { | ||
588 | + packetOut(context, portNumber); | ||
300 | } | 589 | } |
301 | } | 590 | } |
302 | - | ||
303 | } | 591 | } |
304 | - | ||
305 | - | ... | ... |
1 | # | 1 | # |
2 | # Sample configuration for onos-app-fwd. | 2 | # Sample configuration for onos-app-fwd. |
3 | # This configuration file would be placed at: $(KARAF_ROOT)/etc. | 3 | # This configuration file would be placed at: $(KARAF_ROOT)/etc. |
4 | + | ||
5 | +# | ||
6 | +# Reactive flows default matching is InPort, Src MAC, Dst MAC and EtherType fields | ||
4 | # | 7 | # |
5 | 8 | ||
6 | # | 9 | # |
... | @@ -10,6 +13,67 @@ | ... | @@ -10,6 +13,67 @@ |
10 | # packetOutOnly = true | 13 | # packetOutOnly = true |
11 | 14 | ||
12 | # | 15 | # |
16 | +# Enable forwarding of the first packet by using OFPP_TABLE port in the | ||
17 | +# PacketOut message instead of sending it directly to the switch port | ||
18 | +# | ||
19 | +# packetOutOfppTable = true | ||
20 | + | ||
21 | +# | ||
22 | +# Timeout of reactively installed flows (in seconds). | ||
23 | +# Default is 10 sec | ||
24 | +# | ||
25 | +# flowTimeout = 10 | ||
26 | + | ||
27 | +# | ||
28 | +# Priority of reactively installed flows | ||
29 | +# | ||
30 | +# flowPriority = 10 | ||
31 | + | ||
32 | +# | ||
13 | # Enable IPv6 forwarding. | 33 | # Enable IPv6 forwarding. |
14 | # | 34 | # |
15 | # ipv6Forwarding = true | 35 | # ipv6Forwarding = true |
36 | + | ||
37 | +# | ||
38 | +# Flows matching destination MAC only - as legacy L2 switches | ||
39 | +# - This option overrides all other options below | ||
40 | +# | ||
41 | +# matchDstMacOnly = true | ||
42 | + | ||
43 | +# | ||
44 | +# Matching of VLAN ID in Ethernet header | ||
45 | +# | ||
46 | +# matchVlanId = true | ||
47 | + | ||
48 | +# | ||
49 | +# Matching of IPv4 addresses and Protocol field | ||
50 | +# - must be enabled to match IPv4 DSCP, TCP/UDP ports and ICMP type/code | ||
51 | +# | ||
52 | +# matchIpv4Address = true | ||
53 | + | ||
54 | +# | ||
55 | +# Matching of IPv4 DSCP and ECN fields | ||
56 | +# | ||
57 | +# matchIpv4Dscp = true | ||
58 | + | ||
59 | +# | ||
60 | +# Matching of IPv6 addresses and Next-Header field | ||
61 | +# - must be enabled to match IPv6 Flow Label, TCP/UDP ports and ICMP type/code | ||
62 | +# | ||
63 | +# matchIpv6Address = true | ||
64 | + | ||
65 | +# | ||
66 | +# Matching of IPv6 Flow Label | ||
67 | +# | ||
68 | +# matchIpv6FlowLabel = true | ||
69 | + | ||
70 | +# | ||
71 | +# Matching of TCP/UDP ports for IPv4 and IPv6 | ||
72 | +# | ||
73 | +# matchTcpUdpPorts = true | ||
74 | + | ||
75 | +# | ||
76 | +# Matching of ICMP Type and Code fields for IPv4 and IPv6 | ||
77 | +# | ||
78 | +# matchIcmpFields = true | ||
79 | + | ... | ... |
-
Please register or login to post a comment