alshabib

flowrules are pushed: we still have an intermittent hang though

1 package org.onlab.onos.fwd; 1 package org.onlab.onos.fwd;
2 2
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.Set;
6 +
3 import org.apache.felix.scr.annotations.Activate; 7 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 8 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
...@@ -9,6 +13,14 @@ import org.onlab.onos.net.Host; ...@@ -9,6 +13,14 @@ import org.onlab.onos.net.Host;
9 import org.onlab.onos.net.HostId; 13 import org.onlab.onos.net.HostId;
10 import org.onlab.onos.net.Path; 14 import org.onlab.onos.net.Path;
11 import org.onlab.onos.net.PortNumber; 15 import org.onlab.onos.net.PortNumber;
16 +import org.onlab.onos.net.flow.DefaultFlowRule;
17 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
18 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
19 +import org.onlab.onos.net.flow.FlowRule;
20 +import org.onlab.onos.net.flow.FlowRuleService;
21 +import org.onlab.onos.net.flow.TrafficSelector;
22 +import org.onlab.onos.net.flow.TrafficTreatment;
23 +import org.onlab.onos.net.flow.criteria.Criteria;
12 import org.onlab.onos.net.flow.instructions.Instructions; 24 import org.onlab.onos.net.flow.instructions.Instructions;
13 import org.onlab.onos.net.host.HostService; 25 import org.onlab.onos.net.host.HostService;
14 import org.onlab.onos.net.packet.InboundPacket; 26 import org.onlab.onos.net.packet.InboundPacket;
...@@ -16,12 +28,9 @@ import org.onlab.onos.net.packet.PacketContext; ...@@ -16,12 +28,9 @@ import org.onlab.onos.net.packet.PacketContext;
16 import org.onlab.onos.net.packet.PacketProcessor; 28 import org.onlab.onos.net.packet.PacketProcessor;
17 import org.onlab.onos.net.packet.PacketService; 29 import org.onlab.onos.net.packet.PacketService;
18 import org.onlab.onos.net.topology.TopologyService; 30 import org.onlab.onos.net.topology.TopologyService;
31 +import org.onlab.packet.Ethernet;
19 import org.slf4j.Logger; 32 import org.slf4j.Logger;
20 33
21 -import java.util.Set;
22 -
23 -import static org.slf4j.LoggerFactory.getLogger;
24 -
25 /** 34 /**
26 * Sample reactive forwarding application. 35 * Sample reactive forwarding application.
27 */ 36 */
...@@ -39,6 +48,9 @@ public class ReactiveForwarding { ...@@ -39,6 +48,9 @@ public class ReactiveForwarding {
39 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 48 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
40 protected HostService hostService; 49 protected HostService hostService;
41 50
51 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 + protected FlowRuleService flowRuleService;
53 +
42 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 54 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
43 55
44 @Activate 56 @Activate
...@@ -62,6 +74,9 @@ public class ReactiveForwarding { ...@@ -62,6 +74,9 @@ public class ReactiveForwarding {
62 74
63 @Override 75 @Override
64 public void process(PacketContext context) { 76 public void process(PacketContext context) {
77 + if (context.isHandled()) {
78 + return;
79 + }
65 InboundPacket pkt = context.inPacket(); 80 InboundPacket pkt = context.inPacket();
66 HostId id = HostId.hostId(pkt.parsed().getDestinationMAC()); 81 HostId id = HostId.hostId(pkt.parsed().getDestinationMAC());
67 82
...@@ -75,15 +90,16 @@ public class ReactiveForwarding { ...@@ -75,15 +90,16 @@ public class ReactiveForwarding {
75 // Are we on an edge switch that our destination is on? If so, 90 // Are we on an edge switch that our destination is on? If so,
76 // simply forward out to the destination and bail. 91 // simply forward out to the destination and bail.
77 if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) { 92 if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) {
78 - forward(context, dst.location().port()); 93 + installRule(context, dst.location().port());
79 return; 94 return;
80 } 95 }
81 96
82 // Otherwise, get a set of paths that lead from here to the 97 // Otherwise, get a set of paths that lead from here to the
83 // destination edge switch. 98 // destination edge switch.
99 +
84 Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(), 100 Set<Path> paths = topologyService.getPaths(topologyService.currentTopology(),
85 - context.inPacket().receivedFrom().deviceId(), 101 + context.inPacket().receivedFrom().deviceId(),
86 - dst.location().deviceId()); 102 + dst.location().deviceId());
87 if (paths.isEmpty()) { 103 if (paths.isEmpty()) {
88 // If there are no paths, flood and bail. 104 // If there are no paths, flood and bail.
89 flood(context); 105 flood(context);
...@@ -100,7 +116,7 @@ public class ReactiveForwarding { ...@@ -100,7 +116,7 @@ public class ReactiveForwarding {
100 } 116 }
101 117
102 // Otherwise forward and be done with it. 118 // Otherwise forward and be done with it.
103 - forward(context, path.src().port()); 119 + installRule(context, path.src().port());
104 } 120 }
105 } 121 }
106 122
...@@ -118,18 +134,43 @@ public class ReactiveForwarding { ...@@ -118,18 +134,43 @@ public class ReactiveForwarding {
118 // Floods the specified packet. 134 // Floods the specified packet.
119 private void flood(PacketContext context) { 135 private void flood(PacketContext context) {
120 boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(), 136 boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(),
121 - context.inPacket().receivedFrom()); 137 + context.inPacket().receivedFrom());
122 if (canBcast) { 138 if (canBcast) {
123 - forward(context, PortNumber.FLOOD); 139 + packetOutFlood(context);
124 } else { 140 } else {
125 context.block(); 141 context.block();
126 } 142 }
127 } 143 }
128 144
129 - // Forwards the packet to the specified port. 145 + //Floods a packet out
130 - private void forward(PacketContext context, PortNumber portNumber) { 146 + private void packetOutFlood(PacketContext context) {
147 + context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD));
148 + context.send();
149 + }
150 +
151 + // Install a rule forwarding the packet to the specified port.
152 + private void installRule(PacketContext context, PortNumber portNumber) {
153 + // we don't yet support bufferids in the flowservice so packet out and
154 + // then install a flowmod.
131 context.treatmentBuilder().add(Instructions.createOutput(portNumber)); 155 context.treatmentBuilder().add(Instructions.createOutput(portNumber));
132 context.send(); 156 context.send();
157 +
158 +
159 + Ethernet inPkt = context.inPacket().parsed();
160 + TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
161 + builder.add(Criteria.matchEthType(inPkt.getEtherType()))
162 + .add(Criteria.matchEthSrc(inPkt.getSourceMAC()))
163 + .add(Criteria.matchEthDst(inPkt.getDestinationMAC()))
164 + .add(Criteria.matchInPort(context.inPacket().receivedFrom().port()));
165 +
166 + TrafficTreatment.Builder treat = new DefaultTrafficTreatment.Builder();
167 + treat.add(Instructions.createOutput(portNumber));
168 +
169 + FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
170 + builder.build(), treat.build());
171 +
172 + flowRuleService.applyFlowRules(f);
173 +
133 } 174 }
134 175
135 } 176 }
......
1 +package org.onlab.onos.net.flow;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +
5 +public class DefaultFlowRule implements FlowRule {
6 +
7 + private final TrafficSelector selector;
8 + private final TrafficTreatment treatment;
9 + private final DeviceId deviceId;
10 +
11 + public DefaultFlowRule(DeviceId deviceId,
12 + TrafficSelector selector, TrafficTreatment treatment) {
13 + this.treatment = treatment;
14 + this.selector = selector;
15 + this.deviceId = deviceId;
16 + }
17 +
18 + @Override
19 + public int priority() {
20 + return 0;
21 + }
22 +
23 + @Override
24 + public DeviceId deviceId() {
25 + return deviceId;
26 + }
27 +
28 + @Override
29 + public TrafficSelector selector() {
30 + return selector;
31 + }
32 +
33 + @Override
34 + public TrafficTreatment treatment() {
35 + return treatment;
36 + }
37 +
38 +}
1 +package org.onlab.onos.net.flow;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.Collections;
6 +import java.util.LinkedList;
7 +import java.util.List;
8 +
9 +import org.onlab.onos.net.flow.criteria.Criterion;
10 +import org.slf4j.Logger;
11 +
12 +public final class DefaultTrafficSelector implements TrafficSelector {
13 +
14 + private final List<Criterion> selector;
15 +
16 + private DefaultTrafficSelector(List<Criterion> selector) {
17 + this.selector = Collections.unmodifiableList(selector);
18 + }
19 +
20 + @Override
21 + public List<Criterion> criteria() {
22 + return selector;
23 + }
24 +
25 + public static class Builder implements TrafficSelector.Builder {
26 +
27 + private final Logger log = getLogger(getClass());
28 +
29 + private final List<Criterion> selector = new LinkedList<>();
30 +
31 + @Override
32 + public TrafficSelector.Builder add(Criterion criterion) {
33 + selector.add(criterion);
34 + return this;
35 + }
36 +
37 + @Override
38 + public TrafficSelector build() {
39 + return new DefaultTrafficSelector(selector);
40 + }
41 +
42 + }
43 +
44 +}
...@@ -9,12 +9,11 @@ import java.util.List; ...@@ -9,12 +9,11 @@ import java.util.List;
9 import org.onlab.onos.net.flow.instructions.Instruction; 9 import org.onlab.onos.net.flow.instructions.Instruction;
10 import org.slf4j.Logger; 10 import org.slf4j.Logger;
11 11
12 -@SuppressWarnings("rawtypes") 12 +public final class DefaultTrafficTreatment implements TrafficTreatment {
13 -public class DefaultTrafficTreatment implements TrafficTreatment {
14 13
15 private final List<Instruction> instructions; 14 private final List<Instruction> instructions;
16 15
17 - public DefaultTrafficTreatment(List<Instruction> instructions) { 16 + private DefaultTrafficTreatment(List<Instruction> instructions) {
18 this.instructions = Collections.unmodifiableList(instructions); 17 this.instructions = Collections.unmodifiableList(instructions);
19 } 18 }
20 19
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
69 <bundle>mvn:org.onlab.onos/onos-of-provider-link/1.0.0-SNAPSHOT</bundle> 69 <bundle>mvn:org.onlab.onos/onos-of-provider-link/1.0.0-SNAPSHOT</bundle>
70 <bundle>mvn:org.onlab.onos/onos-of-provider-host/1.0.0-SNAPSHOT</bundle> 70 <bundle>mvn:org.onlab.onos/onos-of-provider-host/1.0.0-SNAPSHOT</bundle>
71 <bundle>mvn:org.onlab.onos/onos-of-provider-packet/1.0.0-SNAPSHOT</bundle> 71 <bundle>mvn:org.onlab.onos/onos-of-provider-packet/1.0.0-SNAPSHOT</bundle>
72 + <bundle>mvn:org.onlab.onos/onos-of-provider-flow/1.0.0-SNAPSHOT</bundle>
72 73
73 </feature> 74 </feature>
74 75
......
...@@ -32,7 +32,7 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext ...@@ -32,7 +32,7 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
32 32
33 @Override 33 @Override
34 public void send() { 34 public void send() {
35 - if (blocked() && isBuilt) { 35 + if (block() && isBuilt) {
36 sw.sendMsg(pktout); 36 sw.sendMsg(pktout);
37 } 37 }
38 } 38 }
...@@ -109,8 +109,13 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext ...@@ -109,8 +109,13 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext
109 } 109 }
110 110
111 @Override 111 @Override
112 - public boolean blocked() { 112 + public boolean block() {
113 return free.getAndSet(false); 113 return free.getAndSet(false);
114 } 114 }
115 115
116 + @Override
117 + public boolean isHandled() {
118 + return !free.get();
119 + }
120 +
116 } 121 }
......
...@@ -16,7 +16,13 @@ public interface OpenFlowPacketContext { ...@@ -16,7 +16,13 @@ public interface OpenFlowPacketContext {
16 * Blocks further responses (ie. send() calls) on this 16 * Blocks further responses (ie. send() calls) on this
17 * packet in event. 17 * packet in event.
18 */ 18 */
19 - public boolean blocked(); 19 + public boolean block();
20 +
21 + /**
22 + * Checks whether the packet has been handled.
23 + * @return true if handled, false otherwise.
24 + */
25 + public boolean isHandled();
20 26
21 /** 27 /**
22 * Provided build has been called send the packet 28 * Provided build has been called send the packet
......
...@@ -26,6 +26,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; ...@@ -26,6 +26,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
26 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; 26 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
27 import org.onlab.onos.net.flow.criteria.Criterion; 27 import org.onlab.onos.net.flow.criteria.Criterion;
28 import org.onlab.onos.net.flow.instructions.Instruction; 28 import org.onlab.onos.net.flow.instructions.Instruction;
29 +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
29 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction; 30 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
30 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 31 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
31 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 32 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
...@@ -136,6 +137,9 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -136,6 +137,9 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
136 case L3MODIFICATION: 137 case L3MODIFICATION:
137 acts.add(buildL3Modification(i, factory)); 138 acts.add(buildL3Modification(i, factory));
138 case OUTPUT: 139 case OUTPUT:
140 + OutputInstruction out = (OutputInstruction) i;
141 + acts.add(factory.actions().buildOutput().setPort(
142 + OFPort.of((int) out.port().toLong())).build());
139 break; 143 break;
140 case GROUP: 144 case GROUP:
141 default: 145 default:
...@@ -207,6 +211,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -207,6 +211,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
207 case ETH_TYPE: 211 case ETH_TYPE:
208 EthTypeCriterion ethType = (EthTypeCriterion) c; 212 EthTypeCriterion ethType = (EthTypeCriterion) c;
209 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType())); 213 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
214 + break;
210 case IPV4_DST: 215 case IPV4_DST:
211 ip = (IPCriterion) c; 216 ip = (IPCriterion) c;
212 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt())); 217 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
......
1 package org.onlab.onos.provider.of.host.impl; 1 package org.onlab.onos.provider.of.host.impl;
2 2
3 +import static org.junit.Assert.assertEquals;
4 +import static org.junit.Assert.assertNotNull;
5 +import static org.junit.Assert.assertNull;
6 +
7 +import java.util.Set;
8 +
3 import org.junit.After; 9 import org.junit.After;
4 import org.junit.Before; 10 import org.junit.Before;
5 import org.junit.Test; 11 import org.junit.Test;
...@@ -24,10 +30,6 @@ import org.onlab.packet.VlanId; ...@@ -24,10 +30,6 @@ import org.onlab.packet.VlanId;
24 import org.projectfloodlight.openflow.protocol.OFMessage; 30 import org.projectfloodlight.openflow.protocol.OFMessage;
25 import org.projectfloodlight.openflow.types.OFPort; 31 import org.projectfloodlight.openflow.types.OFPort;
26 32
27 -import java.util.Set;
28 -
29 -import static org.junit.Assert.*;
30 -
31 public class OpenFlowHostProviderTest { 33 public class OpenFlowHostProviderTest {
32 34
33 private static final Integer INPORT = 10; 35 private static final Integer INPORT = 10;
...@@ -40,10 +42,10 @@ public class OpenFlowHostProviderTest { ...@@ -40,10 +42,10 @@ public class OpenFlowHostProviderTest {
40 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff"); 42 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
41 private static final byte[] IP = new byte[]{10, 0, 0, 1}; 43 private static final byte[] IP = new byte[]{10, 0, 0, 1};
42 44
43 - private OpenFlowHostProvider provider = new OpenFlowHostProvider(); 45 + private final OpenFlowHostProvider provider = new OpenFlowHostProvider();
44 - private TestHostRegistry hostService = new TestHostRegistry(); 46 + private final TestHostRegistry hostService = new TestHostRegistry();
45 - private TestController controller = new TestController(); 47 + private final TestController controller = new TestController();
46 - private TestTopologyService topoService = new TestTopologyService(); 48 + private final TestTopologyService topoService = new TestTopologyService();
47 private TestHostProviderService providerService; 49 private TestHostProviderService providerService;
48 50
49 @Before 51 @Before
...@@ -103,8 +105,8 @@ public class OpenFlowHostProviderTest { ...@@ -103,8 +105,8 @@ public class OpenFlowHostProviderTest {
103 } 105 }
104 106
105 private class TestHostProviderService 107 private class TestHostProviderService
106 - extends AbstractProviderService<HostProvider> 108 + extends AbstractProviderService<HostProvider>
107 - implements HostProviderService { 109 + implements HostProviderService {
108 110
109 Dpid added = null; 111 Dpid added = null;
110 Dpid moved = null; 112 Dpid moved = null;
...@@ -150,7 +152,7 @@ public class OpenFlowHostProviderTest { ...@@ -150,7 +152,7 @@ public class OpenFlowHostProviderTest {
150 private class TestTopologyService extends TopologyServiceAdapter { 152 private class TestTopologyService extends TopologyServiceAdapter {
151 @Override 153 @Override
152 public boolean isInfrastructure(Topology topology, 154 public boolean isInfrastructure(Topology topology,
153 - ConnectPoint connectPoint) { 155 + ConnectPoint connectPoint) {
154 //simulate DPID3 as an infrastructure switch 156 //simulate DPID3 as an infrastructure switch
155 if (Dpid.dpid(connectPoint.deviceId().uri()).equals(DPID3)) { 157 if (Dpid.dpid(connectPoint.deviceId().uri()).equals(DPID3)) {
156 return true; 158 return true;
...@@ -168,7 +170,7 @@ public class OpenFlowHostProviderTest { ...@@ -168,7 +170,7 @@ public class OpenFlowHostProviderTest {
168 } 170 }
169 171
170 @Override 172 @Override
171 - public boolean blocked() { 173 + public boolean block() {
172 return false; 174 return false;
173 } 175 }
174 176
...@@ -189,16 +191,16 @@ public class OpenFlowHostProviderTest { ...@@ -189,16 +191,16 @@ public class OpenFlowHostProviderTest {
189 // just things we (and serializers) need 191 // just things we (and serializers) need
190 ARP arp = new ARP(); 192 ARP arp = new ARP();
191 arp.setSenderProtocolAddress(IP) 193 arp.setSenderProtocolAddress(IP)
192 - .setSenderHardwareAddress(MAC.toBytes()) 194 + .setSenderHardwareAddress(MAC.toBytes())
193 - .setTargetHardwareAddress(BCMAC.toBytes()) 195 + .setTargetHardwareAddress(BCMAC.toBytes())
194 - .setTargetProtocolAddress(IP); 196 + .setTargetProtocolAddress(IP);
195 197
196 Ethernet eth = new Ethernet(); 198 Ethernet eth = new Ethernet();
197 eth.setEtherType(Ethernet.TYPE_ARP) 199 eth.setEtherType(Ethernet.TYPE_ARP)
198 - .setVlanID(VLAN.toShort()) 200 + .setVlanID(VLAN.toShort())
199 - .setSourceMACAddress(MAC.toBytes()) 201 + .setSourceMACAddress(MAC.toBytes())
200 - .setDestinationMACAddress(BCMAC.getAddress()) 202 + .setDestinationMACAddress(BCMAC.getAddress())
201 - .setPayload(arp); 203 + .setPayload(arp);
202 204
203 return eth; 205 return eth;
204 } 206 }
...@@ -218,5 +220,10 @@ public class OpenFlowHostProviderTest { ...@@ -218,5 +220,10 @@ public class OpenFlowHostProviderTest {
218 return INPORT; 220 return INPORT;
219 } 221 }
220 222
223 + @Override
224 + public boolean isHandled() {
225 + return false;
226 + }
227 +
221 } 228 }
222 } 229 }
......
...@@ -93,7 +93,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -93,7 +93,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
93 return; 93 return;
94 } 94 }
95 if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) { 95 if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
96 - pktCtx.blocked(); 96 + pktCtx.block();
97 } 97 }
98 98
99 } 99 }
......
...@@ -87,7 +87,7 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr ...@@ -87,7 +87,7 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
87 pktCtx.parsed(), ByteBuffer.wrap(pktCtx.unparsed())); 87 pktCtx.parsed(), ByteBuffer.wrap(pktCtx.unparsed()));
88 88
89 OpenFlowCorePacketContext corePktCtx = 89 OpenFlowCorePacketContext corePktCtx =
90 - new OpenFlowCorePacketContext(0, inPkt, null, false, pktCtx); 90 + new OpenFlowCorePacketContext(0, inPkt, null, pktCtx.isHandled(), pktCtx);
91 providerService.processPacket(corePktCtx); 91 providerService.processPacket(corePktCtx);
92 } 92 }
93 93
......