sangho
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
...@@ -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 }
......