Dusan Pajin
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
...@@ -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");
201 + }
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");
131 } 208 }
132 - boolean ipv6ForwardingEnabled = isPropertyEnabled(properties, "ipv6Forwarding"); 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");
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;
137 } 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,9 +388,10 @@ public class ReactiveForwarding { ...@@ -213,9 +388,10 @@ 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 =
217 - pkt.receivedFrom().deviceId(), 392 + topologyService.getPaths(topologyService.currentTopology(),
218 - dst.location().deviceId()); 393 + pkt.receivedFrom().deviceId(),
394 + dst.location().deviceId());
219 if (paths.isEmpty()) { 395 if (paths.isEmpty()) {
220 // If there are no paths, flood and bail. 396 // If there are no paths, flood and bail.
221 flood(context); 397 flood(context);
...@@ -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 + }
292 513
293 - TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); 514 + if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_TCP) {
294 - treat.setOutput(portNumber); 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 + }
295 530
296 - FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), 531 + //
297 - builder.build(), treat.build(), PRIORITY, appId, TIMEOUT, false); 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 + }
298 551
299 - flowRuleService.applyFlowRules(f); 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 + }
569 + TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
570 + treat.setOutput(portNumber);
571 +
572 + FlowRule f =
573 + new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
574 + builder.build(), treat.build(), flowPriority,
575 + appId, flowTimeout, false);
576 +
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 +
......