avoid other OF listeners overwriting the priority of another listener
Showing
9 changed files
with
76 additions
and
47 deletions
... | @@ -13,12 +13,13 @@ public final class PortNumber { | ... | @@ -13,12 +13,13 @@ public final class PortNumber { |
13 | 13 | ||
14 | private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1; | 14 | private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1; |
15 | 15 | ||
16 | - public static final PortNumber FLOOD = new PortNumber(-1); | 16 | + |
17 | - public static final PortNumber IN_PORT = new PortNumber(-2); | 17 | + public static final PortNumber IN_PORT = new PortNumber(-8); |
18 | - public static final PortNumber TABLE = new PortNumber(-3); | 18 | + public static final PortNumber TABLE = new PortNumber(-7); |
19 | - public static final PortNumber NORMAL = new PortNumber(-4); | 19 | + public static final PortNumber NORMAL = new PortNumber(-6); |
20 | + public static final PortNumber FLOOD = new PortNumber(-5); | ||
20 | public static final PortNumber ALL = new PortNumber(-4); | 21 | public static final PortNumber ALL = new PortNumber(-4); |
21 | - public static final PortNumber LOCAL = new PortNumber(-5); | 22 | + public static final PortNumber LOCAL = new PortNumber(-2); |
22 | 23 | ||
23 | private final long number; | 24 | private final long number; |
24 | 25 | ... | ... |
1 | package org.onlab.onos.net.packet; | 1 | package org.onlab.onos.net.packet; |
2 | 2 | ||
3 | +import java.util.concurrent.atomic.AtomicBoolean; | ||
4 | + | ||
3 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; | 5 | import org.onlab.onos.net.flow.DefaultTrafficTreatment; |
4 | import org.onlab.onos.net.flow.TrafficTreatment; | 6 | import org.onlab.onos.net.flow.TrafficTreatment; |
5 | import org.onlab.onos.net.flow.TrafficTreatment.Builder; | 7 | import org.onlab.onos.net.flow.TrafficTreatment.Builder; |
... | @@ -12,7 +14,7 @@ public abstract class DefaultPacketContext implements PacketContext { | ... | @@ -12,7 +14,7 @@ public abstract class DefaultPacketContext implements PacketContext { |
12 | private final OutboundPacket outPkt; | 14 | private final OutboundPacket outPkt; |
13 | private final TrafficTreatment.Builder builder; | 15 | private final TrafficTreatment.Builder builder; |
14 | 16 | ||
15 | - private boolean block = false; | 17 | + private final AtomicBoolean block; |
16 | 18 | ||
17 | 19 | ||
18 | protected DefaultPacketContext(long time, InboundPacket inPkt, | 20 | protected DefaultPacketContext(long time, InboundPacket inPkt, |
... | @@ -21,7 +23,7 @@ public abstract class DefaultPacketContext implements PacketContext { | ... | @@ -21,7 +23,7 @@ public abstract class DefaultPacketContext implements PacketContext { |
21 | this.time = time; | 23 | this.time = time; |
22 | this.inPkt = inPkt; | 24 | this.inPkt = inPkt; |
23 | this.outPkt = outPkt; | 25 | this.outPkt = outPkt; |
24 | - this.block = block; | 26 | + this.block = new AtomicBoolean(block); |
25 | this.builder = new DefaultTrafficTreatment.Builder(); | 27 | this.builder = new DefaultTrafficTreatment.Builder(); |
26 | } | 28 | } |
27 | 29 | ||
... | @@ -49,13 +51,12 @@ public abstract class DefaultPacketContext implements PacketContext { | ... | @@ -49,13 +51,12 @@ public abstract class DefaultPacketContext implements PacketContext { |
49 | public abstract void send(); | 51 | public abstract void send(); |
50 | 52 | ||
51 | @Override | 53 | @Override |
52 | - public void block() { | 54 | + public boolean blocked() { |
53 | - this.block = true; | 55 | + return this.block.getAndSet(true); |
54 | } | 56 | } |
55 | 57 | ||
56 | @Override | 58 | @Override |
57 | public boolean isHandled() { | 59 | public boolean isHandled() { |
58 | - return this.block; | 60 | + return this.block.get(); |
59 | } | 61 | } |
60 | - | ||
61 | } | 62 | } | ... | ... |
... | @@ -43,14 +43,13 @@ public interface PacketContext { | ... | @@ -43,14 +43,13 @@ public interface PacketContext { |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * Blocks the outbound packet from being sent from this point onward. | 45 | * Blocks the outbound packet from being sent from this point onward. |
46 | + * @return whether the outbound packet is blocked. | ||
46 | */ | 47 | */ |
47 | - void block(); | 48 | + boolean blocked(); |
48 | 49 | ||
49 | /** | 50 | /** |
50 | - * Indicates whether the packet has already been handled, i.e. sent or | 51 | + * Check whether the outbound packet is blocked. |
51 | - * blocked. | 52 | + * @return |
52 | - * | ||
53 | - * @return true if sent or blocked | ||
54 | */ | 53 | */ |
55 | boolean isHandled(); | 54 | boolean isHandled(); |
56 | 55 | ... | ... |
1 | package org.onlab.onos.net.device; | 1 | package org.onlab.onos.net.device; |
2 | 2 | ||
3 | +import static org.junit.Assert.assertEquals; | ||
4 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
5 | + | ||
3 | import org.junit.Test; | 6 | import org.junit.Test; |
4 | import org.onlab.onos.event.AbstractEventTest; | 7 | import org.onlab.onos.event.AbstractEventTest; |
5 | import org.onlab.onos.net.DefaultDevice; | 8 | import org.onlab.onos.net.DefaultDevice; |
... | @@ -9,9 +12,6 @@ import org.onlab.onos.net.Port; | ... | @@ -9,9 +12,6 @@ import org.onlab.onos.net.Port; |
9 | import org.onlab.onos.net.PortNumber; | 12 | import org.onlab.onos.net.PortNumber; |
10 | import org.onlab.onos.net.provider.ProviderId; | 13 | import org.onlab.onos.net.provider.ProviderId; |
11 | 14 | ||
12 | -import static org.junit.Assert.assertEquals; | ||
13 | -import static org.onlab.onos.net.DeviceId.deviceId; | ||
14 | - | ||
15 | /** | 15 | /** |
16 | * Tests of the device event. | 16 | * Tests of the device event. |
17 | */ | 17 | */ |
... | @@ -19,23 +19,25 @@ public class DeviceEventTest extends AbstractEventTest { | ... | @@ -19,23 +19,25 @@ public class DeviceEventTest extends AbstractEventTest { |
19 | 19 | ||
20 | private Device createDevice() { | 20 | private Device createDevice() { |
21 | return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"), | 21 | return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"), |
22 | - Device.Type.SWITCH, "box", "hw", "sw", "sn"); | 22 | + Device.Type.SWITCH, "box", "hw", "sw", "sn"); |
23 | } | 23 | } |
24 | 24 | ||
25 | + @Override | ||
25 | @Test | 26 | @Test |
26 | public void withTime() { | 27 | public void withTime() { |
27 | Device device = createDevice(); | 28 | Device device = createDevice(); |
28 | - Port port = new DefaultPort(device, PortNumber.portNumber(123L), true); | 29 | + Port port = new DefaultPort(device, PortNumber.portNumber(123), true); |
29 | DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, | 30 | DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, |
30 | - device, port, 123L); | 31 | + device, port, 123L); |
31 | validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L); | 32 | validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L); |
32 | assertEquals("incorrect port", port, event.port()); | 33 | assertEquals("incorrect port", port, event.port()); |
33 | } | 34 | } |
34 | 35 | ||
36 | + @Override | ||
35 | @Test | 37 | @Test |
36 | public void withoutTime() { | 38 | public void withoutTime() { |
37 | Device device = createDevice(); | 39 | Device device = createDevice(); |
38 | - Port port = new DefaultPort(device, PortNumber.portNumber(123L), true); | 40 | + Port port = new DefaultPort(device, PortNumber.portNumber(123), true); |
39 | long before = System.currentTimeMillis(); | 41 | long before = System.currentTimeMillis(); |
40 | DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device); | 42 | DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device); |
41 | long after = System.currentTimeMillis(); | 43 | long after = System.currentTimeMillis(); | ... | ... |
... | @@ -3,6 +3,7 @@ package org.onlab.onos.of.controller; | ... | @@ -3,6 +3,7 @@ package org.onlab.onos.of.controller; |
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | import java.util.Collections; | 5 | import java.util.Collections; |
6 | +import java.util.concurrent.atomic.AtomicBoolean; | ||
6 | 7 | ||
7 | import org.onlab.packet.Ethernet; | 8 | import org.onlab.packet.Ethernet; |
8 | import org.projectfloodlight.openflow.protocol.OFPacketIn; | 9 | import org.projectfloodlight.openflow.protocol.OFPacketIn; |
... | @@ -18,7 +19,7 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext | ... | @@ -18,7 +19,7 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext |
18 | 19 | ||
19 | private final Logger log = getLogger(getClass()); | 20 | private final Logger log = getLogger(getClass()); |
20 | 21 | ||
21 | - private boolean free = true; | 22 | + private final AtomicBoolean free = new AtomicBoolean(true); |
22 | private boolean isBuilt = false; | 23 | private boolean isBuilt = false; |
23 | private final OpenFlowSwitch sw; | 24 | private final OpenFlowSwitch sw; |
24 | private final OFPacketIn pktin; | 25 | private final OFPacketIn pktin; |
... | @@ -30,14 +31,8 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext | ... | @@ -30,14 +31,8 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext |
30 | } | 31 | } |
31 | 32 | ||
32 | @Override | 33 | @Override |
33 | - public void block() { | ||
34 | - free = false; | ||
35 | - } | ||
36 | - | ||
37 | - @Override | ||
38 | public void send() { | 34 | public void send() { |
39 | - if (free && isBuilt) { | 35 | + if (blocked() && isBuilt) { |
40 | - block(); | ||
41 | sw.sendMsg(pktout); | 36 | sw.sendMsg(pktout); |
42 | } | 37 | } |
43 | } | 38 | } |
... | @@ -111,4 +106,9 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext | ... | @@ -111,4 +106,9 @@ public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext |
111 | return act; | 106 | return act; |
112 | } | 107 | } |
113 | 108 | ||
109 | + @Override | ||
110 | + public boolean blocked() { | ||
111 | + return free.getAndSet(false); | ||
112 | + } | ||
113 | + | ||
114 | } | 114 | } | ... | ... |
... | @@ -16,7 +16,7 @@ public interface OpenFlowPacketContext { | ... | @@ -16,7 +16,7 @@ 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 void block(); | 19 | + public boolean blocked(); |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * Provided build has been called send the packet | 22 | * Provided build has been called send the packet | ... | ... |
1 | package org.onlab.onos.of.controller.impl; | 1 | package org.onlab.onos.of.controller.impl; |
2 | 2 | ||
3 | import java.util.HashSet; | 3 | import java.util.HashSet; |
4 | -import java.util.Map; | ||
5 | import java.util.Set; | 4 | import java.util.Set; |
6 | -import java.util.TreeMap; | ||
7 | import java.util.concurrent.ConcurrentHashMap; | 5 | import java.util.concurrent.ConcurrentHashMap; |
8 | import java.util.concurrent.locks.Lock; | 6 | import java.util.concurrent.locks.Lock; |
9 | import java.util.concurrent.locks.ReentrantLock; | 7 | import java.util.concurrent.locks.ReentrantLock; |
... | @@ -27,6 +25,9 @@ import org.projectfloodlight.openflow.protocol.OFPortStatus; | ... | @@ -27,6 +25,9 @@ import org.projectfloodlight.openflow.protocol.OFPortStatus; |
27 | import org.slf4j.Logger; | 25 | import org.slf4j.Logger; |
28 | import org.slf4j.LoggerFactory; | 26 | import org.slf4j.LoggerFactory; |
29 | 27 | ||
28 | +import com.google.common.collect.ArrayListMultimap; | ||
29 | +import com.google.common.collect.Multimap; | ||
30 | + | ||
30 | @Component(immediate = true) | 31 | @Component(immediate = true) |
31 | @Service | 32 | @Service |
32 | public class OpenFlowControllerImpl implements OpenFlowController { | 33 | public class OpenFlowControllerImpl implements OpenFlowController { |
... | @@ -44,7 +45,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { | ... | @@ -44,7 +45,9 @@ public class OpenFlowControllerImpl implements OpenFlowController { |
44 | protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); | 45 | protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); |
45 | protected Set<OpenFlowSwitchListener> ofEventListener = new HashSet<>(); | 46 | protected Set<OpenFlowSwitchListener> ofEventListener = new HashSet<>(); |
46 | 47 | ||
47 | - protected Map<Integer, PacketListener> ofPacketListener = new TreeMap<>(); | 48 | + protected Multimap<Integer, PacketListener> ofPacketListener = |
49 | + ArrayListMultimap.create(); | ||
50 | + | ||
48 | 51 | ||
49 | private final Controller ctrl = new Controller(); | 52 | private final Controller ctrl = new Controller(); |
50 | 53 | ... | ... |
1 | package org.onlab.onos.provider.of.link.impl; | 1 | package org.onlab.onos.provider.of.link.impl; |
2 | 2 | ||
3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | + | ||
5 | +import java.util.Map; | ||
6 | +import java.util.concurrent.ConcurrentHashMap; | ||
7 | + | ||
3 | import org.apache.felix.scr.annotations.Activate; | 8 | import org.apache.felix.scr.annotations.Activate; |
4 | import org.apache.felix.scr.annotations.Component; | 9 | import org.apache.felix.scr.annotations.Component; |
5 | import org.apache.felix.scr.annotations.Deactivate; | 10 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -13,9 +18,9 @@ import org.onlab.onos.net.provider.AbstractProvider; | ... | @@ -13,9 +18,9 @@ import org.onlab.onos.net.provider.AbstractProvider; |
13 | import org.onlab.onos.net.provider.ProviderId; | 18 | import org.onlab.onos.net.provider.ProviderId; |
14 | import org.onlab.onos.of.controller.Dpid; | 19 | import org.onlab.onos.of.controller.Dpid; |
15 | import org.onlab.onos.of.controller.OpenFlowController; | 20 | import org.onlab.onos.of.controller.OpenFlowController; |
21 | +import org.onlab.onos.of.controller.OpenFlowPacketContext; | ||
16 | import org.onlab.onos.of.controller.OpenFlowSwitch; | 22 | import org.onlab.onos.of.controller.OpenFlowSwitch; |
17 | import org.onlab.onos.of.controller.OpenFlowSwitchListener; | 23 | import org.onlab.onos.of.controller.OpenFlowSwitchListener; |
18 | -import org.onlab.onos.of.controller.OpenFlowPacketContext; | ||
19 | import org.onlab.onos.of.controller.PacketListener; | 24 | import org.onlab.onos.of.controller.PacketListener; |
20 | import org.projectfloodlight.openflow.protocol.OFPortConfig; | 25 | import org.projectfloodlight.openflow.protocol.OFPortConfig; |
21 | import org.projectfloodlight.openflow.protocol.OFPortDesc; | 26 | import org.projectfloodlight.openflow.protocol.OFPortDesc; |
... | @@ -23,11 +28,6 @@ import org.projectfloodlight.openflow.protocol.OFPortState; | ... | @@ -23,11 +28,6 @@ import org.projectfloodlight.openflow.protocol.OFPortState; |
23 | import org.projectfloodlight.openflow.protocol.OFPortStatus; | 28 | import org.projectfloodlight.openflow.protocol.OFPortStatus; |
24 | import org.slf4j.Logger; | 29 | import org.slf4j.Logger; |
25 | 30 | ||
26 | -import java.util.Map; | ||
27 | -import java.util.concurrent.ConcurrentHashMap; | ||
28 | - | ||
29 | -import static org.slf4j.LoggerFactory.getLogger; | ||
30 | - | ||
31 | /** | 31 | /** |
32 | * Provider which uses an OpenFlow controller to detect network | 32 | * Provider which uses an OpenFlow controller to detect network |
33 | * infrastructure links. | 33 | * infrastructure links. |
... | @@ -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.block(); | 96 | + pktCtx.blocked(); |
97 | } | 97 | } |
98 | 98 | ||
99 | } | 99 | } |
... | @@ -101,7 +101,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid | ... | @@ -101,7 +101,7 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid |
101 | @Override | 101 | @Override |
102 | public void switchAdded(Dpid dpid) { | 102 | public void switchAdded(Dpid dpid) { |
103 | discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid), | 103 | discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid), |
104 | - controller, providerService, useBDDP)); | 104 | + controller, providerService, useBDDP)); |
105 | 105 | ||
106 | } | 106 | } |
107 | 107 | ... | ... |
... | @@ -2,6 +2,11 @@ package org.onlab.onos.provider.of.packet.impl; | ... | @@ -2,6 +2,11 @@ package org.onlab.onos.provider.of.packet.impl; |
2 | 2 | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | +import java.util.List; | ||
6 | + | ||
7 | +import org.onlab.onos.net.PortNumber; | ||
8 | +import org.onlab.onos.net.flow.Instruction; | ||
9 | +import org.onlab.onos.net.flow.Instruction.Type; | ||
5 | import org.onlab.onos.net.packet.DefaultPacketContext; | 10 | import org.onlab.onos.net.packet.DefaultPacketContext; |
6 | import org.onlab.onos.net.packet.InboundPacket; | 11 | import org.onlab.onos.net.packet.InboundPacket; |
7 | import org.onlab.onos.net.packet.OutboundPacket; | 12 | import org.onlab.onos.net.packet.OutboundPacket; |
... | @@ -24,18 +29,36 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { | ... | @@ -24,18 +29,36 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { |
24 | 29 | ||
25 | @Override | 30 | @Override |
26 | public void send() { | 31 | public void send() { |
27 | - if (!this.isHandled()) { | 32 | + if (!this.blocked()) { |
28 | - block(); | ||
29 | if (outPacket() == null) { | 33 | if (outPacket() == null) { |
30 | - ofPktCtx.build(OFPort.FLOOD); | 34 | + sendBufferedPacket(); |
31 | } else { | 35 | } else { |
32 | Ethernet eth = new Ethernet(); | 36 | Ethernet eth = new Ethernet(); |
33 | eth.deserialize(outPacket().data().array(), 0, | 37 | eth.deserialize(outPacket().data().array(), 0, |
34 | outPacket().data().array().length); | 38 | outPacket().data().array().length); |
35 | ofPktCtx.build(eth, OFPort.FLOOD); | 39 | ofPktCtx.build(eth, OFPort.FLOOD); |
36 | } | 40 | } |
37 | - ofPktCtx.send(); | 41 | + |
42 | + } | ||
43 | + } | ||
44 | + | ||
45 | + @SuppressWarnings({ "rawtypes", "unchecked" }) | ||
46 | + private void sendBufferedPacket() { | ||
47 | + List<Instruction> ins = treatmentBuilder().build().instructions(); | ||
48 | + OFPort p = null; | ||
49 | + //TODO: support arbitrary list of treatments | ||
50 | + for (Instruction i : ins) { | ||
51 | + if (i.type() == Type.OUTPUT) { | ||
52 | + p = buildPort(((Instruction<PortNumber>) i).instruction()); | ||
53 | + break; //for now... | ||
54 | + } | ||
38 | } | 55 | } |
56 | + ofPktCtx.build(p); | ||
57 | + ofPktCtx.send(); | ||
58 | + } | ||
59 | + | ||
60 | + private OFPort buildPort(PortNumber port) { | ||
61 | + return OFPort.of((int) port.toLong()); | ||
39 | } | 62 | } |
40 | 63 | ||
41 | } | 64 | } | ... | ... |
-
Please register or login to post a comment