Showing
12 changed files
with
121 additions
and
37 deletions
1 | +package org.onlab.onos.fwd; | ||
2 | + | ||
3 | +import org.apache.felix.scr.annotations.Activate; | ||
4 | +import org.apache.felix.scr.annotations.Component; | ||
5 | +import org.apache.felix.scr.annotations.Deactivate; | ||
6 | +import org.apache.felix.scr.annotations.Reference; | ||
7 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
8 | +import org.onlab.onos.net.packet.PacketProcessor; | ||
9 | +import org.onlab.onos.net.packet.PacketService; | ||
10 | +import org.onlab.onos.net.topology.TopologyService; | ||
11 | + | ||
12 | +@Component | ||
13 | +public class ReactiveForwarding { | ||
14 | + | ||
15 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
16 | + protected TopologyService topologyService; | ||
17 | + | ||
18 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
19 | + protected PacketService packetService; | ||
20 | + | ||
21 | + private ReactivePacketProcessor processor; | ||
22 | + | ||
23 | + @Activate | ||
24 | + public void activate() { | ||
25 | + processor = new ReactivePacketProcessor(topologyService); | ||
26 | + packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); | ||
27 | + } | ||
28 | + | ||
29 | + @Deactivate | ||
30 | + public void deactivate() { | ||
31 | + packetService.removeProcessor(processor); | ||
32 | + processor = null; | ||
33 | + } | ||
34 | +} | ||
35 | + |
1 | -package org.onlab.onos.net.trivial.packet.impl; | 1 | +package org.onlab.onos.fwd; |
2 | 2 | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
... | @@ -6,16 +6,32 @@ import org.onlab.onos.net.PortNumber; | ... | @@ -6,16 +6,32 @@ import org.onlab.onos.net.PortNumber; |
6 | import org.onlab.onos.net.flow.Instructions; | 6 | import org.onlab.onos.net.flow.Instructions; |
7 | import org.onlab.onos.net.packet.PacketContext; | 7 | import org.onlab.onos.net.packet.PacketContext; |
8 | import org.onlab.onos.net.packet.PacketProcessor; | 8 | import org.onlab.onos.net.packet.PacketProcessor; |
9 | +import org.onlab.onos.net.topology.TopologyService; | ||
9 | import org.slf4j.Logger; | 10 | import org.slf4j.Logger; |
10 | 11 | ||
11 | public class ReactivePacketProcessor implements PacketProcessor { | 12 | public class ReactivePacketProcessor implements PacketProcessor { |
12 | 13 | ||
13 | private final Logger log = getLogger(getClass()); | 14 | private final Logger log = getLogger(getClass()); |
15 | + private final TopologyService topologyService; | ||
16 | + | ||
17 | + | ||
18 | + public ReactivePacketProcessor(TopologyService topologyService) { | ||
19 | + this.topologyService = topologyService; | ||
20 | + } | ||
21 | + | ||
14 | 22 | ||
15 | @Override | 23 | @Override |
16 | public void process(PacketContext context) { | 24 | public void process(PacketContext context) { |
25 | + boolean canBcast = topologyService.isBroadcastPoint(topologyService.currentTopology(), | ||
26 | + context.inPacket().receivedFrom()); | ||
27 | + | ||
28 | + if (canBcast) { | ||
17 | context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD)); | 29 | context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD)); |
18 | context.send(); | 30 | context.send(); |
31 | + } else { | ||
32 | + context.block(); | ||
33 | + } | ||
34 | + | ||
19 | } | 35 | } |
20 | 36 | ||
21 | } | 37 | } | ... | ... |
... | @@ -6,7 +6,6 @@ import java.util.Collections; | ... | @@ -6,7 +6,6 @@ import java.util.Collections; |
6 | import java.util.LinkedList; | 6 | import java.util.LinkedList; |
7 | import java.util.List; | 7 | import java.util.List; |
8 | 8 | ||
9 | -import org.onlab.onos.net.PortNumber; | ||
10 | import org.slf4j.Logger; | 9 | import org.slf4j.Logger; |
11 | 10 | ||
12 | @SuppressWarnings("rawtypes") | 11 | @SuppressWarnings("rawtypes") |
... | @@ -33,29 +32,33 @@ public class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -33,29 +32,33 @@ public class DefaultTrafficTreatment implements TrafficTreatment { |
33 | 32 | ||
34 | private final Logger log = getLogger(getClass()); | 33 | private final Logger log = getLogger(getClass()); |
35 | 34 | ||
36 | - List<Instruction<PortNumber>> outputs = new LinkedList<>(); | 35 | + boolean drop = false; |
36 | + | ||
37 | + List<Instruction> outputs = new LinkedList<>(); | ||
37 | 38 | ||
38 | // TODO: should be a list of instructions based on group objects | 39 | // TODO: should be a list of instructions based on group objects |
39 | - List<Instruction<Object>> groups = new LinkedList<>(); | 40 | + List<Instruction> groups = new LinkedList<>(); |
40 | 41 | ||
41 | // TODO: should be a list of instructions based on modification objects | 42 | // TODO: should be a list of instructions based on modification objects |
42 | - List<Instruction<Object>> modifications = new LinkedList<>(); | 43 | + List<Instruction> modifications = new LinkedList<>(); |
43 | 44 | ||
44 | 45 | ||
45 | - @SuppressWarnings("unchecked") | ||
46 | @Override | 46 | @Override |
47 | public Builder add(Instruction instruction) { | 47 | public Builder add(Instruction instruction) { |
48 | switch (instruction.type()) { | 48 | switch (instruction.type()) { |
49 | - case OUTPUT: | ||
50 | case DROP: | 49 | case DROP: |
51 | - // TODO: should check that there is only one drop instruction. | 50 | + drop = true; |
51 | + break; | ||
52 | + case OUTPUT: | ||
52 | outputs.add(instruction); | 53 | outputs.add(instruction); |
53 | break; | 54 | break; |
54 | case MODIFICATION: | 55 | case MODIFICATION: |
55 | // TODO: enforce modification order if any | 56 | // TODO: enforce modification order if any |
56 | modifications.add(instruction); | 57 | modifications.add(instruction); |
58 | + break; | ||
57 | case GROUP: | 59 | case GROUP: |
58 | groups.add(instruction); | 60 | groups.add(instruction); |
61 | + break; | ||
59 | default: | 62 | default: |
60 | log.warn("Unknown instruction type {}", instruction.type()); | 63 | log.warn("Unknown instruction type {}", instruction.type()); |
61 | } | 64 | } |
... | @@ -64,10 +67,14 @@ public class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -64,10 +67,14 @@ public class DefaultTrafficTreatment implements TrafficTreatment { |
64 | 67 | ||
65 | @Override | 68 | @Override |
66 | public TrafficTreatment build() { | 69 | public TrafficTreatment build() { |
70 | + | ||
71 | + //If we are dropping should we just return an emptry list? | ||
67 | List<Instruction> instructions = new LinkedList<Instruction>(); | 72 | List<Instruction> instructions = new LinkedList<Instruction>(); |
68 | instructions.addAll(modifications); | 73 | instructions.addAll(modifications); |
69 | instructions.addAll(groups); | 74 | instructions.addAll(groups); |
75 | + if (!drop) { | ||
70 | instructions.addAll(outputs); | 76 | instructions.addAll(outputs); |
77 | + } | ||
71 | 78 | ||
72 | return new DefaultTrafficTreatment(instructions); | 79 | return new DefaultTrafficTreatment(instructions); |
73 | } | 80 | } | ... | ... |
... | @@ -4,7 +4,7 @@ package org.onlab.onos.net.flow; | ... | @@ -4,7 +4,7 @@ package org.onlab.onos.net.flow; |
4 | * Abstraction of a single traffic treatment step. | 4 | * Abstraction of a single traffic treatment step. |
5 | * @param <T> the type parameter for the instruction | 5 | * @param <T> the type parameter for the instruction |
6 | */ | 6 | */ |
7 | -public interface Instruction<T> { | 7 | +public interface Instruction { |
8 | 8 | ||
9 | /** | 9 | /** |
10 | * Represents the type of traffic treatment. | 10 | * Represents the type of traffic treatment. |
... | @@ -41,10 +41,4 @@ public interface Instruction<T> { | ... | @@ -41,10 +41,4 @@ public interface Instruction<T> { |
41 | */ | 41 | */ |
42 | public Type type(); | 42 | public Type type(); |
43 | 43 | ||
44 | - /** | ||
45 | - * Returns the actual value of the instruction. | ||
46 | - * @return the value for this instruction | ||
47 | - */ | ||
48 | - public T instruction(); | ||
49 | - | ||
50 | } | 44 | } | ... | ... |
1 | package org.onlab.onos.net.flow; | 1 | package org.onlab.onos.net.flow; |
2 | 2 | ||
3 | -import org.onlab.onos.net.PortNumber; | 3 | +import static com.google.common.base.Preconditions.checkNotNull; |
4 | 4 | ||
5 | +import org.onlab.onos.net.PortNumber; | ||
5 | /** | 6 | /** |
6 | * Factory class for creating various traffic treatment instructions. | 7 | * Factory class for creating various traffic treatment instructions. |
7 | */ | 8 | */ |
... | @@ -17,22 +18,44 @@ public final class Instructions { | ... | @@ -17,22 +18,44 @@ public final class Instructions { |
17 | * @param number port number | 18 | * @param number port number |
18 | * @return output instruction | 19 | * @return output instruction |
19 | */ | 20 | */ |
20 | - public static Instruction<PortNumber> createOutput(final PortNumber number) { | 21 | + public static OutputInstruction createOutput(final PortNumber number) { |
21 | - return new Instruction<PortNumber>() { | 22 | + checkNotNull(number, "PortNumber cannot be null"); |
23 | + return new OutputInstruction(number); | ||
24 | + } | ||
22 | 25 | ||
23 | - @Override | 26 | + public static DropInstruction createDrop() { |
24 | - public Instruction.Type type() { | 27 | + return new DropInstruction(); |
25 | - return Type.OUTPUT; | ||
26 | } | 28 | } |
27 | 29 | ||
30 | + // TODO: add create methods | ||
31 | + | ||
32 | + public static final class DropInstruction implements Instruction { | ||
33 | + | ||
28 | @Override | 34 | @Override |
29 | - public PortNumber instruction() { | 35 | + public Type type() { |
30 | - return number; | 36 | + return Type.DROP; |
37 | + } | ||
31 | } | 38 | } |
32 | 39 | ||
33 | - }; | 40 | + |
41 | + public static final class OutputInstruction implements Instruction { | ||
42 | + | ||
43 | + private final PortNumber port; | ||
44 | + | ||
45 | + private OutputInstruction(PortNumber port) { | ||
46 | + this.port = port; | ||
34 | } | 47 | } |
35 | 48 | ||
36 | - // TODO: add create methods | 49 | + public PortNumber port() { |
50 | + return port; | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + public Type type() { | ||
55 | + return Type.OUTPUT; | ||
56 | + } | ||
57 | + | ||
58 | + | ||
59 | + } | ||
37 | 60 | ||
38 | } | 61 | } | ... | ... |
... | @@ -51,7 +51,7 @@ public abstract class DefaultPacketContext implements PacketContext { | ... | @@ -51,7 +51,7 @@ public abstract class DefaultPacketContext implements PacketContext { |
51 | public abstract void send(); | 51 | public abstract void send(); |
52 | 52 | ||
53 | @Override | 53 | @Override |
54 | - public boolean blocked() { | 54 | + public boolean block() { |
55 | return this.block.getAndSet(true); | 55 | return this.block.getAndSet(true); |
56 | } | 56 | } |
57 | 57 | ... | ... |
... | @@ -45,7 +45,7 @@ public interface PacketContext { | ... | @@ -45,7 +45,7 @@ public interface PacketContext { |
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 | * @return whether the outbound packet is blocked. |
47 | */ | 47 | */ |
48 | - boolean blocked(); | 48 | + boolean block(); |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * Check whether the outbound packet is blocked. | 51 | * Check whether the outbound packet is blocked. | ... | ... |
1 | package org.onlab.onos.event; | 1 | package org.onlab.onos.event; |
2 | 2 | ||
3 | -import org.junit.Test; | 3 | +import static org.junit.Assert.assertEquals; |
4 | +import static org.junit.Assert.assertFalse; | ||
5 | +import static org.junit.Assert.assertTrue; | ||
6 | +import static org.onlab.junit.TestTools.delay; | ||
7 | +import static org.onlab.onos.event.TestEvent.Type.FOO; | ||
4 | 8 | ||
5 | import java.util.List; | 9 | import java.util.List; |
6 | import java.util.Timer; | 10 | import java.util.Timer; |
7 | 11 | ||
8 | -import static org.junit.Assert.*; | 12 | +import org.junit.Test; |
9 | -import static org.onlab.junit.TestTools.delay; | ||
10 | -import static org.onlab.onos.event.TestEvent.Type.FOO; | ||
11 | 13 | ||
12 | /** | 14 | /** |
13 | * Tests the operation of the accumulator. | 15 | * Tests the operation of the accumulator. | ... | ... |
1 | package org.onlab.onos.net.trivial.packet.impl; | 1 | package org.onlab.onos.net.trivial.packet.impl; |
2 | 2 | ||
3 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
3 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 5 | ||
5 | import java.util.Map; | 6 | import java.util.Map; |
... | @@ -42,22 +43,20 @@ implements PacketService, PacketProviderRegistry { | ... | @@ -42,22 +43,20 @@ implements PacketService, PacketProviderRegistry { |
42 | 43 | ||
43 | private final Map<Integer, PacketProcessor> processors = new TreeMap<>(); | 44 | private final Map<Integer, PacketProcessor> processors = new TreeMap<>(); |
44 | 45 | ||
45 | - private final PacketProcessor reactiveProcessor = new ReactivePacketProcessor(); | ||
46 | 46 | ||
47 | @Activate | 47 | @Activate |
48 | public void activate() { | 48 | public void activate() { |
49 | - addProcessor(reactiveProcessor, PacketProcessor.ADVISOR_MAX + 1); | ||
50 | log.info("Started"); | 49 | log.info("Started"); |
51 | } | 50 | } |
52 | 51 | ||
53 | @Deactivate | 52 | @Deactivate |
54 | public void deactivate() { | 53 | public void deactivate() { |
55 | - removeProcessor(reactiveProcessor); | ||
56 | log.info("Stopped"); | 54 | log.info("Stopped"); |
57 | } | 55 | } |
58 | 56 | ||
59 | @Override | 57 | @Override |
60 | public void addProcessor(PacketProcessor processor, int priority) { | 58 | public void addProcessor(PacketProcessor processor, int priority) { |
59 | + checkNotNull(processor, "Processor cannot be null"); | ||
61 | processors.put(priority, processor); | 60 | processors.put(priority, processor); |
62 | } | 61 | } |
63 | 62 | ... | ... |
... | @@ -79,4 +79,11 @@ | ... | @@ -79,4 +79,11 @@ |
79 | <bundle>mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT</bundle> | 79 | <bundle>mvn:org.onlab.onos/onos-app-tvue/1.0.0-SNAPSHOT</bundle> |
80 | </feature> | 80 | </feature> |
81 | 81 | ||
82 | + <feature name="onos-app-fwd" version="1.0.0" | ||
83 | + description="ONOS sample forwarding application"> | ||
84 | + <feature>onos-core</feature> | ||
85 | + <bundle>mvn:org.onlab.onos/onos-app-fwd/1.0.0-SNAPSHOT</bundle> | ||
86 | + </feature> | ||
87 | + | ||
88 | + | ||
82 | </features> | 89 | </features> | ... | ... |
... | @@ -7,6 +7,7 @@ import java.util.List; | ... | @@ -7,6 +7,7 @@ import java.util.List; |
7 | import org.onlab.onos.net.PortNumber; | 7 | import org.onlab.onos.net.PortNumber; |
8 | import org.onlab.onos.net.flow.Instruction; | 8 | import org.onlab.onos.net.flow.Instruction; |
9 | import org.onlab.onos.net.flow.Instruction.Type; | 9 | import org.onlab.onos.net.flow.Instruction.Type; |
10 | +import org.onlab.onos.net.flow.Instructions.OutputInstruction; | ||
10 | import org.onlab.onos.net.packet.DefaultPacketContext; | 11 | import org.onlab.onos.net.packet.DefaultPacketContext; |
11 | import org.onlab.onos.net.packet.InboundPacket; | 12 | import org.onlab.onos.net.packet.InboundPacket; |
12 | import org.onlab.onos.net.packet.OutboundPacket; | 13 | import org.onlab.onos.net.packet.OutboundPacket; |
... | @@ -29,7 +30,7 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { | ... | @@ -29,7 +30,7 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { |
29 | 30 | ||
30 | @Override | 31 | @Override |
31 | public void send() { | 32 | public void send() { |
32 | - if (!this.blocked()) { | 33 | + if (!this.block()) { |
33 | if (outPacket() == null) { | 34 | if (outPacket() == null) { |
34 | sendBufferedPacket(); | 35 | sendBufferedPacket(); |
35 | } else { | 36 | } else { |
... | @@ -42,14 +43,13 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { | ... | @@ -42,14 +43,13 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { |
42 | } | 43 | } |
43 | } | 44 | } |
44 | 45 | ||
45 | - @SuppressWarnings({ "rawtypes", "unchecked" }) | ||
46 | private void sendBufferedPacket() { | 46 | private void sendBufferedPacket() { |
47 | List<Instruction> ins = treatmentBuilder().build().instructions(); | 47 | List<Instruction> ins = treatmentBuilder().build().instructions(); |
48 | OFPort p = null; | 48 | OFPort p = null; |
49 | //TODO: support arbitrary list of treatments | 49 | //TODO: support arbitrary list of treatments |
50 | for (Instruction i : ins) { | 50 | for (Instruction i : ins) { |
51 | if (i.type() == Type.OUTPUT) { | 51 | if (i.type() == Type.OUTPUT) { |
52 | - p = buildPort(((Instruction<PortNumber>) i).instruction()); | 52 | + p = buildPort(((OutputInstruction) i).port()); |
53 | break; //for now... | 53 | break; //for now... |
54 | } | 54 | } |
55 | } | 55 | } | ... | ... |
-
Please register or login to post a comment