Committed by
Gerrit Code Review
ONOS-1930 : Tunnel and policy failover with multi-instances
- Prevents tunnel delete from removing groups used for default flows - Removes SegmentRoutingManager reference from Tunnel and Policy class - Adds some error checks such as duplicates tunnel IDs or duplicate polices Change-Id: I0e7d5e2eff0aea6dad13137a872fee58e083b11c
Showing
11 changed files
with
518 additions
and
327 deletions
... | @@ -16,16 +16,8 @@ | ... | @@ -16,16 +16,8 @@ |
16 | 16 | ||
17 | package org.onosproject.segmentrouting; | 17 | package org.onosproject.segmentrouting; |
18 | 18 | ||
19 | -import org.onosproject.net.DeviceId; | ||
20 | -import org.onosproject.net.Link; | ||
21 | -import org.onosproject.segmentrouting.grouphandler.NeighborSet; | ||
22 | -import org.slf4j.Logger; | ||
23 | -import org.slf4j.LoggerFactory; | ||
24 | - | ||
25 | -import java.util.Collections; | ||
26 | -import java.util.HashSet; | ||
27 | import java.util.List; | 19 | import java.util.List; |
28 | -import java.util.Set; | 20 | +import java.util.Objects; |
29 | 21 | ||
30 | import static com.google.common.base.Preconditions.checkNotNull; | 22 | import static com.google.common.base.Preconditions.checkNotNull; |
31 | 23 | ||
... | @@ -34,31 +26,11 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -34,31 +26,11 @@ import static com.google.common.base.Preconditions.checkNotNull; |
34 | */ | 26 | */ |
35 | public class DefaultTunnel implements Tunnel { | 27 | public class DefaultTunnel implements Tunnel { |
36 | 28 | ||
37 | - private static final Logger log = LoggerFactory | 29 | + private final String id; |
38 | - .getLogger(DefaultTunnel.class); | ||
39 | - | ||
40 | - private final String tunnelId; | ||
41 | private final List<Integer> labelIds; | 30 | private final List<Integer> labelIds; |
42 | - private final SegmentRoutingManager srManager; | ||
43 | - private final DeviceConfiguration config; | ||
44 | 31 | ||
45 | private int groupId; | 32 | private int groupId; |
46 | - | 33 | + private boolean allowedToRemoveGroup; |
47 | - /** | ||
48 | - * Creates a Tunnel reference. | ||
49 | - * | ||
50 | - * @param srm SegmentRoutingManager object | ||
51 | - * @param tid Tunnel ID | ||
52 | - * @param labelIds Label stack of the tunnel | ||
53 | - */ | ||
54 | - public DefaultTunnel(SegmentRoutingManager srm, String tid, | ||
55 | - List<Integer> labelIds) { | ||
56 | - this.srManager = checkNotNull(srm); | ||
57 | - this.tunnelId = checkNotNull(tid); | ||
58 | - this.labelIds = Collections.unmodifiableList(labelIds); | ||
59 | - this.config = srManager.deviceConfiguration; | ||
60 | - this.groupId = -1; | ||
61 | - } | ||
62 | 34 | ||
63 | /** | 35 | /** |
64 | * Creates a Tunnel reference. | 36 | * Creates a Tunnel reference. |
... | @@ -67,10 +39,10 @@ public class DefaultTunnel implements Tunnel { | ... | @@ -67,10 +39,10 @@ public class DefaultTunnel implements Tunnel { |
67 | * @param labelIds Label stack of the tunnel | 39 | * @param labelIds Label stack of the tunnel |
68 | */ | 40 | */ |
69 | public DefaultTunnel(String tid, List<Integer> labelIds) { | 41 | public DefaultTunnel(String tid, List<Integer> labelIds) { |
70 | - this.srManager = null; | 42 | + this.id = checkNotNull(tid); |
71 | - this.tunnelId = checkNotNull(tid); | 43 | + this.labelIds = labelIds; |
72 | - this.labelIds = Collections.unmodifiableList(labelIds); | 44 | + //TODO: need to register the class in Kryo for this |
73 | - this.config = null; | 45 | + //this.labelIds = Collections.unmodifiableList(labelIds); |
74 | this.groupId = -1; | 46 | this.groupId = -1; |
75 | } | 47 | } |
76 | 48 | ||
... | @@ -80,16 +52,14 @@ public class DefaultTunnel implements Tunnel { | ... | @@ -80,16 +52,14 @@ public class DefaultTunnel implements Tunnel { |
80 | * @param tunnel DefaultTunnel reference | 52 | * @param tunnel DefaultTunnel reference |
81 | */ | 53 | */ |
82 | public DefaultTunnel(DefaultTunnel tunnel) { | 54 | public DefaultTunnel(DefaultTunnel tunnel) { |
83 | - this.srManager = tunnel.srManager; | 55 | + this.id = tunnel.id; |
84 | - this.tunnelId = tunnel.tunnelId; | ||
85 | this.labelIds = tunnel.labelIds; | 56 | this.labelIds = tunnel.labelIds; |
86 | - this.config = tunnel.config; | ||
87 | this.groupId = tunnel.groupId; | 57 | this.groupId = tunnel.groupId; |
88 | } | 58 | } |
89 | 59 | ||
90 | @Override | 60 | @Override |
91 | public String id() { | 61 | public String id() { |
92 | - return this.tunnelId; | 62 | + return this.id; |
93 | } | 63 | } |
94 | 64 | ||
95 | @Override | 65 | @Override |
... | @@ -98,71 +68,44 @@ public class DefaultTunnel implements Tunnel { | ... | @@ -98,71 +68,44 @@ public class DefaultTunnel implements Tunnel { |
98 | } | 68 | } |
99 | 69 | ||
100 | @Override | 70 | @Override |
101 | - public boolean create() { | 71 | + public int groupId() { |
102 | - | 72 | + return this.groupId; |
103 | - if (labelIds.isEmpty() || labelIds.size() < 3) { | 73 | + } |
104 | - log.error("More than one router needs to specified to created a tunnel"); | ||
105 | - return false; | ||
106 | - } | ||
107 | - | ||
108 | - groupId = createGroupsForTunnel(); | ||
109 | - if (groupId < 0) { | ||
110 | - log.error("Failed to create groups for the tunnel"); | ||
111 | - return false; | ||
112 | - } | ||
113 | 74 | ||
114 | - return true; | 75 | + @Override |
76 | + public void setGroupId(int id) { | ||
77 | + this.groupId = id; | ||
115 | } | 78 | } |
116 | 79 | ||
117 | @Override | 80 | @Override |
118 | - public boolean remove() { | 81 | + public boolean equals(Object o) { |
82 | + if (this == o) { | ||
83 | + return true; | ||
84 | + } | ||
119 | 85 | ||
120 | - DeviceId deviceId = config.getDeviceId(labelIds.get(0)); | 86 | + if (o instanceof DefaultTunnel) { |
121 | - srManager.removeNextObjective(deviceId, groupId); | 87 | + DefaultTunnel tunnel = (DefaultTunnel) o; |
88 | + // We compare only the tunnel paths. | ||
89 | + if (tunnel.labelIds.equals(this.labelIds)) { | ||
90 | + return true; | ||
91 | + } | ||
92 | + } | ||
122 | 93 | ||
123 | - return true; | 94 | + return false; |
124 | } | 95 | } |
125 | 96 | ||
126 | @Override | 97 | @Override |
127 | - public int groupId() { | 98 | + public int hashCode() { |
128 | - return this.groupId; | 99 | + return Objects.hash(labelIds); |
129 | } | 100 | } |
130 | 101 | ||
131 | @Override | 102 | @Override |
132 | - public DeviceId source() { | 103 | + public boolean isAllowedToRemoveGroup() { |
133 | - return config.getDeviceId(labelIds.get(0)); | 104 | + return this.allowedToRemoveGroup; |
134 | } | 105 | } |
135 | 106 | ||
136 | - private int createGroupsForTunnel() { | 107 | + @Override |
137 | - | 108 | + public void allowToRemoveGroup(boolean b) { |
138 | - List<Integer> portNumbers; | 109 | + this.allowedToRemoveGroup = b; |
139 | - | ||
140 | - int groupId; | ||
141 | - | ||
142 | - DeviceId deviceId = config.getDeviceId(labelIds.get(0)); | ||
143 | - if (deviceId == null) { | ||
144 | - log.warn("No device found for SID {}", labelIds.get(0)); | ||
145 | - return -1; | ||
146 | - } | ||
147 | - Set<DeviceId> deviceIds = new HashSet<>(); | ||
148 | - int sid = labelIds.get(1); | ||
149 | - if (config.isAdjacencySid(deviceId, sid)) { | ||
150 | - portNumbers = config.getPortsForAdjacencySid(deviceId, sid); | ||
151 | - for (Link link: srManager.linkService.getDeviceEgressLinks(deviceId)) { | ||
152 | - for (Integer port: portNumbers) { | ||
153 | - if (link.src().port().toLong() == port) { | ||
154 | - deviceIds.add(link.dst().deviceId()); | ||
155 | - } | ||
156 | - } | ||
157 | - } | ||
158 | - } else { | ||
159 | - deviceIds.add(config.getDeviceId(sid)); | ||
160 | - } | ||
161 | - | ||
162 | - NeighborSet ns = new NeighborSet(deviceIds, labelIds.get(2)); | ||
163 | - groupId = srManager.getNextObjectiveId(deviceId, ns); | ||
164 | - | ||
165 | - return groupId; | ||
166 | } | 110 | } |
167 | - | ||
168 | } | 111 | } | ... | ... |
... | @@ -16,8 +16,6 @@ | ... | @@ -16,8 +16,6 @@ |
16 | 16 | ||
17 | package org.onosproject.segmentrouting; | 17 | package org.onosproject.segmentrouting; |
18 | 18 | ||
19 | -import org.onosproject.net.flow.TrafficSelector; | ||
20 | - | ||
21 | /** | 19 | /** |
22 | * Interface for Segment Routing Policy. | 20 | * Interface for Segment Routing Policy. |
23 | */ | 21 | */ |
... | @@ -47,13 +45,6 @@ public interface Policy { | ... | @@ -47,13 +45,6 @@ public interface Policy { |
47 | String id(); | 45 | String id(); |
48 | 46 | ||
49 | /** | 47 | /** |
50 | - * Returns the traffic selector object. | ||
51 | - * | ||
52 | - * @return TrafficSelector object | ||
53 | - */ | ||
54 | - TrafficSelector selector(); | ||
55 | - | ||
56 | - /** | ||
57 | * Returns the priority of the policy. | 48 | * Returns the priority of the policy. |
58 | * | 49 | * |
59 | * @return priority | 50 | * @return priority |
... | @@ -68,16 +59,38 @@ public interface Policy { | ... | @@ -68,16 +59,38 @@ public interface Policy { |
68 | Type type(); | 59 | Type type(); |
69 | 60 | ||
70 | /** | 61 | /** |
71 | - * Creates a policy. | 62 | + * Returns the source IP address of the policy. |
63 | + * | ||
64 | + * @return source IP address | ||
65 | + */ | ||
66 | + String srcIp(); | ||
67 | + | ||
68 | + /** | ||
69 | + * Returns the destination IP address of the policy. | ||
72 | * | 70 | * |
73 | - * @return true if succeeds, false otherwise | 71 | + * @return destination IP address |
74 | */ | 72 | */ |
75 | - boolean create(); | 73 | + String dstIp(); |
76 | 74 | ||
77 | /** | 75 | /** |
78 | - * Removes the policy. | 76 | + * Returns the IP protocol of the policy. |
79 | * | 77 | * |
80 | - * @return true if succeeds, false otherwise | 78 | + * @return IP protocol |
81 | */ | 79 | */ |
82 | - boolean remove(); | 80 | + String ipProto(); |
81 | + | ||
82 | + /** | ||
83 | + * Returns the source port of the policy. | ||
84 | + * | ||
85 | + * @return source port | ||
86 | + */ | ||
87 | + short srcPort(); | ||
88 | + | ||
89 | + /** | ||
90 | + * Returns the destination of the policy. | ||
91 | + * | ||
92 | + * @return destination port | ||
93 | + */ | ||
94 | + short dstPort(); | ||
95 | + | ||
83 | } | 96 | } | ... | ... |
... | @@ -16,10 +16,18 @@ | ... | @@ -16,10 +16,18 @@ |
16 | 16 | ||
17 | package org.onosproject.segmentrouting; | 17 | package org.onosproject.segmentrouting; |
18 | 18 | ||
19 | +import org.onlab.packet.Ethernet; | ||
20 | +import org.onlab.packet.IpPrefix; | ||
21 | +import org.onosproject.cli.net.IpProtocol; | ||
22 | +import org.onosproject.net.DeviceId; | ||
23 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
24 | +import org.onosproject.net.flow.TrafficSelector; | ||
25 | +import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
26 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
27 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
19 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
20 | 29 | ||
21 | import java.util.ArrayList; | 30 | import java.util.ArrayList; |
22 | -import java.util.HashMap; | ||
23 | import java.util.List; | 31 | import java.util.List; |
24 | 32 | ||
25 | import static org.slf4j.LoggerFactory.getLogger; | 33 | import static org.slf4j.LoggerFactory.getLogger; |
... | @@ -31,13 +39,17 @@ public class PolicyHandler { | ... | @@ -31,13 +39,17 @@ public class PolicyHandler { |
31 | 39 | ||
32 | protected final Logger log = getLogger(getClass()); | 40 | protected final Logger log = getLogger(getClass()); |
33 | 41 | ||
34 | - private final HashMap<String, Policy> policyMap; | 42 | + private final SegmentRoutingManager srManager; |
43 | + private final EventuallyConsistentMap<String, Policy> policyStore; | ||
35 | 44 | ||
36 | /** | 45 | /** |
37 | * Creates a reference. | 46 | * Creates a reference. |
47 | + * @param policyStore | ||
38 | */ | 48 | */ |
39 | - public PolicyHandler() { | 49 | + public PolicyHandler(SegmentRoutingManager srManager, |
40 | - policyMap = new HashMap<>(); | 50 | + EventuallyConsistentMap<String, Policy> policyStore) { |
51 | + this.srManager = srManager; | ||
52 | + this.policyStore = policyStore; | ||
41 | } | 53 | } |
42 | 54 | ||
43 | /** | 55 | /** |
... | @@ -47,7 +59,7 @@ public class PolicyHandler { | ... | @@ -47,7 +59,7 @@ public class PolicyHandler { |
47 | */ | 59 | */ |
48 | public List<Policy> getPolicies() { | 60 | public List<Policy> getPolicies() { |
49 | List<Policy> policies = new ArrayList<>(); | 61 | List<Policy> policies = new ArrayList<>(); |
50 | - policyMap.values().forEach(policy -> policies.add( | 62 | + policyStore.values().forEach(policy -> policies.add( |
51 | new TunnelPolicy((TunnelPolicy) policy))); | 63 | new TunnelPolicy((TunnelPolicy) policy))); |
52 | 64 | ||
53 | return policies; | 65 | return policies; |
... | @@ -59,8 +71,43 @@ public class PolicyHandler { | ... | @@ -59,8 +71,43 @@ public class PolicyHandler { |
59 | * @param policy policy reference to create | 71 | * @param policy policy reference to create |
60 | */ | 72 | */ |
61 | public void createPolicy(Policy policy) { | 73 | public void createPolicy(Policy policy) { |
62 | - policy.create(); | 74 | + |
63 | - policyMap.put(policy.id(), policy); | 75 | + if (policyStore.containsKey(policy.id())) { |
76 | + log.warn("The policy id {} exists already", policy.id()); | ||
77 | + return; | ||
78 | + } | ||
79 | + | ||
80 | + if (policyStore.containsValue(policy)) { | ||
81 | + log.warn("The same policy exists already"); | ||
82 | + return; | ||
83 | + } | ||
84 | + | ||
85 | + if (policy.type() == Policy.Type.TUNNEL_FLOW) { | ||
86 | + | ||
87 | + TunnelPolicy tunnelPolicy = (TunnelPolicy) policy; | ||
88 | + Tunnel tunnel = srManager.getTunnel(tunnelPolicy.tunnelId()); | ||
89 | + if (tunnel == null) { | ||
90 | + log.error("Tunnel {} does not exists"); | ||
91 | + return; | ||
92 | + } | ||
93 | + | ||
94 | + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective | ||
95 | + .builder() | ||
96 | + .fromApp(srManager.appId) | ||
97 | + .makePermanent() | ||
98 | + .nextStep(tunnel.groupId()) | ||
99 | + .withPriority(tunnelPolicy.priority()) | ||
100 | + .withSelector(buildSelector(policy)) | ||
101 | + .withFlag(ForwardingObjective.Flag.VERSATILE); | ||
102 | + | ||
103 | + DeviceId source = srManager.deviceConfiguration.getDeviceId(tunnel.labelIds().get(0)); | ||
104 | + srManager.flowObjectiveService.forward(source, fwdBuilder.add()); | ||
105 | + | ||
106 | + } else { | ||
107 | + log.warn("Policy type {} is not supported yet.", policy.type()); | ||
108 | + } | ||
109 | + | ||
110 | + policyStore.put(policy.id(), policy); | ||
64 | } | 111 | } |
65 | 112 | ||
66 | /** | 113 | /** |
... | @@ -69,15 +116,64 @@ public class PolicyHandler { | ... | @@ -69,15 +116,64 @@ public class PolicyHandler { |
69 | * @param policyInfo policy information to remove | 116 | * @param policyInfo policy information to remove |
70 | */ | 117 | */ |
71 | public void removePolicy(Policy policyInfo) { | 118 | public void removePolicy(Policy policyInfo) { |
72 | - if (policyMap.get(policyInfo.id()) != null) { | 119 | + |
73 | - if (policyMap.get(policyInfo.id()).remove()) { | 120 | + if (policyStore.get(policyInfo.id()) != null) { |
74 | - policyMap.remove(policyInfo.id()); | 121 | + Policy policy = policyStore.get(policyInfo.id()); |
75 | - } else { | 122 | + if (policy.type() == Policy.Type.TUNNEL_FLOW) { |
76 | - log.error("Failed to remove the policy {}", policyInfo.id()); | 123 | + TunnelPolicy tunnelPolicy = (TunnelPolicy) policy; |
124 | + Tunnel tunnel = srManager.getTunnel(tunnelPolicy.tunnelId()); | ||
125 | + | ||
126 | + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective | ||
127 | + .builder() | ||
128 | + .fromApp(srManager.appId) | ||
129 | + .makePermanent() | ||
130 | + .withSelector(buildSelector(policy)) | ||
131 | + .withPriority(tunnelPolicy.priority()) | ||
132 | + .nextStep(tunnel.groupId()) | ||
133 | + .withFlag(ForwardingObjective.Flag.VERSATILE); | ||
134 | + | ||
135 | + DeviceId source = srManager.deviceConfiguration.getDeviceId(tunnel.labelIds().get(0)); | ||
136 | + srManager.flowObjectiveService.forward(source, fwdBuilder.remove()); | ||
137 | + | ||
138 | + policyStore.remove(policyInfo.id()); | ||
77 | } | 139 | } |
78 | } else { | 140 | } else { |
79 | log.warn("Policy {} was not found", policyInfo.id()); | 141 | log.warn("Policy {} was not found", policyInfo.id()); |
80 | } | 142 | } |
81 | } | 143 | } |
82 | 144 | ||
145 | + | ||
146 | + private TrafficSelector buildSelector(Policy policy) { | ||
147 | + | ||
148 | + TrafficSelector.Builder tsb = DefaultTrafficSelector.builder(); | ||
149 | + tsb.matchEthType(Ethernet.TYPE_IPV4); | ||
150 | + if (policy.dstIp() != null && !policy.dstIp().isEmpty()) { | ||
151 | + tsb.matchIPDst(IpPrefix.valueOf(policy.dstIp())); | ||
152 | + } | ||
153 | + if (policy.srcIp() != null && !policy.srcIp().isEmpty()) { | ||
154 | + tsb.matchIPSrc(IpPrefix.valueOf(policy.srcIp())); | ||
155 | + } | ||
156 | + if (policy.ipProto() != null && !policy.ipProto().isEmpty()) { | ||
157 | + Short ipProto = Short.valueOf(IpProtocol.valueOf(policy.ipProto()).value()); | ||
158 | + tsb.matchIPProtocol(ipProto.byteValue()); | ||
159 | + if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.TCP)) { | ||
160 | + if (policy.srcPort() != 0) { | ||
161 | + tsb.matchTcpSrc(policy.srcPort()); | ||
162 | + } | ||
163 | + if (policy.dstPort() != 0) { | ||
164 | + tsb.matchTcpDst(policy.dstPort()); | ||
165 | + } | ||
166 | + } else if (IpProtocol.valueOf(policy.ipProto()).equals(IpProtocol.UDP)) { | ||
167 | + if (policy.srcPort() != 0) { | ||
168 | + tsb.matchUdpSrc(policy.srcPort()); | ||
169 | + } | ||
170 | + if (policy.dstPort() != 0) { | ||
171 | + tsb.matchUdpDst(policy.dstPort()); | ||
172 | + } | ||
173 | + } | ||
174 | + } | ||
175 | + | ||
176 | + return tsb.build(); | ||
177 | + } | ||
178 | + | ||
83 | } | 179 | } | ... | ... |
... | @@ -128,6 +128,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -128,6 +128,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
128 | // Per device next objective ID store with (device id + neighbor set) as key | 128 | // Per device next objective ID store with (device id + neighbor set) as key |
129 | private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, | 129 | private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, |
130 | Integer> nsNextObjStore = null; | 130 | Integer> nsNextObjStore = null; |
131 | + private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; | ||
132 | + private EventuallyConsistentMap<String, Policy> policyStore = null; | ||
133 | + | ||
131 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 134 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
132 | protected StorageService storageService; | 135 | protected StorageService storageService; |
133 | 136 | ||
... | @@ -148,13 +151,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -148,13 +151,18 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
148 | 151 | ||
149 | kryoBuilder = new KryoNamespace.Builder() | 152 | kryoBuilder = new KryoNamespace.Builder() |
150 | .register(NeighborSetNextObjectiveStoreKey.class, | 153 | .register(NeighborSetNextObjectiveStoreKey.class, |
151 | - NeighborSet.class, | 154 | + NeighborSet.class, |
152 | - DeviceId.class, | 155 | + DeviceId.class, |
153 | - URI.class, | 156 | + URI.class, |
154 | - WallClockTimestamp.class, | 157 | + WallClockTimestamp.class, |
155 | - org.onosproject.cluster.NodeId.class, | 158 | + org.onosproject.cluster.NodeId.class, |
156 | - HashSet.class | 159 | + HashSet.class, |
157 | - ); | 160 | + Tunnel.class, |
161 | + DefaultTunnel.class, | ||
162 | + Policy.class, | ||
163 | + TunnelPolicy.class, | ||
164 | + Policy.Type.class | ||
165 | + ); | ||
158 | 166 | ||
159 | log.debug("Creating EC map nsnextobjectivestore"); | 167 | log.debug("Creating EC map nsnextobjectivestore"); |
160 | EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer> | 168 | EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer> |
... | @@ -167,6 +175,24 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -167,6 +175,24 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
167 | .build(); | 175 | .build(); |
168 | log.trace("Current size {}", nsNextObjStore.size()); | 176 | log.trace("Current size {}", nsNextObjStore.size()); |
169 | 177 | ||
178 | + EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = | ||
179 | + storageService.eventuallyConsistentMapBuilder(); | ||
180 | + | ||
181 | + tunnelStore = tunnelMapBuilder | ||
182 | + .withName("tunnelstore") | ||
183 | + .withSerializer(kryoBuilder) | ||
184 | + .withClockService(new WallclockClockManager<>()) | ||
185 | + .build(); | ||
186 | + | ||
187 | + EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder = | ||
188 | + storageService.eventuallyConsistentMapBuilder(); | ||
189 | + | ||
190 | + policyStore = policyMapBuilder | ||
191 | + .withName("policystore") | ||
192 | + .withSerializer(kryoBuilder) | ||
193 | + .withClockService(new WallclockClockManager<>()) | ||
194 | + .build(); | ||
195 | + | ||
170 | networkConfigService.init(); | 196 | networkConfigService.init(); |
171 | deviceConfiguration = new DeviceConfiguration(networkConfigService); | 197 | deviceConfiguration = new DeviceConfiguration(networkConfigService); |
172 | arpHandler = new ArpHandler(this); | 198 | arpHandler = new ArpHandler(this); |
... | @@ -174,8 +200,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -174,8 +200,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
174 | ipHandler = new IpHandler(this); | 200 | ipHandler = new IpHandler(this); |
175 | routingRulePopulator = new RoutingRulePopulator(this); | 201 | routingRulePopulator = new RoutingRulePopulator(this); |
176 | defaultRoutingHandler = new DefaultRoutingHandler(this); | 202 | defaultRoutingHandler = new DefaultRoutingHandler(this); |
177 | - tunnelHandler = new TunnelHandler(); | 203 | + tunnelHandler = new TunnelHandler(this, tunnelStore); |
178 | - policyHandler = new PolicyHandler(); | 204 | + policyHandler = new PolicyHandler(this, policyStore); |
179 | 205 | ||
180 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); | 206 | packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); |
181 | linkService.addListener(new InternalLinkListener()); | 207 | linkService.addListener(new InternalLinkListener()); |
... | @@ -295,6 +321,24 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -295,6 +321,24 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
295 | } | 321 | } |
296 | 322 | ||
297 | /** | 323 | /** |
324 | + * Checks if the next objective ID (group) for the neighbor set exists or not in the device. | ||
325 | + * | ||
326 | + * @param deviceId Device ID to check | ||
327 | + * @param ns neighbor set to check | ||
328 | + * @return true if it exists, false otherwise | ||
329 | + */ | ||
330 | + public boolean hasNextObjectiveId(DeviceId deviceId, NeighborSet ns) { | ||
331 | + if (groupHandlerMap.get(deviceId) != null) { | ||
332 | + log.trace("getNextObjectiveId query in device {}", deviceId); | ||
333 | + return groupHandlerMap | ||
334 | + .get(deviceId).hasNextObjectiveId(ns); | ||
335 | + } else { | ||
336 | + log.warn("getNextObjectiveId query in device {} not found", deviceId); | ||
337 | + return false; | ||
338 | + } | ||
339 | + } | ||
340 | + | ||
341 | + /** | ||
298 | * Removes the next objective ID. | 342 | * Removes the next objective ID. |
299 | * | 343 | * |
300 | * @param deviceId Device ID | 344 | * @param deviceId Device ID | ... | ... |
... | @@ -16,8 +16,6 @@ | ... | @@ -16,8 +16,6 @@ |
16 | 16 | ||
17 | package org.onosproject.segmentrouting; | 17 | package org.onosproject.segmentrouting; |
18 | 18 | ||
19 | -import org.onosproject.net.DeviceId; | ||
20 | - | ||
21 | import java.util.List; | 19 | import java.util.List; |
22 | 20 | ||
23 | /** | 21 | /** |
... | @@ -40,30 +38,29 @@ public interface Tunnel { | ... | @@ -40,30 +38,29 @@ public interface Tunnel { |
40 | List<Integer> labelIds(); | 38 | List<Integer> labelIds(); |
41 | 39 | ||
42 | /** | 40 | /** |
43 | - * Creates a tunnel. | 41 | + * Returns the group ID for the tunnel. |
44 | * | 42 | * |
45 | - * @return true if succeeds, false otherwise | 43 | + * @return group ID |
46 | */ | 44 | */ |
47 | - boolean create(); | 45 | + int groupId(); |
48 | 46 | ||
49 | /** | 47 | /** |
50 | - * Removes the tunnel. | 48 | + * Sets group ID for the tunnel. |
51 | * | 49 | * |
52 | - * @return true if succeeds, false otherwise. | ||
53 | */ | 50 | */ |
54 | - boolean remove(); | 51 | + void setGroupId(int groupId); |
55 | 52 | ||
56 | /** | 53 | /** |
57 | - * Returns the group ID for the tunnel. | 54 | + * Sets the flag to allow to remove the group or not. |
58 | * | 55 | * |
59 | - * @return group ID | 56 | + * @param ok the flag; true - allow to remove |
60 | */ | 57 | */ |
61 | - int groupId(); | 58 | + void allowToRemoveGroup(boolean ok); |
62 | 59 | ||
63 | /** | 60 | /** |
64 | - * Returns the source device Id of the tunnel. | 61 | + * Checks if it is allowed to remove the group for the tunnel. |
65 | * | 62 | * |
66 | - * @return source device Id | 63 | + * @return true if allowed, false otherwise |
67 | */ | 64 | */ |
68 | - DeviceId source(); | 65 | + boolean isAllowedToRemoveGroup(); |
69 | } | 66 | } | ... | ... |
... | @@ -15,12 +15,18 @@ | ... | @@ -15,12 +15,18 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.segmentrouting; | 16 | package org.onosproject.segmentrouting; |
17 | 17 | ||
18 | +import org.onosproject.net.DeviceId; | ||
19 | +import org.onosproject.net.Link; | ||
20 | +import org.onosproject.segmentrouting.grouphandler.NeighborSet; | ||
21 | +import org.onosproject.store.service.EventuallyConsistentMap; | ||
18 | import org.slf4j.Logger; | 22 | import org.slf4j.Logger; |
19 | 23 | ||
20 | import java.util.ArrayList; | 24 | import java.util.ArrayList; |
25 | +import java.util.HashSet; | ||
21 | import java.util.List; | 26 | import java.util.List; |
22 | -import java.util.HashMap; | 27 | +import java.util.Set; |
23 | 28 | ||
29 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
24 | import static org.slf4j.LoggerFactory.getLogger; | 30 | import static org.slf4j.LoggerFactory.getLogger; |
25 | 31 | ||
26 | /** | 32 | /** |
... | @@ -29,10 +35,15 @@ import static org.slf4j.LoggerFactory.getLogger; | ... | @@ -29,10 +35,15 @@ import static org.slf4j.LoggerFactory.getLogger; |
29 | public class TunnelHandler { | 35 | public class TunnelHandler { |
30 | protected final Logger log = getLogger(getClass()); | 36 | protected final Logger log = getLogger(getClass()); |
31 | 37 | ||
32 | - private final HashMap<String, Tunnel> tunnelMap; | 38 | + private final SegmentRoutingManager srManager; |
39 | + private final DeviceConfiguration config; | ||
40 | + private final EventuallyConsistentMap<String, Tunnel> tunnelStore; | ||
33 | 41 | ||
34 | - public TunnelHandler() { | 42 | + public TunnelHandler(SegmentRoutingManager srm, |
35 | - tunnelMap = new HashMap<>(); | 43 | + EventuallyConsistentMap<String, Tunnel> tunnelStore) { |
44 | + this.srManager = checkNotNull(srm); | ||
45 | + this.config = srm.deviceConfiguration; | ||
46 | + this.tunnelStore = tunnelStore; | ||
36 | } | 47 | } |
37 | 48 | ||
38 | /** | 49 | /** |
... | @@ -40,9 +51,33 @@ public class TunnelHandler { | ... | @@ -40,9 +51,33 @@ public class TunnelHandler { |
40 | * | 51 | * |
41 | * @param tunnel tunnel reference to create a tunnel | 52 | * @param tunnel tunnel reference to create a tunnel |
42 | */ | 53 | */ |
43 | - public void createTunnel(Tunnel tunnel) { | 54 | + public boolean createTunnel(Tunnel tunnel) { |
44 | - tunnel.create(); | 55 | + |
45 | - tunnelMap.put(tunnel.id(), tunnel); | 56 | + if (tunnel.labelIds().isEmpty() || tunnel.labelIds().size() < 3) { |
57 | + log.error("More than one router needs to specified to created a tunnel"); | ||
58 | + return false; | ||
59 | + } | ||
60 | + | ||
61 | + if (tunnelStore.containsKey(tunnel.id())) { | ||
62 | + log.warn("The same tunnel ID exists already"); | ||
63 | + return false; | ||
64 | + } | ||
65 | + | ||
66 | + if (tunnelStore.containsValue(tunnel)) { | ||
67 | + log.warn("The same tunnel exists already"); | ||
68 | + return false; | ||
69 | + } | ||
70 | + | ||
71 | + int groupId = createGroupsForTunnel(tunnel); | ||
72 | + if (groupId < 0) { | ||
73 | + log.error("Failed to create groups for the tunnel"); | ||
74 | + return false; | ||
75 | + } | ||
76 | + | ||
77 | + tunnel.setGroupId(groupId); | ||
78 | + tunnelStore.put(tunnel.id(), tunnel); | ||
79 | + | ||
80 | + return true; | ||
46 | } | 81 | } |
47 | 82 | ||
48 | /** | 83 | /** |
... | @@ -52,10 +87,19 @@ public class TunnelHandler { | ... | @@ -52,10 +87,19 @@ public class TunnelHandler { |
52 | */ | 87 | */ |
53 | public void removeTunnel(Tunnel tunnelInfo) { | 88 | public void removeTunnel(Tunnel tunnelInfo) { |
54 | 89 | ||
55 | - Tunnel tunnel = tunnelMap.get(tunnelInfo.id()); | 90 | + Tunnel tunnel = tunnelStore.get(tunnelInfo.id()); |
56 | if (tunnel != null) { | 91 | if (tunnel != null) { |
57 | - tunnel.remove(); | 92 | + DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0)); |
58 | - tunnelMap.remove(tunnel.id()); | 93 | + if (tunnel.isAllowedToRemoveGroup()) { |
94 | + if (srManager.removeNextObjective(deviceId, tunnel.groupId())) { | ||
95 | + tunnelStore.remove(tunnel.id()); | ||
96 | + } else { | ||
97 | + log.error("Failed to remove the tunnel {}", tunnelInfo.id()); | ||
98 | + } | ||
99 | + } else { | ||
100 | + log.debug("The group is not removed because it is being used."); | ||
101 | + tunnelStore.remove(tunnel.id()); | ||
102 | + } | ||
59 | } else { | 103 | } else { |
60 | log.warn("No tunnel found for tunnel ID {}", tunnelInfo.id()); | 104 | log.warn("No tunnel found for tunnel ID {}", tunnelInfo.id()); |
61 | } | 105 | } |
... | @@ -68,7 +112,7 @@ public class TunnelHandler { | ... | @@ -68,7 +112,7 @@ public class TunnelHandler { |
68 | * @return Tunnel reference | 112 | * @return Tunnel reference |
69 | */ | 113 | */ |
70 | public Tunnel getTunnel(String tid) { | 114 | public Tunnel getTunnel(String tid) { |
71 | - return tunnelMap.get(tid); | 115 | + return tunnelStore.get(tid); |
72 | } | 116 | } |
73 | 117 | ||
74 | /** | 118 | /** |
... | @@ -78,9 +122,50 @@ public class TunnelHandler { | ... | @@ -78,9 +122,50 @@ public class TunnelHandler { |
78 | */ | 122 | */ |
79 | public List<Tunnel> getTunnels() { | 123 | public List<Tunnel> getTunnels() { |
80 | List<Tunnel> tunnels = new ArrayList<>(); | 124 | List<Tunnel> tunnels = new ArrayList<>(); |
81 | - tunnelMap.values().forEach(tunnel -> tunnels.add( | 125 | + tunnelStore.values().forEach(tunnel -> tunnels.add( |
82 | new DefaultTunnel((DefaultTunnel) tunnel))); | 126 | new DefaultTunnel((DefaultTunnel) tunnel))); |
83 | 127 | ||
84 | return tunnels; | 128 | return tunnels; |
85 | } | 129 | } |
130 | + | ||
131 | + private int createGroupsForTunnel(Tunnel tunnel) { | ||
132 | + | ||
133 | + List<Integer> portNumbers; | ||
134 | + | ||
135 | + int groupId; | ||
136 | + | ||
137 | + DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0)); | ||
138 | + if (deviceId == null) { | ||
139 | + log.warn("No device found for SID {}", tunnel.labelIds().get(0)); | ||
140 | + return -1; | ||
141 | + } | ||
142 | + Set<DeviceId> deviceIds = new HashSet<>(); | ||
143 | + int sid = tunnel.labelIds().get(1); | ||
144 | + if (config.isAdjacencySid(deviceId, sid)) { | ||
145 | + portNumbers = config.getPortsForAdjacencySid(deviceId, sid); | ||
146 | + for (Link link: srManager.linkService.getDeviceEgressLinks(deviceId)) { | ||
147 | + for (Integer port: portNumbers) { | ||
148 | + if (link.src().port().toLong() == port) { | ||
149 | + deviceIds.add(link.dst().deviceId()); | ||
150 | + } | ||
151 | + } | ||
152 | + } | ||
153 | + } else { | ||
154 | + deviceIds.add(config.getDeviceId(sid)); | ||
155 | + } | ||
156 | + | ||
157 | + NeighborSet ns = new NeighborSet(deviceIds, tunnel.labelIds().get(2)); | ||
158 | + | ||
159 | + // If the tunnel reuses any existing groups, then tunnel handler | ||
160 | + // should not remove the group. | ||
161 | + if (srManager.hasNextObjectiveId(deviceId, ns)) { | ||
162 | + tunnel.allowToRemoveGroup(false); | ||
163 | + } else { | ||
164 | + tunnel.allowToRemoveGroup(true); | ||
165 | + } | ||
166 | + groupId = srManager.getNextObjectiveId(deviceId, ns); | ||
167 | + | ||
168 | + return groupId; | ||
169 | + } | ||
170 | + | ||
86 | } | 171 | } | ... | ... |
... | @@ -16,9 +16,7 @@ | ... | @@ -16,9 +16,7 @@ |
16 | 16 | ||
17 | package org.onosproject.segmentrouting; | 17 | package org.onosproject.segmentrouting; |
18 | 18 | ||
19 | -import org.onosproject.net.flow.TrafficSelector; | 19 | +import java.util.Objects; |
20 | -import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
21 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
22 | 20 | ||
23 | import static com.google.common.base.Preconditions.checkNotNull; | 21 | import static com.google.common.base.Preconditions.checkNotNull; |
24 | 22 | ||
... | @@ -27,53 +25,45 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -27,53 +25,45 @@ import static com.google.common.base.Preconditions.checkNotNull; |
27 | */ | 25 | */ |
28 | public final class TunnelPolicy implements Policy { | 26 | public final class TunnelPolicy implements Policy { |
29 | 27 | ||
30 | - // FIXME: We should avoid passing around references to implementation objects | ||
31 | - // Instead, if some operational context is required, we should abstract it to | ||
32 | - // a bare minimum. | ||
33 | - private final SegmentRoutingManager srManager; | ||
34 | private final Type type; | 28 | private final Type type; |
35 | private final String id; | 29 | private final String id; |
36 | - private final TrafficSelector selector; | ||
37 | private final int priority; | 30 | private final int priority; |
38 | private final String tunnelId; | 31 | private final String tunnelId; |
39 | - | 32 | + private String dstIp; |
40 | - private TunnelPolicy(SegmentRoutingManager srm, String policyId, Type type, | 33 | + private String srcIp; |
41 | - TrafficSelector selector, int priority, String tunnelId) { | 34 | + private String ipProto; |
42 | - this.srManager = srm; | 35 | + private short srcPort; |
36 | + private short dstPort; | ||
37 | + | ||
38 | + private TunnelPolicy(String policyId, Type type, int priority, String tunnelId, String srcIp, | ||
39 | + String dstIp, String ipProto, short srcPort, short dstPort) { | ||
43 | this.id = checkNotNull(policyId); | 40 | this.id = checkNotNull(policyId); |
44 | this.type = type; | 41 | this.type = type; |
45 | this.tunnelId = tunnelId; | 42 | this.tunnelId = tunnelId; |
46 | this.priority = priority; | 43 | this.priority = priority; |
47 | - this.selector = selector; | 44 | + this.dstIp = dstIp; |
48 | - } | 45 | + this.srcIp = srcIp; |
46 | + this.ipProto = ipProto; | ||
47 | + this.srcPort = srcPort; | ||
48 | + this.dstPort = dstPort; | ||
49 | 49 | ||
50 | - /** | ||
51 | - * Creates a TunnelPolicy reference. | ||
52 | - * | ||
53 | - * @param p TunnelPolicy reference | ||
54 | - */ | ||
55 | - public TunnelPolicy(TunnelPolicy p) { | ||
56 | - this.srManager = p.srManager; | ||
57 | - this.id = p.id; | ||
58 | - this.type = p.type; | ||
59 | - this.tunnelId = p.tunnelId; | ||
60 | - this.priority = p.priority; | ||
61 | - this.selector = p.selector; | ||
62 | } | 50 | } |
63 | 51 | ||
64 | /** | 52 | /** |
65 | * Creates a TunnelPolicy reference. | 53 | * Creates a TunnelPolicy reference. |
66 | * | 54 | * |
67 | - * @param srm reference to the segment routing component | ||
68 | * @param p TunnelPolicy reference | 55 | * @param p TunnelPolicy reference |
69 | */ | 56 | */ |
70 | - public TunnelPolicy(SegmentRoutingManager srm, TunnelPolicy p) { | 57 | + public TunnelPolicy(TunnelPolicy p) { |
71 | - this.srManager = srm; | ||
72 | this.id = p.id; | 58 | this.id = p.id; |
73 | this.type = p.type; | 59 | this.type = p.type; |
74 | this.tunnelId = p.tunnelId; | 60 | this.tunnelId = p.tunnelId; |
75 | this.priority = p.priority; | 61 | this.priority = p.priority; |
76 | - this.selector = p.selector; | 62 | + this.srcIp = p.srcIp; |
63 | + this.dstIp = p.dstIp; | ||
64 | + this.ipProto = p.ipProto; | ||
65 | + this.srcPort = p.srcPort; | ||
66 | + this.dstPort = p.dstPort; | ||
77 | } | 67 | } |
78 | 68 | ||
79 | /** | 69 | /** |
... | @@ -91,11 +81,6 @@ public final class TunnelPolicy implements Policy { | ... | @@ -91,11 +81,6 @@ public final class TunnelPolicy implements Policy { |
91 | } | 81 | } |
92 | 82 | ||
93 | @Override | 83 | @Override |
94 | - public TrafficSelector selector() { | ||
95 | - return selector; | ||
96 | - } | ||
97 | - | ||
98 | - @Override | ||
99 | public int priority() { | 84 | public int priority() { |
100 | return priority; | 85 | return priority; |
101 | } | 86 | } |
... | @@ -106,41 +91,58 @@ public final class TunnelPolicy implements Policy { | ... | @@ -106,41 +91,58 @@ public final class TunnelPolicy implements Policy { |
106 | } | 91 | } |
107 | 92 | ||
108 | @Override | 93 | @Override |
109 | - public boolean create() { | 94 | + public String srcIp() { |
110 | - | 95 | + return srcIp; |
111 | - Tunnel tunnel = srManager.getTunnel(tunnelId); | 96 | + } |
112 | 97 | ||
113 | - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective | 98 | + @Override |
114 | - .builder() | 99 | + public String dstIp() { |
115 | - .fromApp(srManager.appId) | 100 | + return dstIp; |
116 | - .makePermanent() | 101 | + } |
117 | - .nextStep(tunnel.groupId()) | ||
118 | - .withPriority(priority) | ||
119 | - .withSelector(selector) | ||
120 | - .withFlag(ForwardingObjective.Flag.VERSATILE); | ||
121 | 102 | ||
122 | - srManager.flowObjectiveService.forward(tunnel.source(), fwdBuilder.add()); | 103 | + @Override |
104 | + public String ipProto() { | ||
105 | + return ipProto; | ||
106 | + } | ||
123 | 107 | ||
124 | - return true; | 108 | + @Override |
109 | + public short srcPort() { | ||
110 | + return srcPort; | ||
125 | } | 111 | } |
126 | 112 | ||
127 | @Override | 113 | @Override |
128 | - public boolean remove() { | 114 | + public short dstPort() { |
115 | + return dstPort; | ||
116 | + } | ||
129 | 117 | ||
130 | - Tunnel tunnel = srManager.getTunnel(tunnelId); | 118 | + @Override |
119 | + public boolean equals(Object o) { | ||
120 | + if (this == o) { | ||
121 | + return true; | ||
122 | + } | ||
131 | 123 | ||
132 | - ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective | 124 | + if (o instanceof TunnelPolicy) { |
133 | - .builder() | 125 | + TunnelPolicy that = (TunnelPolicy) o; |
134 | - .fromApp(srManager.appId) | 126 | + // We do not compare the policy ID |
135 | - .makePermanent() | 127 | + if (this.type.equals(that.type) && |
136 | - .withSelector(selector) | 128 | + this.tunnelId.equals(that.tunnelId) && |
137 | - .withPriority(priority) | 129 | + this.priority == that.priority && |
138 | - .nextStep(tunnel.groupId()) | 130 | + this.srcIp.equals(that.srcIp) && |
139 | - .withFlag(ForwardingObjective.Flag.VERSATILE); | 131 | + this.dstIp.equals(that.dstIp) && |
132 | + this.srcPort == that.srcPort && | ||
133 | + this.dstPort == that.dstPort && | ||
134 | + this.ipProto.equals(that.ipProto)) { | ||
135 | + return true; | ||
136 | + } | ||
137 | + } | ||
140 | 138 | ||
141 | - srManager.flowObjectiveService.forward(tunnel.source(), fwdBuilder.remove()); | 139 | + return false; |
140 | + } | ||
142 | 141 | ||
143 | - return true; | 142 | + @Override |
143 | + public int hashCode() { | ||
144 | + return Objects.hash(type, tunnelId, srcIp, dstIp, ipProto, | ||
145 | + srcPort, dstPort, priority); | ||
144 | } | 146 | } |
145 | 147 | ||
146 | /** | 148 | /** |
... | @@ -152,17 +154,21 @@ public final class TunnelPolicy implements Policy { | ... | @@ -152,17 +154,21 @@ public final class TunnelPolicy implements Policy { |
152 | return this.tunnelId; | 154 | return this.tunnelId; |
153 | } | 155 | } |
154 | 156 | ||
157 | + | ||
155 | /** | 158 | /** |
156 | * Tunnel Policy Builder. | 159 | * Tunnel Policy Builder. |
157 | */ | 160 | */ |
158 | public static final class Builder { | 161 | public static final class Builder { |
159 | 162 | ||
160 | - private SegmentRoutingManager srManager; | ||
161 | private String id; | 163 | private String id; |
162 | private Type type; | 164 | private Type type; |
163 | - private TrafficSelector selector; | ||
164 | private int priority; | 165 | private int priority; |
165 | private String tunnelId; | 166 | private String tunnelId; |
167 | + private String dstIp; | ||
168 | + private String srcIp; | ||
169 | + private String ipProto; | ||
170 | + private short srcPort; | ||
171 | + private short dstPort; | ||
166 | 172 | ||
167 | /** | 173 | /** |
168 | * Sets the policy Id. | 174 | * Sets the policy Id. |
... | @@ -189,49 +195,85 @@ public final class TunnelPolicy implements Policy { | ... | @@ -189,49 +195,85 @@ public final class TunnelPolicy implements Policy { |
189 | } | 195 | } |
190 | 196 | ||
191 | /** | 197 | /** |
192 | - * Sets the TrafficSelector. | 198 | + * Sets the source IP address. |
193 | * | 199 | * |
194 | - * @param selector TrafficSelector | 200 | + * @param srcIp source IP address |
195 | * @return Builder object | 201 | * @return Builder object |
196 | */ | 202 | */ |
197 | - public Builder setSelector(TrafficSelector selector) { | 203 | + public Builder setSrcIp(String srcIp) { |
198 | - this.selector = selector; | 204 | + this.srcIp = srcIp; |
199 | 205 | ||
200 | return this; | 206 | return this; |
201 | } | 207 | } |
202 | 208 | ||
203 | /** | 209 | /** |
204 | - * Sets the priority of the policy. | 210 | + * Sets the destination IP address. |
205 | * | 211 | * |
206 | - * @param p priority | 212 | + * @param dstIp destination IP address |
207 | * @return Builder object | 213 | * @return Builder object |
208 | */ | 214 | */ |
209 | - public Builder setPriority(int p) { | 215 | + public Builder setDstIp(String dstIp) { |
210 | - this.priority = p; | 216 | + this.dstIp = dstIp; |
211 | 217 | ||
212 | return this; | 218 | return this; |
213 | } | 219 | } |
214 | 220 | ||
215 | /** | 221 | /** |
216 | - * Sets the tunnel Id. | 222 | + * Sets the IP protocol. |
217 | * | 223 | * |
218 | - * @param tunnelId tunnel Id | 224 | + * @param proto IP protocol |
219 | * @return Builder object | 225 | * @return Builder object |
220 | */ | 226 | */ |
221 | - public Builder setTunnelId(String tunnelId) { | 227 | + public Builder setIpProto(String proto) { |
222 | - this.tunnelId = tunnelId; | 228 | + this.ipProto = proto; |
229 | + | ||
230 | + return this; | ||
231 | + } | ||
232 | + | ||
233 | + /** | ||
234 | + * Sets the source port. | ||
235 | + * | ||
236 | + * @param srcPort source port | ||
237 | + * @return Builder object | ||
238 | + */ | ||
239 | + public Builder setSrcPort(short srcPort) { | ||
240 | + this.srcPort = srcPort; | ||
223 | 241 | ||
224 | return this; | 242 | return this; |
225 | } | 243 | } |
226 | 244 | ||
227 | /** | 245 | /** |
228 | - * Sets the Segment Routing Manager reference. | 246 | + * Sets the destination port. |
229 | * | 247 | * |
230 | - * @param srm Segment Routing Manager reference | 248 | + * @param dstPort destination port |
231 | * @return Builder object | 249 | * @return Builder object |
232 | */ | 250 | */ |
233 | - public Builder setManager(SegmentRoutingManager srm) { | 251 | + public Builder setDstPort(short dstPort) { |
234 | - this.srManager = srm; | 252 | + this.dstPort = dstPort; |
253 | + | ||
254 | + return this; | ||
255 | + } | ||
256 | + | ||
257 | + /** | ||
258 | + * Sets the priority of the policy. | ||
259 | + * | ||
260 | + * @param p priority | ||
261 | + * @return Builder object | ||
262 | + */ | ||
263 | + public Builder setPriority(int p) { | ||
264 | + this.priority = p; | ||
265 | + | ||
266 | + return this; | ||
267 | + } | ||
268 | + | ||
269 | + /** | ||
270 | + * Sets the tunnel Id. | ||
271 | + * | ||
272 | + * @param tunnelId tunnel Id | ||
273 | + * @return Builder object | ||
274 | + */ | ||
275 | + public Builder setTunnelId(String tunnelId) { | ||
276 | + this.tunnelId = tunnelId; | ||
235 | 277 | ||
236 | return this; | 278 | return this; |
237 | } | 279 | } |
... | @@ -242,7 +284,8 @@ public final class TunnelPolicy implements Policy { | ... | @@ -242,7 +284,8 @@ public final class TunnelPolicy implements Policy { |
242 | * @return Tunnel Policy reference | 284 | * @return Tunnel Policy reference |
243 | */ | 285 | */ |
244 | public Policy build() { | 286 | public Policy build() { |
245 | - return new TunnelPolicy(srManager, id, type, selector, priority, tunnelId); | 287 | + return new TunnelPolicy(id, type, priority, tunnelId, srcIp, dstIp, |
288 | + ipProto, srcPort, dstPort); | ||
246 | } | 289 | } |
247 | } | 290 | } |
248 | } | 291 | } | ... | ... |
... | @@ -181,8 +181,8 @@ public class DefaultGroupHandler { | ... | @@ -181,8 +181,8 @@ public class DefaultGroupHandler { |
181 | .contains(newLink.dst().deviceId()))) | 181 | .contains(newLink.dst().deviceId()))) |
182 | .collect(Collectors.toSet()); | 182 | .collect(Collectors.toSet()); |
183 | log.trace("linkUp: nsNextObjStore contents for device {}:", | 183 | log.trace("linkUp: nsNextObjStore contents for device {}:", |
184 | - deviceId, | 184 | + deviceId, |
185 | - nsSet); | 185 | + nsSet); |
186 | for (NeighborSet ns : nsSet) { | 186 | for (NeighborSet ns : nsSet) { |
187 | // Create the new bucket to be updated | 187 | // Create the new bucket to be updated |
188 | TrafficTreatment.Builder tBuilder = | 188 | TrafficTreatment.Builder tBuilder = |
... | @@ -317,6 +317,22 @@ public class DefaultGroupHandler { | ... | @@ -317,6 +317,22 @@ public class DefaultGroupHandler { |
317 | return nextId.intValue(); | 317 | return nextId.intValue(); |
318 | } | 318 | } |
319 | 319 | ||
320 | + /** | ||
321 | + * Checks if the next objective ID (group) for the neighbor set exists or not. | ||
322 | + * | ||
323 | + * @param ns neighbor set to check | ||
324 | + * @return true if it exists, false otherwise | ||
325 | + */ | ||
326 | + public boolean hasNextObjectiveId(NeighborSet ns) { | ||
327 | + Integer nextId = nsNextObjStore. | ||
328 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
329 | + if (nextId == null) { | ||
330 | + return false; | ||
331 | + } | ||
332 | + | ||
333 | + return true; | ||
334 | + } | ||
335 | + | ||
320 | // Empty implementation | 336 | // Empty implementation |
321 | protected void newNeighbor(Link newLink) { | 337 | protected void newNeighbor(Link newLink) { |
322 | } | 338 | } |
... | @@ -489,6 +505,7 @@ public class DefaultGroupHandler { | ... | @@ -489,6 +505,7 @@ public class DefaultGroupHandler { |
489 | break; | 505 | break; |
490 | } | 506 | } |
491 | } | 507 | } |
508 | + return true; | ||
492 | } | 509 | } |
493 | 510 | ||
494 | return false; | 511 | return false; | ... | ... |
... | @@ -15,19 +15,9 @@ | ... | @@ -15,19 +15,9 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.segmentrouting.web; | 16 | package org.onosproject.segmentrouting.web; |
17 | 17 | ||
18 | -import org.onlab.packet.Ethernet; | ||
19 | -import org.onlab.packet.IpPrefix; | ||
20 | -import org.onosproject.cli.net.IpProtocol; | ||
21 | import org.onosproject.codec.CodecContext; | 18 | import org.onosproject.codec.CodecContext; |
22 | import org.onosproject.codec.JsonCodec; | 19 | import org.onosproject.codec.JsonCodec; |
23 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
24 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
25 | -import org.onosproject.net.flow.TrafficSelector; | ||
26 | -import org.onosproject.net.flow.criteria.Criterion; | ||
27 | -import org.onosproject.net.flow.criteria.IPCriterion; | ||
28 | -import org.onosproject.net.flow.criteria.IPProtocolCriterion; | ||
29 | -import org.onosproject.net.flow.criteria.TcpPortCriterion; | ||
30 | -import org.onosproject.net.flow.criteria.UdpPortCriterion; | ||
31 | import org.onosproject.segmentrouting.Policy; | 21 | import org.onosproject.segmentrouting.Policy; |
32 | import org.onosproject.segmentrouting.TunnelPolicy; | 22 | import org.onosproject.segmentrouting.TunnelPolicy; |
33 | 23 | ||
... | @@ -52,45 +42,24 @@ public final class PolicyCodec extends JsonCodec<Policy> { | ... | @@ -52,45 +42,24 @@ public final class PolicyCodec extends JsonCodec<Policy> { |
52 | result.put(PRIORITY, policy.priority()); | 42 | result.put(PRIORITY, policy.priority()); |
53 | result.put(TYPE, policy.type().toString()); | 43 | result.put(TYPE, policy.type().toString()); |
54 | 44 | ||
55 | - if (policy.selector().getCriterion(Criterion.Type.IPV4_DST) != null) { | 45 | + if (policy.dstIp() != null) { |
56 | - IPCriterion criterion = (IPCriterion) policy.selector().getCriterion( | 46 | + result.put(DST_IP, policy.dstIp()); |
57 | - Criterion.Type.IPV4_DST); | ||
58 | - result.put(DST_IP, criterion.ip().toString()); | ||
59 | } | 47 | } |
60 | - if (policy.selector().getCriterion(Criterion.Type.IPV4_SRC) != null) { | 48 | + if (policy.srcIp() != null) { |
61 | - IPCriterion criterion = (IPCriterion) policy.selector().getCriterion( | 49 | + result.put(SRC_IP, policy.srcIp()); |
62 | - Criterion.Type.IPV4_SRC); | ||
63 | - result.put(SRC_IP, criterion.ip().toString()); | ||
64 | } | 50 | } |
65 | - if (policy.selector().getCriterion(Criterion.Type.IP_PROTO) != null) { | 51 | + if (policy.ipProto() != null) { |
66 | - IPProtocolCriterion protocolCriterion = | 52 | + result.put(PROTO_TYPE, policy.ipProto()); |
67 | - (IPProtocolCriterion) policy.selector().getCriterion(Criterion.Type.IP_PROTO); | ||
68 | - result.put(PROTO_TYPE, protocolCriterion.protocol()); | ||
69 | } | 53 | } |
70 | - if (policy.selector().getCriterion(Criterion.Type.TCP_SRC) != null) { | 54 | + |
71 | - TcpPortCriterion tcpPortCriterion = | 55 | + int srcPort = policy.srcPort() & 0xffff; |
72 | - (TcpPortCriterion) policy.selector().getCriterion(Criterion.Type.TCP_SRC); | 56 | + if (policy.srcPort() != 0) { |
73 | - result.put(SRC_PORT, tcpPortCriterion.toString()); | 57 | + result.put(SRC_PORT, srcPort); |
74 | - } else if (policy.selector().getCriterion(Criterion.Type.UDP_SRC) != null) { | ||
75 | - UdpPortCriterion udpPortCriterion = | ||
76 | - (UdpPortCriterion) policy.selector().getCriterion(Criterion.Type.UDP_SRC); | ||
77 | - result.put(SRC_PORT, udpPortCriterion.toString()); | ||
78 | - } | ||
79 | - if (policy.selector().getCriterion(Criterion.Type.TCP_DST) != null) { | ||
80 | - TcpPortCriterion tcpPortCriterion = | ||
81 | - (TcpPortCriterion) policy.selector().getCriterion(Criterion.Type.TCP_DST); | ||
82 | - result.put(DST_PORT, tcpPortCriterion.toString()); | ||
83 | - } else if (policy.selector().getCriterion(Criterion.Type.UDP_DST) != null) { | ||
84 | - UdpPortCriterion udpPortCriterion = | ||
85 | - (UdpPortCriterion) policy.selector().getCriterion(Criterion.Type.UDP_DST); | ||
86 | - result.put(DST_PORT, udpPortCriterion.toString()); | ||
87 | } | 58 | } |
88 | - if (policy.selector().getCriterion(Criterion.Type.IP_PROTO) != null) { | 59 | + int dstPort = policy.dstPort() & 0xffff; |
89 | - IPProtocolCriterion protocolCriterion = | 60 | + if (policy.dstPort() != 0) { |
90 | - (IPProtocolCriterion) policy.selector().getCriterion(Criterion.Type.IP_PROTO); | 61 | + result.put(DST_PORT, dstPort); |
91 | - result.put(PROTO_TYPE, protocolCriterion.toString()); | ||
92 | } | 62 | } |
93 | - | ||
94 | if (policy.type() == Policy.Type.TUNNEL_FLOW) { | 63 | if (policy.type() == Policy.Type.TUNNEL_FLOW) { |
95 | result.put(TUNNEL_ID, ((TunnelPolicy) policy).tunnelId()); | 64 | result.put(TUNNEL_ID, ((TunnelPolicy) policy).tunnelId()); |
96 | } | 65 | } |
... | @@ -111,53 +80,43 @@ public final class PolicyCodec extends JsonCodec<Policy> { | ... | @@ -111,53 +80,43 @@ public final class PolicyCodec extends JsonCodec<Policy> { |
111 | short srcPort = json.path(SRC_PORT).shortValue(); | 80 | short srcPort = json.path(SRC_PORT).shortValue(); |
112 | short dstPort = json.path(DST_PORT).shortValue(); | 81 | short dstPort = json.path(DST_PORT).shortValue(); |
113 | 82 | ||
114 | - if (tunnelId != null) { | 83 | + if (json.path(POLICY_ID).isMissingNode() || pid == null) { |
115 | - TrafficSelector.Builder tsb = DefaultTrafficSelector.builder(); | 84 | + // TODO: handle errors |
116 | - tsb.matchEthType(Ethernet.TYPE_IPV4); | 85 | + return null; |
117 | - if (dstIp != null && !dstIp.isEmpty()) { | 86 | + } |
118 | - tsb.matchIPDst(IpPrefix.valueOf(dstIp)); | 87 | + |
88 | + TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(pid); | ||
89 | + if (!json.path(TYPE).isMissingNode() && type != null && | ||
90 | + Policy.Type.valueOf(type).equals(Policy.Type.TUNNEL_FLOW)) { | ||
91 | + | ||
92 | + if (json.path(TUNNEL_ID).isMissingNode() || tunnelId == null) { | ||
93 | + return null; | ||
119 | } | 94 | } |
120 | - if (srcIp != null && !srcIp.isEmpty()) { | 95 | + |
121 | - tsb.matchIPSrc(IpPrefix.valueOf(srcIp)); | 96 | + tpb.setTunnelId(tunnelId); |
97 | + tpb.setType(Policy.Type.valueOf(type)); | ||
98 | + | ||
99 | + if (!json.path(PRIORITY).isMissingNode()) { | ||
100 | + tpb.setPriority(priority); | ||
122 | } | 101 | } |
123 | - if (protoType != null && !protoType.isEmpty()) { | 102 | + if (dstIp != null) { |
124 | - Short ipProto = Short.valueOf(IpProtocol.valueOf(protoType).value()); | 103 | + tpb.setDstIp(dstIp); |
125 | - tsb.matchIPProtocol(ipProto.byteValue()); | ||
126 | - if (IpProtocol.valueOf(protoType).equals(IpProtocol.TCP)) { | ||
127 | - if (srcPort != 0) { | ||
128 | - tsb.matchTcpSrc(srcPort); | ||
129 | - } | ||
130 | - if (dstPort != 0) { | ||
131 | - tsb.matchTcpDst(dstPort); | ||
132 | - } | ||
133 | - } else if (IpProtocol.valueOf(protoType).equals(IpProtocol.UDP)) { | ||
134 | - if (srcPort != 0) { | ||
135 | - tsb.matchUdpSrc(srcPort); | ||
136 | - } | ||
137 | - if (dstPort != 0) { | ||
138 | - tsb.matchUdpDst(dstPort); | ||
139 | - } | ||
140 | - } | ||
141 | } | 104 | } |
142 | - TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(pid); | 105 | + if (srcIp != null) { |
143 | - if (tunnelId != null) { | 106 | + tpb.setSrcIp(srcIp); |
144 | - tpb.setTunnelId(tunnelId); | ||
145 | } | 107 | } |
146 | - if (!json.path(PRIORITY).isMissingNode()) { | 108 | + if (protoType != null) { |
147 | - tpb.setPriority(priority); | 109 | + tpb.setIpProto(protoType); |
148 | } | 110 | } |
149 | - if (!json.path(TYPE).isMissingNode()) { | 111 | + if (dstPort != 0) { |
150 | - tpb.setType(Policy.Type.valueOf(type)); | 112 | + tpb.setDstPort(dstPort); |
113 | + } | ||
114 | + if (srcPort != 0) { | ||
115 | + tpb.setSrcPort(srcPort); | ||
151 | } | 116 | } |
152 | - tpb.setSelector(tsb.build()); | ||
153 | - | ||
154 | - return tpb.build(); | ||
155 | - } else { | ||
156 | - // TODO: handle more policy types | ||
157 | - return null; | ||
158 | } | 117 | } |
159 | 118 | ||
160 | - | 119 | + return tpb.build(); |
161 | } | 120 | } |
162 | 121 | ||
163 | } | 122 | } | ... | ... |
... | @@ -20,9 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; | ... | @@ -20,9 +20,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | 20 | ||
21 | import org.onosproject.rest.AbstractWebResource; | 21 | import org.onosproject.rest.AbstractWebResource; |
22 | import org.onosproject.segmentrouting.Policy; | 22 | import org.onosproject.segmentrouting.Policy; |
23 | -import org.onosproject.segmentrouting.SegmentRoutingManager; | ||
24 | import org.onosproject.segmentrouting.SegmentRoutingService; | 23 | import org.onosproject.segmentrouting.SegmentRoutingService; |
25 | -import org.onosproject.segmentrouting.TunnelPolicy; | ||
26 | 24 | ||
27 | import javax.ws.rs.Consumes; | 25 | import javax.ws.rs.Consumes; |
28 | import javax.ws.rs.DELETE; | 26 | import javax.ws.rs.DELETE; |
... | @@ -59,10 +57,9 @@ public class PolicyWebResource extends AbstractWebResource { | ... | @@ -59,10 +57,9 @@ public class PolicyWebResource extends AbstractWebResource { |
59 | ObjectNode policyJson = (ObjectNode) mapper.readTree(input); | 57 | ObjectNode policyJson = (ObjectNode) mapper.readTree(input); |
60 | SegmentRoutingService srService = get(SegmentRoutingService.class); | 58 | SegmentRoutingService srService = get(SegmentRoutingService.class); |
61 | Policy policyInfo = POLICY_CODEC.decode(policyJson, this); | 59 | Policy policyInfo = POLICY_CODEC.decode(policyJson, this); |
62 | - if (policyInfo.type() == Policy.Type.TUNNEL_FLOW) { | ||
63 | - TunnelPolicy policy = new TunnelPolicy((SegmentRoutingManager) srService, (TunnelPolicy) policyInfo); | ||
64 | - srService.createPolicy(policy); | ||
65 | 60 | ||
61 | + if (policyInfo.type() == Policy.Type.TUNNEL_FLOW) { | ||
62 | + srService.createPolicy(policyInfo); | ||
66 | return Response.ok().build(); | 63 | return Response.ok().build(); |
67 | } else { | 64 | } else { |
68 | return Response.serverError().build(); | 65 | return Response.serverError().build(); |
... | @@ -78,6 +75,7 @@ public class PolicyWebResource extends AbstractWebResource { | ... | @@ -78,6 +75,7 @@ public class PolicyWebResource extends AbstractWebResource { |
78 | Policy policyInfo = POLICY_CODEC.decode(policyJson, this); | 75 | Policy policyInfo = POLICY_CODEC.decode(policyJson, this); |
79 | // TODO: Check the result | 76 | // TODO: Check the result |
80 | srService.removePolicy(policyInfo); | 77 | srService.removePolicy(policyInfo); |
78 | + | ||
81 | return Response.ok().build(); | 79 | return Response.ok().build(); |
82 | 80 | ||
83 | } | 81 | } | ... | ... |
... | @@ -19,8 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; | ... | @@ -19,8 +19,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; |
19 | import com.fasterxml.jackson.databind.node.ObjectNode; | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | 20 | ||
21 | import org.onosproject.rest.AbstractWebResource; | 21 | import org.onosproject.rest.AbstractWebResource; |
22 | -import org.onosproject.segmentrouting.DefaultTunnel; | ||
23 | -import org.onosproject.segmentrouting.SegmentRoutingManager; | ||
24 | import org.onosproject.segmentrouting.SegmentRoutingService; | 22 | import org.onosproject.segmentrouting.SegmentRoutingService; |
25 | import org.onosproject.segmentrouting.Tunnel; | 23 | import org.onosproject.segmentrouting.Tunnel; |
26 | 24 | ||
... | @@ -59,9 +57,7 @@ public class TunnelWebResource extends AbstractWebResource { | ... | @@ -59,9 +57,7 @@ public class TunnelWebResource extends AbstractWebResource { |
59 | ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input); | 57 | ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input); |
60 | SegmentRoutingService srService = get(SegmentRoutingService.class); | 58 | SegmentRoutingService srService = get(SegmentRoutingService.class); |
61 | Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this); | 59 | Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this); |
62 | - Tunnel tunnel = new DefaultTunnel((SegmentRoutingManager) srService, | 60 | + srService.createTunnel(tunnelInfo); |
63 | - tunnelInfo.id(), tunnelInfo.labelIds()); | ||
64 | - srService.createTunnel(tunnel); | ||
65 | 61 | ||
66 | return Response.ok().build(); | 62 | return Response.ok().build(); |
67 | } | 63 | } | ... | ... |
-
Please register or login to post a comment