Committed by
Gerrit Code Review
SONA: openstackSwitching
- Added event handlers (DEVICE_XX, PORT_XXX) and tested with mininet - Added default flow rule setup for ARP and DHCP - Added neutron network API handler - Added the feature to populate flow rules for the same subnet - Added the feature to populate flow rules for VMs in other Cnode using Nicira ext. - Modified the directory structure - Fixed nicira ext handling logic - Fixed neutron network API handler - Added the tenant isolation feature by checking the source IP address Change-Id: I076d21f3c90f458727e33cb36b47d9b14ccfd68f
Showing
14 changed files
with
1765 additions
and
4 deletions
apps/openstackswitching/pom.xml
0 → 100644
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 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
18 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + | ||
22 | + <parent> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <artifactId>onos-apps</artifactId> | ||
25 | + <version>1.4.0-SNAPSHOT</version> | ||
26 | + <relativePath>../pom.xml</relativePath> | ||
27 | + </parent> | ||
28 | + | ||
29 | + <artifactId>onos-app-openstackswitching</artifactId> | ||
30 | + <packaging>bundle</packaging> | ||
31 | + | ||
32 | + <description>SONA Openstack Switching applications</description> | ||
33 | + <properties> | ||
34 | + <onos.version>1.4.0-SNAPSHOT</onos.version> | ||
35 | + <onos.app.name>org.onosproject.openstackswitching</onos.app.name> | ||
36 | + <web.context>/onos/openstackswitching</web.context> | ||
37 | + <api.version>1.0.0</api.version> | ||
38 | + <api.title>ONOS OpenStack Switching REST API</api.title> | ||
39 | + <api.description> | ||
40 | + APIs for receiving Neutron information. | ||
41 | + </api.description> | ||
42 | + <api.package>org.onosproject.openstackswitching.web</api.package> | ||
43 | + <onos.app.origin>SKT, Inc.</onos.app.origin> | ||
44 | + </properties> | ||
45 | + | ||
46 | + | ||
47 | + <dependencies> | ||
48 | + <dependency> | ||
49 | + <groupId>org.onosproject</groupId> | ||
50 | + <artifactId>onos-rest</artifactId> | ||
51 | + <version>${project.version}</version> | ||
52 | + </dependency> | ||
53 | + <dependency> | ||
54 | + <groupId>org.onosproject</groupId> | ||
55 | + <artifactId>onlab-rest</artifactId> | ||
56 | + <version>${project.version}</version> | ||
57 | + </dependency> | ||
58 | + <dependency> | ||
59 | + <groupId>javax.ws.rs</groupId> | ||
60 | + <artifactId>jsr311-api</artifactId> | ||
61 | + <version>1.1.1</version> | ||
62 | + </dependency> | ||
63 | + <dependency> | ||
64 | + <groupId>com.sun.jersey</groupId> | ||
65 | + <artifactId>jersey-servlet</artifactId> | ||
66 | + </dependency> | ||
67 | + <dependency> | ||
68 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
69 | + <artifactId>jackson-databind</artifactId> | ||
70 | + </dependency> | ||
71 | + <dependency> | ||
72 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
73 | + <artifactId>jackson-annotations</artifactId> | ||
74 | + </dependency> | ||
75 | + <dependency> | ||
76 | + <groupId>org.osgi</groupId> | ||
77 | + <artifactId>org.osgi.compendium</artifactId> | ||
78 | + </dependency> | ||
79 | + <dependency> | ||
80 | + <groupId>org.osgi</groupId> | ||
81 | + <artifactId>org.osgi.core</artifactId> | ||
82 | + </dependency> | ||
83 | + </dependencies> | ||
84 | + | ||
85 | + <build> | ||
86 | + <plugins> | ||
87 | + <plugin> | ||
88 | + <groupId>org.apache.felix</groupId> | ||
89 | + <artifactId>maven-bundle-plugin</artifactId> | ||
90 | + <extensions>true</extensions> | ||
91 | + <configuration> | ||
92 | + <instructions> | ||
93 | + <_wab>src/main/webapp/</_wab> | ||
94 | + <Bundle-SymbolicName> | ||
95 | + ${project.groupId}.${project.artifactId} | ||
96 | + </Bundle-SymbolicName> | ||
97 | + <Import-Package> | ||
98 | + org.slf4j, | ||
99 | + org.osgi.framework, | ||
100 | + javax.ws.rs, | ||
101 | + javax.ws.rs.core, | ||
102 | + com.sun.jersey.api.core, | ||
103 | + com.sun.jersey.spi.container.servlet, | ||
104 | + com.sun.jersey.server.impl.container.servlet, | ||
105 | + com.fasterxml.jackson.databind, | ||
106 | + com.fasterxml.jackson.databind.node, | ||
107 | + com.fasterxml.jackson.core, | ||
108 | + org.apache.karaf.shell.commands, | ||
109 | + com.google.common.*, | ||
110 | + org.onlab.packet.*, | ||
111 | + org.onosproject.* | ||
112 | + </Import-Package> | ||
113 | + <Web-ContextPath>${web.context}</Web-ContextPath> | ||
114 | + </instructions> | ||
115 | + </configuration> | ||
116 | + </plugin> | ||
117 | + </plugins> | ||
118 | + </build> | ||
119 | + | ||
120 | + | ||
121 | +</project> |
apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.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.openstackswitching; | ||
17 | + | ||
18 | +import org.onosproject.net.packet.InboundPacket; | ||
19 | +import org.slf4j.Logger; | ||
20 | +import org.slf4j.LoggerFactory; | ||
21 | + | ||
22 | +import java.util.HashMap; | ||
23 | + | ||
24 | +/** | ||
25 | + * It handles ARP packet from VMs. | ||
26 | + */ | ||
27 | +public class OpenstackArpHandler { | ||
28 | + | ||
29 | + private static Logger log = LoggerFactory | ||
30 | + .getLogger(OpenstackArpHandler.class); | ||
31 | + | ||
32 | + HashMap<String, OpenstackPort> openstackPortHashMap; | ||
33 | + | ||
34 | + /** | ||
35 | + * Returns OpenstackArpHandler reference. | ||
36 | + * | ||
37 | + * @param openstackPortMap | ||
38 | + */ | ||
39 | + public OpenstackArpHandler(HashMap<String, OpenstackPort> openstackPortMap) { | ||
40 | + this.openstackPortHashMap = openstackPortMap; | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * Processes ARP packets. | ||
45 | + * | ||
46 | + * @param pkt ARP request packet | ||
47 | + */ | ||
48 | + public void processPacketIn(InboundPacket pkt) { | ||
49 | + log.warn("Received an ARP packet"); | ||
50 | + } | ||
51 | +} |
apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.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.openstackswitching; | ||
17 | + | ||
18 | +import org.onosproject.net.packet.InboundPacket; | ||
19 | +import org.slf4j.Logger; | ||
20 | +import org.slf4j.LoggerFactory; | ||
21 | + | ||
22 | +/** | ||
23 | + * It handles DHCP request packets. | ||
24 | + */ | ||
25 | +public class OpenstackDhcpHandler { | ||
26 | + | ||
27 | + private static Logger log = LoggerFactory | ||
28 | + .getLogger(OpenstackDhcpHandler.class); | ||
29 | + | ||
30 | + /** | ||
31 | + * Returns OpenstackDhcpHandler reference. | ||
32 | + */ | ||
33 | + public OpenstackDhcpHandler() { | ||
34 | + | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * Processes DHCP request packets. | ||
39 | + * | ||
40 | + * @param pkt DHCP request packet | ||
41 | + */ | ||
42 | + public void processPacketIn(InboundPacket pkt) { | ||
43 | + log.warn("Received a DHCP packet"); | ||
44 | + } | ||
45 | +} |
apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.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.openstackswitching; | ||
17 | + | ||
18 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
19 | + | ||
20 | + | ||
21 | +/** | ||
22 | + * Represents the network information given by Neutron. | ||
23 | + */ | ||
24 | +public final class OpenstackNetwork { | ||
25 | + | ||
26 | + private String name; | ||
27 | + private String tenantId; | ||
28 | + private String segmentId; | ||
29 | + private String networkType; | ||
30 | + private String id; | ||
31 | + | ||
32 | + /** | ||
33 | + * Returns the builder object of the OpenstackNetwork class. | ||
34 | + * | ||
35 | + * @return OpenstackNetwork builder object | ||
36 | + */ | ||
37 | + public static OpenstackNetwork.Builder builder() { | ||
38 | + return new Builder(); | ||
39 | + } | ||
40 | + | ||
41 | + private OpenstackNetwork(String name, String tenantId, String id, String sid, | ||
42 | + String type) { | ||
43 | + this.name = checkNotNull(name); | ||
44 | + this.tenantId = checkNotNull(tenantId); | ||
45 | + this.segmentId = checkNotNull(sid); | ||
46 | + this.id = checkNotNull(id); | ||
47 | + this.networkType = checkNotNull(type); | ||
48 | + } | ||
49 | + | ||
50 | + public String name() { | ||
51 | + return this.name; | ||
52 | + } | ||
53 | + | ||
54 | + public String tenantId() { | ||
55 | + return this.tenantId; | ||
56 | + } | ||
57 | + | ||
58 | + public String id() { | ||
59 | + return this.id; | ||
60 | + } | ||
61 | + | ||
62 | + public String segmentId() { | ||
63 | + return this.segmentId; | ||
64 | + } | ||
65 | + | ||
66 | + public String networkType() { | ||
67 | + return this.networkType; | ||
68 | + } | ||
69 | + | ||
70 | + public static final class Builder { | ||
71 | + private String name; | ||
72 | + private String tenantId; | ||
73 | + private String id; | ||
74 | + private String sid; | ||
75 | + private String networkType; | ||
76 | + | ||
77 | + public Builder name(String name) { | ||
78 | + this.name = name; | ||
79 | + | ||
80 | + return this; | ||
81 | + } | ||
82 | + | ||
83 | + public Builder tenantId(String tenantId) { | ||
84 | + this.tenantId = tenantId; | ||
85 | + | ||
86 | + return this; | ||
87 | + } | ||
88 | + | ||
89 | + public Builder id(String id) { | ||
90 | + this.id = id; | ||
91 | + | ||
92 | + return this; | ||
93 | + } | ||
94 | + | ||
95 | + public Builder segmentId(String sid) { | ||
96 | + this.sid = sid; | ||
97 | + | ||
98 | + return this; | ||
99 | + } | ||
100 | + | ||
101 | + public Builder networkType(String type) { | ||
102 | + this.networkType = type; | ||
103 | + | ||
104 | + return this; | ||
105 | + } | ||
106 | + | ||
107 | + public OpenstackNetwork build() { | ||
108 | + return new OpenstackNetwork(name, tenantId, id, sid, networkType); | ||
109 | + } | ||
110 | + | ||
111 | + } | ||
112 | +} |
apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackPort.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.openstackswitching; | ||
17 | + | ||
18 | +import com.google.common.collect.Lists; | ||
19 | +import org.onlab.packet.Ip4Address; | ||
20 | +import org.onlab.packet.MacAddress; | ||
21 | + | ||
22 | +import java.util.HashMap; | ||
23 | +import java.util.List; | ||
24 | + | ||
25 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
26 | + | ||
27 | +/** | ||
28 | + * It represents the Openstack Port information. | ||
29 | + */ | ||
30 | +public final class OpenstackPort { | ||
31 | + | ||
32 | + public enum PortStatus { | ||
33 | + UP, | ||
34 | + DOWN | ||
35 | + } | ||
36 | + | ||
37 | + private PortStatus status; | ||
38 | + private String name; | ||
39 | + // FIX_ME | ||
40 | + private String allowedAddressPairs; | ||
41 | + private boolean adminStateUp; | ||
42 | + private String networkId; | ||
43 | + private String tenantId; | ||
44 | + private String deviceOwner; | ||
45 | + private MacAddress macAddress; | ||
46 | + // <subnet id, ip address> | ||
47 | + private HashMap<String, Ip4Address> fixedIps; | ||
48 | + private String id; | ||
49 | + private List<String> securityGroups; | ||
50 | + private String deviceId; | ||
51 | + | ||
52 | + private OpenstackPort(PortStatus status, String name, boolean adminStateUp, | ||
53 | + String networkId, String tenantId, String deviceOwner, | ||
54 | + MacAddress macAddress, HashMap fixedIps, String id, | ||
55 | + List<String> securityGroups, String deviceId) { | ||
56 | + | ||
57 | + this.status = status; | ||
58 | + this.name = name; | ||
59 | + this.adminStateUp = adminStateUp; | ||
60 | + this.networkId = checkNotNull(networkId); | ||
61 | + this.tenantId = checkNotNull(tenantId); | ||
62 | + this.deviceOwner = deviceOwner; | ||
63 | + this.macAddress = checkNotNull(macAddress); | ||
64 | + this.fixedIps = checkNotNull(fixedIps); | ||
65 | + this.id = checkNotNull(id); | ||
66 | + this.securityGroups = securityGroups; | ||
67 | + this.deviceId = deviceId; | ||
68 | + } | ||
69 | + | ||
70 | + | ||
71 | + | ||
72 | + /** | ||
73 | + * Returns OpenstackPort builder object. | ||
74 | + * | ||
75 | + * @return OpenstackPort builder | ||
76 | + */ | ||
77 | + public static OpenstackPort.Builder builder() { | ||
78 | + return new Builder(); | ||
79 | + } | ||
80 | + | ||
81 | + /** | ||
82 | + * Returns port status. | ||
83 | + * | ||
84 | + * @return port status | ||
85 | + */ | ||
86 | + public PortStatus status() { | ||
87 | + return status; | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Returns port name. | ||
92 | + * | ||
93 | + * @return port name | ||
94 | + */ | ||
95 | + public String name() { | ||
96 | + return name; | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * Returns whether admin state up or not. | ||
101 | + * | ||
102 | + * @return true if admin state up, false otherwise | ||
103 | + */ | ||
104 | + public boolean isAdminStateUp() { | ||
105 | + return adminStateUp; | ||
106 | + } | ||
107 | + | ||
108 | + /** | ||
109 | + * Returns network ID. | ||
110 | + * | ||
111 | + * @return network ID | ||
112 | + */ | ||
113 | + public String networkId() { | ||
114 | + return networkId; | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * Returns device owner. | ||
119 | + * | ||
120 | + * @return device owner | ||
121 | + */ | ||
122 | + public String deviceOwner() { | ||
123 | + return deviceOwner; | ||
124 | + } | ||
125 | + | ||
126 | + /** | ||
127 | + * Returns mac address. | ||
128 | + * | ||
129 | + * @return mac address | ||
130 | + */ | ||
131 | + public MacAddress macAddress() { | ||
132 | + return macAddress; | ||
133 | + } | ||
134 | + | ||
135 | + /** | ||
136 | + * Returns the fixed IP information. | ||
137 | + * | ||
138 | + * @return fixed IP info | ||
139 | + */ | ||
140 | + public HashMap fixedIps() { | ||
141 | + return fixedIps; | ||
142 | + } | ||
143 | + | ||
144 | + /** | ||
145 | + * Returns port ID. | ||
146 | + * | ||
147 | + * @return port ID | ||
148 | + */ | ||
149 | + public String id() { | ||
150 | + return id; | ||
151 | + } | ||
152 | + | ||
153 | + /** | ||
154 | + * Returns security group information. | ||
155 | + * | ||
156 | + * @return security group info | ||
157 | + */ | ||
158 | + public List<String> securityGroups() { | ||
159 | + return securityGroups; | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * Returns device ID. | ||
164 | + * | ||
165 | + * @return device ID | ||
166 | + */ | ||
167 | + public String deviceId() { | ||
168 | + return deviceId; | ||
169 | + } | ||
170 | + | ||
171 | + // TODO : Implement the following functions when necessary | ||
172 | + //@Override | ||
173 | + //public void equals(Object that) { | ||
174 | + // | ||
175 | + //} | ||
176 | + // | ||
177 | + //@Override | ||
178 | + //public int hashCode() { | ||
179 | + // | ||
180 | + //} | ||
181 | + | ||
182 | + /** | ||
183 | + * OpenstackPort Builder class. | ||
184 | + */ | ||
185 | + public static final class Builder { | ||
186 | + | ||
187 | + private PortStatus status; | ||
188 | + private String name; | ||
189 | + // FIX_ME | ||
190 | + private String allowedAddressPairs; | ||
191 | + private boolean adminStateUp; | ||
192 | + private String networkId; | ||
193 | + private String tenantId; | ||
194 | + private String deviceOwner; | ||
195 | + private MacAddress macAddress; | ||
196 | + // list of hash map <subnet id, ip address> | ||
197 | + private HashMap<String, Ip4Address> fixedIps; | ||
198 | + private String id; | ||
199 | + private List<String> securityGroups; | ||
200 | + private String deviceId; | ||
201 | + | ||
202 | + Builder() { | ||
203 | + fixedIps = new HashMap<>(); | ||
204 | + securityGroups = Lists.newArrayList(); | ||
205 | + } | ||
206 | + | ||
207 | + /** | ||
208 | + * Sets port status. | ||
209 | + * | ||
210 | + * @param status port status | ||
211 | + * @return Builder object | ||
212 | + */ | ||
213 | + public Builder portStatus(PortStatus status) { | ||
214 | + this.status = status; | ||
215 | + | ||
216 | + return this; | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Sets port name. | ||
221 | + * | ||
222 | + * @param name port name | ||
223 | + * @return Builder object | ||
224 | + */ | ||
225 | + public Builder name(String name) { | ||
226 | + this.name = name; | ||
227 | + | ||
228 | + return this; | ||
229 | + } | ||
230 | + | ||
231 | + /** | ||
232 | + * Sets whether admin state up or not. | ||
233 | + * | ||
234 | + * @param isAdminStateUp true if admin state is up, false otherwise | ||
235 | + * @return Builder object | ||
236 | + */ | ||
237 | + public Builder adminState(boolean isAdminStateUp) { | ||
238 | + this.adminStateUp = isAdminStateUp; | ||
239 | + | ||
240 | + return this; | ||
241 | + } | ||
242 | + | ||
243 | + /** | ||
244 | + * Sets network ID. | ||
245 | + * | ||
246 | + * @param networkId network ID | ||
247 | + * @return Builder object | ||
248 | + */ | ||
249 | + public Builder netwrokId(String networkId) { | ||
250 | + this.networkId = networkId; | ||
251 | + | ||
252 | + return this; | ||
253 | + } | ||
254 | + | ||
255 | + /** | ||
256 | + * Sets tenant ID. | ||
257 | + * | ||
258 | + * @param tenantId tenant ID | ||
259 | + * @return Builder object | ||
260 | + */ | ||
261 | + public Builder tenantId(String tenantId) { | ||
262 | + this.tenantId = tenantId; | ||
263 | + | ||
264 | + return this; | ||
265 | + } | ||
266 | + | ||
267 | + /** | ||
268 | + * Sets device owner. | ||
269 | + * | ||
270 | + * @param owner device owner | ||
271 | + * @return Builder object | ||
272 | + */ | ||
273 | + public Builder deviceOwner(String owner) { | ||
274 | + this.deviceOwner = owner; | ||
275 | + | ||
276 | + return this; | ||
277 | + } | ||
278 | + | ||
279 | + /** | ||
280 | + * Sets MAC address of the port. | ||
281 | + * | ||
282 | + * @param mac MAC address | ||
283 | + * @return Builder object | ||
284 | + */ | ||
285 | + public Builder macAddress(MacAddress mac) { | ||
286 | + this.macAddress = mac; | ||
287 | + | ||
288 | + return this; | ||
289 | + } | ||
290 | + | ||
291 | + /** | ||
292 | + * Sets Fixed IP address information. | ||
293 | + * | ||
294 | + * @param fixedIpList Fixed IP info | ||
295 | + * @return Builder object | ||
296 | + */ | ||
297 | + public Builder fixedIps(HashMap<String, Ip4Address> fixedIpList) { | ||
298 | + fixedIps.putAll(fixedIpList); | ||
299 | + | ||
300 | + return this; | ||
301 | + } | ||
302 | + | ||
303 | + /** | ||
304 | + * Sets ID of the port. | ||
305 | + * | ||
306 | + * @param id ID of the port | ||
307 | + * @return Builder object | ||
308 | + */ | ||
309 | + public Builder id(String id) { | ||
310 | + this.id = id; | ||
311 | + | ||
312 | + return this; | ||
313 | + } | ||
314 | + | ||
315 | + /** | ||
316 | + * Sets security group of the port. | ||
317 | + * | ||
318 | + * @param securityGroup security group of the port | ||
319 | + * @return Builder object | ||
320 | + */ | ||
321 | + public Builder securityGroup(String securityGroup) { | ||
322 | + securityGroups.add(securityGroup); | ||
323 | + | ||
324 | + return this; | ||
325 | + } | ||
326 | + | ||
327 | + /** | ||
328 | + * Sets device ID of the port. | ||
329 | + * | ||
330 | + * @param deviceId device ID | ||
331 | + * @return Builder object | ||
332 | + */ | ||
333 | + public Builder deviceId(String deviceId) { | ||
334 | + this.deviceId = deviceId; | ||
335 | + | ||
336 | + return this; | ||
337 | + } | ||
338 | + | ||
339 | + /** | ||
340 | + * Builds an OpenstackPort object. | ||
341 | + * | ||
342 | + * @return OpenstackPort objecet | ||
343 | + */ | ||
344 | + public OpenstackPort build() { | ||
345 | + return new OpenstackPort(status, name, adminStateUp, networkId, networkId, | ||
346 | + deviceOwner, macAddress, fixedIps, id, securityGroups, deviceId); | ||
347 | + } | ||
348 | + } | ||
349 | +} | ||
350 | + |
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.openstackswitching; | ||
17 | + | ||
18 | +import com.google.common.collect.Lists; | ||
19 | +import com.google.common.collect.Maps; | ||
20 | +import org.apache.felix.scr.annotations.Activate; | ||
21 | +import org.apache.felix.scr.annotations.Component; | ||
22 | +import org.apache.felix.scr.annotations.Deactivate; | ||
23 | +import org.apache.felix.scr.annotations.Reference; | ||
24 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
25 | +import org.apache.felix.scr.annotations.Service; | ||
26 | +import org.onlab.packet.Ethernet; | ||
27 | +import org.onlab.packet.IPv4; | ||
28 | +import org.onlab.packet.Ip4Address; | ||
29 | +import org.onlab.packet.Ip4Prefix; | ||
30 | +import org.onlab.packet.MacAddress; | ||
31 | +import org.onlab.packet.UDP; | ||
32 | +import org.onosproject.core.ApplicationId; | ||
33 | +import org.onosproject.core.CoreService; | ||
34 | +import org.onosproject.net.Device; | ||
35 | +import org.onosproject.net.DeviceId; | ||
36 | +import org.onosproject.net.Port; | ||
37 | +import org.onosproject.net.device.DeviceEvent; | ||
38 | +import org.onosproject.net.device.DeviceListener; | ||
39 | +import org.onosproject.net.device.DeviceService; | ||
40 | +import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
41 | +import org.onosproject.net.packet.InboundPacket; | ||
42 | +import org.onosproject.net.packet.PacketContext; | ||
43 | +import org.onosproject.net.packet.PacketProcessor; | ||
44 | +import org.onosproject.net.packet.PacketService; | ||
45 | +import org.slf4j.Logger; | ||
46 | +import org.slf4j.LoggerFactory; | ||
47 | + | ||
48 | +import java.util.HashMap; | ||
49 | +import java.util.List; | ||
50 | +import java.util.concurrent.ExecutorService; | ||
51 | +import java.util.concurrent.Executors; | ||
52 | + | ||
53 | +@SuppressWarnings("ALL") | ||
54 | +@Service | ||
55 | +@Component(immediate = true) | ||
56 | +/** | ||
57 | + * It populates forwarding rules for VMs created by Openstack. | ||
58 | + */ | ||
59 | +public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ||
60 | + | ||
61 | + private static Logger log = LoggerFactory | ||
62 | + .getLogger(OpenstackSwitchingManager.class); | ||
63 | + | ||
64 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
65 | + protected CoreService coreService; | ||
66 | + | ||
67 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
68 | + protected PacketService packetService; | ||
69 | + | ||
70 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
71 | + protected DeviceService deviceService; | ||
72 | + | ||
73 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
74 | + protected FlowObjectiveService flowObjectiveService; | ||
75 | + | ||
76 | + | ||
77 | + public static final int DHCP_PORT = 67; | ||
78 | + | ||
79 | + private ApplicationId appId; | ||
80 | + private OpenstackArpHandler arpHandler; | ||
81 | + private OpenstackDhcpHandler dhcpHandler = new OpenstackDhcpHandler(); | ||
82 | + private OpenstackSwitchingRulePopulator rulePopulator; | ||
83 | + private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10); | ||
84 | + | ||
85 | + private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); | ||
86 | + private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); | ||
87 | + | ||
88 | + // Map <port_id, OpenstackPort> | ||
89 | + private HashMap<String, OpenstackPort> openstackPortMap; | ||
90 | + // Map <network_id, OpenstackNetwork> | ||
91 | + private HashMap<String, OpenstackNetwork> openstackNetworkMap; | ||
92 | + // Map <vni, List <Entry <portName, host ip>> | ||
93 | + private HashMap<String, List<PortInfo>> vniPortMap; | ||
94 | + private HashMap<Ip4Address, Port> tunnelPortMap; | ||
95 | + | ||
96 | + | ||
97 | + @Activate | ||
98 | + protected void activate() { | ||
99 | + appId = coreService | ||
100 | + .registerApplication("org.onosproject.openstackswitching"); | ||
101 | + rulePopulator = new OpenstackSwitchingRulePopulator(appId, flowObjectiveService); | ||
102 | + packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); | ||
103 | + deviceService.addListener(internalDeviceListener); | ||
104 | + | ||
105 | + openstackPortMap = Maps.newHashMap(); | ||
106 | + openstackNetworkMap = Maps.newHashMap(); | ||
107 | + vniPortMap = Maps.newHashMap(); | ||
108 | + tunnelPortMap = Maps.newHashMap(); | ||
109 | + | ||
110 | + arpHandler = new OpenstackArpHandler(openstackPortMap); | ||
111 | + | ||
112 | + log.info("Started"); | ||
113 | + } | ||
114 | + | ||
115 | + @Deactivate | ||
116 | + protected void deactivate() { | ||
117 | + packetService.removeProcessor(internalPacketProcessor); | ||
118 | + deviceService.removeListener(internalDeviceListener); | ||
119 | + | ||
120 | + deviceEventExcutorService.shutdown(); | ||
121 | + | ||
122 | + log.info("Stopped"); | ||
123 | + } | ||
124 | + | ||
125 | + @Override | ||
126 | + public void createPorts(OpenstackPort openstackPort) { | ||
127 | + openstackPortMap.put(openstackPort.id(), openstackPort); | ||
128 | + } | ||
129 | + | ||
130 | + @Override | ||
131 | + public void deletePorts() { | ||
132 | + | ||
133 | + } | ||
134 | + | ||
135 | + @Override | ||
136 | + public void updatePorts() { | ||
137 | + | ||
138 | + } | ||
139 | + | ||
140 | + @Override | ||
141 | + public void createNetwork(OpenstackNetwork openstackNetwork) { | ||
142 | + openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork); | ||
143 | + } | ||
144 | + | ||
145 | + private void processDeviceAdded(Device device) { | ||
146 | + log.warn("device {} is added", device.id()); | ||
147 | + rulePopulator.populateDefaultRules(device.id()); | ||
148 | + } | ||
149 | + | ||
150 | + private void processPortAdded(Device device, Port port) { | ||
151 | + // TODO: Simplify the data structure to store the network info | ||
152 | + // TODO: Make it stateless | ||
153 | + // TODO: All the logics need to be processed inside of the rulePopulator class | ||
154 | + synchronized (vniPortMap) { | ||
155 | + log.warn("port {} is updated", port.toString()); | ||
156 | + | ||
157 | + updatePortMaps(device, port); | ||
158 | + if (!port.annotations().value("portName").equals("vxlan")) { | ||
159 | + populateFlowRulesForTrafficToSameCnode(device, port); | ||
160 | + populateFlowRulesForTrafficToDifferentCnode(device, port); | ||
161 | + } | ||
162 | + } | ||
163 | + } | ||
164 | + | ||
165 | + private void processPortRemoved(Device device, Port port) { | ||
166 | + log.warn("port {} is removed", port.toString()); | ||
167 | + // TODO: need to update the vniPortMap | ||
168 | + } | ||
169 | + | ||
170 | + /** | ||
171 | + * Populates the flow rules for traffic to VMs in different Cnode using | ||
172 | + * Nicira extention. | ||
173 | + * | ||
174 | + * @param device device to put rules | ||
175 | + * @param port port information of the VM | ||
176 | + */ | ||
177 | + private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) { | ||
178 | + String portName = port.annotations().value("portName"); | ||
179 | + String channelId = device.annotations().value("channelId"); | ||
180 | + Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); | ||
181 | + Ip4Address fixedIp = getFixedIpAddressForPort(portName); | ||
182 | + // TODO: Avoid duplicate flow rule set up for VMs in other Cnode | ||
183 | + // (possibly avoided by flowrule subsystem?) | ||
184 | + if (tunnelPortMap.get(hostIpAddress) == null) { | ||
185 | + log.warn("There is no tunnel port information"); | ||
186 | + return; | ||
187 | + } | ||
188 | + String vni = getVniForPort(portName); | ||
189 | + MacAddress vmMac = getVmMacAddressForPort(portName); | ||
190 | + if (!vniPortMap.isEmpty() && vniPortMap.get(vni) != null) { | ||
191 | + for (PortInfo portInfo : vniPortMap.get(vni)) { | ||
192 | + if (!portInfo.portName.equals(portName) && | ||
193 | + !portInfo.hostIp.equals(hostIpAddress)) { | ||
194 | + MacAddress vmMacx = getVmMacAddressForPort(portInfo.portName); | ||
195 | + rulePopulator.populateForwardingRuleForOtherCnode(vni, | ||
196 | + device.id(), portInfo.hostIp, portInfo.fixedIp, vmMacx, | ||
197 | + tunnelPortMap.get(hostIpAddress).number(), | ||
198 | + portInfo.deviceId, hostIpAddress, fixedIp, vmMac, | ||
199 | + tunnelPortMap.get(portInfo.hostIp).number()); | ||
200 | + } | ||
201 | + } | ||
202 | + } | ||
203 | + } | ||
204 | + | ||
205 | + /** | ||
206 | + * Populates the flow rules for traffic to VMs in the same Cnode as the sender. | ||
207 | + * | ||
208 | + * @param device device to put the rules | ||
209 | + * @param port port info of the VM | ||
210 | + */ | ||
211 | + private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) { | ||
212 | + Ip4Prefix cidr = getCidrForPort(port.annotations().value("portName")); | ||
213 | + Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName")); | ||
214 | + if (vmIp != null) { | ||
215 | + rulePopulator.populateForwardingRule(vmIp, device.id(), port, cidr); | ||
216 | + } | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Updates the port maps using the port information. | ||
221 | + * | ||
222 | + * @param device device info | ||
223 | + * @param port port of the VM | ||
224 | + */ | ||
225 | + private void updatePortMaps(Device device, Port port) { | ||
226 | + String portName = port.annotations().value("portName"); | ||
227 | + String channelId = device.annotations().value("channelId"); | ||
228 | + Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]); | ||
229 | + if (portName.startsWith("vxlan")) { | ||
230 | + tunnelPortMap.put(hostIpAddress, port); | ||
231 | + } else { | ||
232 | + String vni = getVniForPort(portName); | ||
233 | + Ip4Address fixedIp = getFixedIpAddressForPort(portName); | ||
234 | + if (vniPortMap.get(vni) == null) { | ||
235 | + vniPortMap.put(vni, Lists.newArrayList()); | ||
236 | + } | ||
237 | + vniPortMap.get(vni).add(new PortInfo(device.id(), portName, fixedIp, hostIpAddress)); | ||
238 | + } | ||
239 | + } | ||
240 | + | ||
241 | + /** | ||
242 | + * Returns CIDR information from the subnet map for the port. | ||
243 | + * | ||
244 | + * @param portName port name of the port of the VM | ||
245 | + * @return CIDR of the VNI of the VM | ||
246 | + */ | ||
247 | + private Ip4Prefix getCidrForPort(String portName) { | ||
248 | + String networkId = null; | ||
249 | + String uuid = portName.substring(3); | ||
250 | + OpenstackPort port = openstackPortMap.values().stream() | ||
251 | + .filter(p -> p.id().startsWith(uuid)) | ||
252 | + .findFirst().get(); | ||
253 | + if (port == null) { | ||
254 | + log.warn("No port information for port {}", portName); | ||
255 | + return null; | ||
256 | + } | ||
257 | + | ||
258 | + //OpenstackSubnet subnet = openstackSubnetMap.values().stream() | ||
259 | + // .filter(s -> s.networkId().equals(port.networkId())) | ||
260 | + // .findFirst().get(); | ||
261 | + //if (subnet == null) { | ||
262 | + // log.warn("No subnet information for network {}", subnet.id()); | ||
263 | + // return null; | ||
264 | + //} | ||
265 | + | ||
266 | + //return Ip4Prefix.valueOf(subnet.cidr()); | ||
267 | + return null; | ||
268 | + } | ||
269 | + | ||
270 | + /** | ||
271 | + * Returns the VNI of the VM of the port. | ||
272 | + * | ||
273 | + * @param portName VM port | ||
274 | + * @return VNI | ||
275 | + */ | ||
276 | + private String getVniForPort(String portName) { | ||
277 | + String networkId = null; | ||
278 | + String uuid = portName.substring(3); | ||
279 | + OpenstackPort port = openstackPortMap.values().stream() | ||
280 | + .filter(p -> p.id().startsWith(uuid)) | ||
281 | + .findFirst().get(); | ||
282 | + if (port == null) { | ||
283 | + log.warn("No port information for port {}", portName); | ||
284 | + return null; | ||
285 | + } | ||
286 | + OpenstackNetwork network = openstackNetworkMap.values().stream() | ||
287 | + .filter(n -> n.id().equals(port.networkId())) | ||
288 | + .findFirst().get(); | ||
289 | + if (network == null) { | ||
290 | + log.warn("No VNI information for network {}", network.id()); | ||
291 | + return null; | ||
292 | + } | ||
293 | + | ||
294 | + return network.segmentId(); | ||
295 | + } | ||
296 | + | ||
297 | + /** | ||
298 | + * Returns the Fixed IP address of the VM. | ||
299 | + * | ||
300 | + * @param portName VM port info | ||
301 | + * @return IP address of the VM | ||
302 | + */ | ||
303 | + private Ip4Address getFixedIpAddressForPort(String portName) { | ||
304 | + | ||
305 | + // FIXME - For now we use the information stored from neutron Rest API call. | ||
306 | + // TODO - Later, the information needs to be extracted from Neutron on-demand. | ||
307 | + String uuid = portName.substring(3); | ||
308 | + OpenstackPort port = openstackPortMap.values().stream() | ||
309 | + .filter(p -> p.id().startsWith(uuid)) | ||
310 | + .findFirst().get(); | ||
311 | + | ||
312 | + if (port == null) { | ||
313 | + log.error("There is no port information for port name {}", portName); | ||
314 | + return null; | ||
315 | + } | ||
316 | + | ||
317 | + if (port.fixedIps().isEmpty()) { | ||
318 | + log.error("There is no fixed IP info in the port information"); | ||
319 | + return null; | ||
320 | + } | ||
321 | + | ||
322 | + return (Ip4Address) port.fixedIps().values().toArray()[0]; | ||
323 | + } | ||
324 | + | ||
325 | + /** | ||
326 | + * Returns the MAC address of the VM of the port. | ||
327 | + * | ||
328 | + * @param portName VM port | ||
329 | + * @return MAC address of the VM | ||
330 | + */ | ||
331 | + private MacAddress getVmMacAddressForPort(String portName) { | ||
332 | + | ||
333 | + String uuid = portName.substring(3); | ||
334 | + OpenstackPort port = openstackPortMap.values().stream() | ||
335 | + .filter(p -> p.id().startsWith(uuid)) | ||
336 | + .findFirst().get(); | ||
337 | + | ||
338 | + if (port == null) { | ||
339 | + log.error("There is no mac information for port name {}", portName); | ||
340 | + return null; | ||
341 | + } | ||
342 | + | ||
343 | + return port.macAddress(); | ||
344 | + } | ||
345 | + | ||
346 | + private class InternalPacketProcessor implements PacketProcessor { | ||
347 | + | ||
348 | + @Override | ||
349 | + public void process(PacketContext context) { | ||
350 | + | ||
351 | + if (context.isHandled()) { | ||
352 | + return; | ||
353 | + } | ||
354 | + | ||
355 | + InboundPacket pkt = context.inPacket(); | ||
356 | + Ethernet ethernet = pkt.parsed(); | ||
357 | + | ||
358 | + if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { | ||
359 | + arpHandler.processPacketIn(pkt); | ||
360 | + } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { | ||
361 | + IPv4 ipPacket = (IPv4) ethernet.getPayload(); | ||
362 | + | ||
363 | + if (ipPacket.getProtocol() == IPv4.PROTOCOL_UDP) { | ||
364 | + UDP udpPacket = (UDP) ipPacket.getPayload(); | ||
365 | + if (udpPacket.getDestinationPort() == DHCP_PORT) { | ||
366 | + dhcpHandler.processPacketIn(pkt); | ||
367 | + } | ||
368 | + } | ||
369 | + } | ||
370 | + } | ||
371 | + } | ||
372 | + | ||
373 | + private class InternalDeviceListener implements DeviceListener { | ||
374 | + | ||
375 | + @Override | ||
376 | + public void event(DeviceEvent event) { | ||
377 | + deviceEventExcutorService.execute(new InternalEventHandler(event)); | ||
378 | + } | ||
379 | + } | ||
380 | + | ||
381 | + private class InternalEventHandler implements Runnable { | ||
382 | + | ||
383 | + volatile DeviceEvent deviceEvent; | ||
384 | + | ||
385 | + InternalEventHandler(DeviceEvent deviceEvent) { | ||
386 | + this.deviceEvent = deviceEvent; | ||
387 | + } | ||
388 | + | ||
389 | + @Override | ||
390 | + public void run() { | ||
391 | + switch (deviceEvent.type()) { | ||
392 | + case DEVICE_ADDED: | ||
393 | + processDeviceAdded((Device) deviceEvent.subject()); | ||
394 | + break; | ||
395 | + case DEVICE_UPDATED: | ||
396 | + Port port = (Port) deviceEvent.subject(); | ||
397 | + if (port.isEnabled()) { | ||
398 | + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); | ||
399 | + } | ||
400 | + break; | ||
401 | + case DEVICE_AVAILABILITY_CHANGED: | ||
402 | + Device device = (Device) deviceEvent.subject(); | ||
403 | + if (deviceService.isAvailable(device.id())) { | ||
404 | + processDeviceAdded(device); | ||
405 | + } | ||
406 | + break; | ||
407 | + case PORT_ADDED: | ||
408 | + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); | ||
409 | + break; | ||
410 | + case PORT_UPDATED: | ||
411 | + processPortAdded((Device) deviceEvent.subject(), deviceEvent.port()); | ||
412 | + break; | ||
413 | + case PORT_REMOVED: | ||
414 | + processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port()); | ||
415 | + break; | ||
416 | + default: | ||
417 | + break; | ||
418 | + } | ||
419 | + } | ||
420 | + } | ||
421 | + | ||
422 | + private final class PortInfo { | ||
423 | + DeviceId deviceId; | ||
424 | + String portName; | ||
425 | + Ip4Address fixedIp; | ||
426 | + Ip4Address hostIp; | ||
427 | + | ||
428 | + private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp, | ||
429 | + Ip4Address hostIp) { | ||
430 | + this.deviceId = deviceId; | ||
431 | + this.portName = portName; | ||
432 | + this.fixedIp = fixedIp; | ||
433 | + this.hostIp = hostIp; | ||
434 | + } | ||
435 | + } | ||
436 | + | ||
437 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
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.openstackswitching; | ||
18 | + | ||
19 | +import org.onlab.packet.Ethernet; | ||
20 | +import org.onlab.packet.IPv4; | ||
21 | +import org.onlab.packet.Ip4Address; | ||
22 | +import org.onlab.packet.Ip4Prefix; | ||
23 | +import org.onlab.packet.MacAddress; | ||
24 | +import org.onlab.packet.TpPort; | ||
25 | +import org.onosproject.core.ApplicationId; | ||
26 | +import org.onosproject.net.DeviceId; | ||
27 | +import org.onosproject.net.Port; | ||
28 | +import org.onosproject.net.PortNumber; | ||
29 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
30 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
31 | +import org.onosproject.net.flow.TrafficSelector; | ||
32 | +import org.onosproject.net.flow.TrafficTreatment; | ||
33 | +import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
34 | +import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
35 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
36 | +import org.slf4j.Logger; | ||
37 | +import org.slf4j.LoggerFactory; | ||
38 | + | ||
39 | +/** | ||
40 | + * It populates switching flow rules. | ||
41 | + * | ||
42 | + */ | ||
43 | +public class OpenstackSwitchingRulePopulator { | ||
44 | + | ||
45 | + private static Logger log = LoggerFactory | ||
46 | + .getLogger(OpenstackSwitchingRulePopulator.class); | ||
47 | + | ||
48 | + private FlowObjectiveService flowObjectiveService; | ||
49 | + private ApplicationId appId; | ||
50 | + | ||
51 | + /** | ||
52 | + * Returns OpenstackSwitchingRule reference. | ||
53 | + * @param flowObjectiveService FlowObjectiveService reference | ||
54 | + */ | ||
55 | + public OpenstackSwitchingRulePopulator(ApplicationId appId, | ||
56 | + FlowObjectiveService flowObjectiveService) { | ||
57 | + this.flowObjectiveService = flowObjectiveService; | ||
58 | + this.appId = appId; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Populates flows rules for forwarding packets to and from VMs. | ||
63 | + * | ||
64 | + * @return true if it succeeds to populate rules, false otherwise. | ||
65 | + */ | ||
66 | + public boolean populateForwardingRule(Ip4Address ip, DeviceId id, Port port, Ip4Prefix cidr) { | ||
67 | + | ||
68 | + | ||
69 | + setFlowRuleForVMsInSameCnode(ip, id, port, cidr); | ||
70 | + | ||
71 | + return true; | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * Populates the common flows rules for all VMs. | ||
76 | + * | ||
77 | + * - Send ARP packets to the controller | ||
78 | + * - Send DHCP packets to the controller | ||
79 | + * | ||
80 | + * @param id Device ID to populates rules to | ||
81 | + */ | ||
82 | + public void populateDefaultRules(DeviceId id) { | ||
83 | + | ||
84 | + //setFlowRuleForDHCP(id); | ||
85 | + setFlowRuleForArp(id); | ||
86 | + | ||
87 | + log.warn("Default rule has been set"); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Populates the forwarding rules for VMs with the same VNI but in other Code. | ||
92 | + * | ||
93 | + * @param vni VNI for the networks | ||
94 | + * @param id device ID to populates the flow rules | ||
95 | + * @param hostIp host IP address of the VM | ||
96 | + * @param vmIp fixed IP address for the VM | ||
97 | + * @param idx device ID for OVS of the other VM | ||
98 | + * @param hostIpx host IP address of the other VM | ||
99 | + * @param vmIpx fixed IP address of the other VM | ||
100 | + */ | ||
101 | + public void populateForwardingRuleForOtherCnode(String vni, DeviceId id, Ip4Address hostIp, | ||
102 | + Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort, | ||
103 | + DeviceId idx, Ip4Address hostIpx, | ||
104 | + Ip4Address vmIpx, MacAddress vmMacx, PortNumber tunnelPortx) { | ||
105 | + setVxLanFlowRule(vni, id, hostIp, vmIp, vmMac, tunnelPort); | ||
106 | + setVxLanFlowRule(vni, idx, hostIpx, vmIpx, vmMacx, tunnelPortx); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * Populates the flow rules for DHCP packets from VMs. | ||
111 | + * | ||
112 | + * @param id device ID to set the rules | ||
113 | + */ | ||
114 | + private void setFlowRuleForDHCP(DeviceId id) { | ||
115 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
116 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
117 | + | ||
118 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
119 | + .matchIPProtocol(IPv4.PROTOCOL_UDP) | ||
120 | + .matchUdpDst(TpPort.tpPort(OpenstackSwitchingManager.DHCP_PORT)); | ||
121 | + tBuilder.setOutput(PortNumber.CONTROLLER); | ||
122 | + | ||
123 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
124 | + .withSelector(sBuilder.build()) | ||
125 | + .withTreatment(tBuilder.build()) | ||
126 | + .withPriority(5000) | ||
127 | + .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
128 | + .fromApp(appId) | ||
129 | + .add(); | ||
130 | + | ||
131 | + flowObjectiveService.forward(id, fo); | ||
132 | + } | ||
133 | + | ||
134 | + /** | ||
135 | + * Populates the flow rules for ARP packets from VMs. | ||
136 | + * | ||
137 | + * @param id device ID to put rules. | ||
138 | + */ | ||
139 | + private void setFlowRuleForArp(DeviceId id) { | ||
140 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
141 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
142 | + | ||
143 | + sBuilder.matchEthType(Ethernet.TYPE_ARP); | ||
144 | + tBuilder.setOutput(PortNumber.CONTROLLER); | ||
145 | + | ||
146 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
147 | + .withSelector(sBuilder.build()) | ||
148 | + .withTreatment(tBuilder.build()) | ||
149 | + .withPriority(5000) | ||
150 | + .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
151 | + .fromApp(appId) | ||
152 | + .add(); | ||
153 | + | ||
154 | + flowObjectiveService.forward(id, fo); | ||
155 | + } | ||
156 | + | ||
157 | + /** | ||
158 | + * Sets the flow rules for traffic between VMs in the same Cnode. | ||
159 | + * | ||
160 | + * @param ip4Address VM IP address | ||
161 | + * @param id device ID to put rules | ||
162 | + * @param port VM port | ||
163 | + * @param cidr subnet info of the VMs | ||
164 | + */ | ||
165 | + private void setFlowRuleForVMsInSameCnode(Ip4Address ip4Address, DeviceId id, | ||
166 | + Port port, Ip4Prefix cidr) { | ||
167 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
168 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
169 | + | ||
170 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
171 | + .matchIPDst(ip4Address.toIpPrefix()) | ||
172 | + .matchIPSrc(cidr); | ||
173 | + tBuilder.setOutput(port.number()); | ||
174 | + | ||
175 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
176 | + .withSelector(sBuilder.build()) | ||
177 | + .withTreatment(tBuilder.build()) | ||
178 | + .withPriority(5000) | ||
179 | + .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
180 | + .fromApp(appId) | ||
181 | + .add(); | ||
182 | + | ||
183 | + flowObjectiveService.forward(id, fo); | ||
184 | + } | ||
185 | + | ||
186 | + /** | ||
187 | + * Sets the flow rules between traffic from VMs in different Cnode. | ||
188 | + * | ||
189 | + * @param vni VNI | ||
190 | + * @param id device ID | ||
191 | + * @param hostIp host IP of the VM | ||
192 | + * @param vmIp fixed IP of the VM | ||
193 | + * @param vmMac MAC address of the VM | ||
194 | + * @param tunnelPort tunnel port to forward traffic to | ||
195 | + */ | ||
196 | + private void setVxLanFlowRule(String vni, DeviceId id, Ip4Address hostIp, | ||
197 | + Ip4Address vmIp, MacAddress vmMac, PortNumber tunnelPort) { | ||
198 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
199 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
200 | + | ||
201 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
202 | + .matchIPDst(vmIp.toIpPrefix()); | ||
203 | + tBuilder.setTunnelId(Long.parseLong(vni)) | ||
204 | + //.setTunnelDst() <- for Nicira ext | ||
205 | + //.setEthDst(vmMac) | ||
206 | + .setOutput(tunnelPort); | ||
207 | + | ||
208 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
209 | + .withSelector(sBuilder.build()) | ||
210 | + .withTreatment(tBuilder.build()) | ||
211 | + .withPriority(5000) | ||
212 | + .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
213 | + .fromApp(appId) | ||
214 | + .add(); | ||
215 | + | ||
216 | + flowObjectiveService.forward(id, fo); | ||
217 | + } | ||
218 | +} |
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.openstackswitching; | ||
17 | + | ||
18 | +/** | ||
19 | + * It handles port management REST API from Openstack for VMs. | ||
20 | + */ | ||
21 | +public interface OpenstackSwitchingService { | ||
22 | + | ||
23 | + /** | ||
24 | + * Store the port information created by Openstack. | ||
25 | + * | ||
26 | + * @param openstackPort port information | ||
27 | + */ | ||
28 | + void createPorts(OpenstackPort openstackPort); | ||
29 | + | ||
30 | + /** | ||
31 | + * Removes flow rules corresponding to the port removed by Openstack. | ||
32 | + * | ||
33 | + */ | ||
34 | + void deletePorts(); | ||
35 | + | ||
36 | + /** | ||
37 | + * Updates flow rules corresponding to the port information updated by Openstack. | ||
38 | + * | ||
39 | + */ | ||
40 | + void updatePorts(); | ||
41 | + | ||
42 | + /** | ||
43 | + * Store the network information created by openstack. | ||
44 | + * | ||
45 | + * @param openstackNetwork network information | ||
46 | + */ | ||
47 | + void createNetwork(OpenstackNetwork openstackNetwork); | ||
48 | + | ||
49 | +} |
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.openstackswitching.web; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import org.onosproject.codec.CodecContext; | ||
21 | +import org.onosproject.codec.JsonCodec; | ||
22 | +import org.onosproject.openstackswitching.OpenstackNetwork; | ||
23 | +import org.slf4j.Logger; | ||
24 | +import org.slf4j.LoggerFactory; | ||
25 | + | ||
26 | +/** | ||
27 | + * Implementation of the OpenstackNetwork Codec. | ||
28 | + * | ||
29 | + */ | ||
30 | +public class OpenstackNetworkCodec extends JsonCodec<OpenstackNetwork> { | ||
31 | + | ||
32 | + protected static final Logger log = LoggerFactory | ||
33 | + .getLogger(OpenstackNetworkCodec.class); | ||
34 | + | ||
35 | + private static final String NETWORK = "network"; | ||
36 | + private static final String NAME = "name"; | ||
37 | + private static final String TENANT_ID = "tenant_id"; | ||
38 | + private static final String SEGMENTATION_ID = "provider:segmentation_id"; | ||
39 | + private static final String NETWORK_TYPE = "provider:network_type"; | ||
40 | + private static final String ID = "id"; | ||
41 | + | ||
42 | + @Override | ||
43 | + public OpenstackNetwork decode(ObjectNode json, CodecContext context) { | ||
44 | + | ||
45 | + JsonNode networkInfo = json.get(NETWORK); | ||
46 | + | ||
47 | + String name = networkInfo.path(NAME).asText(); | ||
48 | + String tenantId = networkInfo.path(TENANT_ID).asText(); | ||
49 | + String id = networkInfo.path(ID).asText(); | ||
50 | + | ||
51 | + OpenstackNetwork.Builder onb = OpenstackNetwork.builder(); | ||
52 | + onb.name(name) | ||
53 | + .tenantId(tenantId) | ||
54 | + .id(id); | ||
55 | + | ||
56 | + if (!networkInfo.path(NETWORK_TYPE).isMissingNode()) { | ||
57 | + onb.name(networkInfo.path(NETWORK_TYPE).asText()); | ||
58 | + onb.segmentId(networkInfo.path(SEGMENTATION_ID).asText()); | ||
59 | + } | ||
60 | + | ||
61 | + return onb.build(); | ||
62 | + } | ||
63 | + | ||
64 | +} |
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.openstackswitching.web; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import org.onosproject.openstackswitching.OpenstackNetwork; | ||
21 | +import org.onosproject.openstackswitching.OpenstackSwitchingService; | ||
22 | +import org.onosproject.rest.AbstractWebResource; | ||
23 | +import org.slf4j.Logger; | ||
24 | +import org.slf4j.LoggerFactory; | ||
25 | + | ||
26 | +import javax.ws.rs.Consumes; | ||
27 | +import javax.ws.rs.POST; | ||
28 | +import javax.ws.rs.Path; | ||
29 | +import javax.ws.rs.Produces; | ||
30 | +import javax.ws.rs.core.MediaType; | ||
31 | +import javax.ws.rs.core.Response; | ||
32 | +import java.io.InputStream; | ||
33 | + | ||
34 | +@Path("networks") | ||
35 | +public class OpenstackNetworkWebResource extends AbstractWebResource { | ||
36 | + | ||
37 | + protected static final Logger log = LoggerFactory | ||
38 | + .getLogger(OpenstackNetworkWebResource.class); | ||
39 | + | ||
40 | + private static final OpenstackNetworkCodec NETWORK_CODEC = new OpenstackNetworkCodec(); | ||
41 | + | ||
42 | + @POST | ||
43 | + @Consumes(MediaType.APPLICATION_JSON) | ||
44 | + @Produces(MediaType.APPLICATION_JSON) | ||
45 | + public Response createNetwork(InputStream input) { | ||
46 | + try { | ||
47 | + ObjectMapper mapper = new ObjectMapper(); | ||
48 | + ObjectNode networkNode = (ObjectNode) mapper.readTree(input); | ||
49 | + | ||
50 | + OpenstackNetwork openstackNetwork = NETWORK_CODEC.decode(networkNode, this); | ||
51 | + | ||
52 | + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); | ||
53 | + switchingService.createNetwork(openstackNetwork); | ||
54 | + return Response.status(Response.Status.OK).build(); | ||
55 | + } catch (Exception e) { | ||
56 | + log.error("Creates VirtualPort failed because of exception {}", | ||
57 | + e.toString()); | ||
58 | + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) | ||
59 | + .build(); | ||
60 | + } | ||
61 | + } | ||
62 | +} |
apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortCodec.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.openstackswitching.web; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
21 | +import org.onlab.packet.Ip4Address; | ||
22 | +import org.onlab.packet.MacAddress; | ||
23 | +import org.onosproject.codec.CodecContext; | ||
24 | +import org.onosproject.codec.JsonCodec; | ||
25 | +import org.onosproject.openstackswitching.OpenstackPort; | ||
26 | +import org.slf4j.Logger; | ||
27 | +import org.slf4j.LoggerFactory; | ||
28 | + | ||
29 | +import java.util.HashMap; | ||
30 | + | ||
31 | +/** | ||
32 | + * It encodes and decodes the OpenstackPort. | ||
33 | + */ | ||
34 | +public class OpenstackPortCodec extends JsonCodec<OpenstackPort> { | ||
35 | + | ||
36 | + private static Logger log = LoggerFactory | ||
37 | + .getLogger(OpenstackPortCodec.class); | ||
38 | + | ||
39 | + // JSON field names | ||
40 | + private static final String PORT = "port"; | ||
41 | + private static final String STATUS = "status"; | ||
42 | + private static final String NAME = "name"; | ||
43 | + private static final String ADDRESS_PAIR = "allowed_address_pairs"; | ||
44 | + private static final String ADMIN_STATUS = "admin_status"; | ||
45 | + private static final String NETWORK_ID = "network_id"; | ||
46 | + private static final String TENANT_ID = "tenant_id"; | ||
47 | + private static final String DEVICE_OWNER = "device_owner"; | ||
48 | + private static final String MAC_ADDRESS = "mac_address"; | ||
49 | + private static final String FIXED_IPS = "fixed_ips"; | ||
50 | + private static final String SUBNET_ID = "subnet_id"; | ||
51 | + private static final String IP_ADDRESS = "ip_address"; | ||
52 | + private static final String ID = "id"; | ||
53 | + private static final String SECURITY_GROUPS = "security_groups"; | ||
54 | + private static final String DEVICE_ID = "device_id"; | ||
55 | + | ||
56 | + @Override | ||
57 | + public OpenstackPort decode(ObjectNode json, CodecContext context) { | ||
58 | + | ||
59 | + HashMap<String, Ip4Address> fixedIpMap = new HashMap<>(); | ||
60 | + JsonNode portInfo = json.get(PORT); | ||
61 | + | ||
62 | + String status = portInfo.path(STATUS).asText(); | ||
63 | + String name = portInfo.path(NAME).asText(); | ||
64 | + boolean adminStateUp = portInfo.path(ADMIN_STATUS).asBoolean(); | ||
65 | + String networkId = portInfo.path(NETWORK_ID).asText(); | ||
66 | + String tenantId = portInfo.path(TENANT_ID).asText(); | ||
67 | + String deviceOwner = portInfo.path(DEVICE_OWNER).asText(); | ||
68 | + String macStr = portInfo.path(MAC_ADDRESS).asText(); | ||
69 | + ArrayNode fixedIpList = (ArrayNode) portInfo.path(FIXED_IPS); | ||
70 | + for (JsonNode fixedIpInfo: fixedIpList) { | ||
71 | + String subnetId = fixedIpInfo.path(SUBNET_ID).asText(); | ||
72 | + String ipAddressStr = fixedIpInfo.path(IP_ADDRESS).asText(); | ||
73 | + if (ipAddressStr != null) { | ||
74 | + Ip4Address ipAddress = Ip4Address.valueOf(ipAddressStr); | ||
75 | + fixedIpMap.put(subnetId, ipAddress); | ||
76 | + } | ||
77 | + } | ||
78 | + String id = portInfo.path(ID).asText(); | ||
79 | + String securityGroups = portInfo.path(SECURITY_GROUPS).asText(); | ||
80 | + String deviceId = portInfo.path(DEVICE_ID).asText(); | ||
81 | + | ||
82 | + OpenstackPort.Builder openstackPortBuilder = OpenstackPort.builder(); | ||
83 | + openstackPortBuilder.portStatus(OpenstackPort.PortStatus.valueOf(status)) | ||
84 | + .name(name) | ||
85 | + .adminState(adminStateUp) | ||
86 | + .netwrokId(networkId) | ||
87 | + .tenantId(tenantId) | ||
88 | + .deviceOwner(deviceOwner) | ||
89 | + .macAddress(MacAddress.valueOf(macStr)) | ||
90 | + .fixedIps(fixedIpMap) | ||
91 | + .id(id) | ||
92 | + .deviceId(deviceId); | ||
93 | + | ||
94 | + // FIX ME | ||
95 | + if (!securityGroups.isEmpty()) { | ||
96 | + openstackPortBuilder.securityGroup(securityGroups); | ||
97 | + } | ||
98 | + | ||
99 | + OpenstackPort openstackPort = openstackPortBuilder.build(); | ||
100 | + | ||
101 | + return openstackPort; | ||
102 | + } | ||
103 | + | ||
104 | +} |
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.openstackswitching.web; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import org.onosproject.openstackswitching.OpenstackPort; | ||
21 | +import org.onosproject.openstackswitching.OpenstackSwitchingService; | ||
22 | +import org.onosproject.rest.AbstractWebResource; | ||
23 | +import org.slf4j.Logger; | ||
24 | +import org.slf4j.LoggerFactory; | ||
25 | + | ||
26 | +import javax.ws.rs.Consumes; | ||
27 | +import javax.ws.rs.DELETE; | ||
28 | +import javax.ws.rs.POST; | ||
29 | +import javax.ws.rs.PUT; | ||
30 | +import javax.ws.rs.Path; | ||
31 | +import javax.ws.rs.Produces; | ||
32 | +import javax.ws.rs.core.MediaType; | ||
33 | +import javax.ws.rs.core.Response; | ||
34 | +import java.io.InputStream; | ||
35 | + | ||
36 | +@Path("ports") | ||
37 | +public class OpenstackPortWebResource extends AbstractWebResource { | ||
38 | + | ||
39 | + protected static final Logger log = LoggerFactory | ||
40 | + .getLogger(OpenstackPortWebResource.class); | ||
41 | + | ||
42 | + private static final OpenstackPortCodec PORT_CODEC = new OpenstackPortCodec(); | ||
43 | + | ||
44 | + @POST | ||
45 | + @Consumes(MediaType.APPLICATION_JSON) | ||
46 | + @Produces(MediaType.APPLICATION_JSON) | ||
47 | + public Response createPorts(InputStream input) { | ||
48 | + try { | ||
49 | + ObjectMapper mapper = new ObjectMapper(); | ||
50 | + ObjectNode portNode = (ObjectNode) mapper.readTree(input); | ||
51 | + | ||
52 | + OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this); | ||
53 | + | ||
54 | + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); | ||
55 | + switchingService.createPorts(openstackPort); | ||
56 | + log.info("REST API ports is called with {}", portNode.toString()); | ||
57 | + return Response.status(Response.Status.OK).build(); | ||
58 | + } catch (Exception e) { | ||
59 | + log.error("Creates VirtualPort failed because of exception {}", | ||
60 | + e.toString()); | ||
61 | + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) | ||
62 | + .build(); | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + @DELETE | ||
67 | + @Consumes(MediaType.APPLICATION_JSON) | ||
68 | + @Produces(MediaType.APPLICATION_JSON) | ||
69 | + public Response deletesPorts(InputStream input) { | ||
70 | + try { | ||
71 | + ObjectMapper mapper = new ObjectMapper(); | ||
72 | + ObjectNode portNode = (ObjectNode) mapper.readTree(input); | ||
73 | + | ||
74 | + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); | ||
75 | + switchingService.deletePorts(); | ||
76 | + log.info("REST API ports is called with {}", portNode.toString()); | ||
77 | + return Response.status(Response.Status.OK).build(); | ||
78 | + } catch (Exception e) { | ||
79 | + log.error("Delete VirtualPort failed because of exception {}", | ||
80 | + e.toString()); | ||
81 | + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) | ||
82 | + .build(); | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + @PUT | ||
87 | + @Path("{id}") | ||
88 | + @Consumes(MediaType.APPLICATION_JSON) | ||
89 | + @Produces(MediaType.APPLICATION_JSON) | ||
90 | + public Response updatePorts(InputStream input) { | ||
91 | + try { | ||
92 | + ObjectMapper mapper = new ObjectMapper(); | ||
93 | + ObjectNode portNode = (ObjectNode) mapper.readTree(input); | ||
94 | + | ||
95 | + OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class); | ||
96 | + switchingService.updatePorts(); | ||
97 | + log.info("REST API ports is called with {}", portNode.toString()); | ||
98 | + return Response.status(Response.Status.OK).build(); | ||
99 | + } catch (Exception e) { | ||
100 | + log.error("Update VirtualPort failed because of exception {}", | ||
101 | + e.toString()); | ||
102 | + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) | ||
103 | + .build(); | ||
104 | + } | ||
105 | + } | ||
106 | +} |
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>Openstack Switching 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.openstackswitching.web.OpenstackPortWebResource, | ||
34 | + org.onosproject.openstackswitching.web.OpenstackNetworkWebResource | ||
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> |
... | @@ -13,10 +13,7 @@ | ... | @@ -13,10 +13,7 @@ |
13 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 13 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | ~ See the License for the specific language governing permissions and | 14 | ~ See the License for the specific language governing permissions and |
15 | ~ limitations under the License. | 15 | ~ limitations under the License. |
16 | - --> | 16 | + --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
17 | -<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
18 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
20 | <modelVersion>4.0.0</modelVersion> | 17 | <modelVersion>4.0.0</modelVersion> |
21 | 18 | ||
22 | <parent> | 19 | <parent> |
... | @@ -60,6 +57,7 @@ | ... | @@ -60,6 +57,7 @@ |
60 | <module>igmp</module> | 57 | <module>igmp</module> |
61 | <module>pim</module> | 58 | <module>pim</module> |
62 | <module>mlb</module> | 59 | <module>mlb</module> |
60 | + <module>openstackswitching</module> | ||
63 | </modules> | 61 | </modules> |
64 | 62 | ||
65 | <properties> | 63 | <properties> | ... | ... |
-
Please register or login to post a comment