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
1539 additions
and
17 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 |
... | @@ -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 | } | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
0 → 100644
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 |
... | @@ -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 | +} |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java
0 → 100644
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 | +} |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/web/TunnelWebResource.java
0 → 100644
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,10 +370,91 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -369,10 +370,91 @@ 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"); |
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()); | ||
373 | return Collections.emptySet(); | 412 | return Collections.emptySet(); |
374 | } | 413 | } |
375 | 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()); | ||
456 | + } | ||
457 | + | ||
376 | protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 458 | protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) { |
377 | log.debug("Processing specific"); | 459 | log.debug("Processing specific"); |
378 | TrafficSelector selector = fwd.selector(); | 460 | TrafficSelector selector = fwd.selector(); |
... | @@ -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"); | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment