Committed by
Gerrit Code Review
CORD-367 L2 bridging and L3 routing support with internal VLANs in OF-DPA.
Also includes: All forwarding in app is now via nextObjectives (not treatments) - Spring Open driver converts non-ECMP forwarding to flow-actions, while OF-DPA driver continues to use groups. Convert 'setMeta' methods to 'withMeta' in Flow Objectives API. Bug fix in Flow Objective Manager - set of PendingNext is now threadsafe. Bug fix in ArpHandler - now recognizes routerIp in addition to gatewayIps Removed a bunch of testcode Added group count in CLI Change-Id: Id3b879c5dda78151ca0ec359179f1604066d39fc
Showing
20 changed files
with
271 additions
and
74 deletions
... | @@ -107,7 +107,7 @@ public class ArpHandler { | ... | @@ -107,7 +107,7 @@ public class ArpHandler { |
107 | vlanId); | 107 | vlanId); |
108 | 108 | ||
109 | // ARP request for router. Send ARP reply. | 109 | // ARP request for router. Send ARP reply. |
110 | - if (isArpReqForRouter(deviceId, arpRequest)) { | 110 | + if (isArpForRouter(deviceId, arpRequest)) { |
111 | Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()); | 111 | Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()); |
112 | sendArpResponse(arpRequest, config.getRouterMacForAGatewayIp(targetAddress), vlanId); | 112 | sendArpResponse(arpRequest, config.getRouterMacForAGatewayIp(targetAddress), vlanId); |
113 | } else { | 113 | } else { |
... | @@ -130,7 +130,7 @@ public class ArpHandler { | ... | @@ -130,7 +130,7 @@ public class ArpHandler { |
130 | vlanId); | 130 | vlanId); |
131 | 131 | ||
132 | // ARP reply for router. Process all pending IP packets. | 132 | // ARP reply for router. Process all pending IP packets. |
133 | - if (isArpReqForRouter(deviceId, arpReply)) { | 133 | + if (isArpForRouter(deviceId, arpReply)) { |
134 | Ip4Address hostIpAddress = Ip4Address.valueOf(arpReply.getSenderProtocolAddress()); | 134 | Ip4Address hostIpAddress = Ip4Address.valueOf(arpReply.getSenderProtocolAddress()); |
135 | srManager.ipHandler.forwardPackets(deviceId, hostIpAddress); | 135 | srManager.ipHandler.forwardPackets(deviceId, hostIpAddress); |
136 | } else { | 136 | } else { |
... | @@ -141,7 +141,8 @@ public class ArpHandler { | ... | @@ -141,7 +141,8 @@ public class ArpHandler { |
141 | // ARP reply for unknown host, Flood in the subnet. | 141 | // ARP reply for unknown host, Flood in the subnet. |
142 | } else { | 142 | } else { |
143 | // Don't flood to non-edge ports | 143 | // Don't flood to non-edge ports |
144 | - if (vlanId.equals(VlanId.vlanId(srManager.ASSIGNED_VLAN_NO_SUBNET))) { | 144 | + if (vlanId.equals( |
145 | + VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET))) { | ||
145 | return; | 146 | return; |
146 | } | 147 | } |
147 | removeVlanAndFlood(payload, inPort); | 148 | removeVlanAndFlood(payload, inPort); |
... | @@ -150,14 +151,21 @@ public class ArpHandler { | ... | @@ -150,14 +151,21 @@ public class ArpHandler { |
150 | } | 151 | } |
151 | 152 | ||
152 | 153 | ||
153 | - private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) { | 154 | + private boolean isArpForRouter(DeviceId deviceId, ARP arpMsg) { |
154 | - Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId); | 155 | + Ip4Address targetProtocolAddress = Ip4Address.valueOf( |
155 | - if (gatewayIpAddresses != null) { | 156 | + arpMsg.getTargetProtocolAddress()); |
156 | - Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest | 157 | + Set<Ip4Address> gatewayIpAddresses = null; |
157 | - .getTargetProtocolAddress()); | 158 | + try { |
158 | - if (gatewayIpAddresses.contains(targetProtocolAddress)) { | 159 | + if (targetProtocolAddress.equals(config.getRouterIp(deviceId))) { |
159 | return true; | 160 | return true; |
160 | } | 161 | } |
162 | + gatewayIpAddresses = config.getPortIPs(deviceId); | ||
163 | + } catch (DeviceConfigNotFoundException e) { | ||
164 | + log.warn(e.getMessage() + " Aborting check for router IP in processing arp"); | ||
165 | + } | ||
166 | + if (gatewayIpAddresses != null && | ||
167 | + gatewayIpAddresses.contains(targetProtocolAddress)) { | ||
168 | + return true; | ||
161 | } | 169 | } |
162 | return false; | 170 | return false; |
163 | } | 171 | } | ... | ... |
... | @@ -88,10 +88,10 @@ public class IcmpHandler { | ... | @@ -88,10 +88,10 @@ public class IcmpHandler { |
88 | (destinationAddress.equals(routerIpAddress) || | 88 | (destinationAddress.equals(routerIpAddress) || |
89 | gatewayIpAddresses.contains(destinationAddress))) { | 89 | gatewayIpAddresses.contains(destinationAddress))) { |
90 | sendICMPResponse(ethernet, connectPoint); | 90 | sendICMPResponse(ethernet, connectPoint); |
91 | - // TODO: do we need to set the flow rule again ?? | ||
92 | 91 | ||
93 | // ICMP for any known host | 92 | // ICMP for any known host |
94 | } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) { | 93 | } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) { |
94 | + // TODO: known host packet should not be coming to controller - resend flows? | ||
95 | srManager.ipHandler.forwardPackets(deviceId, destinationAddress); | 95 | srManager.ipHandler.forwardPackets(deviceId, destinationAddress); |
96 | 96 | ||
97 | // ICMP for an unknown host in the subnet of the router | 97 | // ICMP for an unknown host in the subnet of the router | ... | ... |
... | @@ -98,7 +98,7 @@ public class IpHandler { | ... | @@ -98,7 +98,7 @@ public class IpHandler { |
98 | */ | 98 | */ |
99 | public void addToPacketBuffer(IPv4 ipPacket) { | 99 | public void addToPacketBuffer(IPv4 ipPacket) { |
100 | 100 | ||
101 | - // Better not buffer TPC packets due to out-of-order packet transfer | 101 | + // Better not buffer TCP packets due to out-of-order packet transfer |
102 | if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) { | 102 | if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) { |
103 | return; | 103 | return; |
104 | } | 104 | } | ... | ... |
... | @@ -147,20 +147,34 @@ public class RoutingRulePopulator { | ... | @@ -147,20 +147,34 @@ public class RoutingRulePopulator { |
147 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); | 147 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); |
148 | TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); | 148 | TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); |
149 | 149 | ||
150 | - sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); | ||
151 | sbuilder.matchEthType(Ethernet.TYPE_IPV4); | 150 | sbuilder.matchEthType(Ethernet.TYPE_IPV4); |
151 | + sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); | ||
152 | + TrafficSelector selector = sbuilder.build(); | ||
152 | 153 | ||
153 | tbuilder.deferred() | 154 | tbuilder.deferred() |
154 | .setEthDst(hostMac) | 155 | .setEthDst(hostMac) |
155 | .setEthSrc(deviceMac) | 156 | .setEthSrc(deviceMac) |
156 | .setOutput(outPort); | 157 | .setOutput(outPort); |
157 | - | ||
158 | TrafficTreatment treatment = tbuilder.build(); | 158 | TrafficTreatment treatment = tbuilder.build(); |
159 | - TrafficSelector selector = sbuilder.build(); | 159 | + |
160 | + // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed. | ||
161 | + // for switch pipelines that need it, provide outgoing vlan as metadata | ||
162 | + VlanId outvlan = null; | ||
163 | + Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outPort); | ||
164 | + if (subnet == null) { | ||
165 | + outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET); | ||
166 | + } else { | ||
167 | + outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet); | ||
168 | + } | ||
169 | + TrafficSelector meta = DefaultTrafficSelector.builder() | ||
170 | + .matchVlanId(outvlan).build(); | ||
171 | + int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort, | ||
172 | + treatment, meta); | ||
160 | 173 | ||
161 | return DefaultForwardingObjective.builder() | 174 | return DefaultForwardingObjective.builder() |
175 | + .withSelector(selector) | ||
176 | + .nextStep(portNextObjId) | ||
162 | .fromApp(srManager.appId).makePermanent() | 177 | .fromApp(srManager.appId).makePermanent() |
163 | - .withSelector(selector).withTreatment(treatment) | ||
164 | .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); | 178 | .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); |
165 | } | 179 | } |
166 | 180 | ||
... | @@ -454,7 +468,7 @@ public class RoutingRulePopulator { | ... | @@ -454,7 +468,7 @@ public class RoutingRulePopulator { |
454 | if (srManager.mastershipService.isLocalMaster(deviceId)) { | 468 | if (srManager.mastershipService.isLocalMaster(deviceId)) { |
455 | TrafficTreatment tt = DefaultTrafficTreatment.builder() | 469 | TrafficTreatment tt = DefaultTrafficTreatment.builder() |
456 | .pushVlan().setVlanId(assignedVlan).build(); | 470 | .pushVlan().setVlanId(assignedVlan).build(); |
457 | - fob.setMeta(tt); | 471 | + fob.withMeta(tt); |
458 | } | 472 | } |
459 | fob.permit().fromApp(srManager.appId); | 473 | fob.permit().fromApp(srManager.appId); |
460 | srManager.flowObjectiveService. | 474 | srManager.flowObjectiveService. |
... | @@ -559,6 +573,12 @@ public class RoutingRulePopulator { | ... | @@ -559,6 +573,12 @@ public class RoutingRulePopulator { |
559 | int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet); | 573 | int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet); |
560 | VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet); | 574 | VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet); |
561 | 575 | ||
576 | + if (nextId < 0 || vlanId == null) { | ||
577 | + log.error("Cannot install subnet broadcast rule in dev:{} due" | ||
578 | + + "to vlanId:{} or nextId:{}", vlanId, nextId); | ||
579 | + return; | ||
580 | + } | ||
581 | + | ||
562 | /* Driver should treat objective with MacAddress.NONE as the | 582 | /* Driver should treat objective with MacAddress.NONE as the |
563 | * subnet broadcast rule | 583 | * subnet broadcast rule |
564 | */ | 584 | */ | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -56,9 +56,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -56,9 +56,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
56 | NeighborSetNextObjectiveStoreKey, | 56 | NeighborSetNextObjectiveStoreKey, |
57 | Integer> nsNextObjStore, | 57 | Integer> nsNextObjStore, |
58 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | 58 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, |
59 | - Integer> subnetNextObjStore) { | 59 | + Integer> subnetNextObjStore, |
60 | + EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
61 | + Integer> portNextObjStore) { | ||
60 | super(deviceId, appId, config, linkService, flowObjService, | 62 | super(deviceId, appId, config, linkService, flowObjService, |
61 | - nsNextObjStore, subnetNextObjStore); | 63 | + nsNextObjStore, subnetNextObjStore, portNextObjStore); |
62 | } | 64 | } |
63 | 65 | ||
64 | @Override | 66 | @Override | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -50,9 +50,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -50,9 +50,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
50 | NeighborSetNextObjectiveStoreKey, | 50 | NeighborSetNextObjectiveStoreKey, |
51 | Integer> nsNextObjStore, | 51 | Integer> nsNextObjStore, |
52 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | 52 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, |
53 | - Integer> subnetNextObjStore) { | 53 | + Integer> subnetNextObjStore, |
54 | + EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
55 | + Integer> portNextObjStore) { | ||
54 | super(deviceId, appId, config, linkService, flowObjService, | 56 | super(deviceId, appId, config, linkService, flowObjService, |
55 | - nsNextObjStore, subnetNextObjStore); | 57 | + nsNextObjStore, subnetNextObjStore, portNextObjStore); |
56 | } | 58 | } |
57 | 59 | ||
58 | @Override | 60 | @Override | ... | ... |
... | @@ -68,9 +68,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { | ... | @@ -68,9 +68,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { |
68 | EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, | 68 | EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, |
69 | Integer> nsNextObjStore, | 69 | Integer> nsNextObjStore, |
70 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, | 70 | EventuallyConsistentMap<SubnetNextObjectiveStoreKey, |
71 | - Integer> subnetNextObjStore) { | 71 | + Integer> subnetNextObjStore, |
72 | + EventuallyConsistentMap<PortNextObjectiveStoreKey, | ||
73 | + Integer> portNextObjStore) { | ||
72 | super(deviceId, appId, config, linkService, flowObjService, | 74 | super(deviceId, appId, config, linkService, flowObjService, |
73 | - nsNextObjStore, subnetNextObjStore); | 75 | + nsNextObjStore, subnetNextObjStore, portNextObjStore); |
74 | } | 76 | } |
75 | 77 | ||
76 | public PolicyGroupIdentifier createPolicyGroupChain(String id, | 78 | public PolicyGroupIdentifier createPolicyGroupChain(String id, | ... | ... |
1 | +package org.onosproject.segmentrouting.grouphandler; | ||
2 | + | ||
3 | +import org.onosproject.net.DeviceId; | ||
4 | +import org.onosproject.net.PortNumber; | ||
5 | +import org.onosproject.net.flow.TrafficTreatment; | ||
6 | + | ||
7 | +import java.util.Objects; | ||
8 | + | ||
9 | +/** | ||
10 | + * Class definition of Key for Device/Port to NextObjective store. Since there | ||
11 | + * can be multiple next objectives to the same physical port, we differentiate | ||
12 | + * between them by including the treatment in the key. | ||
13 | + */ | ||
14 | +public class PortNextObjectiveStoreKey { | ||
15 | + private final DeviceId deviceId; | ||
16 | + private final PortNumber portNum; | ||
17 | + private final TrafficTreatment treatment; | ||
18 | + | ||
19 | + public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, | ||
20 | + TrafficTreatment treatment) { | ||
21 | + this.deviceId = deviceId; | ||
22 | + this.portNum = portNum; | ||
23 | + this.treatment = treatment; | ||
24 | + } | ||
25 | + | ||
26 | + /** | ||
27 | + * Gets device id in this PortNextObjectiveStoreKey. | ||
28 | + * | ||
29 | + * @return device id | ||
30 | + */ | ||
31 | + public DeviceId deviceId() { | ||
32 | + return deviceId; | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * Gets port information in this PortNextObjectiveStoreKey. | ||
37 | + * | ||
38 | + * @return port information | ||
39 | + */ | ||
40 | + public PortNumber portNumber() { | ||
41 | + return portNum; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Gets treatment information in this PortNextObjectiveStoreKey. | ||
46 | + * | ||
47 | + * @return treatment information | ||
48 | + */ | ||
49 | + public TrafficTreatment treatment() { | ||
50 | + return treatment; | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + public boolean equals(Object o) { | ||
55 | + if (this == o) { | ||
56 | + return true; | ||
57 | + } | ||
58 | + if (!(o instanceof PortNextObjectiveStoreKey)) { | ||
59 | + return false; | ||
60 | + } | ||
61 | + PortNextObjectiveStoreKey that = | ||
62 | + (PortNextObjectiveStoreKey) o; | ||
63 | + return (Objects.equals(this.deviceId, that.deviceId) && | ||
64 | + Objects.equals(this.portNum, that.portNum) && | ||
65 | + Objects.equals(this.treatment, that.treatment)); | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public int hashCode() { | ||
70 | + return Objects.hash(deviceId, portNum, treatment); | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + public String toString() { | ||
75 | + return "Device: " + deviceId + " Port: " + portNum + " Treatment: " + treatment; | ||
76 | + } | ||
77 | +} |
... | @@ -119,7 +119,7 @@ public class GroupsListCommand extends AbstractShellCommand { | ... | @@ -119,7 +119,7 @@ public class GroupsListCommand extends AbstractShellCommand { |
119 | } | 119 | } |
120 | 120 | ||
121 | private void printGroups(DeviceId deviceId, List<Group> groups) { | 121 | private void printGroups(DeviceId deviceId, List<Group> groups) { |
122 | - print("deviceId=%s", deviceId); | 122 | + print("deviceId=%s, groupCount=%s", deviceId, groups.size()); |
123 | for (Group group : groups) { | 123 | for (Group group : groups) { |
124 | print(FORMAT, Integer.toHexString(group.id().id()), group.state(), group.type(), | 124 | print(FORMAT, Integer.toHexString(group.id().id()), group.state(), group.type(), |
125 | group.bytes(), group.packets(), group.appId().name()); | 125 | group.bytes(), group.packets(), group.appId().name()); | ... | ... |
... | @@ -196,7 +196,7 @@ public final class DefaultFilteringObjective implements FilteringObjective { | ... | @@ -196,7 +196,7 @@ public final class DefaultFilteringObjective implements FilteringObjective { |
196 | } | 196 | } |
197 | 197 | ||
198 | @Override | 198 | @Override |
199 | - public Builder setMeta(TrafficTreatment treatment) { | 199 | + public Builder withMeta(TrafficTreatment treatment) { |
200 | this.meta = treatment; | 200 | this.meta = treatment; |
201 | return this; | 201 | return this; |
202 | } | 202 | } | ... | ... |
... | @@ -181,7 +181,7 @@ public final class DefaultNextObjective implements NextObjective { | ... | @@ -181,7 +181,7 @@ public final class DefaultNextObjective implements NextObjective { |
181 | } | 181 | } |
182 | 182 | ||
183 | @Override | 183 | @Override |
184 | - public Builder setMeta(TrafficSelector meta) { | 184 | + public Builder withMeta(TrafficSelector meta) { |
185 | this.meta = meta; | 185 | this.meta = meta; |
186 | return this; | 186 | return this; |
187 | } | 187 | } | ... | ... |
... | @@ -133,7 +133,7 @@ public interface FilteringObjective extends Objective { | ... | @@ -133,7 +133,7 @@ public interface FilteringObjective extends Objective { |
133 | * @param treatment traffic treatment to use | 133 | * @param treatment traffic treatment to use |
134 | * @return a filtering builder | 134 | * @return a filtering builder |
135 | */ | 135 | */ |
136 | - Builder setMeta(TrafficTreatment treatment); | 136 | + Builder withMeta(TrafficTreatment treatment); |
137 | 137 | ||
138 | /** | 138 | /** |
139 | * Assigns an application id. | 139 | * Assigns an application id. | ... | ... |
... | @@ -147,7 +147,7 @@ public interface NextObjective extends Objective { | ... | @@ -147,7 +147,7 @@ public interface NextObjective extends Objective { |
147 | * @param selector match conditions | 147 | * @param selector match conditions |
148 | * @return an objective builder | 148 | * @return an objective builder |
149 | */ | 149 | */ |
150 | - Builder setMeta(TrafficSelector selector); | 150 | + Builder withMeta(TrafficSelector selector); |
151 | 151 | ||
152 | /** | 152 | /** |
153 | * Builds the next objective that will be added. | 153 | * Builds the next objective that will be added. | ... | ... |
... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
16 | package org.onosproject.net.flowobjective.impl; | 16 | package org.onosproject.net.flowobjective.impl; |
17 | 17 | ||
18 | import com.google.common.collect.Maps; | 18 | import com.google.common.collect.Maps; |
19 | -import com.google.common.collect.Sets; | ||
20 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
22 | import org.apache.felix.scr.annotations.Deactivate; | 21 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -53,9 +52,11 @@ import org.onosproject.net.group.GroupService; | ... | @@ -53,9 +52,11 @@ import org.onosproject.net.group.GroupService; |
53 | import org.slf4j.Logger; | 52 | import org.slf4j.Logger; |
54 | import org.slf4j.LoggerFactory; | 53 | import org.slf4j.LoggerFactory; |
55 | 54 | ||
55 | +import java.util.Collections; | ||
56 | import java.util.Map; | 56 | import java.util.Map; |
57 | import java.util.Objects; | 57 | import java.util.Objects; |
58 | import java.util.Set; | 58 | import java.util.Set; |
59 | +import java.util.concurrent.ConcurrentHashMap; | ||
59 | import java.util.concurrent.ExecutorService; | 60 | import java.util.concurrent.ExecutorService; |
60 | 61 | ||
61 | import static com.google.common.base.Preconditions.checkNotNull; | 62 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -228,8 +229,10 @@ public class FlowObjectiveManager implements FlowObjectiveService { | ... | @@ -228,8 +229,10 @@ public class FlowObjectiveManager implements FlowObjectiveService { |
228 | flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { | 229 | flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { |
229 | log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); | 230 | log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); |
230 | // TODO: change to computeIfAbsent | 231 | // TODO: change to computeIfAbsent |
231 | - Set<PendingNext> pnext = pendingForwards.putIfAbsent(fwd.nextId(), | 232 | + Set<PendingNext> newset = Collections.newSetFromMap( |
232 | - Sets.newHashSet(new PendingNext(deviceId, fwd))); | 233 | + new ConcurrentHashMap<PendingNext, Boolean>()); |
234 | + newset.add(new PendingNext(deviceId, fwd)); | ||
235 | + Set<PendingNext> pnext = pendingForwards.putIfAbsent(fwd.nextId(), newset); | ||
233 | if (pnext != null) { | 236 | if (pnext != null) { |
234 | pnext.add(new PendingNext(deviceId, fwd)); | 237 | pnext.add(new PendingNext(deviceId, fwd)); |
235 | } | 238 | } | ... | ... |
... | @@ -350,7 +350,7 @@ public class DistributedGroupStore | ... | @@ -350,7 +350,7 @@ public class DistributedGroupStore |
350 | // Check if a group is existing with the same key | 350 | // Check if a group is existing with the same key |
351 | Group existingGroup = getGroup(groupDesc.deviceId(), groupDesc.appCookie()); | 351 | Group existingGroup = getGroup(groupDesc.deviceId(), groupDesc.appCookie()); |
352 | if (existingGroup != null) { | 352 | if (existingGroup != null) { |
353 | - log.warn("Group already exists with the same key {} in dev:{} with id:{}", | 353 | + log.warn("Group already exists with the same key {} in dev:{} with id:0x{}", |
354 | groupDesc.appCookie(), groupDesc.deviceId(), | 354 | groupDesc.appCookie(), groupDesc.deviceId(), |
355 | Integer.toHexString(existingGroup.id().id())); | 355 | Integer.toHexString(existingGroup.id().id())); |
356 | return; | 356 | return; | ... | ... |
... | @@ -39,7 +39,9 @@ import org.onosproject.net.flow.FlowRuleOperations; | ... | @@ -39,7 +39,9 @@ import org.onosproject.net.flow.FlowRuleOperations; |
39 | import org.onosproject.net.flow.FlowRuleOperationsContext; | 39 | import org.onosproject.net.flow.FlowRuleOperationsContext; |
40 | import org.onosproject.net.flow.TrafficSelector; | 40 | import org.onosproject.net.flow.TrafficSelector; |
41 | import org.onosproject.net.flow.TrafficTreatment; | 41 | import org.onosproject.net.flow.TrafficTreatment; |
42 | +import org.onosproject.net.flow.criteria.Criteria; | ||
42 | import org.onosproject.net.flow.criteria.Criterion; | 43 | import org.onosproject.net.flow.criteria.Criterion; |
44 | +import org.onosproject.net.flow.criteria.EthCriterion; | ||
43 | import org.onosproject.net.flow.criteria.EthTypeCriterion; | 45 | import org.onosproject.net.flow.criteria.EthTypeCriterion; |
44 | import org.onosproject.net.flow.criteria.IPCriterion; | 46 | import org.onosproject.net.flow.criteria.IPCriterion; |
45 | import org.onosproject.net.flow.criteria.MplsBosCriterion; | 47 | import org.onosproject.net.flow.criteria.MplsBosCriterion; |
... | @@ -62,6 +64,14 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -62,6 +64,14 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
62 | 64 | ||
63 | private final Logger log = getLogger(getClass()); | 65 | private final Logger log = getLogger(getClass()); |
64 | 66 | ||
67 | + /* | ||
68 | + * Cpqd emulation does not require the non-OF standard rules for | ||
69 | + * matching untagged packets. | ||
70 | + * | ||
71 | + * (non-Javadoc) | ||
72 | + * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter | ||
73 | + */ | ||
74 | + | ||
65 | @Override | 75 | @Override |
66 | protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion, | 76 | protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion, |
67 | VlanIdCriterion vidCriterion, | 77 | VlanIdCriterion vidCriterion, |
... | @@ -122,16 +132,101 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -122,16 +132,101 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
122 | return rules; | 132 | return rules; |
123 | } | 133 | } |
124 | 134 | ||
135 | + /* | ||
136 | + * Cpqd emulation does not handle vlan tags and mpls labels correctly. | ||
137 | + * Workaround requires popping off the VLAN tags in the TMAC table. | ||
138 | + * | ||
139 | + * (non-Javadoc) | ||
140 | + * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthDstFilter | ||
141 | + */ | ||
125 | @Override | 142 | @Override |
126 | - protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 143 | + protected List<FlowRule> processEthDstFilter(PortCriterion portCriterion, |
144 | + EthCriterion ethCriterion, | ||
145 | + VlanIdCriterion vidCriterion, | ||
146 | + VlanId assignedVlan, | ||
147 | + ApplicationId applicationId) { | ||
148 | + //handling untagged packets via assigned VLAN | ||
149 | + if (vidCriterion.vlanId() == VlanId.NONE) { | ||
150 | + vidCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | ||
151 | + } | ||
152 | + // ofdpa cannot match on ALL portnumber, so we need to use separate | ||
153 | + // rules for each port. | ||
154 | + List<PortNumber> portnums = new ArrayList<PortNumber>(); | ||
155 | + if (portCriterion.port() == PortNumber.ALL) { | ||
156 | + for (Port port : deviceService.getPorts(deviceId)) { | ||
157 | + if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) { | ||
158 | + portnums.add(port.number()); | ||
159 | + } | ||
160 | + } | ||
161 | + } else { | ||
162 | + portnums.add(portCriterion.port()); | ||
163 | + } | ||
164 | + | ||
165 | + List<FlowRule> rules = new ArrayList<FlowRule>(); | ||
166 | + for (PortNumber pnum : portnums) { | ||
167 | + // for unicast IP packets | ||
168 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
169 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
170 | + selector.matchInPort(pnum); | ||
171 | + selector.matchVlanId(vidCriterion.vlanId()); | ||
172 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
173 | + selector.matchEthDst(ethCriterion.mac()); | ||
174 | + /* | ||
175 | + * Note: CpqD switches do not handle MPLS-related operation properly | ||
176 | + * for a packet with VLAN tag. We pop VLAN here as a workaround. | ||
177 | + * Side effect: HostService learns redundant hosts with same MAC but | ||
178 | + * different VLAN. No known side effect on the network reachability. | ||
179 | + */ | ||
180 | + treatment.popVlan(); | ||
181 | + treatment.transition(UNICAST_ROUTING_TABLE); | ||
182 | + FlowRule rule = DefaultFlowRule.builder() | ||
183 | + .forDevice(deviceId) | ||
184 | + .withSelector(selector.build()) | ||
185 | + .withTreatment(treatment.build()) | ||
186 | + .withPriority(DEFAULT_PRIORITY) | ||
187 | + .fromApp(applicationId) | ||
188 | + .makePermanent() | ||
189 | + .forTable(TMAC_TABLE).build(); | ||
190 | + rules.add(rule); | ||
191 | + //for MPLS packets | ||
192 | + selector = DefaultTrafficSelector.builder(); | ||
193 | + treatment = DefaultTrafficTreatment.builder(); | ||
194 | + selector.matchInPort(pnum); | ||
195 | + selector.matchVlanId(vidCriterion.vlanId()); | ||
196 | + selector.matchEthType(Ethernet.MPLS_UNICAST); | ||
197 | + selector.matchEthDst(ethCriterion.mac()); | ||
198 | + // workaround here again | ||
199 | + treatment.popVlan(); | ||
200 | + treatment.transition(MPLS_TABLE_0); | ||
201 | + rule = DefaultFlowRule.builder() | ||
202 | + .forDevice(deviceId) | ||
203 | + .withSelector(selector.build()) | ||
204 | + .withTreatment(treatment.build()) | ||
205 | + .withPriority(DEFAULT_PRIORITY) | ||
206 | + .fromApp(applicationId) | ||
207 | + .makePermanent() | ||
208 | + .forTable(TMAC_TABLE).build(); | ||
209 | + rules.add(rule); | ||
210 | + } | ||
211 | + return rules; | ||
212 | + } | ||
213 | + | ||
214 | + /* | ||
215 | + * Cpqd emulation allows MPLS ecmp. | ||
216 | + * | ||
217 | + * (non-Javadoc) | ||
218 | + * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processEthTypeSpecific | ||
219 | + */ | ||
220 | + @Override | ||
221 | + protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) { | ||
127 | TrafficSelector selector = fwd.selector(); | 222 | TrafficSelector selector = fwd.selector(); |
128 | EthTypeCriterion ethType = | 223 | EthTypeCriterion ethType = |
129 | (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); | 224 | (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); |
130 | if ((ethType == null) || | 225 | if ((ethType == null) || |
131 | (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && | 226 | (ethType.ethType().toShort() != Ethernet.TYPE_IPV4) && |
132 | (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) { | 227 | (ethType.ethType().toShort() != Ethernet.MPLS_UNICAST)) { |
133 | - log.warn("processSpecific: Unsupported " | 228 | + log.warn("processSpecific: Unsupported forwarding objective criteria" |
134 | - + "forwarding objective criteraia"); | 229 | + + "ethType:{} in dev:{}", ethType, deviceId); |
135 | fail(fwd, ObjectiveError.UNSUPPORTED); | 230 | fail(fwd, ObjectiveError.UNSUPPORTED); |
136 | return Collections.emptySet(); | 231 | return Collections.emptySet(); |
137 | } | 232 | } |
... | @@ -143,8 +238,8 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -143,8 +238,8 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
143 | .matchIPDst(((IPCriterion) | 238 | .matchIPDst(((IPCriterion) |
144 | selector.getCriterion(Criterion.Type.IPV4_DST)).ip()); | 239 | selector.getCriterion(Criterion.Type.IPV4_DST)).ip()); |
145 | forTableId = UNICAST_ROUTING_TABLE; | 240 | forTableId = UNICAST_ROUTING_TABLE; |
146 | - log.debug("processing IPv4 specific forwarding objective {} hash{} in dev:{}", | 241 | + log.debug("processing IPv4 specific forwarding objective {} -> next:{}" |
147 | - fwd.id(), fwd.hashCode(), deviceId); | 242 | + + " in dev:{}", fwd.id(), fwd.nextId(), deviceId); |
148 | } else { | 243 | } else { |
149 | filteredSelector | 244 | filteredSelector |
150 | .matchEthType(Ethernet.MPLS_UNICAST) | 245 | .matchEthType(Ethernet.MPLS_UNICAST) |
... | @@ -156,8 +251,8 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -156,8 +251,8 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
156 | filteredSelector.matchMplsBos(bos.mplsBos()); | 251 | filteredSelector.matchMplsBos(bos.mplsBos()); |
157 | } | 252 | } |
158 | forTableId = MPLS_TABLE_1; | 253 | forTableId = MPLS_TABLE_1; |
159 | - log.debug("processing MPLS specific forwarding objective {} hash:{} in dev {}", | 254 | + log.debug("processing MPLS specific forwarding objective {} -> next:{}" |
160 | - fwd.id(), fwd.hashCode(), deviceId); | 255 | + + " in dev {}", fwd.id(), fwd.nextId(), deviceId); |
161 | } | 256 | } |
162 | 257 | ||
163 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); | 258 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); |
... | @@ -197,7 +292,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -197,7 +292,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
197 | return Collections.singletonList(ruleBuilder.build()); | 292 | return Collections.singletonList(ruleBuilder.build()); |
198 | } | 293 | } |
199 | 294 | ||
200 | - | ||
201 | @Override | 295 | @Override |
202 | protected void initializePipeline() { | 296 | protected void initializePipeline() { |
203 | processPortTable(); | 297 | processPortTable(); |
... | @@ -210,7 +304,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -210,7 +304,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
210 | processAclTable(); | 304 | processAclTable(); |
211 | } | 305 | } |
212 | 306 | ||
213 | - @Override | ||
214 | protected void processPortTable() { | 307 | protected void processPortTable() { |
215 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 308 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
216 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 309 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
... | @@ -239,7 +332,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -239,7 +332,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
239 | })); | 332 | })); |
240 | } | 333 | } |
241 | 334 | ||
242 | - @Override | ||
243 | protected void processTmacTable() { | 335 | protected void processTmacTable() { |
244 | //table miss entry | 336 | //table miss entry |
245 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 337 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
... | @@ -270,7 +362,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -270,7 +362,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
270 | })); | 362 | })); |
271 | } | 363 | } |
272 | 364 | ||
273 | - @Override | ||
274 | protected void processIpTable() { | 365 | protected void processIpTable() { |
275 | //table miss entry | 366 | //table miss entry |
276 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 367 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
... | @@ -278,6 +369,7 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -278,6 +369,7 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
278 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 369 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
279 | selector = DefaultTrafficSelector.builder(); | 370 | selector = DefaultTrafficSelector.builder(); |
280 | treatment = DefaultTrafficTreatment.builder(); | 371 | treatment = DefaultTrafficTreatment.builder(); |
372 | + treatment.deferred().setOutput(PortNumber.CONTROLLER); | ||
281 | treatment.transition(ACL_TABLE); | 373 | treatment.transition(ACL_TABLE); |
282 | FlowRule rule = DefaultFlowRule.builder() | 374 | FlowRule rule = DefaultFlowRule.builder() |
283 | .forDevice(deviceId) | 375 | .forDevice(deviceId) |
... | @@ -301,7 +393,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -301,7 +393,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
301 | })); | 393 | })); |
302 | } | 394 | } |
303 | 395 | ||
304 | - @Override | ||
305 | protected void processMplsTable() { | 396 | protected void processMplsTable() { |
306 | //table miss entry | 397 | //table miss entry |
307 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 398 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
... | @@ -374,7 +465,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -374,7 +465,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
374 | })); | 465 | })); |
375 | } | 466 | } |
376 | 467 | ||
377 | - @Override | ||
378 | protected void processAclTable() { | 468 | protected void processAclTable() { |
379 | //table miss entry - catch all to executed action-set | 469 | //table miss entry - catch all to executed action-set |
380 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 470 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -287,24 +287,14 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -287,24 +287,14 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
287 | case SIMPLE: | 287 | case SIMPLE: |
288 | Collection<TrafficTreatment> treatments = nextObjective.next(); | 288 | Collection<TrafficTreatment> treatments = nextObjective.next(); |
289 | if (treatments.size() == 1) { | 289 | if (treatments.size() == 1) { |
290 | - TrafficTreatment treatment = treatments.iterator().next(); | 290 | + // Spring Open TTP converts simple nextObjective to flow-actions |
291 | - GroupBucket bucket = DefaultGroupBucket | 291 | + // in a dummy group |
292 | - .createIndirectGroupBucket(treatment); | 292 | + TrafficTreatment treatment = nextObjective.next().iterator().next(); |
293 | - final GroupKey key = new DefaultGroupKey( | 293 | + log.debug("Converting SIMPLE group for next objective id {} " + |
294 | - appKryo.serialize(nextObjective | 294 | + "to {} flow-actions in device:{}", nextObjective.id(), |
295 | - .id())); | 295 | + treatment.allInstructions().size(), deviceId); |
296 | - GroupDescription groupDescription = new DefaultGroupDescription( | 296 | + flowObjectiveStore.putNextGroup(nextObjective.id(), |
297 | - deviceId, | 297 | + new SpringOpenGroup(null, treatment)); |
298 | - GroupDescription.Type.INDIRECT, | ||
299 | - new GroupBuckets( | ||
300 | - Collections.singletonList(bucket)), | ||
301 | - key, | ||
302 | - null, | ||
303 | - nextObjective.appId()); | ||
304 | - log.debug("Creating SIMPLE group for next objective id {} " | ||
305 | - + "in dev:{}", nextObjective.id(), deviceId); | ||
306 | - pendingGroups.put(key, nextObjective); | ||
307 | - groupService.addGroup(groupDescription); | ||
308 | } | 298 | } |
309 | break; | 299 | break; |
310 | case HASHED: | 300 | case HASHED: |
... | @@ -624,8 +614,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -624,8 +614,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
624 | if (next != null) { | 614 | if (next != null) { |
625 | SpringOpenGroup soGroup = appKryo.deserialize(next.data()); | 615 | SpringOpenGroup soGroup = appKryo.deserialize(next.data()); |
626 | if (soGroup.dummy) { | 616 | if (soGroup.dummy) { |
627 | - log.debug("Adding flow-actions for fwd. obj. {} " | 617 | + log.debug("Adding {} flow-actions for fwd. obj. {} -> next:{} " |
628 | - + "in dev: {}", fwd.id(), deviceId); | 618 | + + "in dev: {}", soGroup.treatment.allInstructions().size(), |
619 | + fwd.id(), fwd.nextId(), deviceId); | ||
629 | for (Instruction ins : soGroup.treatment.allInstructions()) { | 620 | for (Instruction ins : soGroup.treatment.allInstructions()) { |
630 | treatmentBuilder.add(ins); | 621 | treatmentBuilder.add(ins); |
631 | } | 622 | } |
... | @@ -639,7 +630,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -639,7 +630,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
639 | } | 630 | } |
640 | treatmentBuilder.deferred().group(group.id()); | 631 | treatmentBuilder.deferred().group(group.id()); |
641 | log.debug("Adding OUTGROUP action to group:{} for fwd. obj. {} " | 632 | log.debug("Adding OUTGROUP action to group:{} for fwd. obj. {} " |
642 | - + "in dev: {}", group.id(), fwd.id(), deviceId); | 633 | + + "for next:{} in dev: {}", group.id(), fwd.id(), |
634 | + fwd.nextId(), deviceId); | ||
643 | } | 635 | } |
644 | } else { | 636 | } else { |
645 | log.warn("processSpecific: No associated next objective object"); | 637 | log.warn("processSpecific: No associated next objective object"); |
... | @@ -705,10 +697,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -705,10 +697,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
705 | if (next != null) { | 697 | if (next != null) { |
706 | SpringOpenGroup soGrp = appKryo.deserialize(next.data()); | 698 | SpringOpenGroup soGrp = appKryo.deserialize(next.data()); |
707 | if (soGrp.dummy) { | 699 | if (soGrp.dummy) { |
708 | - log.debug("Adding flow-actions for fwd. obj. {} " | 700 | + log.debug("Adding {} flow-actions for fwd. obj. {} " |
709 | - + "in dev: {}", fwd.id(), deviceId); | 701 | + + "in dev: {}", soGrp.treatment.allInstructions().size(), |
702 | + fwd.id(), deviceId); | ||
710 | for (Instruction ins : soGrp.treatment.allInstructions()) { | 703 | for (Instruction ins : soGrp.treatment.allInstructions()) { |
711 | - treatmentBuilder.add(ins); | 704 | + treatmentBuilder.deferred().add(ins); |
712 | } | 705 | } |
713 | } else { | 706 | } else { |
714 | GroupKey key = soGrp.key; | 707 | GroupKey key = soGrp.key; |
... | @@ -773,6 +766,12 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -773,6 +766,12 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
773 | return rules; | 766 | return rules; |
774 | } | 767 | } |
775 | 768 | ||
769 | + /* | ||
770 | + * Note: CpqD switches do not handle MPLS-related operation properly | ||
771 | + * for a packet with VLAN tag. We pop VLAN here as a workaround. | ||
772 | + * Side effect: HostService learns redundant hosts with same MAC but | ||
773 | + * different VLAN. No known side effect on the network reachability. | ||
774 | + */ | ||
776 | protected List<FlowRule> processEthDstFilter(EthCriterion ethCriterion, | 775 | protected List<FlowRule> processEthDstFilter(EthCriterion ethCriterion, |
777 | VlanIdCriterion vlanIdCriterion, | 776 | VlanIdCriterion vlanIdCriterion, |
778 | FilteringObjective filt, | 777 | FilteringObjective filt, |
... | @@ -783,12 +782,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -783,12 +782,6 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
783 | vlanIdCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); | 782 | vlanIdCriterion = (VlanIdCriterion) Criteria.matchVlanId(assignedVlan); |
784 | } | 783 | } |
785 | 784 | ||
786 | - /* | ||
787 | - * Note: CpqD switches do not handle MPLS-related operation properly | ||
788 | - * for a packet with VLAN tag. We pop VLAN here as a workaround. | ||
789 | - * Side effect: HostService learns redundant hosts with same MAC but | ||
790 | - * different VLAN. No known side effect on the network reachability. | ||
791 | - */ | ||
792 | List<FlowRule> rules = new ArrayList<>(); | 785 | List<FlowRule> rules = new ArrayList<>(); |
793 | TrafficSelector.Builder selectorIp = DefaultTrafficSelector | 786 | TrafficSelector.Builder selectorIp = DefaultTrafficSelector |
794 | .builder(); | 787 | .builder(); | ... | ... |
-
Please register or login to post a comment