sangho
Committed by Gerrit Code Review

ONOS-688 (ONOS-1835,1836,1837) :

 - Implements features to create and remove tunnels and tunnel flow policies.
 - Implements REST API to create/show/delete tunnels and policies.
 - Supports only single instance for now.
 - Fix "apply" actions to "write" actions of all flow rules
Change-Id: I3740ed82fed8eab4ab8b03839192da72d3e223f1
Showing 20 changed files with 1542 additions and 20 deletions
...@@ -32,6 +32,96 @@ ...@@ -32,6 +32,96 @@
32 32
33 <properties> 33 <properties>
34 <onos.app.name>org.onosproject.segmentrouting</onos.app.name> 34 <onos.app.name>org.onosproject.segmentrouting</onos.app.name>
35 + <web.context>/onos/segmentrouting</web.context>
35 </properties> 36 </properties>
36 37
38 + <dependencies>
39 + <dependency>
40 + <groupId>org.onosproject</groupId>
41 + <artifactId>onos-cli</artifactId>
42 + <version>${project.version}</version>
43 + </dependency>
44 +
45 + <dependency>
46 + <groupId>org.apache.karaf.shell</groupId>
47 + <artifactId>org.apache.karaf.shell.console</artifactId>
48 + </dependency>
49 + <dependency>
50 + <groupId>org.onosproject</groupId>
51 + <artifactId>onos-rest</artifactId>
52 + <version>${project.version}</version>
53 + </dependency>
54 + <dependency>
55 + <groupId>org.onosproject</groupId>
56 + <artifactId>onlab-rest</artifactId>
57 + <version>${project.version}</version>
58 + </dependency>
59 + <dependency>
60 + <groupId>javax.ws.rs</groupId>
61 + <artifactId>jsr311-api</artifactId>
62 + <version>1.1.1</version>
63 + </dependency>
64 + <dependency>
65 + <groupId>com.sun.jersey</groupId>
66 + <artifactId>jersey-servlet</artifactId>
67 + </dependency>
68 + <dependency>
69 + <groupId>com.fasterxml.jackson.core</groupId>
70 + <artifactId>jackson-databind</artifactId>
71 + </dependency>
72 +
73 + <dependency>
74 + <groupId>com.fasterxml.jackson.core</groupId>
75 + <artifactId>jackson-annotations</artifactId>
76 + </dependency>
77 +
78 + <dependency>
79 + <groupId>org.osgi</groupId>
80 + <artifactId>org.osgi.compendium</artifactId>
81 + </dependency>
82 + <dependency>
83 + <groupId>org.osgi</groupId>
84 + <artifactId>org.osgi.core</artifactId>
85 + </dependency>
86 + </dependencies>
87 +
88 + <build>
89 + <plugins>
90 + <plugin>
91 + <groupId>org.apache.felix</groupId>
92 + <artifactId>maven-bundle-plugin</artifactId>
93 + <extensions>true</extensions>
94 + <configuration>
95 + <instructions>
96 + <_wab>src/main/webapp/</_wab>
97 + <Bundle-SymbolicName>
98 + ${project.groupId}.${project.artifactId}
99 + </Bundle-SymbolicName>
100 + <Import-Package>
101 + org.slf4j,
102 + org.osgi.framework,
103 + javax.ws.rs,
104 + javax.ws.rs.core,
105 + com.sun.jersey.api.core,
106 + com.sun.jersey.spi.container.servlet,
107 + com.sun.jersey.server.impl.container.servlet,
108 + com.fasterxml.jackson.databind,
109 + com.fasterxml.jackson.databind.node,
110 + com.fasterxml.jackson.core,
111 + org.apache.karaf.shell.commands,
112 + org.apache.commons.lang.math.*,
113 + com.google.common.*,
114 + org.onlab.packet.*,
115 + org.onlab.rest.*,
116 + org.onosproject.*,
117 + org.onlab.util.*,
118 + org.jboss.netty.util.*
119 + </Import-Package>
120 + <Web-ContextPath>${web.context}</Web-ContextPath>
121 + </instructions>
122 + </configuration>
123 + </plugin>
124 + </plugins>
125 + </build>
126 +
37 </project> 127 </project>
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting;
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;
28 +import java.util.Set;
29 +
30 +import static com.google.common.base.Preconditions.checkNotNull;
31 +
32 +/**
33 + * Tunnel class.
34 + */
35 +public class DefaultTunnel implements Tunnel {
36 +
37 + private static final Logger log = LoggerFactory
38 + .getLogger(DefaultTunnel.class);
39 +
40 + private final String tunnelId;
41 + private final List<Integer> labelIds;
42 + private final SegmentRoutingManager srManager;
43 + private final DeviceConfiguration config;
44 +
45 + private int groupId;
46 +
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 +
63 + /**
64 + * Creates a Tunnel reference.
65 + *
66 + * @param tid Tunnel ID
67 + * @param labelIds Label stack of the tunnel
68 + */
69 + public DefaultTunnel(String tid, List<Integer> labelIds) {
70 + this.srManager = null;
71 + this.tunnelId = checkNotNull(tid);
72 + this.labelIds = Collections.unmodifiableList(labelIds);
73 + this.config = null;
74 + this.groupId = -1;
75 + }
76 +
77 + /**
78 + * Creates a new DefaultTunnel reference using the tunnel reference.
79 + *
80 + * @param tunnel DefaultTunnel reference
81 + */
82 + public DefaultTunnel(DefaultTunnel tunnel) {
83 + this.srManager = tunnel.srManager;
84 + this.tunnelId = tunnel.tunnelId;
85 + this.labelIds = tunnel.labelIds;
86 + this.config = tunnel.config;
87 + this.groupId = tunnel.groupId;
88 + }
89 +
90 + @Override
91 + public String id() {
92 + return this.tunnelId;
93 + }
94 +
95 + @Override
96 + public List<Integer> labelIds() {
97 + return this.labelIds;
98 + }
99 +
100 + @Override
101 + public boolean create() {
102 +
103 + if (labelIds.isEmpty() || labelIds.size() < 3) {
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 +
114 + return true;
115 + }
116 +
117 + @Override
118 + public boolean remove() {
119 +
120 + DeviceId deviceId = config.getDeviceId(labelIds.get(0));
121 + srManager.removeNextObjective(deviceId, groupId);
122 +
123 + return true;
124 + }
125 +
126 + @Override
127 + public int groupId() {
128 + return this.groupId;
129 + }
130 +
131 + @Override
132 + public DeviceId source() {
133 + return config.getDeviceId(labelIds.get(0));
134 + }
135 +
136 + private int createGroupsForTunnel() {
137 +
138 + List<Integer> portNumbers;
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 + }
167 +
168 +}
1 package org.onosproject.segmentrouting; 1 package org.onosproject.segmentrouting;
2 2
3 +import com.google.common.collect.Lists;
3 import org.onlab.packet.Ip4Address; 4 import org.onlab.packet.Ip4Address;
4 import org.onlab.packet.Ip4Prefix; 5 import org.onlab.packet.Ip4Prefix;
5 import org.onlab.packet.IpPrefix; 6 import org.onlab.packet.IpPrefix;
...@@ -44,6 +45,7 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -44,6 +45,7 @@ public class DeviceConfiguration implements DeviceProperties {
44 boolean isEdge; 45 boolean isEdge;
45 HashMap<PortNumber, Ip4Address> gatewayIps; 46 HashMap<PortNumber, Ip4Address> gatewayIps;
46 HashMap<PortNumber, Ip4Prefix> subnets; 47 HashMap<PortNumber, Ip4Prefix> subnets;
48 + List<SegmentRouterConfig.AdjacencySid> adjacencySids;
47 } 49 }
48 50
49 /** 51 /**
...@@ -80,8 +82,10 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -80,8 +82,10 @@ public class DeviceConfiguration implements DeviceProperties {
80 info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()), 82 info.gatewayIps.put(PortNumber.portNumber(s.getPortNo()),
81 Ip4Address.valueOf(gatewayIp)); 83 Ip4Address.valueOf(gatewayIp));
82 } 84 }
85 + info.adjacencySids = ((SegmentRouterConfig) cfg).getAdjacencySids();
83 this.deviceConfigMap.put(info.deviceId, info); 86 this.deviceConfigMap.put(info.deviceId, info);
84 this.allSegmentIds.add(info.nodeSid); 87 this.allSegmentIds.add(info.nodeSid);
88 +
85 } 89 }
86 } 90 }
87 91
...@@ -352,4 +356,49 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -352,4 +356,49 @@ public class DeviceConfiguration implements DeviceProperties {
352 356
353 return false; 357 return false;
354 } 358 }
359 +
360 + /**
361 + * Returns the ports corresponding to the adjacency Sid given.
362 + *
363 + * @param deviceId device identification of the router
364 + * @param sid adjacency Sid
365 + * @return list of port numbers
366 + */
367 + public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) {
368 + if (deviceConfigMap.get(deviceId) != null) {
369 + for (SegmentRouterConfig.AdjacencySid asid : deviceConfigMap.get(deviceId).adjacencySids) {
370 + if (asid.getAdjSid() == sid) {
371 + return asid.getPorts();
372 + }
373 + }
374 + }
375 +
376 + return Lists.newArrayList();
377 + }
378 +
379 + /**
380 + * Check if the Sid given is whether adjacency Sid of the router device or not.
381 + *
382 + * @param deviceId device identification of the router
383 + * @param sid Sid to check
384 + * @return true if the Sid given is the adjacency Sid of the device,
385 + * otherwise false
386 + */
387 + public boolean isAdjacencySid(DeviceId deviceId, int sid) {
388 + if (deviceConfigMap.get(deviceId) != null) {
389 + if (deviceConfigMap.get(deviceId).adjacencySids.isEmpty()) {
390 + return false;
391 + } else {
392 + for (SegmentRouterConfig.AdjacencySid asid:
393 + deviceConfigMap.get(deviceId).adjacencySids) {
394 + if (asid.getAdjSid() == sid) {
395 + return true;
396 + }
397 + }
398 + return false;
399 + }
400 + }
401 +
402 + return false;
403 + }
355 } 404 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting;
18 +
19 +import org.onosproject.net.flow.TrafficSelector;
20 +
21 +/**
22 + * Interface for Segment Routing Policy.
23 + */
24 +public interface Policy {
25 + /**
26 + * Enums for policy type.
27 + */
28 + enum Type {
29 + // Tunnel flow policy type
30 + TUNNEL_FLOW,
31 +
32 + // Load balancing policy type
33 + LOADBALANCE,
34 +
35 + // policy to avoid specific routers or links
36 + AVOID,
37 +
38 + // Access Control policy type
39 + DENY
40 + }
41 +
42 + /**
43 + * Returns the policy ID.
44 + *
45 + * @return policy ID
46 + */
47 + String id();
48 +
49 + /**
50 + * Returns the traffic selector object.
51 + *
52 + * @return TrafficSelector object
53 + */
54 + TrafficSelector selector();
55 +
56 + /**
57 + * Returns the priority of the policy.
58 + *
59 + * @return priority
60 + */
61 + int priority();
62 +
63 + /**
64 + * Returns the policy type.
65 + *
66 + * @return policy type
67 + */
68 + Type type();
69 +
70 + /**
71 + * Creates a policy.
72 + *
73 + * @return true if succeeds, false otherwise
74 + */
75 + boolean create();
76 +
77 + /**
78 + * Removes the policy.
79 + *
80 + * @return true if succeeds, false otherwise
81 + */
82 + boolean remove();
83 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting;
18 +
19 +import org.slf4j.Logger;
20 +
21 +import java.util.ArrayList;
22 +import java.util.HashMap;
23 +import java.util.List;
24 +
25 +import static org.slf4j.LoggerFactory.getLogger;
26 +
27 +/**
28 + * Segment Routing Policy Handler.
29 + */
30 +public class PolicyHandler {
31 +
32 + protected final Logger log = getLogger(getClass());
33 +
34 + private final HashMap<String, Policy> policyMap;
35 +
36 + /**
37 + * Creates a reference.
38 + */
39 + public PolicyHandler() {
40 + policyMap = new HashMap<>();
41 + }
42 +
43 + /**
44 + * Returns the policies.
45 + *
46 + * @return policy list
47 + */
48 + public List<Policy> getPolicies() {
49 + List<Policy> policies = new ArrayList<>();
50 + policyMap.values().forEach(policy -> policies.add(
51 + new TunnelPolicy((TunnelPolicy) policy)));
52 +
53 + return policies;
54 + }
55 +
56 + /**
57 + * Creates a policy using the policy information given.
58 + *
59 + * @param policy policy reference to create
60 + */
61 + public void createPolicy(Policy policy) {
62 + policy.create();
63 + policyMap.put(policy.id(), policy);
64 + }
65 +
66 + /**
67 + * Removes the policy given.
68 + *
69 + * @param policyInfo policy information to remove
70 + */
71 + public void removePolicy(Policy policyInfo) {
72 + if (policyMap.get(policyInfo.id()) != null) {
73 + if (policyMap.get(policyInfo.id()).remove()) {
74 + policyMap.remove(policyInfo.id());
75 + } else {
76 + log.error("Failed to remove the policy {}", policyInfo.id());
77 + }
78 + } else {
79 + log.warn("Policy {} was not found", policyInfo.id());
80 + }
81 + }
82 +
83 +}
...@@ -98,7 +98,8 @@ public class RoutingRulePopulator { ...@@ -98,7 +98,8 @@ public class RoutingRulePopulator {
98 sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32)); 98 sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
99 sbuilder.matchEthType(Ethernet.TYPE_IPV4); 99 sbuilder.matchEthType(Ethernet.TYPE_IPV4);
100 100
101 - tbuilder.setEthDst(hostMac) 101 + tbuilder.deferred()
102 + .setEthDst(hostMac)
102 .setEthSrc(config.getDeviceMac(deviceId)) 103 .setEthSrc(config.getDeviceMac(deviceId))
103 .setOutput(outPort); 104 .setOutput(outPort);
104 105
...@@ -163,10 +164,10 @@ public class RoutingRulePopulator { ...@@ -163,10 +164,10 @@ public class RoutingRulePopulator {
163 // If the next hop is the same as the final destination, then MPLS label 164 // If the next hop is the same as the final destination, then MPLS label
164 // is not set. 165 // is not set.
165 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) { 166 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
166 - tbuilder.decNwTtl(); 167 + tbuilder.deferred().decNwTtl();
167 ns = new NeighborSet(nextHops); 168 ns = new NeighborSet(nextHops);
168 } else { 169 } else {
169 - tbuilder.copyTtlOut(); 170 + tbuilder.deferred().copyTtlOut();
170 ns = new NeighborSet(nextHops, config.getSegmentId(destSw)); 171 ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
171 } 172 }
172 173
...@@ -295,15 +296,15 @@ public class RoutingRulePopulator { ...@@ -295,15 +296,15 @@ public class RoutingRulePopulator {
295 296
296 if (phpRequired) { 297 if (phpRequired) {
297 log.debug("getMplsForwardingObjective: php required"); 298 log.debug("getMplsForwardingObjective: php required");
298 - tbuilder.copyTtlIn(); 299 + tbuilder.deferred().copyTtlIn();
299 if (isBos) { 300 if (isBos) {
300 - tbuilder.popMpls(Ethernet.TYPE_IPV4).decNwTtl(); 301 + tbuilder.deferred().popMpls(Ethernet.TYPE_IPV4).decNwTtl();
301 } else { 302 } else {
302 - tbuilder.popMpls(Ethernet.MPLS_UNICAST).decMplsTtl(); 303 + tbuilder.deferred().popMpls(Ethernet.MPLS_UNICAST).decMplsTtl();
303 } 304 }
304 } else { 305 } else {
305 log.debug("getMplsForwardingObjective: php not required"); 306 log.debug("getMplsForwardingObjective: php not required");
306 - tbuilder.decMplsTtl(); 307 + tbuilder.deferred().decMplsTtl();
307 } 308 }
308 309
309 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) { 310 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
...@@ -313,7 +314,8 @@ public class RoutingRulePopulator { ...@@ -313,7 +314,8 @@ public class RoutingRulePopulator {
313 log.warn("No link from {} to {}", deviceId, nextHops); 314 log.warn("No link from {} to {}", deviceId, nextHops);
314 return null; 315 return null;
315 } 316 }
316 - tbuilder.setEthSrc(config.getDeviceMac(deviceId)) 317 + tbuilder.deferred()
318 + .setEthSrc(config.getDeviceMac(deviceId))
317 .setEthDst(config.getDeviceMac(nextHop)) 319 .setEthDst(config.getDeviceMac(nextHop))
318 .setOutput(port); 320 .setOutput(port);
319 fwdBuilder.withTreatment(tbuilder.build()); 321 fwdBuilder.withTreatment(tbuilder.build());
......
...@@ -20,6 +20,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -20,6 +20,7 @@ import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 20 import org.apache.felix.scr.annotations.Deactivate;
21 import org.apache.felix.scr.annotations.Reference; 21 import org.apache.felix.scr.annotations.Reference;
22 import org.apache.felix.scr.annotations.ReferenceCardinality; 22 import org.apache.felix.scr.annotations.ReferenceCardinality;
23 +import org.apache.felix.scr.annotations.Service;
23 import org.onlab.packet.Ethernet; 24 import org.onlab.packet.Ethernet;
24 import org.onlab.packet.IPv4; 25 import org.onlab.packet.IPv4;
25 import org.onlab.util.KryoNamespace; 26 import org.onlab.util.KryoNamespace;
...@@ -60,6 +61,7 @@ import org.slf4j.LoggerFactory; ...@@ -60,6 +61,7 @@ import org.slf4j.LoggerFactory;
60 61
61 import java.net.URI; 62 import java.net.URI;
62 import java.util.HashSet; 63 import java.util.HashSet;
64 +import java.util.List;
63 import java.util.Map; 65 import java.util.Map;
64 import java.util.concurrent.ConcurrentHashMap; 66 import java.util.concurrent.ConcurrentHashMap;
65 import java.util.concurrent.ConcurrentLinkedQueue; 67 import java.util.concurrent.ConcurrentLinkedQueue;
...@@ -69,8 +71,9 @@ import java.util.concurrent.ScheduledFuture; ...@@ -69,8 +71,9 @@ import java.util.concurrent.ScheduledFuture;
69 import java.util.concurrent.TimeUnit; 71 import java.util.concurrent.TimeUnit;
70 72
71 @SuppressWarnings("ALL") 73 @SuppressWarnings("ALL")
74 +@Service
72 @Component(immediate = true) 75 @Component(immediate = true)
73 -public class SegmentRoutingManager { 76 +public class SegmentRoutingManager implements SegmentRoutingService {
74 77
75 private static Logger log = LoggerFactory 78 private static Logger log = LoggerFactory
76 .getLogger(SegmentRoutingManager.class); 79 .getLogger(SegmentRoutingManager.class);
...@@ -101,6 +104,7 @@ public class SegmentRoutingManager { ...@@ -101,6 +104,7 @@ public class SegmentRoutingManager {
101 104
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected MastershipService mastershipService; 106 protected MastershipService mastershipService;
107 +
104 protected ArpHandler arpHandler = null; 108 protected ArpHandler arpHandler = null;
105 protected IcmpHandler icmpHandler = null; 109 protected IcmpHandler icmpHandler = null;
106 protected IpHandler ipHandler = null; 110 protected IpHandler ipHandler = null;
...@@ -108,7 +112,10 @@ public class SegmentRoutingManager { ...@@ -108,7 +112,10 @@ public class SegmentRoutingManager {
108 protected ApplicationId appId; 112 protected ApplicationId appId;
109 protected DeviceConfiguration deviceConfiguration = null; 113 protected DeviceConfiguration deviceConfiguration = null;
110 114
115 +
111 private DefaultRoutingHandler defaultRoutingHandler = null; 116 private DefaultRoutingHandler defaultRoutingHandler = null;
117 + private TunnelHandler tunnelHandler = null;
118 + private PolicyHandler policyHandler = null;
112 private InternalPacketProcessor processor = new InternalPacketProcessor(); 119 private InternalPacketProcessor processor = new InternalPacketProcessor();
113 private InternalEventHandler eventHandler = new InternalEventHandler(); 120 private InternalEventHandler eventHandler = new InternalEventHandler();
114 121
...@@ -165,6 +172,8 @@ public class SegmentRoutingManager { ...@@ -165,6 +172,8 @@ public class SegmentRoutingManager {
165 ipHandler = new IpHandler(this); 172 ipHandler = new IpHandler(this);
166 routingRulePopulator = new RoutingRulePopulator(this); 173 routingRulePopulator = new RoutingRulePopulator(this);
167 defaultRoutingHandler = new DefaultRoutingHandler(this); 174 defaultRoutingHandler = new DefaultRoutingHandler(this);
175 + tunnelHandler = new TunnelHandler();
176 + policyHandler = new PolicyHandler();
168 177
169 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); 178 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
170 linkService.addListener(new InternalLinkListener()); 179 linkService.addListener(new InternalLinkListener());
...@@ -187,6 +196,7 @@ public class SegmentRoutingManager { ...@@ -187,6 +196,7 @@ public class SegmentRoutingManager {
187 196
188 defaultRoutingHandler.startPopulationProcess(); 197 defaultRoutingHandler.startPopulationProcess();
189 log.info("Started"); 198 log.info("Started");
199 +
190 } 200 }
191 201
192 @Deactivate 202 @Deactivate
...@@ -196,6 +206,51 @@ public class SegmentRoutingManager { ...@@ -196,6 +206,51 @@ public class SegmentRoutingManager {
196 log.info("Stopped"); 206 log.info("Stopped");
197 } 207 }
198 208
209 +
210 + @Override
211 + public List<Tunnel> getTunnels() {
212 + return tunnelHandler.getTunnels();
213 + }
214 +
215 + @Override
216 + public void createTunnel(Tunnel tunnel) {
217 + tunnelHandler.createTunnel(tunnel);
218 + }
219 +
220 + @Override
221 + public void removeTunnel(Tunnel tunnel) {
222 + for (Policy policy: policyHandler.getPolicies()) {
223 + if (policy.type() == Policy.Type.TUNNEL_FLOW) {
224 + TunnelPolicy tunnelPolicy = (TunnelPolicy) policy;
225 + if (tunnelPolicy.tunnelId().equals(tunnel.id())) {
226 + log.warn("Cannot remove the tunnel used by a policy");
227 + return;
228 + }
229 + }
230 + }
231 + tunnelHandler.removeTunnel(tunnel);
232 + }
233 +
234 + @Override
235 + public void removePolicy(Policy policy) {
236 + policyHandler.removePolicy(policy);
237 +
238 + }
239 +
240 + @Override
241 + public void createPolicy(Policy policy) {
242 + policyHandler.createPolicy(policy);
243 + }
244 +
245 + @Override
246 + public List<Policy> getPolicies() {
247 + return policyHandler.getPolicies();
248 + }
249 +
250 + public Tunnel getTunnel(String tunnelId) {
251 + return tunnelHandler.getTunnel(tunnelId);
252 + }
253 +
199 /** 254 /**
200 * Returns the GrouopKey object for the device and the NighborSet given. 255 * Returns the GrouopKey object for the device and the NighborSet given.
201 * 256 *
...@@ -211,6 +266,12 @@ public class SegmentRoutingManager { ...@@ -211,6 +266,12 @@ public class SegmentRoutingManager {
211 return null; 266 return null;
212 } 267 }
213 268
269 + /**
270 + *
271 + * @param deviceId
272 + * @param ns
273 + * @return
274 + */
214 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) { 275 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
215 276
216 if (groupHandlerMap.get(deviceId) != null) { 277 if (groupHandlerMap.get(deviceId) != null) {
...@@ -223,6 +284,16 @@ public class SegmentRoutingManager { ...@@ -223,6 +284,16 @@ public class SegmentRoutingManager {
223 } 284 }
224 } 285 }
225 286
287 + /**
288 + *
289 + * @param deviceId
290 + * @param objectiveId
291 + * @return
292 + */
293 + public boolean removeNextObjective(DeviceId deviceId, int objectiveId) {
294 + return groupHandlerMap.get(deviceId).removeGroup(objectiveId);
295 + }
296 +
226 private class InternalPacketProcessor implements PacketProcessor { 297 private class InternalPacketProcessor implements PacketProcessor {
227 298
228 @Override 299 @Override
...@@ -295,7 +366,7 @@ public class SegmentRoutingManager { ...@@ -295,7 +366,7 @@ public class SegmentRoutingManager {
295 } 366 }
296 367
297 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, 368 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
298 - numOfHandlerScheduled); 369 + numOfHandlerScheduled);
299 370
300 } 371 }
301 372
...@@ -403,4 +474,7 @@ public class SegmentRoutingManager { ...@@ -403,4 +474,7 @@ public class SegmentRoutingManager {
403 groupHandler.portDown(port.number()); 474 groupHandler.portDown(port.number());
404 } 475 }
405 } 476 }
477 +
478 +
479 +
406 } 480 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting;
17 +
18 +import java.util.List;
19 +
20 +/**
21 + * Segment Routing Service for REST API.
22 + */
23 +public interface SegmentRoutingService {
24 +
25 + /**
26 + * Returns all tunnels.
27 + *
28 + * @return list of tunnels
29 + */
30 + List<Tunnel> getTunnels();
31 +
32 + /**
33 + * Creates a tunnel.
34 + *
35 + * @param tunnel tunnel reference to create
36 + */
37 + void createTunnel(Tunnel tunnel);
38 +
39 + /**
40 + * Returns all policies.
41 + *
42 + * @return list of policy
43 + */
44 + List<Policy> getPolicies();
45 +
46 + /**
47 + * Creates a policy.
48 + *
49 + * @param policy policy reference to create
50 + */
51 + void createPolicy(Policy policy);
52 +
53 + /**
54 + * Removes a tunnel.
55 + *
56 + * @param tunnel tunnel reference to remove
57 + */
58 + void removeTunnel(Tunnel tunnel);
59 +
60 + /**
61 + * Removes a policy.
62 + *
63 + * @param policy policy reference to remove
64 + */
65 + void removePolicy(Policy policy);
66 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting;
18 +
19 +import org.onosproject.net.DeviceId;
20 +
21 +import java.util.List;
22 +
23 +/**
24 + * Tunnel interface.
25 + */
26 +public interface Tunnel {
27 +
28 + /**
29 + * Returns the tunnel ID.
30 + *
31 + * @return tunnel ID
32 + */
33 + String id();
34 +
35 + /**
36 + * Returns Segment IDs for the tunnel including source and destination.
37 + *
38 + * @return List of Node ID
39 + */
40 + List<Integer> labelIds();
41 +
42 + /**
43 + * Creates a tunnel.
44 + *
45 + * @return true if succeeds, false otherwise
46 + */
47 + boolean create();
48 +
49 + /**
50 + * Removes the tunnel.
51 + *
52 + * @return true if succeeds, false otherwise.
53 + */
54 + boolean remove();
55 +
56 + /**
57 + * Returns the group ID for the tunnel.
58 + *
59 + * @return group ID
60 + */
61 + int groupId();
62 +
63 + /**
64 + * Returns the source device Id of the tunnel.
65 + *
66 + * @return source device Id
67 + */
68 + DeviceId source();
69 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting;
17 +
18 +import org.slf4j.Logger;
19 +
20 +import java.util.ArrayList;
21 +import java.util.List;
22 +import java.util.HashMap;
23 +
24 +import static org.slf4j.LoggerFactory.getLogger;
25 +
26 +/**
27 + * Tunnel Handler.
28 + */
29 +public class TunnelHandler {
30 + protected final Logger log = getLogger(getClass());
31 +
32 + private final HashMap<String, Tunnel> tunnelMap;
33 +
34 + public TunnelHandler() {
35 + tunnelMap = new HashMap<>();
36 + }
37 +
38 + /**
39 + * Creates a tunnel.
40 + *
41 + * @param tunnel tunnel reference to create a tunnel
42 + */
43 + public void createTunnel(Tunnel tunnel) {
44 + tunnel.create();
45 + tunnelMap.put(tunnel.id(), tunnel);
46 + }
47 +
48 + /**
49 + * Removes the tunnel with the tunnel ID given.
50 + *
51 + * @param tunnelInfo tunnel information to delete tunnels
52 + */
53 + public void removeTunnel(Tunnel tunnelInfo) {
54 +
55 + Tunnel tunnel = tunnelMap.get(tunnelInfo.id());
56 + if (tunnel != null) {
57 + tunnel.remove();
58 + tunnelMap.remove(tunnel.id());
59 + } else {
60 + log.warn("No tunnel found for tunnel ID {}", tunnelInfo.id());
61 + }
62 + }
63 +
64 + /**
65 + * Returns the tunnel with the tunnel ID given.
66 + *
67 + * @param tid Tunnel ID
68 + * @return Tunnel reference
69 + */
70 + public Tunnel getTunnel(String tid) {
71 + return tunnelMap.get(tid);
72 + }
73 +
74 + /**
75 + * Returns all tunnels.
76 + *
77 + * @return list of Tunnels
78 + */
79 + public List<Tunnel> getTunnels() {
80 + List<Tunnel> tunnels = new ArrayList<>();
81 + tunnelMap.values().forEach(tunnel -> tunnels.add(
82 + new DefaultTunnel((DefaultTunnel) tunnel)));
83 +
84 + return tunnels;
85 + }
86 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting;
18 +
19 +import org.onosproject.net.flow.TrafficSelector;
20 +import org.onosproject.net.flowobjective.DefaultForwardingObjective;
21 +import org.onosproject.net.flowobjective.ForwardingObjective;
22 +
23 +import static com.google.common.base.Preconditions.checkNotNull;
24 +
25 +/**
26 + * Tunnel Policy.
27 + */
28 +public final class TunnelPolicy implements Policy {
29 +
30 + private final SegmentRoutingManager srManager;
31 + private final Type type;
32 + private final String id;
33 + private final TrafficSelector selector;
34 + private final int priority;
35 + private final String tunnelId;
36 +
37 + private TunnelPolicy(SegmentRoutingManager srm, String policyId, Type type,
38 + TrafficSelector selector, int priority, String tunnelId) {
39 + this.srManager = srm;
40 + this.id = checkNotNull(policyId);
41 + this.type = type;
42 + this.tunnelId = tunnelId;
43 + this.priority = priority;
44 + this.selector = selector;
45 + }
46 +
47 + /**
48 + * Creates a TunnelPolicy reference.
49 + *
50 + * @param p TunnelPolicy reference
51 + */
52 + public TunnelPolicy(TunnelPolicy p) {
53 + this.srManager = p.srManager;
54 + this.id = p.id;
55 + this.type = p.type;
56 + this.tunnelId = p.tunnelId;
57 + this.priority = p.priority;
58 + this.selector = p.selector;
59 + }
60 +
61 + /**
62 + * Creates a TunnelPolicy reference.
63 + *
64 + * @param p TunnelPolicy reference
65 + */
66 + public TunnelPolicy(SegmentRoutingManager srm, TunnelPolicy p) {
67 + this.srManager = srm;
68 + this.id = p.id;
69 + this.type = p.type;
70 + this.tunnelId = p.tunnelId;
71 + this.priority = p.priority;
72 + this.selector = p.selector;
73 + }
74 +
75 + /**
76 + * Returns the TunnelPolicy builder reference.
77 + *
78 + * @return TunnelPolicy builder
79 + */
80 + public static TunnelPolicy.Builder builder() {
81 + return new Builder();
82 + }
83 +
84 + @Override
85 + public String id() {
86 + return this.id;
87 + }
88 +
89 + @Override
90 + public TrafficSelector selector() {
91 + return selector;
92 + }
93 +
94 + @Override
95 + public int priority() {
96 + return priority;
97 + }
98 +
99 + @Override
100 + public Type type() {
101 + return type;
102 + }
103 +
104 + @Override
105 + public boolean create() {
106 +
107 + Tunnel tunnel = srManager.getTunnel(tunnelId);
108 +
109 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
110 + .builder()
111 + .fromApp(srManager.appId)
112 + .makePermanent()
113 + .nextStep(tunnel.groupId())
114 + .withPriority(priority)
115 + .withSelector(selector)
116 + .withFlag(ForwardingObjective.Flag.VERSATILE);
117 +
118 + srManager.flowObjectiveService.forward(tunnel.source(), fwdBuilder.add());
119 +
120 + return true;
121 + }
122 +
123 + @Override
124 + public boolean remove() {
125 +
126 + Tunnel tunnel = srManager.getTunnel(tunnelId);
127 +
128 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
129 + .builder()
130 + .fromApp(srManager.appId)
131 + .makePermanent()
132 + .withSelector(selector)
133 + .withPriority(priority)
134 + .nextStep(tunnel.groupId())
135 + .withFlag(ForwardingObjective.Flag.VERSATILE);
136 +
137 + srManager.flowObjectiveService.forward(tunnel.source(), fwdBuilder.remove());
138 +
139 + return true;
140 + }
141 +
142 + /**
143 + * Returns the tunnel ID of the policy.
144 + *
145 + * @return Tunnel ID
146 + */
147 + public String tunnelId() {
148 + return this.tunnelId;
149 + }
150 +
151 + /**
152 + * Tunnel Policy Builder.
153 + */
154 + public static final class Builder {
155 +
156 + private SegmentRoutingManager srManager;
157 + private String id;
158 + private Type type;
159 + private TrafficSelector selector;
160 + private int priority;
161 + private String tunnelId;
162 +
163 + /**
164 + * Sets the policy Id.
165 + *
166 + * @param id policy Id
167 + * @return Builder object
168 + */
169 + public Builder setPolicyId(String id) {
170 + this.id = id;
171 +
172 + return this;
173 + }
174 +
175 + /**
176 + * Sets the policy type.
177 + *
178 + * @param type policy type
179 + * @return Builder object
180 + */
181 + public Builder setType(Type type) {
182 + this.type = type;
183 +
184 + return this;
185 + }
186 +
187 + /**
188 + * Sets the TrafficSelector.
189 + *
190 + * @param selector TrafficSelector
191 + * @return Builder object
192 + */
193 + public Builder setSelector(TrafficSelector selector) {
194 + this.selector = selector;
195 +
196 + return this;
197 + }
198 +
199 + /**
200 + * Sets the priority of the policy.
201 + *
202 + * @param p priority
203 + * @return Builder object
204 + */
205 + public Builder setPriority(int p) {
206 + this.priority = p;
207 +
208 + return this;
209 + }
210 +
211 + /**
212 + * Sets the tunnel Id.
213 + *
214 + * @param tunnelId tunnel Id
215 + * @return Builder object
216 + */
217 + public Builder setTunnelId(String tunnelId) {
218 + this.tunnelId = tunnelId;
219 +
220 + return this;
221 + }
222 +
223 + /**
224 + * Sets the Segment Routing Manager reference.
225 + *
226 + * @param srm Segment Routing Manager reference
227 + * @return Builder object
228 + */
229 + public Builder setManager(SegmentRoutingManager srm) {
230 + this.srManager = srm;
231 +
232 + return this;
233 + }
234 +
235 + /**
236 + * Builds the policy.
237 + *
238 + * @return Tunnel Policy reference
239 + */
240 + public Policy build() {
241 + return new TunnelPolicy(srManager, id, type, selector, priority, tunnelId);
242 + }
243 + }
244 +}
...@@ -24,6 +24,7 @@ import java.util.Collections; ...@@ -24,6 +24,7 @@ import java.util.Collections;
24 import java.util.HashMap; 24 import java.util.HashMap;
25 import java.util.HashSet; 25 import java.util.HashSet;
26 import java.util.List; 26 import java.util.List;
27 +import java.util.Map;
27 import java.util.Random; 28 import java.util.Random;
28 import java.util.Set; 29 import java.util.Set;
29 import java.util.stream.Collectors; 30 import java.util.stream.Collectors;
...@@ -418,7 +419,12 @@ public class DefaultGroupHandler { ...@@ -418,7 +419,12 @@ public class DefaultGroupHandler {
418 return nsSegmentIds; 419 return nsSegmentIds;
419 } 420 }
420 421
421 - protected void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) { 422 + /**
423 + * Creates Groups from a set of NeighborSet given.
424 + *
425 + * @param nsSet a set of NeighborSet
426 + */
427 + public void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) {
422 for (NeighborSet ns : nsSet) { 428 for (NeighborSet ns : nsSet) {
423 int nextId = flowObjectiveService.allocateNextId(); 429 int nextId = flowObjectiveService.allocateNextId();
424 NextObjective.Builder nextObjBuilder = DefaultNextObjective 430 NextObjective.Builder nextObjBuilder = DefaultNextObjective
...@@ -451,7 +457,7 @@ public class DefaultGroupHandler { ...@@ -451,7 +457,7 @@ public class DefaultGroupHandler {
451 NextObjective nextObj = nextObjBuilder.add(); 457 NextObjective nextObj = nextObjBuilder.add();
452 flowObjectiveService.next(deviceId, nextObj); 458 flowObjectiveService.next(deviceId, nextObj);
453 log.debug("createGroupsFromNeighborsets: Submited " 459 log.debug("createGroupsFromNeighborsets: Submited "
454 - + "next objective {} in device {}", 460 + + "next objective {} in device {}",
455 nextId, deviceId); 461 nextId, deviceId);
456 nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns), 462 nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns),
457 nextId); 463 nextId);
...@@ -462,4 +468,29 @@ public class DefaultGroupHandler { ...@@ -462,4 +468,29 @@ public class DefaultGroupHandler {
462 return new DefaultGroupKey(kryo.build().serialize(obj)); 468 return new DefaultGroupKey(kryo.build().serialize(obj));
463 } 469 }
464 470
471 + /**
472 + * Removes groups for the next objective ID given.
473 + *
474 + * @param objectiveId next objective ID to remove
475 + * @return true if succeeds, false otherwise
476 + */
477 + public boolean removeGroup(int objectiveId) {
478 +
479 + if (nsNextObjStore.containsValue(objectiveId)) {
480 + NextObjective.Builder nextObjBuilder = DefaultNextObjective
481 + .builder().withId(objectiveId)
482 + .withType(NextObjective.Type.HASHED).fromApp(appId);
483 + NextObjective nextObjective = nextObjBuilder.remove();
484 + flowObjectiveService.next(deviceId, nextObjective);
485 +
486 + for (Map.Entry<NeighborSetNextObjectiveStoreKey, Integer> entry: nsNextObjStore.entrySet()) {
487 + if (entry.getValue().equals(objectiveId)) {
488 + nsNextObjStore.remove(entry.getKey());
489 + break;
490 + }
491 + }
492 + }
493 +
494 + return false;
495 + }
465 } 496 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting.web;
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;
22 +import org.onosproject.codec.JsonCodec;
23 +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.segmentrouting.Policy;
30 +import org.onosproject.segmentrouting.TunnelPolicy;
31 +
32 +public final class PolicyCodec extends JsonCodec<Policy> {
33 +
34 + // JSON field names
35 + private static final String POLICY_ID = "policy_id";
36 + private static final String PRIORITY = "priority";
37 + private static final String TYPE = "policy_type";
38 + private static final String TUNNEL_ID = "tunnel_id";
39 + private static final String DST_IP = "dst_ip";
40 + private static final String SRC_IP = "src_ip";
41 + private static final String PROTO_TYPE = "proto_type";
42 +
43 + @Override
44 + public ObjectNode encode(Policy policy, CodecContext context) {
45 + final ObjectNode result = context.mapper().createObjectNode()
46 + .put(POLICY_ID, policy.id());
47 +
48 + result.put(PRIORITY, policy.priority());
49 + result.put(TYPE, policy.type().toString());
50 +
51 + if (policy.selector().getCriterion(Criterion.Type.IPV4_DST) != null) {
52 + IPCriterion criterion = (IPCriterion) policy.selector().getCriterion(
53 + Criterion.Type.IPV4_DST);
54 + result.put(DST_IP, criterion.ip().toString());
55 + }
56 + if (policy.selector().getCriterion(Criterion.Type.IPV4_SRC) != null) {
57 + IPCriterion criterion = (IPCriterion) policy.selector().getCriterion(
58 + Criterion.Type.IPV4_SRC);
59 + result.put(SRC_IP, criterion.ip().toString());
60 + }
61 + if (policy.selector().getCriterion(Criterion.Type.IP_PROTO) != null) {
62 + IPProtocolCriterion protocolCriterion =
63 + (IPProtocolCriterion) policy.selector().getCriterion(Criterion.Type.IP_PROTO);
64 + result.put(PROTO_TYPE, protocolCriterion.toString());
65 + }
66 +
67 + if (policy.type() == Policy.Type.TUNNEL_FLOW) {
68 + result.put(TUNNEL_ID, ((TunnelPolicy) policy).tunnelId());
69 + }
70 +
71 + return result;
72 + }
73 +
74 + @Override
75 + public Policy decode(ObjectNode json, CodecContext context) {
76 +
77 + String pid = json.path(POLICY_ID).asText();
78 + String type = json.path(TYPE).asText();
79 + int priority = json.path(PRIORITY).asInt();
80 + String dstIp = json.path(DST_IP).asText();
81 + String srcIp = json.path(SRC_IP).asText();
82 + String tunnelId = json.path(TUNNEL_ID).asText();
83 + String protoType = json.path(PROTO_TYPE).asText();
84 +
85 + if (tunnelId != null) {
86 + TrafficSelector.Builder tsb = DefaultTrafficSelector.builder();
87 + tsb.matchEthType(Ethernet.TYPE_IPV4);
88 + if (dstIp != null && !dstIp.isEmpty()) {
89 + tsb.matchIPDst(IpPrefix.valueOf(dstIp));
90 + }
91 + if (srcIp != null && !srcIp.isEmpty()) {
92 + tsb.matchIPSrc(IpPrefix.valueOf(srcIp));
93 + }
94 + if (protoType != null && !protoType.isEmpty()) {
95 + Short ipProto = Short.valueOf(IpProtocol.valueOf(protoType).value());
96 + tsb.matchIPProtocol(ipProto.byteValue());
97 + }
98 +
99 + TunnelPolicy.Builder tpb = TunnelPolicy.builder().setPolicyId(pid);
100 + if (tunnelId != null) {
101 + tpb.setTunnelId(tunnelId);
102 + }
103 + if (!json.path(PRIORITY).isMissingNode()) {
104 + tpb.setPriority(priority);
105 + }
106 + if (!json.path(TYPE).isMissingNode()) {
107 + tpb.setType(Policy.Type.valueOf(type));
108 + }
109 + tpb.setSelector(tsb.build());
110 +
111 + return tpb.build();
112 + } else {
113 + // TODO: handle more policy types
114 + return null;
115 + }
116 +
117 +
118 + }
119 +
120 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting.web;
17 +
18 +import com.fasterxml.jackson.databind.ObjectMapper;
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +
21 +import org.onosproject.rest.AbstractWebResource;
22 +import org.onosproject.segmentrouting.Policy;
23 +import org.onosproject.segmentrouting.SegmentRoutingManager;
24 +import org.onosproject.segmentrouting.SegmentRoutingService;
25 +import org.onosproject.segmentrouting.TunnelPolicy;
26 +
27 +import javax.ws.rs.Consumes;
28 +import javax.ws.rs.DELETE;
29 +import javax.ws.rs.GET;
30 +import javax.ws.rs.POST;
31 +import javax.ws.rs.Path;
32 +import javax.ws.rs.Produces;
33 +import javax.ws.rs.core.MediaType;
34 +import javax.ws.rs.core.Response;
35 +import java.io.IOException;
36 +import java.io.InputStream;
37 +import java.util.List;
38 +
39 +@Path("policy")
40 +public class PolicyWebResource extends AbstractWebResource {
41 +
42 + private static final PolicyCodec POLICY_CODEC = new PolicyCodec();
43 +
44 + @GET
45 + @Produces(MediaType.APPLICATION_JSON)
46 + public Response getPolicy() {
47 + SegmentRoutingService srService = get(SegmentRoutingService.class);
48 + List<Policy> policies = srService.getPolicies();
49 + ObjectNode result = new ObjectMapper().createObjectNode();
50 + result.set("policy", new PolicyCodec().encode(policies, this));
51 +
52 + return ok(result.toString()).build();
53 + }
54 +
55 + @POST
56 + @Consumes(MediaType.APPLICATION_JSON)
57 + public Response createPolicy(InputStream input) throws IOException {
58 + ObjectMapper mapper = new ObjectMapper();
59 + ObjectNode policyJson = (ObjectNode) mapper.readTree(input);
60 + SegmentRoutingService srService = get(SegmentRoutingService.class);
61 + 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 +
66 + return Response.ok().build();
67 + } else {
68 + return Response.serverError().build();
69 + }
70 + }
71 +
72 + @DELETE
73 + @Consumes(MediaType.APPLICATION_JSON)
74 + public Response removePolicy(InputStream input) throws IOException {
75 + ObjectMapper mapper = new ObjectMapper();
76 + ObjectNode policyJson = (ObjectNode) mapper.readTree(input);
77 + SegmentRoutingService srService = get(SegmentRoutingService.class);
78 + Policy policyInfo = POLICY_CODEC.decode(policyJson, this);
79 + // TODO: Check the result
80 + srService.removePolicy(policyInfo);
81 + return Response.ok().build();
82 +
83 + }
84 +
85 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting.web;
17 +
18 +import com.fasterxml.jackson.databind.JsonNode;
19 +import com.fasterxml.jackson.databind.node.ArrayNode;
20 +import org.onosproject.codec.CodecContext;
21 +import org.onosproject.codec.JsonCodec;
22 +import com.fasterxml.jackson.databind.node.ObjectNode;
23 +import org.onosproject.segmentrouting.DefaultTunnel;
24 +import org.onosproject.segmentrouting.Tunnel;
25 +
26 +import java.util.ArrayList;
27 +import java.util.List;
28 +
29 +public final class TunnelCodec extends JsonCodec<Tunnel> {
30 +
31 + // JSON field names
32 + private static final String TUNNEL_ID = "tunnel_id";
33 + private static final String GROUP_ID = "group_id";
34 + private static final String LABEL_PATH = "label_path";
35 +
36 + @Override
37 + public ObjectNode encode(Tunnel tunnel, CodecContext context) {
38 + final ObjectNode result = context.mapper().createObjectNode()
39 + .put(TUNNEL_ID, tunnel.id());
40 +
41 + result.put(GROUP_ID, tunnel.groupId());
42 +
43 + final ArrayNode jsonLabelIds = result.putArray(LABEL_PATH);
44 +
45 + tunnel.labelIds().forEach(label -> jsonLabelIds.add(label.intValue()));
46 +
47 + return result;
48 + }
49 +
50 + @Override
51 + public DefaultTunnel decode(ObjectNode json, CodecContext context) {
52 +
53 + String tid = json.path(TUNNEL_ID).asText();
54 + List<Integer> labels = new ArrayList<>();
55 +
56 + if (!json.path(LABEL_PATH).isMissingNode()) {
57 + ArrayNode labelArray = (ArrayNode) json.path(LABEL_PATH);
58 + for (JsonNode o : labelArray) {
59 + labels.add(o.asInt());
60 + }
61 + }
62 +
63 + return new DefaultTunnel(tid, labels);
64 + }
65 +
66 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.segmentrouting.web;
17 +
18 +import com.fasterxml.jackson.databind.ObjectMapper;
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +
21 +import org.onosproject.rest.AbstractWebResource;
22 +import org.onosproject.segmentrouting.DefaultTunnel;
23 +import org.onosproject.segmentrouting.SegmentRoutingManager;
24 +import org.onosproject.segmentrouting.SegmentRoutingService;
25 +import org.onosproject.segmentrouting.Tunnel;
26 +
27 +import javax.ws.rs.Consumes;
28 +import javax.ws.rs.DELETE;
29 +import javax.ws.rs.GET;
30 +import javax.ws.rs.POST;
31 +import javax.ws.rs.Path;
32 +import javax.ws.rs.Produces;
33 +import javax.ws.rs.core.MediaType;
34 +import javax.ws.rs.core.Response;
35 +import java.io.IOException;
36 +import java.io.InputStream;
37 +import java.util.List;
38 +
39 +@Path("tunnel")
40 +public class TunnelWebResource extends AbstractWebResource {
41 +
42 + private static final TunnelCodec TUNNEL_CODEC = new TunnelCodec();
43 +
44 + @GET
45 + @Produces(MediaType.APPLICATION_JSON)
46 + public Response getTunnel() {
47 + SegmentRoutingService srService = get(SegmentRoutingService.class);
48 + List<Tunnel> tunnels = srService.getTunnels();
49 + ObjectNode result = new ObjectMapper().createObjectNode();
50 + result.set("tunnel", new TunnelCodec().encode(tunnels, this));
51 +
52 + return ok(result.toString()).build();
53 + }
54 +
55 + @POST
56 + @Consumes(MediaType.APPLICATION_JSON)
57 + public Response createTunnel(InputStream input) throws IOException {
58 + ObjectMapper mapper = new ObjectMapper();
59 + ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input);
60 + SegmentRoutingService srService = get(SegmentRoutingService.class);
61 + Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this);
62 + Tunnel tunnel = new DefaultTunnel((SegmentRoutingManager) srService,
63 + tunnelInfo.id(), tunnelInfo.labelIds());
64 + srService.createTunnel(tunnel);
65 +
66 + return Response.ok().build();
67 + }
68 +
69 + @DELETE
70 + @Consumes(MediaType.APPLICATION_JSON)
71 + public Response removeTunnel(InputStream input) throws IOException {
72 + ObjectMapper mapper = new ObjectMapper();
73 + ObjectNode tunnelJson = (ObjectNode) mapper.readTree(input);
74 + SegmentRoutingService srService = get(SegmentRoutingService.class);
75 + Tunnel tunnelInfo = TUNNEL_CODEC.decode(tunnelJson, this);
76 + srService.removeTunnel(tunnelInfo);
77 +
78 + return Response.ok().build();
79 + }
80 +
81 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
18 + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
19 + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
20 + id="ONOS" version="2.5">
21 + <display-name>Segment Routing REST API v1.0</display-name>
22 +
23 + <servlet>
24 + <servlet-name>JAX-RS Service</servlet-name>
25 + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
26 + <init-param>
27 + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
28 + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
29 + </init-param>
30 + <init-param>
31 + <param-name>com.sun.jersey.config.property.classnames</param-name>
32 + <param-value>
33 + org.onosproject.segmentrouting.web.TunnelWebResource,
34 + org.onosproject.segmentrouting.web.PolicyWebResource
35 + </param-value>
36 + </init-param>
37 + <load-on-startup>1</load-on-startup>
38 + </servlet>
39 +
40 + <servlet-mapping>
41 + <servlet-name>JAX-RS Service</servlet-name>
42 + <url-pattern>/*</url-pattern>
43 + </servlet-mapping>
44 +</web-app>
...@@ -195,7 +195,6 @@ public final class DefaultNextObjective implements NextObjective { ...@@ -195,7 +195,6 @@ public final class DefaultNextObjective implements NextObjective {
195 checkNotNull(appId, "Must supply an application id"); 195 checkNotNull(appId, "Must supply an application id");
196 checkNotNull(id, "id cannot be null"); 196 checkNotNull(id, "id cannot be null");
197 checkNotNull(type, "The type cannot be null"); 197 checkNotNull(type, "The type cannot be null");
198 - checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
199 198
200 return new DefaultNextObjective(id, treatments, appId, type, Operation.REMOVE); 199 return new DefaultNextObjective(id, treatments, appId, type, Operation.REMOVE);
201 } 200 }
......
...@@ -49,6 +49,7 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -49,6 +49,7 @@ import org.onosproject.net.flow.criteria.Criterion;
49 import org.onosproject.net.flow.criteria.EthCriterion; 49 import org.onosproject.net.flow.criteria.EthCriterion;
50 import org.onosproject.net.flow.criteria.EthTypeCriterion; 50 import org.onosproject.net.flow.criteria.EthTypeCriterion;
51 import org.onosproject.net.flow.criteria.IPCriterion; 51 import org.onosproject.net.flow.criteria.IPCriterion;
52 +import org.onosproject.net.flow.criteria.IPProtocolCriterion;
52 import org.onosproject.net.flow.criteria.MplsCriterion; 53 import org.onosproject.net.flow.criteria.MplsCriterion;
53 import org.onosproject.net.flow.criteria.PortCriterion; 54 import org.onosproject.net.flow.criteria.PortCriterion;
54 import org.onosproject.net.flow.criteria.VlanIdCriterion; 55 import org.onosproject.net.flow.criteria.VlanIdCriterion;
...@@ -215,7 +216,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -215,7 +216,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
215 public void next(NextObjective nextObjective) { 216 public void next(NextObjective nextObjective) {
216 217
217 if (nextObjective.op() == Objective.Operation.REMOVE) { 218 if (nextObjective.op() == Objective.Operation.REMOVE) {
218 - if (nextObjective.next() == null) { 219 + if (nextObjective.next().isEmpty()) {
219 removeGroup(nextObjective); 220 removeGroup(nextObjective);
220 } else { 221 } else {
221 removeBucketFromGroup(nextObjective); 222 removeBucketFromGroup(nextObjective);
...@@ -369,8 +370,89 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -369,8 +370,89 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
369 } 370 }
370 371
371 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { 372 private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
372 - fail(fwd, ObjectiveError.UNSUPPORTED); 373 + log.debug("Processing versatile forwarding objective");
373 - return Collections.emptySet(); 374 + TrafficSelector selector = fwd.selector();
375 +
376 + EthTypeCriterion ethType =
377 + (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
378 + if (ethType == null) {
379 + log.error("Versatile forwarding objective must include ethType");
380 + fail(fwd, ObjectiveError.UNKNOWN);
381 + return Collections.emptySet();
382 + }
383 +
384 + TrafficSelector.Builder filteredSelectorBuilder =
385 + DefaultTrafficSelector.builder();
386 + if (ethType.ethType() == Ethernet.TYPE_IPV4) {
387 + IPCriterion ipSrc = (IPCriterion) selector
388 + .getCriterion(Criterion.Type.IPV4_SRC);
389 + IPCriterion ipDst = (IPCriterion) selector
390 + .getCriterion(Criterion.Type.IPV4_DST);
391 + IPProtocolCriterion ipProto = (IPProtocolCriterion) selector
392 + .getCriterion(Criterion.Type.IP_PROTO);
393 +
394 + filteredSelectorBuilder
395 + .matchEthType(Ethernet.TYPE_IPV4);
396 +
397 + if (ipSrc != null) {
398 + filteredSelectorBuilder.matchIPSrc(ipSrc.ip());
399 + }
400 + if (ipDst != null) {
401 + filteredSelectorBuilder.matchIPDst(ipDst.ip());
402 + }
403 + if (ipProto != null) {
404 + filteredSelectorBuilder.matchIPProtocol(
405 + Short.valueOf(ipProto.protocol()).byteValue());
406 + }
407 +
408 + log.debug("processing IPv4 specific forwarding objective");
409 + } else {
410 + log.warn("VERSATILE forwarding objective does not support {} yet.",
411 + ethType.ethType());
412 + return Collections.emptySet();
413 + }
414 +
415 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
416 + .builder();
417 + treatmentBuilder.wipeDeferred();
418 +
419 + if (fwd.nextId() != null) {
420 + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
421 +
422 + if (next != null) {
423 + GroupKey key = appKryo.deserialize(next.data());
424 +
425 + Group group = groupService.getGroup(deviceId, key);
426 +
427 + if (group == null) {
428 + log.warn("The group left!");
429 + fail(fwd, ObjectiveError.GROUPMISSING);
430 + return Collections.emptySet();
431 + }
432 + treatmentBuilder.deferred().group(group.id());
433 + log.debug("Adding OUTGROUP action");
434 + }
435 + } else {
436 + log.warn("VERSATILE forwarding objective need next objective ID.");
437 + return Collections.emptySet();
438 + }
439 +
440 + TrafficSelector filteredSelector = filteredSelectorBuilder.build();
441 + TrafficTreatment treatment = treatmentBuilder.build();
442 +
443 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
444 + .fromApp(fwd.appId()).withPriority(fwd.priority())
445 + .forDevice(deviceId).withSelector(filteredSelector)
446 + .withTreatment(treatment);
447 +
448 + if (fwd.permanent()) {
449 + ruleBuilder.makePermanent();
450 + } else {
451 + ruleBuilder.makeTemporary(fwd.timeout());
452 + }
453 +
454 + ruleBuilder.forTable(aclTableId);
455 + return Collections.singletonList(ruleBuilder.build());
374 } 456 }
375 457
376 protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { 458 protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
...@@ -434,7 +516,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -434,7 +516,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
434 fail(fwd, ObjectiveError.GROUPMISSING); 516 fail(fwd, ObjectiveError.GROUPMISSING);
435 return Collections.emptySet(); 517 return Collections.emptySet();
436 } 518 }
437 - treatmentBuilder.group(group.id()); 519 + treatmentBuilder.deferred().group(group.id());
438 log.debug("Adding OUTGROUP action"); 520 log.debug("Adding OUTGROUP action");
439 } else { 521 } else {
440 log.warn("processSpecific: No associated next objective object"); 522 log.warn("processSpecific: No associated next objective object");
......
...@@ -104,12 +104,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -104,12 +104,12 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
104 List<OFInstruction> instructions = Lists.newLinkedList(); 104 List<OFInstruction> instructions = Lists.newLinkedList();
105 105
106 106
107 - if (immediateActions.size() > 0) {
108 - instructions.add(factory().instructions().applyActions(immediateActions));
109 - }
110 if (treatment.clearedDeferred()) { 107 if (treatment.clearedDeferred()) {
111 instructions.add(factory().instructions().clearActions()); 108 instructions.add(factory().instructions().clearActions());
112 } 109 }
110 + if (immediateActions.size() > 0) {
111 + instructions.add(factory().instructions().applyActions(immediateActions));
112 + }
113 if (deferredActions.size() > 0) { 113 if (deferredActions.size() > 0) {
114 instructions.add(factory().instructions().writeActions(deferredActions)); 114 instructions.add(factory().instructions().writeActions(deferredActions));
115 } 115 }
......