Committed by
Ali Al-Shabibi
removing cord-related applications
Change-Id: Ia232adeecf0f5ea17061b3fb7ca851b6a00e0f99
Showing
96 changed files
with
0 additions
and
12114 deletions
... | @@ -99,7 +99,6 @@ APPS = [ | ... | @@ -99,7 +99,6 @@ APPS = [ |
99 | # Apps | 99 | # Apps |
100 | '//apps/dhcp:onos-apps-dhcp-oar', | 100 | '//apps/dhcp:onos-apps-dhcp-oar', |
101 | '//apps/fwd:onos-apps-fwd-oar', | 101 | '//apps/fwd:onos-apps-fwd-oar', |
102 | - '//apps/aaa:onos-apps-aaa-oar', | ||
103 | '//apps/acl:onos-apps-acl-oar', | 102 | '//apps/acl:onos-apps-acl-oar', |
104 | '//apps/bgprouter:onos-apps-bgprouter-oar', | 103 | '//apps/bgprouter:onos-apps-bgprouter-oar', |
105 | '//apps/cip:onos-apps-cip-oar', | 104 | '//apps/cip:onos-apps-cip-oar', |
... | @@ -109,10 +108,7 @@ APPS = [ | ... | @@ -109,10 +108,7 @@ APPS = [ |
109 | '//apps/segmentrouting:onos-apps-segmentrouting-oar', | 108 | '//apps/segmentrouting:onos-apps-segmentrouting-oar', |
110 | '//apps/gangliametrics:onos-apps-gangliametrics-oar', | 109 | '//apps/gangliametrics:onos-apps-gangliametrics-oar', |
111 | '//apps/graphitemetrics:onos-apps-graphitemetrics-oar', | 110 | '//apps/graphitemetrics:onos-apps-graphitemetrics-oar', |
112 | - '//apps/igmp:onos-apps-igmp-oar', | ||
113 | - '//apps/cordmcast:onos-apps-cordmcast-oar', | ||
114 | '//apps/flowanalyzer:onos-apps-flowanalyzer-oar', | 111 | '//apps/flowanalyzer:onos-apps-flowanalyzer-oar', |
115 | - '//apps/olt:onos-apps-olt-oar', | ||
116 | '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar', | 112 | '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar', |
117 | '//apps/metrics:onos-apps-metrics-oar', | 113 | '//apps/metrics:onos-apps-metrics-oar', |
118 | '//apps/mfwd:onos-apps-mfwd-oar', | 114 | '//apps/mfwd:onos-apps-mfwd-oar', |
... | @@ -137,7 +133,6 @@ APPS = [ | ... | @@ -137,7 +133,6 @@ APPS = [ |
137 | '//apps/test/loadtest:onos-apps-test-loadtest-oar', | 133 | '//apps/test/loadtest:onos-apps-test-loadtest-oar', |
138 | '//apps/test/messaging-perf:onos-apps-test-messaging-perf-oar', | 134 | '//apps/test/messaging-perf:onos-apps-test-messaging-perf-oar', |
139 | '//apps/virtualbng:onos-apps-virtualbng-oar', | 135 | '//apps/virtualbng:onos-apps-virtualbng-oar', |
140 | - '//apps/cordvtn:onos-apps-cordvtn-oar', | ||
141 | '//apps/vpls:onos-apps-vpls-oar', | 136 | '//apps/vpls:onos-apps-vpls-oar', |
142 | '//apps/vrouter:onos-apps-vrouter-oar', | 137 | '//apps/vrouter:onos-apps-vrouter-oar', |
143 | '//apps/vtn:onos-apps-vtn-oar', | 138 | '//apps/vtn:onos-apps-vtn-oar', |
... | @@ -145,7 +140,6 @@ APPS = [ | ... | @@ -145,7 +140,6 @@ APPS = [ |
145 | '//apps/openstacknode:onos-apps-openstacknode-oar', | 140 | '//apps/openstacknode:onos-apps-openstacknode-oar', |
146 | '//apps/cpman/app:onos-apps-cpman-app-oar', | 141 | '//apps/cpman/app:onos-apps-cpman-app-oar', |
147 | '//apps/xosclient:onos-apps-xosclient-oar', | 142 | '//apps/xosclient:onos-apps-xosclient-oar', |
148 | - '//apps/cordconfig:onos-apps-cordconfig', | ||
149 | ] | 143 | ] |
150 | 144 | ||
151 | APP_JARS = [ | 145 | APP_JARS = [ |
... | @@ -154,7 +148,6 @@ APP_JARS = [ | ... | @@ -154,7 +148,6 @@ APP_JARS = [ |
154 | '//apps/dhcp/api:onos-apps-dhcp-api', | 148 | '//apps/dhcp/api:onos-apps-dhcp-api', |
155 | '//apps/dhcp/app:onos-apps-dhcp-app', | 149 | '//apps/dhcp/app:onos-apps-dhcp-app', |
156 | '//apps/fwd:onos-apps-fwd', | 150 | '//apps/fwd:onos-apps-fwd', |
157 | - '//apps/olt:onos-apps-olt-api', | ||
158 | '//apps/iptopology-api:onos-apps-iptopology-api', | 151 | '//apps/iptopology-api:onos-apps-iptopology-api', |
159 | '//apps/openstacknode:onos-apps-openstacknode', | 152 | '//apps/openstacknode:onos-apps-openstacknode', |
160 | '//apps/routing:onos-apps-routing', | 153 | '//apps/routing:onos-apps-routing', | ... | ... |
apps/aaa/BUCK
deleted
100644 → 0
1 | -COMPILE_DEPS = [ | ||
2 | - '//lib:CORE_DEPS', | ||
3 | - '//lib:org.apache.karaf.shell.console', | ||
4 | - '//cli:onos-cli', | ||
5 | -] | ||
6 | - | ||
7 | -TEST_DEPS = [ | ||
8 | - '//lib:TEST_ADAPTERS', | ||
9 | - '//core/common:onos-core-common', | ||
10 | -] | ||
11 | - | ||
12 | -osgi_jar_with_tests ( | ||
13 | - deps = COMPILE_DEPS, | ||
14 | - test_deps = TEST_DEPS, | ||
15 | -) | ||
16 | - | ||
17 | -onos_app ( | ||
18 | - title = 'Authentication App', | ||
19 | - category = 'Security', | ||
20 | - url = 'http://onosproject.org', | ||
21 | - description = 'ONOS authentication application.', | ||
22 | -) |
apps/aaa/app.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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 | -<app name="org.onosproject.aaa" origin="ATT" version="${project.version}" | ||
18 | - category="Security" url="http://onosproject.org" title="Authentication App" | ||
19 | - featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" | ||
20 | - features="${project.artifactId}"> | ||
21 | - <description>${project.description}</description> | ||
22 | - <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> | ||
23 | -</app> |
apps/aaa/features.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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 | -<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> | ||
18 | - <feature name="${project.artifactId}" version="${project.version}" | ||
19 | - description="${project.description}"> | ||
20 | - <feature>onos-api</feature> | ||
21 | - <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> | ||
22 | - </feature> | ||
23 | -</features> |
apps/aaa/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-app-aaa</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <description>ONOS authentication application</description> | ||
33 | - | ||
34 | - <dependencies> | ||
35 | - <dependency> | ||
36 | - <groupId>org.osgi</groupId> | ||
37 | - <artifactId>org.osgi.compendium</artifactId> | ||
38 | - </dependency> | ||
39 | - | ||
40 | - <dependency> | ||
41 | - <groupId>org.onosproject</groupId> | ||
42 | - <artifactId>onos-api</artifactId> | ||
43 | - <version>${project.version}</version> | ||
44 | - </dependency> | ||
45 | - | ||
46 | - <dependency> | ||
47 | - <groupId>org.onosproject</groupId> | ||
48 | - <artifactId>onlab-junit</artifactId> | ||
49 | - <scope>test</scope> | ||
50 | - </dependency> | ||
51 | - | ||
52 | - <dependency> | ||
53 | - <groupId>org.onosproject</groupId> | ||
54 | - <artifactId>onlab-osgi</artifactId> | ||
55 | - <version>${project.version}</version> | ||
56 | - <classifier>tests</classifier> | ||
57 | - <scope>test</scope> | ||
58 | - </dependency> | ||
59 | - | ||
60 | - <dependency> | ||
61 | - <groupId>org.onosproject</groupId> | ||
62 | - <artifactId>onos-api</artifactId> | ||
63 | - <version>${project.version}</version> | ||
64 | - <classifier>tests</classifier> | ||
65 | - <scope>test</scope> | ||
66 | - </dependency> | ||
67 | - | ||
68 | - <dependency> | ||
69 | - <groupId>org.onosproject</groupId> | ||
70 | - <artifactId>onos-cli</artifactId> | ||
71 | - <version>${project.version}</version> | ||
72 | - </dependency> | ||
73 | - | ||
74 | - <dependency> | ||
75 | - <groupId>org.apache.karaf.shell</groupId> | ||
76 | - <artifactId>org.apache.karaf.shell.console</artifactId> | ||
77 | - </dependency> | ||
78 | - </dependencies> | ||
79 | - | ||
80 | - | ||
81 | - <build> | ||
82 | - <plugins> | ||
83 | - <plugin> | ||
84 | - <groupId>org.apache.felix</groupId> | ||
85 | - <artifactId>maven-bundle-plugin</artifactId> | ||
86 | - </plugin> | ||
87 | - | ||
88 | - <plugin> | ||
89 | - <groupId>org.apache.felix</groupId> | ||
90 | - <artifactId>maven-scr-plugin</artifactId> | ||
91 | - </plugin> | ||
92 | - <plugin> | ||
93 | - <groupId>org.onosproject</groupId> | ||
94 | - <artifactId>onos-maven-plugin</artifactId> | ||
95 | - </plugin> | ||
96 | - </plugins> | ||
97 | - </build> | ||
98 | -</project> |
1 | -/* | ||
2 | - * Copyright 2015-present 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.aaa; | ||
17 | - | ||
18 | -import org.onosproject.core.ApplicationId; | ||
19 | -import org.onosproject.net.config.Config; | ||
20 | -import org.onosproject.net.config.basics.BasicElementConfig; | ||
21 | - | ||
22 | -import java.net.InetAddress; | ||
23 | -import java.net.UnknownHostException; | ||
24 | - | ||
25 | -/** | ||
26 | - * Network config for the AAA app. | ||
27 | - */ | ||
28 | -public class AaaConfig extends Config<ApplicationId> { | ||
29 | - | ||
30 | - private static final String RADIUS_IP = "radiusIp"; | ||
31 | - private static final String RADIUS_SERVER_PORT = "1812"; | ||
32 | - private static final String RADIUS_MAC = "radiusMac"; | ||
33 | - private static final String NAS_IP = "nasIp"; | ||
34 | - private static final String NAS_MAC = "nasMac"; | ||
35 | - private static final String RADIUS_SECRET = "radiusSecret"; | ||
36 | - private static final String RADIUS_SWITCH = "radiusSwitch"; | ||
37 | - private static final String RADIUS_PORT = "radiusPort"; | ||
38 | - | ||
39 | - // RADIUS server IP address | ||
40 | - protected static final String DEFAULT_RADIUS_IP = "10.128.10.4"; | ||
41 | - | ||
42 | - // RADIUS MAC address | ||
43 | - protected static final String DEFAULT_RADIUS_MAC = "00:00:00:00:01:10"; | ||
44 | - | ||
45 | - // NAS IP address | ||
46 | - protected static final String DEFAULT_NAS_IP = "10.128.9.244"; | ||
47 | - | ||
48 | - // NAS MAC address | ||
49 | - protected static final String DEFAULT_NAS_MAC = "00:00:00:00:10:01"; | ||
50 | - | ||
51 | - // RADIUS server shared secret | ||
52 | - protected static final String DEFAULT_RADIUS_SECRET = "ONOSecret"; | ||
53 | - | ||
54 | - // Radius Switch Id | ||
55 | - protected static final String DEFAULT_RADIUS_SWITCH = "of:90e2ba82f97791e9"; | ||
56 | - | ||
57 | - // Radius Port Number | ||
58 | - protected static final String DEFAULT_RADIUS_PORT = "129"; | ||
59 | - | ||
60 | - // Radius Server UDP Port Number | ||
61 | - protected static final String DEFAULT_RADIUS_SERVER_PORT = "1812"; | ||
62 | - | ||
63 | - /** | ||
64 | - * Gets the value of a string property, protecting for an empty | ||
65 | - * JSON object. | ||
66 | - * | ||
67 | - * @param name name of the property | ||
68 | - * @param defaultValue default value if none has been specified | ||
69 | - * @return String value if one os found, default value otherwise | ||
70 | - */ | ||
71 | - private String getStringProperty(String name, String defaultValue) { | ||
72 | - if (object == null) { | ||
73 | - return defaultValue; | ||
74 | - } | ||
75 | - return get(name, defaultValue); | ||
76 | - } | ||
77 | - | ||
78 | - /** | ||
79 | - * Returns the NAS ip. | ||
80 | - * | ||
81 | - * @return ip address or null if not set | ||
82 | - */ | ||
83 | - public InetAddress nasIp() { | ||
84 | - try { | ||
85 | - return InetAddress.getByName(getStringProperty(NAS_IP, DEFAULT_NAS_IP)); | ||
86 | - } catch (UnknownHostException e) { | ||
87 | - return null; | ||
88 | - } | ||
89 | - } | ||
90 | - | ||
91 | - /** | ||
92 | - * Sets the NAS ip. | ||
93 | - * | ||
94 | - * @param ip new ip address; null to clear | ||
95 | - * @return self | ||
96 | - */ | ||
97 | - public BasicElementConfig nasIp(String ip) { | ||
98 | - return (BasicElementConfig) setOrClear(NAS_IP, ip); | ||
99 | - } | ||
100 | - | ||
101 | - /** | ||
102 | - * Returns the RADIUS server ip. | ||
103 | - * | ||
104 | - * @return ip address or null if not set | ||
105 | - */ | ||
106 | - public InetAddress radiusIp() { | ||
107 | - try { | ||
108 | - return InetAddress.getByName(getStringProperty(RADIUS_IP, DEFAULT_RADIUS_IP)); | ||
109 | - } catch (UnknownHostException e) { | ||
110 | - return null; | ||
111 | - } | ||
112 | - } | ||
113 | - | ||
114 | - /** | ||
115 | - * Sets the RADIUS server ip. | ||
116 | - * | ||
117 | - * @param ip new ip address; null to clear | ||
118 | - * @return self | ||
119 | - */ | ||
120 | - public BasicElementConfig radiusIp(String ip) { | ||
121 | - return (BasicElementConfig) setOrClear(RADIUS_IP, ip); | ||
122 | - } | ||
123 | - | ||
124 | - /** | ||
125 | - * Returns the RADIUS MAC address. | ||
126 | - * | ||
127 | - * @return mac address or null if not set | ||
128 | - */ | ||
129 | - public String radiusMac() { | ||
130 | - return getStringProperty(RADIUS_MAC, DEFAULT_RADIUS_MAC); | ||
131 | - } | ||
132 | - | ||
133 | - /** | ||
134 | - * Sets the RADIUS MAC address. | ||
135 | - * | ||
136 | - * @param mac new MAC address; null to clear | ||
137 | - * @return self | ||
138 | - */ | ||
139 | - public BasicElementConfig radiusMac(String mac) { | ||
140 | - return (BasicElementConfig) setOrClear(RADIUS_MAC, mac); | ||
141 | - } | ||
142 | - | ||
143 | - /** | ||
144 | - * Returns the RADIUS MAC address. | ||
145 | - * | ||
146 | - * @return mac address or null if not set | ||
147 | - */ | ||
148 | - public String nasMac() { | ||
149 | - return getStringProperty(NAS_MAC, DEFAULT_NAS_MAC); | ||
150 | - } | ||
151 | - | ||
152 | - /** | ||
153 | - * Sets the RADIUS MAC address. | ||
154 | - * | ||
155 | - * @param mac new MAC address; null to clear | ||
156 | - * @return self | ||
157 | - */ | ||
158 | - public BasicElementConfig nasMac(String mac) { | ||
159 | - return (BasicElementConfig) setOrClear(NAS_MAC, mac); | ||
160 | - } | ||
161 | - | ||
162 | - /** | ||
163 | - * Returns the RADIUS secret. | ||
164 | - * | ||
165 | - * @return radius secret or null if not set | ||
166 | - */ | ||
167 | - public String radiusSecret() { | ||
168 | - return getStringProperty(RADIUS_SECRET, DEFAULT_RADIUS_SECRET); | ||
169 | - } | ||
170 | - | ||
171 | - /** | ||
172 | - * Sets the RADIUS secret. | ||
173 | - * | ||
174 | - * @param secret new MAC address; null to clear | ||
175 | - * @return self | ||
176 | - */ | ||
177 | - public BasicElementConfig radiusSecret(String secret) { | ||
178 | - return (BasicElementConfig) setOrClear(RADIUS_SECRET, secret); | ||
179 | - } | ||
180 | - | ||
181 | - /** | ||
182 | - * Returns the ID of the RADIUS switch. | ||
183 | - * | ||
184 | - * @return radius switch ID or null if not set | ||
185 | - */ | ||
186 | - public String radiusSwitch() { | ||
187 | - return getStringProperty(RADIUS_SWITCH, DEFAULT_RADIUS_SWITCH); | ||
188 | - } | ||
189 | - | ||
190 | - /** | ||
191 | - * Sets the ID of the RADIUS switch. | ||
192 | - * | ||
193 | - * @param switchId new RADIUS switch ID; null to clear | ||
194 | - * @return self | ||
195 | - */ | ||
196 | - public BasicElementConfig radiusSwitch(String switchId) { | ||
197 | - return (BasicElementConfig) setOrClear(RADIUS_SWITCH, switchId); | ||
198 | - } | ||
199 | - | ||
200 | - /** | ||
201 | - * Returns the RADIUS port. | ||
202 | - * | ||
203 | - * @return radius port or null if not set | ||
204 | - */ | ||
205 | - public long radiusPort() { | ||
206 | - return Integer.parseInt(getStringProperty(RADIUS_PORT, DEFAULT_RADIUS_PORT)); | ||
207 | - } | ||
208 | - | ||
209 | - /** | ||
210 | - * Sets the RADIUS port. | ||
211 | - * | ||
212 | - * @param port new RADIUS port; null to clear | ||
213 | - * @return self | ||
214 | - */ | ||
215 | - public BasicElementConfig radiusPort(long port) { | ||
216 | - return (BasicElementConfig) setOrClear(RADIUS_PORT, port); | ||
217 | - } | ||
218 | - | ||
219 | - /** | ||
220 | - * Returns the RADIUS server UDP port. | ||
221 | - * | ||
222 | - * @return radius server UDP port. | ||
223 | - */ | ||
224 | - public short radiusServerUdpPort() { | ||
225 | - return Short.parseShort(getStringProperty(RADIUS_SERVER_PORT, | ||
226 | - DEFAULT_RADIUS_SERVER_PORT)); | ||
227 | - } | ||
228 | - | ||
229 | - /** | ||
230 | - * Sets the RADIUS port. | ||
231 | - * | ||
232 | - * @param port new RADIUS UDP port; -1 to clear | ||
233 | - * @return self | ||
234 | - */ | ||
235 | - public BasicElementConfig radiusServerUdpPort(short port) { | ||
236 | - return (BasicElementConfig) setOrClear(RADIUS_SERVER_PORT, (long) port); | ||
237 | - } | ||
238 | - | ||
239 | -} |
1 | -/* | ||
2 | - * Copyright 2015 AT&T Foundry | ||
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.aaa; | ||
17 | - | ||
18 | -import java.io.IOException; | ||
19 | -import java.net.DatagramPacket; | ||
20 | -import java.net.DatagramSocket; | ||
21 | -import java.net.InetAddress; | ||
22 | -import java.net.InetSocketAddress; | ||
23 | -import java.nio.ByteBuffer; | ||
24 | -import java.util.concurrent.ExecutorService; | ||
25 | -import java.util.concurrent.Executors; | ||
26 | - | ||
27 | -import org.apache.felix.scr.annotations.Activate; | ||
28 | -import org.apache.felix.scr.annotations.Component; | ||
29 | -import org.apache.felix.scr.annotations.Deactivate; | ||
30 | -import org.apache.felix.scr.annotations.Reference; | ||
31 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
32 | -import org.onlab.packet.DeserializationException; | ||
33 | -import org.onlab.packet.EAP; | ||
34 | -import org.onlab.packet.EAPOL; | ||
35 | -import org.onlab.packet.EthType; | ||
36 | -import org.onlab.packet.Ethernet; | ||
37 | -import org.onlab.packet.MacAddress; | ||
38 | -import org.onlab.packet.RADIUS; | ||
39 | -import org.onlab.packet.RADIUSAttribute; | ||
40 | -import org.onosproject.core.ApplicationId; | ||
41 | -import org.onosproject.core.CoreService; | ||
42 | -import org.onosproject.net.ConnectPoint; | ||
43 | -import org.onosproject.net.DeviceId; | ||
44 | -import org.onosproject.net.PortNumber; | ||
45 | -import org.onosproject.net.config.ConfigFactory; | ||
46 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
47 | -import org.onosproject.net.config.NetworkConfigListener; | ||
48 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
49 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
50 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
51 | -import org.onosproject.net.flow.TrafficSelector; | ||
52 | -import org.onosproject.net.flow.TrafficTreatment; | ||
53 | -import org.onosproject.net.packet.DefaultOutboundPacket; | ||
54 | -import org.onosproject.net.packet.InboundPacket; | ||
55 | -import org.onosproject.net.packet.OutboundPacket; | ||
56 | -import org.onosproject.net.packet.PacketContext; | ||
57 | -import org.onosproject.net.packet.PacketProcessor; | ||
58 | -import org.onosproject.net.packet.PacketService; | ||
59 | -import org.slf4j.Logger; | ||
60 | - | ||
61 | -import com.google.common.util.concurrent.ThreadFactoryBuilder; | ||
62 | - | ||
63 | -import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; | ||
64 | -import static org.onosproject.net.packet.PacketPriority.CONTROL; | ||
65 | -import static org.slf4j.LoggerFactory.getLogger; | ||
66 | - | ||
67 | -/** | ||
68 | - * AAA application for ONOS. | ||
69 | - */ | ||
70 | -@Component(immediate = true) | ||
71 | -public class AaaManager { | ||
72 | - | ||
73 | - // for verbose output | ||
74 | - private final Logger log = getLogger(getClass()); | ||
75 | - | ||
76 | - // a list of our dependencies : | ||
77 | - // to register with ONOS as an application - described next | ||
78 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
79 | - protected CoreService coreService; | ||
80 | - | ||
81 | - // to receive Packet-in events that we'll respond to | ||
82 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
83 | - protected PacketService packetService; | ||
84 | - | ||
85 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
86 | - protected NetworkConfigRegistry netCfgService; | ||
87 | - | ||
88 | - // Parsed RADIUS server addresses | ||
89 | - protected InetAddress radiusIpAddress; | ||
90 | - protected String radiusMacAddress; | ||
91 | - | ||
92 | - // NAS IP address | ||
93 | - protected InetAddress nasIpAddress; | ||
94 | - protected String nasMacAddress; | ||
95 | - | ||
96 | - // RADIUS server secret | ||
97 | - protected String radiusSecret; | ||
98 | - | ||
99 | - // ID of RADIUS switch | ||
100 | - protected String radiusSwitch; | ||
101 | - | ||
102 | - // RADIUS port number | ||
103 | - protected long radiusPort; | ||
104 | - | ||
105 | - // RADIUS server TCP port number | ||
106 | - protected short radiusServerPort; | ||
107 | - | ||
108 | - // our application-specific event handler | ||
109 | - private ReactivePacketProcessor processor = new ReactivePacketProcessor(); | ||
110 | - | ||
111 | - // our unique identifier | ||
112 | - private ApplicationId appId; | ||
113 | - | ||
114 | - // Socket used for UDP communications with RADIUS server | ||
115 | - private DatagramSocket radiusSocket; | ||
116 | - | ||
117 | - // Executor for RADIUS communication thread | ||
118 | - private ExecutorService executor; | ||
119 | - | ||
120 | - // Configuration properties factory | ||
121 | - private final ConfigFactory factory = | ||
122 | - new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY, | ||
123 | - AaaConfig.class, | ||
124 | - "AAA") { | ||
125 | - @Override | ||
126 | - public AaaConfig createConfig() { | ||
127 | - return new AaaConfig(); | ||
128 | - } | ||
129 | - }; | ||
130 | - | ||
131 | - // Listener for config changes | ||
132 | - private final InternalConfigListener cfgListener = new InternalConfigListener(); | ||
133 | - | ||
134 | - /** | ||
135 | - * Builds an EAPOL packet based on the given parameters. | ||
136 | - * | ||
137 | - * @param dstMac destination MAC address | ||
138 | - * @param srcMac source MAC address | ||
139 | - * @param vlan vlan identifier | ||
140 | - * @param eapolType EAPOL type | ||
141 | - * @param eap EAP payload | ||
142 | - * @return Ethernet frame | ||
143 | - */ | ||
144 | - private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac, | ||
145 | - short vlan, byte eapolType, EAP eap) { | ||
146 | - | ||
147 | - Ethernet eth = new Ethernet(); | ||
148 | - eth.setDestinationMACAddress(dstMac.toBytes()); | ||
149 | - eth.setSourceMACAddress(srcMac.toBytes()); | ||
150 | - eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); | ||
151 | - if (vlan != Ethernet.VLAN_UNTAGGED) { | ||
152 | - eth.setVlanID(vlan); | ||
153 | - } | ||
154 | - //eapol header | ||
155 | - EAPOL eapol = new EAPOL(); | ||
156 | - eapol.setEapolType(eapolType); | ||
157 | - eapol.setPacketLength(eap.getLength()); | ||
158 | - | ||
159 | - //eap part | ||
160 | - eapol.setPayload(eap); | ||
161 | - | ||
162 | - eth.setPayload(eapol); | ||
163 | - eth.setPad(true); | ||
164 | - return eth; | ||
165 | - } | ||
166 | - | ||
167 | - private void initializeLocalState() { | ||
168 | - try { | ||
169 | - radiusSocket = new DatagramSocket(null); | ||
170 | - radiusSocket.setReuseAddress(true); | ||
171 | - radiusSocket.bind(new InetSocketAddress(radiusServerPort)); | ||
172 | - } catch (Exception ex) { | ||
173 | - log.error("Can't open RADIUS socket", ex); | ||
174 | - } | ||
175 | - | ||
176 | - executor = Executors.newSingleThreadExecutor( | ||
177 | - new ThreadFactoryBuilder() | ||
178 | - .setNameFormat("AAA-radius-%d").build()); | ||
179 | - executor.execute(radiusListener); | ||
180 | - } | ||
181 | - | ||
182 | - @Activate | ||
183 | - public void activate() { | ||
184 | - netCfgService.addListener(cfgListener); | ||
185 | - netCfgService.registerConfigFactory(factory); | ||
186 | - | ||
187 | - // "org.onosproject.aaa" is the FQDN of our app | ||
188 | - appId = coreService.registerApplication("org.onosproject.aaa"); | ||
189 | - | ||
190 | - cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class)); | ||
191 | - | ||
192 | - // register our event handler | ||
193 | - packetService.addProcessor(processor, PacketProcessor.director(2)); | ||
194 | - requestIntercepts(); | ||
195 | - | ||
196 | - StateMachine.initializeMaps(); | ||
197 | - | ||
198 | - initializeLocalState(); | ||
199 | - log.info("Started"); | ||
200 | - } | ||
201 | - | ||
202 | - @Deactivate | ||
203 | - public void deactivate() { | ||
204 | - withdrawIntercepts(); | ||
205 | - // de-register and null our handler | ||
206 | - packetService.removeProcessor(processor); | ||
207 | - processor = null; | ||
208 | - StateMachine.destroyMaps(); | ||
209 | - radiusSocket.close(); | ||
210 | - executor.shutdownNow(); | ||
211 | - log.info("Stopped"); | ||
212 | - } | ||
213 | - | ||
214 | - protected void sendRadiusPacket(RADIUS radiusPacket) { | ||
215 | - | ||
216 | - try { | ||
217 | - final byte[] data = radiusPacket.serialize(); | ||
218 | - final DatagramSocket socket = radiusSocket; | ||
219 | - | ||
220 | - DatagramPacket packet = | ||
221 | - new DatagramPacket(data, data.length, | ||
222 | - radiusIpAddress, radiusServerPort); | ||
223 | - | ||
224 | - socket.send(packet); | ||
225 | - } catch (IOException e) { | ||
226 | - log.info("Cannot send packet to RADIUS server", e); | ||
227 | - } | ||
228 | - } | ||
229 | - | ||
230 | - /** | ||
231 | - * Request packet in via PacketService. | ||
232 | - */ | ||
233 | - private void requestIntercepts() { | ||
234 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
235 | - selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); | ||
236 | - packetService.requestPackets(selector.build(), | ||
237 | - CONTROL, appId); | ||
238 | - } | ||
239 | - | ||
240 | - /** | ||
241 | - * Cancel request for packet in via PacketService. | ||
242 | - */ | ||
243 | - private void withdrawIntercepts() { | ||
244 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
245 | - selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort()); | ||
246 | - packetService.cancelPackets(selector.build(), CONTROL, appId); | ||
247 | - } | ||
248 | - | ||
249 | - /** | ||
250 | - * Send the ethernet packet to the supplicant. | ||
251 | - * | ||
252 | - * @param ethernetPkt the ethernet packet | ||
253 | - * @param connectPoint the connect point to send out | ||
254 | - */ | ||
255 | - private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) { | ||
256 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build(); | ||
257 | - OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(), | ||
258 | - treatment, ByteBuffer.wrap(ethernetPkt.serialize())); | ||
259 | - packetService.emit(packet); | ||
260 | - } | ||
261 | - | ||
262 | - // our handler defined as a private inner class | ||
263 | - | ||
264 | - /** | ||
265 | - * Packet processor responsible for forwarding packets along their paths. | ||
266 | - */ | ||
267 | - private class ReactivePacketProcessor implements PacketProcessor { | ||
268 | - @Override | ||
269 | - public void process(PacketContext context) { | ||
270 | - | ||
271 | - // Extract the original Ethernet frame from the packet information | ||
272 | - InboundPacket pkt = context.inPacket(); | ||
273 | - Ethernet ethPkt = pkt.parsed(); | ||
274 | - if (ethPkt == null) { | ||
275 | - return; | ||
276 | - } | ||
277 | - try { | ||
278 | - // identify if incoming packet comes from supplicant (EAP) or RADIUS | ||
279 | - switch (EthType.EtherType.lookup(ethPkt.getEtherType())) { | ||
280 | - case EAPOL: | ||
281 | - handleSupplicantPacket(context.inPacket()); | ||
282 | - break; | ||
283 | - default: | ||
284 | - log.trace("Skipping Ethernet packet type {}", | ||
285 | - EthType.EtherType.lookup(ethPkt.getEtherType())); | ||
286 | - } | ||
287 | - } catch (StateMachineException e) { | ||
288 | - log.warn("Unable to process RADIUS packet:", e); | ||
289 | - } | ||
290 | - } | ||
291 | - | ||
292 | - /** | ||
293 | - * Creates and initializes common fields of a RADIUS packet. | ||
294 | - * | ||
295 | - * @param stateMachine state machine for the request | ||
296 | - * @param eapPacket EAP packet | ||
297 | - * @return RADIUS packet | ||
298 | - */ | ||
299 | - private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) { | ||
300 | - RADIUS radiusPayload = | ||
301 | - new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST, | ||
302 | - eapPacket.getIdentifier()); | ||
303 | - | ||
304 | - // set Request Authenticator in StateMachine | ||
305 | - stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); | ||
306 | - | ||
307 | - radiusPayload.setIdentifier(identifier); | ||
308 | - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME, | ||
309 | - stateMachine.username()); | ||
310 | - | ||
311 | - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP, | ||
312 | - AaaManager.this.nasIpAddress.getAddress()); | ||
313 | - | ||
314 | - radiusPayload.encapsulateMessage(eapPacket); | ||
315 | - | ||
316 | - return radiusPayload; | ||
317 | - } | ||
318 | - | ||
319 | - /** | ||
320 | - * Handles PAE packets (supplicant). | ||
321 | - * | ||
322 | - * @param inPacket Ethernet packet coming from the supplicant | ||
323 | - */ | ||
324 | - private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException { | ||
325 | - Ethernet ethPkt = inPacket.parsed(); | ||
326 | - // Where does it come from? | ||
327 | - MacAddress srcMac = ethPkt.getSourceMAC(); | ||
328 | - | ||
329 | - DeviceId deviceId = inPacket.receivedFrom().deviceId(); | ||
330 | - PortNumber portNumber = inPacket.receivedFrom().port(); | ||
331 | - String sessionId = deviceId.toString() + portNumber.toString(); | ||
332 | - StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId); | ||
333 | - if (stateMachine == null) { | ||
334 | - stateMachine = new StateMachine(sessionId); | ||
335 | - } | ||
336 | - | ||
337 | - | ||
338 | - EAPOL eapol = (EAPOL) ethPkt.getPayload(); | ||
339 | - | ||
340 | - switch (eapol.getEapolType()) { | ||
341 | - case EAPOL.EAPOL_START: | ||
342 | - stateMachine.start(); | ||
343 | - stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom()); | ||
344 | - | ||
345 | - //send an EAP Request/Identify to the supplicant | ||
346 | - EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null); | ||
347 | - Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress), | ||
348 | - ethPkt.getVlanID(), EAPOL.EAPOL_PACKET, | ||
349 | - eapPayload); | ||
350 | - stateMachine.setSupplicantAddress(srcMac); | ||
351 | - stateMachine.setVlanId(ethPkt.getVlanID()); | ||
352 | - | ||
353 | - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); | ||
354 | - | ||
355 | - break; | ||
356 | - case EAPOL.EAPOL_LOGOFF: | ||
357 | - if (stateMachine.state() == StateMachine.STATE_AUTHORIZED) { | ||
358 | - stateMachine.logoff(); | ||
359 | - } | ||
360 | - | ||
361 | - break; | ||
362 | - case EAPOL.EAPOL_PACKET: | ||
363 | - RADIUS radiusPayload; | ||
364 | - // check if this is a Response/Identify or a Response/TLS | ||
365 | - EAP eapPacket = (EAP) eapol.getPayload(); | ||
366 | - | ||
367 | - byte dataType = eapPacket.getDataType(); | ||
368 | - switch (dataType) { | ||
369 | - | ||
370 | - case EAP.ATTR_IDENTITY: | ||
371 | - // request id access to RADIUS | ||
372 | - stateMachine.setUsername(eapPacket.getData()); | ||
373 | - | ||
374 | - radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); | ||
375 | - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); | ||
376 | - | ||
377 | - sendRadiusPacket(radiusPayload); | ||
378 | - | ||
379 | - // change the state to "PENDING" | ||
380 | - stateMachine.requestAccess(); | ||
381 | - break; | ||
382 | - case EAP.ATTR_MD5: | ||
383 | - // verify if the EAP identifier corresponds to the | ||
384 | - // challenge identifier from the client state | ||
385 | - // machine. | ||
386 | - if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) { | ||
387 | - //send the RADIUS challenge response | ||
388 | - radiusPayload = | ||
389 | - getRadiusPayload(stateMachine, | ||
390 | - stateMachine.identifier(), | ||
391 | - eapPacket); | ||
392 | - | ||
393 | - if (stateMachine.challengeState() != null) { | ||
394 | - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, | ||
395 | - stateMachine.challengeState()); | ||
396 | - } | ||
397 | - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); | ||
398 | - sendRadiusPacket(radiusPayload); | ||
399 | - } | ||
400 | - break; | ||
401 | - case EAP.ATTR_TLS: | ||
402 | - // request id access to RADIUS | ||
403 | - radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket); | ||
404 | - | ||
405 | - if (stateMachine.challengeState() != null) { | ||
406 | - radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, | ||
407 | - stateMachine.challengeState()); | ||
408 | - } | ||
409 | - stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode()); | ||
410 | - | ||
411 | - radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret); | ||
412 | - sendRadiusPacket(radiusPayload); | ||
413 | - | ||
414 | - if (stateMachine.state() != StateMachine.STATE_PENDING) { | ||
415 | - stateMachine.requestAccess(); | ||
416 | - } | ||
417 | - | ||
418 | - break; | ||
419 | - default: | ||
420 | - return; | ||
421 | - } | ||
422 | - break; | ||
423 | - default: | ||
424 | - log.trace("Skipping EAPOL message {}", eapol.getEapolType()); | ||
425 | - } | ||
426 | - | ||
427 | - } | ||
428 | - } | ||
429 | - | ||
430 | - class RadiusListener implements Runnable { | ||
431 | - | ||
432 | - /** | ||
433 | - * Handles RADIUS packets. | ||
434 | - * | ||
435 | - * @param radiusPacket RADIUS packet coming from the RADIUS server. | ||
436 | - * @throws StateMachineException if an illegal state transition is triggered | ||
437 | - */ | ||
438 | - protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException { | ||
439 | - StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier()); | ||
440 | - if (stateMachine == null) { | ||
441 | - log.error("Invalid session identifier, exiting..."); | ||
442 | - return; | ||
443 | - } | ||
444 | - | ||
445 | - EAP eapPayload; | ||
446 | - Ethernet eth; | ||
447 | - switch (radiusPacket.getCode()) { | ||
448 | - case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE: | ||
449 | - RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE); | ||
450 | - byte[] challengeState = null; | ||
451 | - if (radiusAttrState != null) { | ||
452 | - challengeState = radiusAttrState.getValue(); | ||
453 | - } | ||
454 | - eapPayload = radiusPacket.decapsulateMessage(); | ||
455 | - stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState); | ||
456 | - eth = buildEapolResponse(stateMachine.supplicantAddress(), | ||
457 | - MacAddress.valueOf(nasMacAddress), | ||
458 | - stateMachine.vlanId(), | ||
459 | - EAPOL.EAPOL_PACKET, | ||
460 | - eapPayload); | ||
461 | - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); | ||
462 | - break; | ||
463 | - case RADIUS.RADIUS_CODE_ACCESS_ACCEPT: | ||
464 | - //send an EAPOL - Success to the supplicant. | ||
465 | - byte[] eapMessage = | ||
466 | - radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue(); | ||
467 | - eapPayload = new EAP(); | ||
468 | - eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length); | ||
469 | - eth = buildEapolResponse(stateMachine.supplicantAddress(), | ||
470 | - MacAddress.valueOf(nasMacAddress), | ||
471 | - stateMachine.vlanId(), | ||
472 | - EAPOL.EAPOL_PACKET, | ||
473 | - eapPayload); | ||
474 | - sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint()); | ||
475 | - | ||
476 | - stateMachine.authorizeAccess(); | ||
477 | - break; | ||
478 | - case RADIUS.RADIUS_CODE_ACCESS_REJECT: | ||
479 | - stateMachine.denyAccess(); | ||
480 | - break; | ||
481 | - default: | ||
482 | - log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode()); | ||
483 | - } | ||
484 | - } | ||
485 | - | ||
486 | - | ||
487 | - @Override | ||
488 | - public void run() { | ||
489 | - boolean done = false; | ||
490 | - int packetNumber = 1; | ||
491 | - | ||
492 | - log.info("UDP listener thread starting up"); | ||
493 | - RADIUS inboundRadiusPacket; | ||
494 | - while (!done) { | ||
495 | - try { | ||
496 | - byte[] packetBuffer = new byte[RADIUS.RADIUS_MAX_LENGTH]; | ||
497 | - DatagramPacket inboundBasePacket = | ||
498 | - new DatagramPacket(packetBuffer, packetBuffer.length); | ||
499 | - DatagramSocket socket = radiusSocket; | ||
500 | - socket.receive(inboundBasePacket); | ||
501 | - log.info("Packet #{} received", packetNumber++); | ||
502 | - try { | ||
503 | - inboundRadiusPacket = | ||
504 | - RADIUS.deserializer() | ||
505 | - .deserialize(inboundBasePacket.getData(), | ||
506 | - 0, | ||
507 | - inboundBasePacket.getLength()); | ||
508 | - handleRadiusPacket(inboundRadiusPacket); | ||
509 | - } catch (DeserializationException dex) { | ||
510 | - log.error("Cannot deserialize packet", dex); | ||
511 | - } catch (StateMachineException sme) { | ||
512 | - log.error("Illegal state machine operation", sme); | ||
513 | - } | ||
514 | - | ||
515 | - } catch (IOException e) { | ||
516 | - log.info("Socket was closed, exiting listener thread"); | ||
517 | - done = true; | ||
518 | - } | ||
519 | - } | ||
520 | - } | ||
521 | - } | ||
522 | - | ||
523 | - RadiusListener radiusListener = new RadiusListener(); | ||
524 | - | ||
525 | - private class InternalConfigListener implements NetworkConfigListener { | ||
526 | - | ||
527 | - /** | ||
528 | - * Reconfigures the AAA application according to the | ||
529 | - * configuration parameters passed. | ||
530 | - * | ||
531 | - * @param cfg configuration object | ||
532 | - */ | ||
533 | - private void reconfigureNetwork(AaaConfig cfg) { | ||
534 | - AaaConfig newCfg; | ||
535 | - if (cfg == null) { | ||
536 | - newCfg = new AaaConfig(); | ||
537 | - } else { | ||
538 | - newCfg = cfg; | ||
539 | - } | ||
540 | - if (newCfg.nasIp() != null) { | ||
541 | - nasIpAddress = newCfg.nasIp(); | ||
542 | - } | ||
543 | - if (newCfg.radiusIp() != null) { | ||
544 | - radiusIpAddress = newCfg.radiusIp(); | ||
545 | - } | ||
546 | - if (newCfg.radiusMac() != null) { | ||
547 | - radiusMacAddress = newCfg.radiusMac(); | ||
548 | - } | ||
549 | - if (newCfg.nasMac() != null) { | ||
550 | - nasMacAddress = newCfg.nasMac(); | ||
551 | - } | ||
552 | - if (newCfg.radiusSecret() != null) { | ||
553 | - radiusSecret = newCfg.radiusSecret(); | ||
554 | - } | ||
555 | - if (newCfg.radiusSwitch() != null) { | ||
556 | - radiusSwitch = newCfg.radiusSwitch(); | ||
557 | - } | ||
558 | - if (newCfg.radiusPort() != -1) { | ||
559 | - radiusPort = newCfg.radiusPort(); | ||
560 | - } | ||
561 | - if (newCfg.radiusServerUdpPort() != -1) { | ||
562 | - radiusServerPort = newCfg.radiusServerUdpPort(); | ||
563 | - } | ||
564 | - } | ||
565 | - | ||
566 | - @Override | ||
567 | - public void event(NetworkConfigEvent event) { | ||
568 | - | ||
569 | - if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
570 | - event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && | ||
571 | - event.configClass().equals(AaaConfig.class)) { | ||
572 | - | ||
573 | - AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class); | ||
574 | - reconfigureNetwork(cfg); | ||
575 | - radiusSocket.close(); | ||
576 | - executor.shutdownNow(); | ||
577 | - initializeLocalState(); | ||
578 | - log.info("Reconfigured"); | ||
579 | - } | ||
580 | - } | ||
581 | - } | ||
582 | - | ||
583 | - | ||
584 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.aaa; | ||
17 | - | ||
18 | -import org.apache.karaf.shell.commands.Command; | ||
19 | -import org.onosproject.cli.AbstractShellCommand; | ||
20 | - | ||
21 | -/** | ||
22 | - * Shows the users in the aaa. | ||
23 | - */ | ||
24 | -@Command(scope = "onos", name = "aaa-users", | ||
25 | - description = "Shows the aaa users") | ||
26 | -public class AaaShowUsersCommand extends AbstractShellCommand { | ||
27 | - @Override | ||
28 | - protected void execute() { | ||
29 | - String[] state = { | ||
30 | - "IDLE", | ||
31 | - "STARTED", | ||
32 | - "PENDING", | ||
33 | - "AUTHORIZED", | ||
34 | - "UNAUTHORIZED" | ||
35 | - }; | ||
36 | - for (StateMachine stateMachine : StateMachine.sessionIdMap().values()) { | ||
37 | - String deviceId = stateMachine.supplicantConnectpoint().deviceId().toString(); | ||
38 | - String portNum = stateMachine.supplicantConnectpoint().port().toString(); | ||
39 | - String username = new String(stateMachine.username()); | ||
40 | - print("UserName=%s,CurrentState=%s,DeviceId=%s,PortNumber=%s", | ||
41 | - username, state[stateMachine.state()], deviceId, portNum); | ||
42 | - } | ||
43 | - } | ||
44 | -} |
1 | -/* | ||
2 | - * | ||
3 | - * Copyright 2015 AT&T Foundry | ||
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 | - */ | ||
18 | - | ||
19 | -package org.onosproject.aaa; | ||
20 | - | ||
21 | -import java.util.BitSet; | ||
22 | -import java.util.Map; | ||
23 | - | ||
24 | -import org.onlab.packet.MacAddress; | ||
25 | -import org.onosproject.net.ConnectPoint; | ||
26 | -import org.slf4j.Logger; | ||
27 | - | ||
28 | -import com.google.common.collect.Maps; | ||
29 | - | ||
30 | -import static org.slf4j.LoggerFactory.getLogger; | ||
31 | - | ||
32 | -/** | ||
33 | - * AAA Finite State Machine. | ||
34 | - */ | ||
35 | - | ||
36 | -class StateMachine { | ||
37 | - //INDEX to identify the state in the transition table | ||
38 | - static final int STATE_IDLE = 0; | ||
39 | - static final int STATE_STARTED = 1; | ||
40 | - static final int STATE_PENDING = 2; | ||
41 | - static final int STATE_AUTHORIZED = 3; | ||
42 | - static final int STATE_UNAUTHORIZED = 4; | ||
43 | - | ||
44 | - //INDEX to identify the transition in the transition table | ||
45 | - static final int TRANSITION_START = 0; // --> started | ||
46 | - static final int TRANSITION_REQUEST_ACCESS = 1; | ||
47 | - static final int TRANSITION_AUTHORIZE_ACCESS = 2; | ||
48 | - static final int TRANSITION_DENY_ACCESS = 3; | ||
49 | - static final int TRANSITION_LOGOFF = 4; | ||
50 | - | ||
51 | - //map of access identifiers (issued at EAPOL START) | ||
52 | - static BitSet bitSet = new BitSet(); | ||
53 | - | ||
54 | - private int identifier = -1; | ||
55 | - private byte challengeIdentifier; | ||
56 | - private byte[] challengeState; | ||
57 | - private byte[] username; | ||
58 | - private byte[] requestAuthenticator; | ||
59 | - | ||
60 | - // Supplicant connectivity info | ||
61 | - private ConnectPoint supplicantConnectpoint; | ||
62 | - private MacAddress supplicantAddress; | ||
63 | - private short vlanId; | ||
64 | - | ||
65 | - private String sessionId = null; | ||
66 | - | ||
67 | - private final Logger log = getLogger(getClass()); | ||
68 | - | ||
69 | - | ||
70 | - private State[] states = { | ||
71 | - new Idle(), new Started(), new Pending(), new Authorized(), new Unauthorized() | ||
72 | - }; | ||
73 | - | ||
74 | - | ||
75 | - //State transition table | ||
76 | - /* | ||
77 | - | ||
78 | - state IDLE | STARTED | PENDING | AUTHORIZED | UNAUTHORIZED | ||
79 | - //// | ||
80 | - input | ||
81 | - ---------------------------------------------------------------------------------------------------- | ||
82 | - | ||
83 | - START STARTED | _ | _ | STARTED | _ | ||
84 | - | ||
85 | - REQUEST_ACCESS _ | PENDING | _ | _ | _ | ||
86 | - | ||
87 | - AUTHORIZE_ACCESS _ | _ | AUTHORIZED | _ | _ | ||
88 | - | ||
89 | - DENY_ACCESS _ | - | UNAUTHORIZED | _ | _ | ||
90 | - | ||
91 | - LOGOFF _ | _ | _ | IDLE | IDLE | ||
92 | - */ | ||
93 | - | ||
94 | - private int[] idleTransition = | ||
95 | - {STATE_STARTED, STATE_IDLE, STATE_IDLE, STATE_IDLE, STATE_IDLE}; | ||
96 | - private int[] startedTransition = | ||
97 | - {STATE_STARTED, STATE_PENDING, STATE_STARTED, STATE_STARTED, STATE_STARTED}; | ||
98 | - private int[] pendingTransition = | ||
99 | - {STATE_PENDING, STATE_PENDING, STATE_AUTHORIZED, STATE_UNAUTHORIZED, STATE_PENDING}; | ||
100 | - private int[] authorizedTransition = | ||
101 | - {STATE_STARTED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_IDLE}; | ||
102 | - private int[] unauthorizedTransition = | ||
103 | - {STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_IDLE}; | ||
104 | - | ||
105 | - //THE TRANSITION TABLE | ||
106 | - private int[][] transition = | ||
107 | - {idleTransition, startedTransition, pendingTransition, authorizedTransition, | ||
108 | - unauthorizedTransition}; | ||
109 | - | ||
110 | - private int currentState = STATE_IDLE; | ||
111 | - | ||
112 | - // Maps of state machines. Each state machine is represented by an | ||
113 | - // unique identifier on the switch: dpid + port number | ||
114 | - private static Map<String, StateMachine> sessionIdMap; | ||
115 | - private static Map<Integer, StateMachine> identifierMap; | ||
116 | - | ||
117 | - public static void initializeMaps() { | ||
118 | - sessionIdMap = Maps.newConcurrentMap(); | ||
119 | - identifierMap = Maps.newConcurrentMap(); | ||
120 | - } | ||
121 | - | ||
122 | - public static void destroyMaps() { | ||
123 | - sessionIdMap = null; | ||
124 | - identifierMap = null; | ||
125 | - } | ||
126 | - | ||
127 | - public static Map<String, StateMachine> sessionIdMap() { | ||
128 | - return sessionIdMap; | ||
129 | - } | ||
130 | - | ||
131 | - public static StateMachine lookupStateMachineById(byte identifier) { | ||
132 | - return identifierMap.get((int) identifier); | ||
133 | - } | ||
134 | - | ||
135 | - public static StateMachine lookupStateMachineBySessionId(String sessionId) { | ||
136 | - return sessionIdMap.get(sessionId); | ||
137 | - } /** | ||
138 | - * State Machine Constructor. | ||
139 | - * | ||
140 | - * @param sessionId session Id represented by the switch dpid + port number | ||
141 | - */ | ||
142 | - public StateMachine(String sessionId) { | ||
143 | - log.info("Creating a new state machine for {}", sessionId); | ||
144 | - this.sessionId = sessionId; | ||
145 | - sessionIdMap.put(sessionId, this); | ||
146 | - } | ||
147 | - | ||
148 | - /** | ||
149 | - * Gets the connect point for the supplicant side. | ||
150 | - * | ||
151 | - * @return supplicant connect point | ||
152 | - */ | ||
153 | - public ConnectPoint supplicantConnectpoint() { | ||
154 | - return supplicantConnectpoint; | ||
155 | - } | ||
156 | - | ||
157 | - /** | ||
158 | - * Sets the supplicant side connect point. | ||
159 | - * | ||
160 | - * @param supplicantConnectpoint supplicant select point. | ||
161 | - */ | ||
162 | - public void setSupplicantConnectpoint(ConnectPoint supplicantConnectpoint) { | ||
163 | - this.supplicantConnectpoint = supplicantConnectpoint; | ||
164 | - } | ||
165 | - | ||
166 | - /** | ||
167 | - * Gets the MAC address of the supplicant. | ||
168 | - * | ||
169 | - * @return supplicant MAC address | ||
170 | - */ | ||
171 | - public MacAddress supplicantAddress() { | ||
172 | - return supplicantAddress; | ||
173 | - } | ||
174 | - | ||
175 | - /** | ||
176 | - * Sets the supplicant MAC address. | ||
177 | - * | ||
178 | - * @param supplicantAddress new supplicant MAC address | ||
179 | - */ | ||
180 | - public void setSupplicantAddress(MacAddress supplicantAddress) { | ||
181 | - this.supplicantAddress = supplicantAddress; | ||
182 | - } | ||
183 | - | ||
184 | - /** | ||
185 | - * Gets the client's Vlan ID. | ||
186 | - * | ||
187 | - * @return client vlan ID | ||
188 | - */ | ||
189 | - public short vlanId() { | ||
190 | - return vlanId; | ||
191 | - } | ||
192 | - | ||
193 | - /** | ||
194 | - * Sets the client's vlan ID. | ||
195 | - * | ||
196 | - * @param vlanId new client vlan ID | ||
197 | - */ | ||
198 | - public void setVlanId(short vlanId) { | ||
199 | - this.vlanId = vlanId; | ||
200 | - } | ||
201 | - | ||
202 | - /** | ||
203 | - * Gets the client id that is requesting for access. | ||
204 | - * | ||
205 | - * @return The client id. | ||
206 | - */ | ||
207 | - public String sessionId() { | ||
208 | - return this.sessionId; | ||
209 | - } | ||
210 | - | ||
211 | - /** | ||
212 | - * Create the identifier for the state machine (happens when goes to STARTED state). | ||
213 | - */ | ||
214 | - private void createIdentifier() throws StateMachineException { | ||
215 | - log.debug("Creating Identifier."); | ||
216 | - int index; | ||
217 | - | ||
218 | - try { | ||
219 | - //find the first available spot for identifier assignment | ||
220 | - index = StateMachine.bitSet.nextClearBit(0); | ||
221 | - | ||
222 | - //there is a limit of 256 identifiers | ||
223 | - if (index == 256) { | ||
224 | - throw new StateMachineException("Cannot handle any new identifier. Limit is 256."); | ||
225 | - } | ||
226 | - } catch (IndexOutOfBoundsException e) { | ||
227 | - throw new StateMachineException(e.getMessage()); | ||
228 | - } | ||
229 | - | ||
230 | - log.info("Assigning identifier {}", index); | ||
231 | - StateMachine.bitSet.set(index); | ||
232 | - this.identifier = index; | ||
233 | - } | ||
234 | - | ||
235 | - /** | ||
236 | - * Set the challenge identifier and the state issued by the RADIUS. | ||
237 | - * | ||
238 | - * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message. | ||
239 | - * @param challengeState The challenge state from the RADIUS. | ||
240 | - */ | ||
241 | - protected void setChallengeInfo(byte challengeIdentifier, byte[] challengeState) { | ||
242 | - this.challengeIdentifier = challengeIdentifier; | ||
243 | - this.challengeState = challengeState; | ||
244 | - } | ||
245 | - | ||
246 | - /** | ||
247 | - * Set the challenge identifier issued by the RADIUS on the access challenge request. | ||
248 | - * | ||
249 | - * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message. | ||
250 | - */ | ||
251 | - protected void setChallengeIdentifier(byte challengeIdentifier) { | ||
252 | - log.info("Set Challenge Identifier to {}", challengeIdentifier); | ||
253 | - this.challengeIdentifier = challengeIdentifier; | ||
254 | - } | ||
255 | - | ||
256 | - /** | ||
257 | - * Gets the challenge EAP identifier set by the RADIUS. | ||
258 | - * | ||
259 | - * @return The challenge EAP identifier. | ||
260 | - */ | ||
261 | - protected byte challengeIdentifier() { | ||
262 | - return this.challengeIdentifier; | ||
263 | - } | ||
264 | - | ||
265 | - | ||
266 | - /** | ||
267 | - * Set the challenge state info issued by the RADIUS. | ||
268 | - * | ||
269 | - * @param challengeState The challenge state from the RADIUS. | ||
270 | - */ | ||
271 | - protected void setChallengeState(byte[] challengeState) { | ||
272 | - log.info("Set Challenge State"); | ||
273 | - this.challengeState = challengeState; | ||
274 | - } | ||
275 | - | ||
276 | - /** | ||
277 | - * Gets the challenge state set by the RADIUS. | ||
278 | - * | ||
279 | - * @return The challenge state. | ||
280 | - */ | ||
281 | - protected byte[] challengeState() { | ||
282 | - return this.challengeState; | ||
283 | - } | ||
284 | - | ||
285 | - /** | ||
286 | - * Set the username. | ||
287 | - * | ||
288 | - * @param username The username sent to the RADIUS upon access request. | ||
289 | - */ | ||
290 | - protected void setUsername(byte[] username) { | ||
291 | - this.username = username; | ||
292 | - } | ||
293 | - | ||
294 | - | ||
295 | - /** | ||
296 | - * Gets the username. | ||
297 | - * | ||
298 | - * @return The requestAuthenticator. | ||
299 | - */ | ||
300 | - protected byte[] requestAuthenticator() { | ||
301 | - return this.requestAuthenticator; | ||
302 | - } | ||
303 | - | ||
304 | - /** | ||
305 | - * Sets the authenticator. | ||
306 | - * | ||
307 | - * @param authenticator The username sent to the RADIUS upon access request. | ||
308 | - */ | ||
309 | - protected void setRequestAuthenticator(byte[] authenticator) { | ||
310 | - this.requestAuthenticator = authenticator; | ||
311 | - } | ||
312 | - | ||
313 | - | ||
314 | - /** | ||
315 | - * Gets the username. | ||
316 | - * | ||
317 | - * @return The username. | ||
318 | - */ | ||
319 | - protected byte[] username() { | ||
320 | - return this.username; | ||
321 | - } | ||
322 | - | ||
323 | - /** | ||
324 | - * Return the identifier of the state machine. | ||
325 | - * | ||
326 | - * @return The state machine identifier. | ||
327 | - */ | ||
328 | - public byte identifier() { | ||
329 | - return (byte) this.identifier; | ||
330 | - } | ||
331 | - | ||
332 | - | ||
333 | - protected void deleteIdentifier() { | ||
334 | - if (this.identifier != -1) { | ||
335 | - log.info("Freeing up " + this.identifier); | ||
336 | - //this state machine should be deleted and free up the identifier | ||
337 | - StateMachine.bitSet.clear(this.identifier); | ||
338 | - this.identifier = -1; | ||
339 | - } | ||
340 | - } | ||
341 | - | ||
342 | - | ||
343 | - /** | ||
344 | - * Move to the next state. | ||
345 | - * | ||
346 | - * @param msg message | ||
347 | - */ | ||
348 | - private void next(int msg) { | ||
349 | - currentState = transition[currentState][msg]; | ||
350 | - log.info("Current State " + currentState); | ||
351 | - } | ||
352 | - | ||
353 | - /** | ||
354 | - * Client has requested the start action to allow network access. | ||
355 | - * | ||
356 | - * @throws StateMachineException if authentication protocol is violated | ||
357 | - */ | ||
358 | - public void start() throws StateMachineException { | ||
359 | - states[currentState].start(); | ||
360 | - //move to the next state | ||
361 | - next(TRANSITION_START); | ||
362 | - createIdentifier(); | ||
363 | - identifierMap.put(identifier, this); | ||
364 | - } | ||
365 | - | ||
366 | - /** | ||
367 | - * An Identification information has been sent by the supplicant. | ||
368 | - * Move to the next state if possible. | ||
369 | - * | ||
370 | - * @throws StateMachineException if authentication protocol is violated | ||
371 | - */ | ||
372 | - public void requestAccess() throws StateMachineException { | ||
373 | - states[currentState].requestAccess(); | ||
374 | - //move to the next state | ||
375 | - next(TRANSITION_REQUEST_ACCESS); | ||
376 | - } | ||
377 | - | ||
378 | - /** | ||
379 | - * RADIUS has accepted the identification. | ||
380 | - * Move to the next state if possible. | ||
381 | - * | ||
382 | - * @throws StateMachineException if authentication protocol is violated | ||
383 | - */ | ||
384 | - public void authorizeAccess() throws StateMachineException { | ||
385 | - states[currentState].radiusAccepted(); | ||
386 | - //move to the next state | ||
387 | - next(TRANSITION_AUTHORIZE_ACCESS); | ||
388 | - | ||
389 | - // TODO: put in calls to launch vSG here | ||
390 | - | ||
391 | - deleteIdentifier(); | ||
392 | - } | ||
393 | - | ||
394 | - /** | ||
395 | - * RADIUS has denied the identification. | ||
396 | - * Move to the next state if possible. | ||
397 | - * | ||
398 | - * @throws StateMachineException if authentication protocol is violated | ||
399 | - */ | ||
400 | - public void denyAccess() throws StateMachineException { | ||
401 | - states[currentState].radiusDenied(); | ||
402 | - //move to the next state | ||
403 | - next(TRANSITION_DENY_ACCESS); | ||
404 | - deleteIdentifier(); | ||
405 | - } | ||
406 | - | ||
407 | - /** | ||
408 | - * Logoff request has been requested. | ||
409 | - * Move to the next state if possible. | ||
410 | - * | ||
411 | - * @throws StateMachineException if authentication protocol is violated | ||
412 | - */ | ||
413 | - public void logoff() throws StateMachineException { | ||
414 | - states[currentState].logoff(); | ||
415 | - //move to the next state | ||
416 | - next(TRANSITION_LOGOFF); | ||
417 | - } | ||
418 | - | ||
419 | - /** | ||
420 | - * Gets the current state. | ||
421 | - * | ||
422 | - * @return The current state. Could be STATE_IDLE, STATE_STARTED, STATE_PENDING, STATE_AUTHORIZED, | ||
423 | - * STATE_UNAUTHORIZED. | ||
424 | - */ | ||
425 | - public int state() { | ||
426 | - return currentState; | ||
427 | - } | ||
428 | - | ||
429 | - @Override | ||
430 | - public String toString() { | ||
431 | - return ("sessionId: " + this.sessionId) + "\t" + ("identifier: " + this.identifier) + "\t" + | ||
432 | - ("state: " + this.currentState); | ||
433 | - } | ||
434 | - | ||
435 | - abstract class State { | ||
436 | - private final Logger log = getLogger(getClass()); | ||
437 | - | ||
438 | - private String name = "State"; | ||
439 | - | ||
440 | - public void start() throws StateMachineInvalidTransitionException { | ||
441 | - log.warn("START transition from this state is not allowed."); | ||
442 | - } | ||
443 | - | ||
444 | - public void requestAccess() throws StateMachineInvalidTransitionException { | ||
445 | - log.warn("REQUEST ACCESS transition from this state is not allowed."); | ||
446 | - } | ||
447 | - | ||
448 | - public void radiusAccepted() throws StateMachineInvalidTransitionException { | ||
449 | - log.warn("AUTHORIZE ACCESS transition from this state is not allowed."); | ||
450 | - } | ||
451 | - | ||
452 | - public void radiusDenied() throws StateMachineInvalidTransitionException { | ||
453 | - log.warn("DENY ACCESS transition from this state is not allowed."); | ||
454 | - } | ||
455 | - | ||
456 | - public void logoff() throws StateMachineInvalidTransitionException { | ||
457 | - log.warn("LOGOFF transition from this state is not allowed."); | ||
458 | - } | ||
459 | - } | ||
460 | - | ||
461 | - /** | ||
462 | - * Idle state: supplicant is logged of from the network. | ||
463 | - */ | ||
464 | - class Idle extends State { | ||
465 | - private final Logger log = getLogger(getClass()); | ||
466 | - private String name = "IDLE_STATE"; | ||
467 | - | ||
468 | - public void start() { | ||
469 | - log.info("Moving from IDLE state to STARTED state."); | ||
470 | - } | ||
471 | - } | ||
472 | - | ||
473 | - /** | ||
474 | - * Started state: supplicant has entered the network and informed the authenticator. | ||
475 | - */ | ||
476 | - class Started extends State { | ||
477 | - private final Logger log = getLogger(getClass()); | ||
478 | - private String name = "STARTED_STATE"; | ||
479 | - | ||
480 | - public void requestAccess() { | ||
481 | - log.info("Moving from STARTED state to PENDING state."); | ||
482 | - } | ||
483 | - } | ||
484 | - | ||
485 | - /** | ||
486 | - * Pending state: supplicant has been identified by the authenticator but has not access yet. | ||
487 | - */ | ||
488 | - class Pending extends State { | ||
489 | - private final Logger log = getLogger(getClass()); | ||
490 | - private String name = "PENDING_STATE"; | ||
491 | - | ||
492 | - public void radiusAccepted() { | ||
493 | - log.info("Moving from PENDING state to AUTHORIZED state."); | ||
494 | - } | ||
495 | - | ||
496 | - public void radiusDenied() { | ||
497 | - log.info("Moving from PENDING state to UNAUTHORIZED state."); | ||
498 | - } | ||
499 | - } | ||
500 | - | ||
501 | - /** | ||
502 | - * Authorized state: supplicant port has been accepted, access is granted. | ||
503 | - */ | ||
504 | - class Authorized extends State { | ||
505 | - private final Logger log = getLogger(getClass()); | ||
506 | - private String name = "AUTHORIZED_STATE"; | ||
507 | - | ||
508 | - public void start() { | ||
509 | - log.info("Moving from AUTHORIZED state to STARTED state."); | ||
510 | - } | ||
511 | - | ||
512 | - public void logoff() { | ||
513 | - | ||
514 | - log.info("Moving from AUTHORIZED state to IDLE state."); | ||
515 | - } | ||
516 | - } | ||
517 | - | ||
518 | - /** | ||
519 | - * Unauthorized state: supplicant port has been rejected, access is denied. | ||
520 | - */ | ||
521 | - class Unauthorized extends State { | ||
522 | - private final Logger log = getLogger(getClass()); | ||
523 | - private String name = "UNAUTHORIZED_STATE"; | ||
524 | - | ||
525 | - public void logoff() { | ||
526 | - log.info("Moving from UNAUTHORIZED state to IDLE state."); | ||
527 | - } | ||
528 | - } | ||
529 | - | ||
530 | - | ||
531 | -} |
1 | -/* | ||
2 | - * | ||
3 | - * Copyright 2015 AT&T Foundry | ||
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 | - */ | ||
18 | -package org.onosproject.aaa; | ||
19 | - | ||
20 | -/** | ||
21 | - * Exception for the State Machine. | ||
22 | - */ | ||
23 | -class StateMachineException extends Exception { | ||
24 | - public StateMachineException(String message) { | ||
25 | - super(message); | ||
26 | - | ||
27 | - } | ||
28 | -} |
apps/aaa/src/main/java/org/onosproject/aaa/StateMachineInvalidTransitionException.java
deleted
100644 → 0
1 | -/* | ||
2 | - * | ||
3 | - * Copyright 2015 AT&T Foundry | ||
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 | - */ | ||
18 | -package org.onosproject.aaa; | ||
19 | - | ||
20 | -/** | ||
21 | - * Exception raised when the transition from one state to another is invalid. | ||
22 | - */ | ||
23 | -class StateMachineInvalidTransitionException extends StateMachineException { | ||
24 | - public StateMachineInvalidTransitionException(String message) { | ||
25 | - super(message); | ||
26 | - } | ||
27 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -/** | ||
18 | - * AAA implmentation. | ||
19 | - */ | ||
20 | -package org.onosproject.aaa; |
1 | -<!-- | ||
2 | - ~ Copyright 2016-present 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 | -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
17 | - | ||
18 | - <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
19 | - <command> | ||
20 | - <action class="org.onosproject.aaa.AaaShowUsersCommand"/> | ||
21 | - </command> | ||
22 | - </command-bundle> | ||
23 | -</blueprint> |
1 | -/* | ||
2 | - * Copyright 2015-present 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.aaa; | ||
17 | - | ||
18 | -import org.junit.Before; | ||
19 | -import org.junit.Ignore; | ||
20 | -import org.junit.Test; | ||
21 | -import org.onlab.packet.EAP; | ||
22 | -import org.onlab.packet.EAPOL; | ||
23 | -import org.onlab.packet.Ethernet; | ||
24 | -import org.onosproject.core.CoreServiceAdapter; | ||
25 | -import org.onosproject.net.config.Config; | ||
26 | -import org.onosproject.net.config.NetworkConfigRegistryAdapter; | ||
27 | - | ||
28 | -import static org.hamcrest.Matchers.is; | ||
29 | -import static org.hamcrest.Matchers.notNullValue; | ||
30 | -import static org.junit.Assert.assertThat; | ||
31 | - | ||
32 | -/** | ||
33 | - * Set of tests of the ONOS application component. These use an existing RADIUS | ||
34 | - * server and sends live packets over the network to it. | ||
35 | - */ | ||
36 | -@Ignore ("This should not be run as part of the standard build") | ||
37 | -public class AaaIntegrationTest extends AaaTestBase { | ||
38 | - | ||
39 | - private AaaManager aaa; | ||
40 | - | ||
41 | - /** | ||
42 | - * Mocks the network config registry. | ||
43 | - */ | ||
44 | - @SuppressWarnings("unchecked") | ||
45 | - static final class TestNetworkConfigRegistry | ||
46 | - extends NetworkConfigRegistryAdapter { | ||
47 | - @Override | ||
48 | - public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { | ||
49 | - return (C) new AaaConfig(); | ||
50 | - } | ||
51 | - } | ||
52 | - | ||
53 | - /** | ||
54 | - * Sets up the services required by the AAA application. | ||
55 | - */ | ||
56 | - @Before | ||
57 | - public void setUp() { | ||
58 | - aaa = new AaaManager(); | ||
59 | - aaa.netCfgService = new TestNetworkConfigRegistry(); | ||
60 | - aaa.coreService = new CoreServiceAdapter(); | ||
61 | - aaa.packetService = new MockPacketService(); | ||
62 | - aaa.activate(); | ||
63 | - } | ||
64 | - | ||
65 | - /** | ||
66 | - * Fetches the sent packet at the given index. The requested packet | ||
67 | - * must be the last packet on the list. | ||
68 | - * | ||
69 | - * @param index index into sent packets array | ||
70 | - * @return packet | ||
71 | - */ | ||
72 | - private Ethernet fetchPacket(int index) { | ||
73 | - for (int iteration = 0; iteration < 20; iteration++) { | ||
74 | - if (savedPackets.size() > index) { | ||
75 | - return (Ethernet) savedPackets.get(index); | ||
76 | - } else { | ||
77 | - try { | ||
78 | - Thread.sleep(250); | ||
79 | - } catch (Exception ex) { | ||
80 | - return null; | ||
81 | - } | ||
82 | - } | ||
83 | - } | ||
84 | - return null; | ||
85 | - } | ||
86 | - | ||
87 | - /** | ||
88 | - * Tests the authentication path through the AAA application by sending | ||
89 | - * packets to the RADIUS server and checking the state machine | ||
90 | - * transitions. | ||
91 | - * | ||
92 | - * @throws Exception when an unhandled error occurs | ||
93 | - */ | ||
94 | - @Test | ||
95 | - public void testAuthentication() throws Exception { | ||
96 | - | ||
97 | - // (1) Supplicant start up | ||
98 | - | ||
99 | - Ethernet startPacket = constructSupplicantStartPacket(); | ||
100 | - sendPacket(startPacket); | ||
101 | - | ||
102 | - Ethernet responsePacket = fetchPacket(0); | ||
103 | - assertThat(responsePacket, notNullValue()); | ||
104 | - checkRadiusPacket(aaa, responsePacket, EAP.REQUEST); | ||
105 | - | ||
106 | - // (2) Supplicant identify | ||
107 | - | ||
108 | - Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); | ||
109 | - sendPacket(identifyPacket); | ||
110 | - | ||
111 | - // State machine should have been created by now | ||
112 | - | ||
113 | - StateMachine stateMachine = | ||
114 | - StateMachine.lookupStateMachineBySessionId(SESSION_ID); | ||
115 | - assertThat(stateMachine, notNullValue()); | ||
116 | - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); | ||
117 | - | ||
118 | - // (3) RADIUS MD5 challenge | ||
119 | - | ||
120 | - Ethernet radiusChallengeMD5Packet = fetchPacket(1); | ||
121 | - assertThat(radiusChallengeMD5Packet, notNullValue()); | ||
122 | - checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.REQUEST); | ||
123 | - | ||
124 | - | ||
125 | - // (4) Supplicant MD5 response | ||
126 | - | ||
127 | - Ethernet md5RadiusPacket = | ||
128 | - constructSupplicantIdentifyPacket(stateMachine, | ||
129 | - EAP.ATTR_MD5, | ||
130 | - stateMachine.challengeIdentifier(), | ||
131 | - radiusChallengeMD5Packet); | ||
132 | - sendPacket(md5RadiusPacket); | ||
133 | - | ||
134 | - | ||
135 | - // (5) RADIUS Success | ||
136 | - | ||
137 | - Ethernet successRadiusPacket = fetchPacket(2); | ||
138 | - assertThat(successRadiusPacket, notNullValue()); | ||
139 | - EAPOL successEapol = (EAPOL) successRadiusPacket.getPayload(); | ||
140 | - EAP successEap = (EAP) successEapol.getPayload(); | ||
141 | - assertThat(successEap.getCode(), is(EAP.SUCCESS)); | ||
142 | - | ||
143 | - // State machine should be in authorized state | ||
144 | - | ||
145 | - assertThat(stateMachine, notNullValue()); | ||
146 | - assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); | ||
147 | - | ||
148 | - } | ||
149 | - | ||
150 | -} | ||
151 | - |
1 | -/* | ||
2 | - * Copyright 2015-present 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.aaa; | ||
17 | - | ||
18 | -import com.google.common.base.Charsets; | ||
19 | -import org.junit.After; | ||
20 | -import org.junit.Before; | ||
21 | -import org.junit.Test; | ||
22 | -import org.onlab.packet.BasePacket; | ||
23 | -import org.onlab.packet.DeserializationException; | ||
24 | -import org.onlab.packet.EAP; | ||
25 | -import org.onlab.packet.Ethernet; | ||
26 | -import org.onlab.packet.IpAddress; | ||
27 | -import org.onlab.packet.RADIUS; | ||
28 | -import org.onlab.packet.RADIUSAttribute; | ||
29 | -import org.onosproject.core.CoreServiceAdapter; | ||
30 | -import org.onosproject.net.config.Config; | ||
31 | -import org.onosproject.net.config.NetworkConfigRegistryAdapter; | ||
32 | - | ||
33 | -import java.net.InetAddress; | ||
34 | -import java.net.UnknownHostException; | ||
35 | - | ||
36 | -import static org.hamcrest.Matchers.is; | ||
37 | -import static org.hamcrest.Matchers.notNullValue; | ||
38 | -import static org.junit.Assert.assertThat; | ||
39 | - | ||
40 | -/** | ||
41 | - * Set of tests of the ONOS application component. | ||
42 | - */ | ||
43 | -public class AaaManagerTest extends AaaTestBase { | ||
44 | - | ||
45 | - static final String BAD_IP_ADDRESS = "198.51.100.0"; | ||
46 | - | ||
47 | - private AaaManager aaaManager; | ||
48 | - | ||
49 | - class AaaManagerWithoutRadiusServer extends AaaManager { | ||
50 | - protected void sendRadiusPacket(RADIUS radiusPacket) { | ||
51 | - savePacket(radiusPacket); | ||
52 | - } | ||
53 | - } | ||
54 | - | ||
55 | - /** | ||
56 | - * Mocks the AAAConfig class to force usage of an unroutable address for the | ||
57 | - * RADIUS server. | ||
58 | - */ | ||
59 | - static class MockAaaConfig extends AaaConfig { | ||
60 | - @Override | ||
61 | - public InetAddress radiusIp() { | ||
62 | - try { | ||
63 | - return InetAddress.getByName(BAD_IP_ADDRESS); | ||
64 | - } catch (UnknownHostException ex) { | ||
65 | - // can't happen | ||
66 | - throw new IllegalStateException(ex); | ||
67 | - } | ||
68 | - } | ||
69 | - } | ||
70 | - | ||
71 | - /** | ||
72 | - * Mocks the network config registry. | ||
73 | - */ | ||
74 | - @SuppressWarnings("unchecked") | ||
75 | - private static final class TestNetworkConfigRegistry | ||
76 | - extends NetworkConfigRegistryAdapter { | ||
77 | - @Override | ||
78 | - public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) { | ||
79 | - AaaConfig aaaConfig = new MockAaaConfig(); | ||
80 | - return (C) aaaConfig; | ||
81 | - } | ||
82 | - } | ||
83 | - | ||
84 | - /** | ||
85 | - * Constructs an Ethernet packet containing a RADIUS challenge | ||
86 | - * packet. | ||
87 | - * | ||
88 | - * @param challengeCode code to use in challenge packet | ||
89 | - * @param challengeType type to use in challenge packet | ||
90 | - * @return Ethernet packet | ||
91 | - */ | ||
92 | - private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) { | ||
93 | - | ||
94 | - String challenge = "12345678901234567"; | ||
95 | - | ||
96 | - EAP eap = new EAP(challengeType, (byte) 1, challengeType, | ||
97 | - challenge.getBytes(Charsets.US_ASCII)); | ||
98 | - eap.setIdentifier((byte) 1); | ||
99 | - | ||
100 | - RADIUS radius = new RADIUS(); | ||
101 | - radius.setCode(challengeCode); | ||
102 | - | ||
103 | - radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE, | ||
104 | - challenge.getBytes(Charsets.US_ASCII)); | ||
105 | - | ||
106 | - radius.setPayload(eap); | ||
107 | - radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE, | ||
108 | - eap.serialize()); | ||
109 | - | ||
110 | - return radius; | ||
111 | - } | ||
112 | - | ||
113 | - /** | ||
114 | - * Sets up the services required by the AAA application. | ||
115 | - */ | ||
116 | - @Before | ||
117 | - public void setUp() { | ||
118 | - aaaManager = new AaaManagerWithoutRadiusServer(); | ||
119 | - aaaManager.netCfgService = new TestNetworkConfigRegistry(); | ||
120 | - aaaManager.coreService = new CoreServiceAdapter(); | ||
121 | - aaaManager.packetService = new MockPacketService(); | ||
122 | - aaaManager.activate(); | ||
123 | - } | ||
124 | - | ||
125 | - /** | ||
126 | - * Tears down the AAA application. | ||
127 | - */ | ||
128 | - @After | ||
129 | - public void tearDown() { | ||
130 | - aaaManager.deactivate(); | ||
131 | - } | ||
132 | - | ||
133 | - /** | ||
134 | - * Extracts the RADIUS packet from a packet sent by the supplicant. | ||
135 | - * | ||
136 | - * @param radius RADIUS packet sent by the supplicant | ||
137 | - * @throws DeserializationException if deserialization of the packet contents | ||
138 | - * fails. | ||
139 | - */ | ||
140 | - private void checkRadiusPacketFromSupplicant(RADIUS radius) | ||
141 | - throws DeserializationException { | ||
142 | - assertThat(radius, notNullValue()); | ||
143 | - | ||
144 | - EAP eap = radius.decapsulateMessage(); | ||
145 | - assertThat(eap, notNullValue()); | ||
146 | - } | ||
147 | - | ||
148 | - /** | ||
149 | - * Fetches the sent packet at the given index. The requested packet | ||
150 | - * must be the last packet on the list. | ||
151 | - * | ||
152 | - * @param index index into sent packets array | ||
153 | - * @return packet | ||
154 | - */ | ||
155 | - private BasePacket fetchPacket(int index) { | ||
156 | - BasePacket packet = savedPackets.get(index); | ||
157 | - assertThat(packet, notNullValue()); | ||
158 | - return packet; | ||
159 | - } | ||
160 | - | ||
161 | - /** | ||
162 | - * Tests the authentication path through the AAA application. | ||
163 | - * | ||
164 | - * @throws DeserializationException if packed deserialization fails. | ||
165 | - */ | ||
166 | - @Test | ||
167 | - public void testAuthentication() throws Exception { | ||
168 | - | ||
169 | - // (1) Supplicant start up | ||
170 | - | ||
171 | - Ethernet startPacket = constructSupplicantStartPacket(); | ||
172 | - sendPacket(startPacket); | ||
173 | - | ||
174 | - Ethernet responsePacket = (Ethernet) fetchPacket(0); | ||
175 | - checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY); | ||
176 | - | ||
177 | - // (2) Supplicant identify | ||
178 | - | ||
179 | - Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null); | ||
180 | - sendPacket(identifyPacket); | ||
181 | - | ||
182 | - RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1); | ||
183 | - | ||
184 | - checkRadiusPacketFromSupplicant(radiusIdentifyPacket); | ||
185 | - | ||
186 | - assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); | ||
187 | - assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()), | ||
188 | - is("testuser")); | ||
189 | - | ||
190 | - IpAddress nasIp = | ||
191 | - IpAddress.valueOf(IpAddress.Version.INET, | ||
192 | - radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP) | ||
193 | - .getValue()); | ||
194 | - assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress())); | ||
195 | - | ||
196 | - // State machine should have been created by now | ||
197 | - | ||
198 | - StateMachine stateMachine = | ||
199 | - StateMachine.lookupStateMachineBySessionId(SESSION_ID); | ||
200 | - assertThat(stateMachine, notNullValue()); | ||
201 | - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); | ||
202 | - | ||
203 | - // (3) RADIUS MD5 challenge | ||
204 | - | ||
205 | - RADIUS radiusCodeAccessChallengePacket = | ||
206 | - constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5); | ||
207 | - aaaManager.radiusListener.handleRadiusPacket(radiusCodeAccessChallengePacket); | ||
208 | - | ||
209 | - Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2); | ||
210 | - checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5); | ||
211 | - | ||
212 | - // (4) Supplicant MD5 response | ||
213 | - | ||
214 | - Ethernet md5RadiusPacket = | ||
215 | - constructSupplicantIdentifyPacket(stateMachine, | ||
216 | - EAP.ATTR_MD5, | ||
217 | - stateMachine.challengeIdentifier(), | ||
218 | - radiusChallengeMD5Packet); | ||
219 | - sendPacket(md5RadiusPacket); | ||
220 | - | ||
221 | - RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3); | ||
222 | - | ||
223 | - checkRadiusPacketFromSupplicant(responseMd5RadiusPacket); | ||
224 | - assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 0)); | ||
225 | - assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST)); | ||
226 | - | ||
227 | - // State machine should be in pending state | ||
228 | - | ||
229 | - assertThat(stateMachine, notNullValue()); | ||
230 | - assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING)); | ||
231 | - | ||
232 | - // (5) RADIUS Success | ||
233 | - | ||
234 | - RADIUS successPacket = | ||
235 | - constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS); | ||
236 | - aaaManager.radiusListener.handleRadiusPacket((successPacket)); | ||
237 | - Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4); | ||
238 | - | ||
239 | - checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS); | ||
240 | - | ||
241 | - // State machine should be in authorized state | ||
242 | - | ||
243 | - assertThat(stateMachine, notNullValue()); | ||
244 | - assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED)); | ||
245 | - | ||
246 | - } | ||
247 | - | ||
248 | - /** | ||
249 | - * Tests the default configuration. | ||
250 | - */ | ||
251 | - @Test | ||
252 | - public void testConfig() { | ||
253 | - assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP)); | ||
254 | - assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC)); | ||
255 | - assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS)); | ||
256 | - assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC)); | ||
257 | - } | ||
258 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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.aaa; | ||
17 | - | ||
18 | -import org.onlab.packet.BasePacket; | ||
19 | -import org.onlab.packet.EAP; | ||
20 | -import org.onlab.packet.EAPOL; | ||
21 | -import org.onlab.packet.EthType; | ||
22 | -import org.onlab.packet.Ethernet; | ||
23 | -import org.onlab.packet.MacAddress; | ||
24 | -import org.onosproject.net.packet.DefaultInboundPacket; | ||
25 | -import org.onosproject.net.packet.DefaultPacketContext; | ||
26 | -import org.onosproject.net.packet.InboundPacket; | ||
27 | -import org.onosproject.net.packet.OutboundPacket; | ||
28 | -import org.onosproject.net.packet.PacketContext; | ||
29 | -import org.onosproject.net.packet.PacketProcessor; | ||
30 | -import org.onosproject.net.packet.PacketServiceAdapter; | ||
31 | - | ||
32 | -import java.nio.ByteBuffer; | ||
33 | -import java.security.MessageDigest; | ||
34 | -import java.util.LinkedList; | ||
35 | -import java.util.List; | ||
36 | - | ||
37 | -import static org.hamcrest.Matchers.instanceOf; | ||
38 | -import static org.hamcrest.Matchers.is; | ||
39 | -import static org.hamcrest.Matchers.notNullValue; | ||
40 | -import static org.junit.Assert.assertThat; | ||
41 | -import static org.junit.Assert.fail; | ||
42 | -import static org.onosproject.net.NetTestTools.connectPoint; | ||
43 | - | ||
44 | -/** | ||
45 | - * Common methods for AAA app testing. | ||
46 | - */ | ||
47 | -public class AaaTestBase { | ||
48 | - | ||
49 | - MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a"); | ||
50 | - MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a"); | ||
51 | - | ||
52 | - // Our session id will be the device ID ("of:1") with the port ("1") concatenated | ||
53 | - static final String SESSION_ID = "of:11"; | ||
54 | - | ||
55 | - List<BasePacket> savedPackets = new LinkedList<>(); | ||
56 | - PacketProcessor packetProcessor; | ||
57 | - | ||
58 | - /** | ||
59 | - * Saves the given packet onto the saved packets list. | ||
60 | - * | ||
61 | - * @param packet packet to save | ||
62 | - */ | ||
63 | - void savePacket(BasePacket packet) { | ||
64 | - savedPackets.add(packet); | ||
65 | - } | ||
66 | - | ||
67 | - /** | ||
68 | - * Keeps a reference to the PacketProcessor and saves the OutboundPackets. | ||
69 | - */ | ||
70 | - class MockPacketService extends PacketServiceAdapter { | ||
71 | - | ||
72 | - @Override | ||
73 | - public void addProcessor(PacketProcessor processor, int priority) { | ||
74 | - packetProcessor = processor; | ||
75 | - } | ||
76 | - | ||
77 | - @Override | ||
78 | - public void emit(OutboundPacket packet) { | ||
79 | - try { | ||
80 | - Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), | ||
81 | - 0, packet.data().array().length); | ||
82 | - savePacket(eth); | ||
83 | - } catch (Exception e) { | ||
84 | - fail(e.getMessage()); | ||
85 | - } | ||
86 | - } | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * Mocks the DefaultPacketContext. | ||
91 | - */ | ||
92 | - final class TestPacketContext extends DefaultPacketContext { | ||
93 | - | ||
94 | - private TestPacketContext(long time, InboundPacket inPkt, | ||
95 | - OutboundPacket outPkt, boolean block) { | ||
96 | - super(time, inPkt, outPkt, block); | ||
97 | - } | ||
98 | - | ||
99 | - @Override | ||
100 | - public void send() { | ||
101 | - // We don't send anything out. | ||
102 | - } | ||
103 | - } | ||
104 | - | ||
105 | - /** | ||
106 | - * Sends an Ethernet packet to the process method of the Packet Processor. | ||
107 | - * | ||
108 | - * @param reply Ethernet packet | ||
109 | - */ | ||
110 | - void sendPacket(Ethernet reply) { | ||
111 | - final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); | ||
112 | - InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), | ||
113 | - reply, | ||
114 | - byteBuffer); | ||
115 | - | ||
116 | - PacketContext context = new TestPacketContext(127L, inPacket, null, false); | ||
117 | - packetProcessor.process(context); | ||
118 | - } | ||
119 | - | ||
120 | - /** | ||
121 | - * Constructs an Ethernet packet containing identification payload. | ||
122 | - * | ||
123 | - * @return Ethernet packet | ||
124 | - */ | ||
125 | - Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine, | ||
126 | - byte type, | ||
127 | - byte id, | ||
128 | - Ethernet radiusChallenge) | ||
129 | - throws Exception { | ||
130 | - Ethernet eth = new Ethernet(); | ||
131 | - eth.setDestinationMACAddress(clientMac.toBytes()); | ||
132 | - eth.setSourceMACAddress(serverMac.toBytes()); | ||
133 | - eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); | ||
134 | - eth.setVlanID((short) 2); | ||
135 | - | ||
136 | - String username = "testuser"; | ||
137 | - byte[] data = username.getBytes(); | ||
138 | - | ||
139 | - | ||
140 | - if (type == EAP.ATTR_MD5) { | ||
141 | - String password = "testpassword"; | ||
142 | - EAPOL eapol = (EAPOL) radiusChallenge.getPayload(); | ||
143 | - EAP eap = (EAP) eapol.getPayload(); | ||
144 | - | ||
145 | - byte[] identifier = new byte[password.length() + eap.getData().length]; | ||
146 | - | ||
147 | - identifier[0] = stateMachine.challengeIdentifier(); | ||
148 | - System.arraycopy(password.getBytes(), 0, identifier, 1, password.length()); | ||
149 | - System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16); | ||
150 | - | ||
151 | - MessageDigest md = MessageDigest.getInstance("MD5"); | ||
152 | - byte[] hash = md.digest(identifier); | ||
153 | - data = new byte[17]; | ||
154 | - data[0] = (byte) 16; | ||
155 | - System.arraycopy(hash, 0, data, 1, 16); | ||
156 | - } | ||
157 | - EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type, | ||
158 | - data); | ||
159 | - eap.setIdentifier(id); | ||
160 | - | ||
161 | - // eapol header | ||
162 | - EAPOL eapol = new EAPOL(); | ||
163 | - eapol.setEapolType(EAPOL.EAPOL_PACKET); | ||
164 | - eapol.setPacketLength(eap.getLength()); | ||
165 | - | ||
166 | - // eap part | ||
167 | - eapol.setPayload(eap); | ||
168 | - | ||
169 | - eth.setPayload(eapol); | ||
170 | - eth.setPad(true); | ||
171 | - return eth; | ||
172 | - } | ||
173 | - | ||
174 | - /** | ||
175 | - * Constructs an Ethernet packet containing a EAPOL_START Payload. | ||
176 | - * | ||
177 | - * @return Ethernet packet | ||
178 | - */ | ||
179 | - Ethernet constructSupplicantStartPacket() { | ||
180 | - Ethernet eth = new Ethernet(); | ||
181 | - eth.setDestinationMACAddress(clientMac.toBytes()); | ||
182 | - eth.setSourceMACAddress(serverMac.toBytes()); | ||
183 | - eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort()); | ||
184 | - eth.setVlanID((short) 2); | ||
185 | - | ||
186 | - EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null); | ||
187 | - | ||
188 | - // eapol header | ||
189 | - EAPOL eapol = new EAPOL(); | ||
190 | - eapol.setEapolType(EAPOL.EAPOL_START); | ||
191 | - eapol.setPacketLength(eap.getLength()); | ||
192 | - | ||
193 | - // eap part | ||
194 | - eapol.setPayload(eap); | ||
195 | - | ||
196 | - eth.setPayload(eapol); | ||
197 | - eth.setPad(true); | ||
198 | - return eth; | ||
199 | - } | ||
200 | - | ||
201 | - /** | ||
202 | - * Checks the contents of a RADIUS packet being sent to the RADIUS server. | ||
203 | - * | ||
204 | - * @param radiusPacket packet to check | ||
205 | - * @param code expected code | ||
206 | - */ | ||
207 | - void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) { | ||
208 | - | ||
209 | - assertThat(radiusPacket.getSourceMAC(), | ||
210 | - is(MacAddress.valueOf(aaaManager.nasMacAddress))); | ||
211 | - assertThat(radiusPacket.getDestinationMAC(), is(serverMac)); | ||
212 | - | ||
213 | - assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class)); | ||
214 | - EAPOL eapol = (EAPOL) radiusPacket.getPayload(); | ||
215 | - assertThat(eapol, notNullValue()); | ||
216 | - | ||
217 | - assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET)); | ||
218 | - assertThat(eapol.getPayload(), instanceOf(EAP.class)); | ||
219 | - EAP eap = (EAP) eapol.getPayload(); | ||
220 | - assertThat(eap, notNullValue()); | ||
221 | - | ||
222 | - assertThat(eap.getCode(), is(code)); | ||
223 | - } | ||
224 | -} |
1 | -/* | ||
2 | - * | ||
3 | - * Copyright 2015 AT&T Foundry | ||
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 | - */ | ||
18 | -package org.onosproject.aaa; | ||
19 | - | ||
20 | -import org.junit.After; | ||
21 | -import org.junit.Assert; | ||
22 | -import org.junit.Before; | ||
23 | -import org.junit.Test; | ||
24 | - | ||
25 | -import static org.junit.Assert.assertEquals; | ||
26 | -import static org.junit.Assert.assertNull; | ||
27 | - | ||
28 | - | ||
29 | -public class StateMachineTest { | ||
30 | - StateMachine stateMachine = null; | ||
31 | - | ||
32 | - @Before | ||
33 | - public void setUp() { | ||
34 | - System.out.println("Set Up."); | ||
35 | - StateMachine.bitSet.clear(); | ||
36 | - StateMachine.initializeMaps(); | ||
37 | - stateMachine = new StateMachine("session0"); | ||
38 | - } | ||
39 | - | ||
40 | - @After | ||
41 | - public void tearDown() { | ||
42 | - System.out.println("Tear Down."); | ||
43 | - StateMachine.bitSet.clear(); | ||
44 | - StateMachine.destroyMaps(); | ||
45 | - stateMachine = null; | ||
46 | - } | ||
47 | - | ||
48 | - @Test | ||
49 | - /** | ||
50 | - * Test all the basic inputs from state to state: IDLE -> STARTED -> PENDING -> AUTHORIZED -> IDLE | ||
51 | - */ | ||
52 | - public void basic() throws StateMachineException { | ||
53 | - System.out.println("======= BASIC =======."); | ||
54 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
55 | - | ||
56 | - stateMachine.start(); | ||
57 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
58 | - | ||
59 | - stateMachine.requestAccess(); | ||
60 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
61 | - | ||
62 | - stateMachine.authorizeAccess(); | ||
63 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); | ||
64 | - | ||
65 | - stateMachine.logoff(); | ||
66 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
67 | - } | ||
68 | - | ||
69 | - @Test | ||
70 | - /** | ||
71 | - * Test all inputs from an IDLE state (starting with the ones that are not impacting the current state) | ||
72 | - */ | ||
73 | - public void testIdleState() throws StateMachineException { | ||
74 | - System.out.println("======= IDLE STATE TEST =======."); | ||
75 | - stateMachine.requestAccess(); | ||
76 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
77 | - | ||
78 | - stateMachine.authorizeAccess(); | ||
79 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
80 | - | ||
81 | - stateMachine.denyAccess(); | ||
82 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
83 | - | ||
84 | - stateMachine.logoff(); | ||
85 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
86 | - | ||
87 | - stateMachine.start(); | ||
88 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
89 | - } | ||
90 | - | ||
91 | - @Test | ||
92 | - /** | ||
93 | - * Test all inputs from an STARTED state (starting with the ones that are not impacting the current state) | ||
94 | - */ | ||
95 | - public void testStartedState() throws StateMachineException { | ||
96 | - System.out.println("======= STARTED STATE TEST =======."); | ||
97 | - stateMachine.start(); | ||
98 | - | ||
99 | - stateMachine.authorizeAccess(); | ||
100 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
101 | - | ||
102 | - stateMachine.denyAccess(); | ||
103 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
104 | - | ||
105 | - stateMachine.logoff(); | ||
106 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
107 | - | ||
108 | - stateMachine.start(); | ||
109 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
110 | - | ||
111 | - stateMachine.requestAccess(); | ||
112 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
113 | - } | ||
114 | - | ||
115 | - @Test | ||
116 | - /** | ||
117 | - * Test all inputs from a PENDING state (starting with the ones that are not impacting the current state). | ||
118 | - * The next valid state for this test is AUTHORIZED | ||
119 | - */ | ||
120 | - public void testPendingStateToAuthorized() throws StateMachineException { | ||
121 | - System.out.println("======= PENDING STATE TEST (AUTHORIZED) =======."); | ||
122 | - stateMachine.start(); | ||
123 | - stateMachine.requestAccess(); | ||
124 | - | ||
125 | - stateMachine.logoff(); | ||
126 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
127 | - | ||
128 | - stateMachine.start(); | ||
129 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
130 | - | ||
131 | - stateMachine.requestAccess(); | ||
132 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
133 | - | ||
134 | - stateMachine.authorizeAccess(); | ||
135 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); | ||
136 | - | ||
137 | - stateMachine.denyAccess(); | ||
138 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); | ||
139 | - } | ||
140 | - | ||
141 | - @Test | ||
142 | - /** | ||
143 | - * Test all inputs from an PENDING state (starting with the ones that are not impacting the current state). | ||
144 | - * The next valid state for this test is UNAUTHORIZED | ||
145 | - */ | ||
146 | - public void testPendingStateToUnauthorized() throws StateMachineException { | ||
147 | - System.out.println("======= PENDING STATE TEST (DENIED) =======."); | ||
148 | - stateMachine.start(); | ||
149 | - stateMachine.requestAccess(); | ||
150 | - | ||
151 | - stateMachine.logoff(); | ||
152 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
153 | - | ||
154 | - stateMachine.start(); | ||
155 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
156 | - | ||
157 | - stateMachine.requestAccess(); | ||
158 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
159 | - | ||
160 | - stateMachine.denyAccess(); | ||
161 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
162 | - | ||
163 | - stateMachine.authorizeAccess(); | ||
164 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
165 | - } | ||
166 | - | ||
167 | - @Test | ||
168 | - /** | ||
169 | - * Test all inputs from an AUTHORIZED state (starting with the ones that are not impacting the current state). | ||
170 | - */ | ||
171 | - public void testAuthorizedState() throws StateMachineException { | ||
172 | - System.out.println("======= AUTHORIZED STATE TEST =======."); | ||
173 | - stateMachine.start(); | ||
174 | - stateMachine.requestAccess(); | ||
175 | - stateMachine.authorizeAccess(); | ||
176 | - | ||
177 | - stateMachine.start(); | ||
178 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED); | ||
179 | - | ||
180 | - stateMachine.requestAccess(); | ||
181 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING); | ||
182 | - | ||
183 | - stateMachine.authorizeAccess(); | ||
184 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); | ||
185 | - | ||
186 | - stateMachine.denyAccess(); | ||
187 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED); | ||
188 | - | ||
189 | - stateMachine.logoff(); | ||
190 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
191 | - } | ||
192 | - | ||
193 | - @Test | ||
194 | - /** | ||
195 | - * Test all inputs from an UNAUTHORIZED state (starting with the ones that are not impacting the current state). | ||
196 | - */ | ||
197 | - public void testUnauthorizedState() throws StateMachineException { | ||
198 | - System.out.println("======= UNAUTHORIZED STATE TEST =======."); | ||
199 | - stateMachine.start(); | ||
200 | - stateMachine.requestAccess(); | ||
201 | - stateMachine.denyAccess(); | ||
202 | - | ||
203 | - stateMachine.start(); | ||
204 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
205 | - | ||
206 | - stateMachine.requestAccess(); | ||
207 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
208 | - | ||
209 | - stateMachine.authorizeAccess(); | ||
210 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
211 | - | ||
212 | - stateMachine.denyAccess(); | ||
213 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED); | ||
214 | - | ||
215 | - stateMachine.logoff(); | ||
216 | - Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE); | ||
217 | - } | ||
218 | - | ||
219 | - | ||
220 | - @Test | ||
221 | - public void testIdentifierAvailability() throws StateMachineException { | ||
222 | - System.out.println("======= IDENTIFIER TEST =======."); | ||
223 | - byte identifier = stateMachine.identifier(); | ||
224 | - System.out.println("State: " + stateMachine.state()); | ||
225 | - System.out.println("Identifier: " + Byte.toUnsignedInt(identifier)); | ||
226 | - Assert.assertEquals(-1, identifier); | ||
227 | - stateMachine.start(); | ||
228 | - | ||
229 | - | ||
230 | - StateMachine sm247 = null; | ||
231 | - StateMachine sm3 = null; | ||
232 | - | ||
233 | - | ||
234 | - //create 255 others state machines | ||
235 | - for (int i = 1; i <= 255; i++) { | ||
236 | - StateMachine sm = new StateMachine("session" + i); | ||
237 | - sm.start(); | ||
238 | - byte id = sm.identifier(); | ||
239 | - Assert.assertEquals(i, Byte.toUnsignedInt(id)); | ||
240 | - if (i == 3) { | ||
241 | - sm3 = sm; | ||
242 | - System.out.println("SM3: " + sm3.toString()); | ||
243 | - } | ||
244 | - if (i == 247) { | ||
245 | - sm247 = sm; | ||
246 | - System.out.println("SM247: " + sm247.toString()); | ||
247 | - } | ||
248 | - } | ||
249 | - | ||
250 | - //simulate the state machine for a specific session and logoff so we can free up a spot for an identifier | ||
251 | - //let's choose identifier 247 then we free up 3 | ||
252 | - Assert.assertNotNull(sm247); | ||
253 | - sm247.requestAccess(); | ||
254 | - sm247.authorizeAccess(); | ||
255 | - sm247.logoff(); | ||
256 | - | ||
257 | - Assert.assertNotNull(sm3); | ||
258 | - sm3.requestAccess(); | ||
259 | - sm3.authorizeAccess(); | ||
260 | - sm3.logoff(); | ||
261 | - | ||
262 | - StateMachine otherSM3 = new StateMachine("session3b"); | ||
263 | - otherSM3.start(); | ||
264 | - otherSM3.requestAccess(); | ||
265 | - byte id3 = otherSM3.identifier(); | ||
266 | - Assert.assertEquals(3, Byte.toUnsignedInt(id3)); | ||
267 | - | ||
268 | - StateMachine otherSM247 = new StateMachine("session247b"); | ||
269 | - otherSM247.start(); | ||
270 | - otherSM247.requestAccess(); | ||
271 | - byte id247 = otherSM247.identifier(); | ||
272 | - Assert.assertEquals(247, Byte.toUnsignedInt(id247)); | ||
273 | - } | ||
274 | - | ||
275 | - @Test | ||
276 | - public void testSessionIdLookups() { | ||
277 | - String sessionId1 = "session1"; | ||
278 | - String sessionId2 = "session2"; | ||
279 | - String sessionId3 = "session3"; | ||
280 | - | ||
281 | - StateMachine machine1ShouldBeNull = | ||
282 | - StateMachine.lookupStateMachineBySessionId(sessionId1); | ||
283 | - assertNull(machine1ShouldBeNull); | ||
284 | - StateMachine machine2ShouldBeNull = | ||
285 | - StateMachine.lookupStateMachineBySessionId(sessionId2); | ||
286 | - assertNull(machine2ShouldBeNull); | ||
287 | - | ||
288 | - StateMachine stateMachine1 = new StateMachine(sessionId1); | ||
289 | - StateMachine stateMachine2 = new StateMachine(sessionId2); | ||
290 | - | ||
291 | - assertEquals(stateMachine1, | ||
292 | - StateMachine.lookupStateMachineBySessionId(sessionId1)); | ||
293 | - assertEquals(stateMachine2, | ||
294 | - StateMachine.lookupStateMachineBySessionId(sessionId2)); | ||
295 | - assertNull(StateMachine.lookupStateMachineBySessionId(sessionId3)); | ||
296 | - } | ||
297 | - | ||
298 | - @Test | ||
299 | - public void testIdentifierLookups() throws StateMachineException { | ||
300 | - String sessionId1 = "session1"; | ||
301 | - String sessionId2 = "session2"; | ||
302 | - | ||
303 | - StateMachine machine1ShouldBeNull = | ||
304 | - StateMachine.lookupStateMachineById((byte) 1); | ||
305 | - assertNull(machine1ShouldBeNull); | ||
306 | - StateMachine machine2ShouldBeNull = | ||
307 | - StateMachine.lookupStateMachineById((byte) 2); | ||
308 | - assertNull(machine2ShouldBeNull); | ||
309 | - | ||
310 | - StateMachine stateMachine1 = new StateMachine(sessionId1); | ||
311 | - stateMachine1.start(); | ||
312 | - StateMachine stateMachine2 = new StateMachine(sessionId2); | ||
313 | - stateMachine2.start(); | ||
314 | - | ||
315 | - assertEquals(stateMachine1, | ||
316 | - StateMachine.lookupStateMachineById(stateMachine1.identifier())); | ||
317 | - assertEquals(stateMachine2, | ||
318 | - StateMachine.lookupStateMachineById(stateMachine2.identifier())); | ||
319 | - } | ||
320 | -} |
apps/cordconfig/BUCK
deleted
100644 → 0
apps/cordconfig/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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/xsd/maven-4.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.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - | ||
30 | - <artifactId>onos-cord-config</artifactId> | ||
31 | - <packaging>bundle</packaging> | ||
32 | - | ||
33 | - <description>Cord configuration meta applications </description> | ||
34 | - | ||
35 | - <properties> | ||
36 | - <onos.app.name>org.onosproject.cord-config</onos.app.name> | ||
37 | - <onos.app.title>Cord Configuratuon Meta Application</onos.app.title> | ||
38 | - <onos.app.category>Utility</onos.app.category> | ||
39 | - <onos.app.url>http://opencord.org</onos.app.url> | ||
40 | - </properties> | ||
41 | - | ||
42 | - <dependencies> | ||
43 | - <dependency> | ||
44 | - <groupId>org.onosproject</groupId> | ||
45 | - <artifactId>onos-api</artifactId> | ||
46 | - </dependency> | ||
47 | - </dependencies> | ||
48 | - | ||
49 | - | ||
50 | -</project> |
apps/cordconfig/src/main/java/org/onosproject/cordconfig/access/AccessAgentConfig.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordconfig.access; | ||
18 | - | ||
19 | -import com.fasterxml.jackson.databind.JsonNode; | ||
20 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
21 | -import com.google.common.collect.Iterators; | ||
22 | -import com.google.common.collect.Maps; | ||
23 | -import org.apache.commons.lang.StringUtils; | ||
24 | -import org.onlab.packet.MacAddress; | ||
25 | -import org.onosproject.net.ConnectPoint; | ||
26 | -import org.onosproject.net.DeviceId; | ||
27 | -import org.onosproject.net.PortNumber; | ||
28 | -import org.onosproject.net.config.Config; | ||
29 | - | ||
30 | -import java.util.Map; | ||
31 | -import java.util.Optional; | ||
32 | - | ||
33 | -import static org.onosproject.net.config.Config.FieldPresence.MANDATORY; | ||
34 | -import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL; | ||
35 | - | ||
36 | -/** | ||
37 | - * Represents configuration for an OLT agent. | ||
38 | - */ | ||
39 | -public class AccessAgentConfig extends Config<DeviceId> { | ||
40 | - | ||
41 | - private static final String OLTS = "olts"; | ||
42 | - private static final String AGENT_MAC = "mac"; | ||
43 | - | ||
44 | - // TODO: Remove this, it is only useful as long as XOS doesn't manage this. | ||
45 | - private static final String VTN_LOCATION = "vtn-location"; | ||
46 | - | ||
47 | - @Override | ||
48 | - public boolean isValid() { | ||
49 | - return hasOnlyFields(OLTS, AGENT_MAC, VTN_LOCATION) && | ||
50 | - isMacAddress(AGENT_MAC, MANDATORY) && | ||
51 | - isConnectPoint(VTN_LOCATION, OPTIONAL) && | ||
52 | - isValidOlts(); | ||
53 | - } | ||
54 | - | ||
55 | - /** | ||
56 | - * Gets the access agent configuration for this device. | ||
57 | - * | ||
58 | - * @return access agent configuration | ||
59 | - */ | ||
60 | - public AccessAgentData getAgent() { | ||
61 | - JsonNode olts = node.get(OLTS); | ||
62 | - Map<ConnectPoint, MacAddress> oltMacInfo = Maps.newHashMap(); | ||
63 | - olts.fields().forEachRemaining(item -> oltMacInfo.put( | ||
64 | - new ConnectPoint(subject(), PortNumber.fromString(item.getKey())), | ||
65 | - MacAddress.valueOf(item.getValue().asText()))); | ||
66 | - | ||
67 | - MacAddress agentMac = MacAddress.valueOf(node.path(AGENT_MAC).asText()); | ||
68 | - | ||
69 | - JsonNode vtn = node.path(VTN_LOCATION); | ||
70 | - Optional<ConnectPoint> vtnLocation; | ||
71 | - if (vtn.isMissingNode()) { | ||
72 | - vtnLocation = Optional.empty(); | ||
73 | - } else { | ||
74 | - vtnLocation = Optional.of(ConnectPoint.deviceConnectPoint(vtn.asText())); | ||
75 | - } | ||
76 | - | ||
77 | - return new AccessAgentData(subject(), oltMacInfo, agentMac, vtnLocation); | ||
78 | - } | ||
79 | - | ||
80 | - private boolean isValidOlts() { | ||
81 | - JsonNode olts = node.get(OLTS); | ||
82 | - if (!olts.isObject()) { | ||
83 | - return false; | ||
84 | - } | ||
85 | - return !Iterators.any(olts.fields(), item -> !StringUtils.isNumeric(item.getKey()) || | ||
86 | - !isMacAddress((ObjectNode) olts, item.getKey(), MANDATORY)); | ||
87 | - } | ||
88 | -} |
apps/cordconfig/src/main/java/org/onosproject/cordconfig/access/AccessAgentData.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordconfig.access; | ||
18 | - | ||
19 | -import com.google.common.collect.ImmutableMap; | ||
20 | -import org.onlab.packet.MacAddress; | ||
21 | -import org.onosproject.net.ConnectPoint; | ||
22 | -import org.onosproject.net.DeviceId; | ||
23 | - | ||
24 | -import java.util.Map; | ||
25 | -import java.util.Optional; | ||
26 | - | ||
27 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
28 | - | ||
29 | -/** | ||
30 | - * Information about an access agent. | ||
31 | - */ | ||
32 | -public class AccessAgentData { | ||
33 | - private static final String DEVICE_ID_MISSING = "Device ID cannot be null"; | ||
34 | - private static final String OLT_INFO_MISSING = "OLT information cannot be null"; | ||
35 | - private static final String AGENT_MAC_MISSING = "Agent mac cannot be null"; | ||
36 | - private static final String VTN_MISSING = "VTN location cannot be null"; | ||
37 | - | ||
38 | - | ||
39 | - private final Map<ConnectPoint, MacAddress> oltMacInfo; | ||
40 | - private final MacAddress agentMac; | ||
41 | - private final Optional<ConnectPoint> vtnLocation; | ||
42 | - private final DeviceId deviceId; | ||
43 | - | ||
44 | - | ||
45 | - /** | ||
46 | - * Constucts an agent configuration for a given device. | ||
47 | - * | ||
48 | - * @param deviceId access device id | ||
49 | - * @param oltMacInfo a map of olt chips and their mac address | ||
50 | - * @param agentMac the mac address of the agent | ||
51 | - * @param vtnLocation the location of the agent | ||
52 | - */ | ||
53 | - public AccessAgentData(DeviceId deviceId, Map<ConnectPoint, MacAddress> oltMacInfo, | ||
54 | - MacAddress agentMac, Optional<ConnectPoint> vtnLocation) { | ||
55 | - this.deviceId = checkNotNull(deviceId, DEVICE_ID_MISSING); | ||
56 | - this.oltMacInfo = checkNotNull(oltMacInfo, OLT_INFO_MISSING); | ||
57 | - this.agentMac = checkNotNull(agentMac, AGENT_MAC_MISSING); | ||
58 | - this.vtnLocation = checkNotNull(vtnLocation, VTN_MISSING); | ||
59 | - } | ||
60 | - | ||
61 | - /** | ||
62 | - * Retrieves the access device ID. | ||
63 | - * | ||
64 | - * @return device ID | ||
65 | - */ | ||
66 | - public DeviceId deviceId() { | ||
67 | - return deviceId; | ||
68 | - } | ||
69 | - | ||
70 | - /** | ||
71 | - * Returns the mapping of olt chips to mac addresses. Each chip is | ||
72 | - * symbolized by a connect point. | ||
73 | - * | ||
74 | - * @return a mapping of chips (as connect points) to mac addresses | ||
75 | - */ | ||
76 | - public Map<ConnectPoint, MacAddress> getOltMacInfo() { | ||
77 | - return ImmutableMap.copyOf(oltMacInfo); | ||
78 | - } | ||
79 | - | ||
80 | - /** | ||
81 | - * Reuturns the agents mac address. | ||
82 | - * | ||
83 | - * @return a mac address | ||
84 | - */ | ||
85 | - public MacAddress getAgentMac() { | ||
86 | - return agentMac; | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * Returns the location of the agent. | ||
91 | - * | ||
92 | - * @return a connection point | ||
93 | - */ | ||
94 | - public Optional<ConnectPoint> getVtnLocation() { | ||
95 | - return vtnLocation; | ||
96 | - } | ||
97 | -} |
apps/cordconfig/src/main/java/org/onosproject/cordconfig/access/AccessDeviceConfig.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordconfig.access; | ||
18 | - | ||
19 | -import org.onosproject.net.DeviceId; | ||
20 | -import com.fasterxml.jackson.databind.JsonNode; | ||
21 | -import org.onlab.packet.VlanId; | ||
22 | - | ||
23 | -import org.onosproject.net.PortNumber; | ||
24 | -import org.onosproject.net.config.Config; | ||
25 | - | ||
26 | -import java.util.Optional; | ||
27 | - | ||
28 | -/** | ||
29 | - * Config object for access device data. | ||
30 | - */ | ||
31 | -public class AccessDeviceConfig extends Config<DeviceId> { | ||
32 | - | ||
33 | - private static final String UPLINK = "uplink"; | ||
34 | - private static final String VLAN = "vlan"; | ||
35 | - private static final String DEFAULT_VLAN = "defaultVlan"; | ||
36 | - | ||
37 | - /** | ||
38 | - * Gets the access device configuration for this device. | ||
39 | - * | ||
40 | - * @return access device configuration | ||
41 | - */ | ||
42 | - public AccessDeviceData getOlt() { | ||
43 | - PortNumber uplink = PortNumber.portNumber(node.path(UPLINK).asText()); | ||
44 | - VlanId vlan = VlanId.vlanId(Short.parseShort(node.path(VLAN).asText())); | ||
45 | - JsonNode defaultVlanNode = node.path(DEFAULT_VLAN); | ||
46 | - | ||
47 | - Optional<VlanId> defaultVlan; | ||
48 | - if (defaultVlanNode.isMissingNode()) { | ||
49 | - defaultVlan = Optional.empty(); | ||
50 | - } else { | ||
51 | - defaultVlan = Optional.of(VlanId.vlanId(Short.parseShort(defaultVlanNode.asText()))); | ||
52 | - } | ||
53 | - | ||
54 | - return new AccessDeviceData(subject(), uplink, vlan, defaultVlan); | ||
55 | - } | ||
56 | -} |
apps/cordconfig/src/main/java/org/onosproject/cordconfig/access/AccessDeviceData.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordconfig.access; | ||
18 | - | ||
19 | -import org.onlab.packet.VlanId; | ||
20 | -import org.onosproject.net.DeviceId; | ||
21 | -import org.onosproject.net.PortNumber; | ||
22 | - | ||
23 | -import java.util.Optional; | ||
24 | - | ||
25 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
26 | - | ||
27 | -/** | ||
28 | - * Information about an access device. | ||
29 | - */ | ||
30 | -public class AccessDeviceData { | ||
31 | - private static final String DEVICE_ID_MISSING = "Device ID cannot be null"; | ||
32 | - private static final String UPLINK_MISSING = "Uplink cannot be null"; | ||
33 | - private static final String VLAN_MISSING = "VLAN ID cannot be null"; | ||
34 | - | ||
35 | - private final DeviceId deviceId; | ||
36 | - private final PortNumber uplink; | ||
37 | - private final VlanId vlan; | ||
38 | - private final Optional<VlanId> defaultVlan; | ||
39 | - | ||
40 | - /** | ||
41 | - * Class constructor. | ||
42 | - * | ||
43 | - * @param deviceId access device ID | ||
44 | - * @param uplink uplink port number | ||
45 | - * @param vlan device VLAN ID | ||
46 | - * @param defaultVlan default device VLAN ID | ||
47 | - */ | ||
48 | - public AccessDeviceData(DeviceId deviceId, PortNumber uplink, VlanId vlan, | ||
49 | - Optional<VlanId> defaultVlan) { | ||
50 | - this.deviceId = checkNotNull(deviceId, DEVICE_ID_MISSING); | ||
51 | - this.uplink = checkNotNull(uplink, UPLINK_MISSING); | ||
52 | - this.vlan = checkNotNull(vlan, VLAN_MISSING); | ||
53 | - this.defaultVlan = checkNotNull(defaultVlan); | ||
54 | - } | ||
55 | - | ||
56 | - /** | ||
57 | - * Retrieves the access device ID. | ||
58 | - * | ||
59 | - * @return device ID | ||
60 | - */ | ||
61 | - public DeviceId deviceId() { | ||
62 | - return deviceId; | ||
63 | - } | ||
64 | - | ||
65 | - /** | ||
66 | - * Retrieves the uplink port number. | ||
67 | - * | ||
68 | - * @return port number | ||
69 | - */ | ||
70 | - public PortNumber uplink() { | ||
71 | - return uplink; | ||
72 | - } | ||
73 | - | ||
74 | - /** | ||
75 | - * Retrieves the VLAN ID assigned to the device. | ||
76 | - * | ||
77 | - * @return VLAN ID | ||
78 | - */ | ||
79 | - public VlanId vlan() { | ||
80 | - return vlan; | ||
81 | - } | ||
82 | - | ||
83 | - /** | ||
84 | - * Retrieves the default VLAN ID that will be used for this device. | ||
85 | - * | ||
86 | - * @return default VLAN ID | ||
87 | - */ | ||
88 | - public Optional<VlanId> defaultVlan() { | ||
89 | - return defaultVlan; | ||
90 | - } | ||
91 | -} |
apps/cordconfig/src/main/java/org/onosproject/cordconfig/access/package-info.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * Meta Application for hosting common cord configuration classes. | ||
19 | - */ | ||
20 | -package org.onosproject.cordconfig.access; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/cordmcast/BUCK
deleted
100644 → 0
1 | -COMPILE_DEPS = [ | ||
2 | - '//lib:CORE_DEPS', | ||
3 | - '//lib:javax.ws.rs-api', | ||
4 | - '//lib:jersey-client', | ||
5 | - '//lib:jersey-common', | ||
6 | - '//utils/rest:onlab-rest', | ||
7 | - '//apps/olt:onos-apps-olt-api', | ||
8 | - '//apps/cordconfig:onos-apps-cordconfig', | ||
9 | -] | ||
10 | - | ||
11 | -BUNDLES = [ | ||
12 | - '//apps/olt:onos-apps-olt-api', | ||
13 | - '//apps/cordmcast:onos-apps-cordmcast', | ||
14 | -] | ||
15 | - | ||
16 | -osgi_jar_with_tests ( | ||
17 | - deps = COMPILE_DEPS, | ||
18 | -) | ||
19 | - | ||
20 | -onos_app ( | ||
21 | - title = 'CORD Multicast App', | ||
22 | - category = 'Traffic Steering', | ||
23 | - url = 'http://onosproject.org', | ||
24 | - description = 'CORD Multicast application', | ||
25 | - included_bundles = BUNDLES, | ||
26 | -) |
apps/cordmcast/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-app-cord-mcast</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <description>CORD Multicast application</description> | ||
33 | - | ||
34 | - <properties> | ||
35 | - <onos.app.name>org.onosproject.cordmcast</onos.app.name> | ||
36 | - <onos.app.category>Traffic Steering</onos.app.category> | ||
37 | - <onos.app.title>CORD Multicast App</onos.app.title> | ||
38 | - <onos.app.url>http://opencord.org</onos.app.url> | ||
39 | - <onos.app.requires>org.onosproject.cord-config</onos.app.requires> | ||
40 | - </properties> | ||
41 | - | ||
42 | - <dependencies> | ||
43 | - <dependency> | ||
44 | - <groupId>org.onosproject</groupId> | ||
45 | - <artifactId>onos-cli</artifactId> | ||
46 | - <version>${project.version}</version> | ||
47 | - </dependency> | ||
48 | - <dependency> | ||
49 | - <groupId>org.onosproject</groupId> | ||
50 | - <artifactId>onos-cord-config</artifactId> | ||
51 | - <version>${project.version}</version> | ||
52 | - </dependency> | ||
53 | - <dependency> | ||
54 | - <groupId>org.apache.karaf.shell</groupId> | ||
55 | - <artifactId>org.apache.karaf.shell.console</artifactId> | ||
56 | - </dependency> | ||
57 | - <dependency> | ||
58 | - <groupId>com.google.guava</groupId> | ||
59 | - <artifactId>guava</artifactId> | ||
60 | - </dependency> | ||
61 | - <dependency> | ||
62 | - <groupId>org.onosproject</groupId> | ||
63 | - <artifactId>onlab-misc</artifactId> | ||
64 | - </dependency> | ||
65 | - <dependency> | ||
66 | - <groupId>org.apache.felix</groupId> | ||
67 | - <artifactId>org.apache.felix.scr</artifactId> | ||
68 | - <version>1.8.2</version> | ||
69 | - </dependency> | ||
70 | - <dependency> | ||
71 | - <groupId>org.osgi</groupId> | ||
72 | - <artifactId>org.osgi.compendium</artifactId> | ||
73 | - <version>5.0.0</version> | ||
74 | - </dependency> | ||
75 | - <dependency> | ||
76 | - <groupId>org.glassfish.jersey.core</groupId> | ||
77 | - <artifactId>jersey-client</artifactId> | ||
78 | - <version>2.22.2</version> | ||
79 | - </dependency> | ||
80 | - <dependency> | ||
81 | - <groupId>org.onosproject</groupId> | ||
82 | - <artifactId>onos-app-olt-api</artifactId> | ||
83 | - <version>${project.version}</version> | ||
84 | - </dependency> | ||
85 | - </dependencies> | ||
86 | -</project> |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordmcast; | ||
17 | - | ||
18 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | -import com.fasterxml.jackson.databind.node.ArrayNode; | ||
20 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
21 | -import com.google.common.collect.Lists; | ||
22 | -import com.google.common.collect.Maps; | ||
23 | -import org.apache.commons.lang3.tuple.ImmutablePair; | ||
24 | -import org.apache.felix.scr.annotations.Activate; | ||
25 | -import org.apache.felix.scr.annotations.Component; | ||
26 | -import org.apache.felix.scr.annotations.Deactivate; | ||
27 | -import org.apache.felix.scr.annotations.Modified; | ||
28 | -import org.apache.felix.scr.annotations.Property; | ||
29 | -import org.apache.felix.scr.annotations.Reference; | ||
30 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
31 | -import org.glassfish.jersey.client.ClientConfig; | ||
32 | -import org.glassfish.jersey.client.ClientProperties; | ||
33 | -import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; | ||
34 | -import org.onlab.packet.Ethernet; | ||
35 | -import org.onlab.packet.IpAddress; | ||
36 | -import org.onlab.packet.VlanId; | ||
37 | -import org.onosproject.cfg.ComponentConfigService; | ||
38 | -import org.onosproject.codec.CodecService; | ||
39 | -import org.onosproject.codec.JsonCodec; | ||
40 | -import org.onosproject.cordconfig.access.AccessDeviceConfig; | ||
41 | -import org.onosproject.cordconfig.access.AccessDeviceData; | ||
42 | -import org.onosproject.core.ApplicationId; | ||
43 | -import org.onosproject.core.CoreService; | ||
44 | -import org.onosproject.net.ConnectPoint; | ||
45 | -import org.onosproject.net.DeviceId; | ||
46 | -import org.onosproject.net.config.ConfigFactory; | ||
47 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
48 | -import org.onosproject.net.config.NetworkConfigListener; | ||
49 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
50 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
51 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
52 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
53 | -import org.onosproject.net.flow.TrafficSelector; | ||
54 | -import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
55 | -import org.onosproject.net.flowobjective.DefaultNextObjective; | ||
56 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
57 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
58 | -import org.onosproject.net.flowobjective.NextObjective; | ||
59 | -import org.onosproject.net.flowobjective.Objective; | ||
60 | -import org.onosproject.net.flowobjective.ObjectiveContext; | ||
61 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
62 | -import org.onosproject.net.mcast.McastEvent; | ||
63 | -import org.onosproject.net.mcast.McastListener; | ||
64 | -import org.onosproject.net.mcast.McastRoute; | ||
65 | -import org.onosproject.net.mcast.McastRouteInfo; | ||
66 | -import org.onosproject.net.mcast.MulticastRouteService; | ||
67 | - | ||
68 | -import org.onosproject.rest.AbstractWebResource; | ||
69 | -import org.osgi.service.component.ComponentContext; | ||
70 | -import org.slf4j.Logger; | ||
71 | - | ||
72 | -import javax.ws.rs.ProcessingException; | ||
73 | -import javax.ws.rs.client.Client; | ||
74 | -import javax.ws.rs.client.ClientBuilder; | ||
75 | -import javax.ws.rs.client.Entity; | ||
76 | -import javax.ws.rs.client.Invocation; | ||
77 | -import javax.ws.rs.client.WebTarget; | ||
78 | -import javax.ws.rs.core.MediaType; | ||
79 | -import java.io.IOException; | ||
80 | -import java.util.Dictionary; | ||
81 | -import java.util.List; | ||
82 | -import java.util.Map; | ||
83 | -import java.util.Properties; | ||
84 | -import java.util.concurrent.ConcurrentHashMap; | ||
85 | -import java.util.concurrent.atomic.AtomicBoolean; | ||
86 | - | ||
87 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
88 | -import static com.google.common.base.Strings.isNullOrEmpty; | ||
89 | -import static com.google.common.net.MediaType.JSON_UTF_8; | ||
90 | -import static org.onlab.util.Tools.get; | ||
91 | -import static org.slf4j.LoggerFactory.getLogger; | ||
92 | - | ||
93 | -/** | ||
94 | - * CORD multicast provisioning application. Operates by listening to | ||
95 | - * events on the multicast rib and provisioning groups to program multicast | ||
96 | - * flows on the dataplane. | ||
97 | - */ | ||
98 | -@Component(immediate = true) | ||
99 | -public class CordMcast { | ||
100 | - | ||
101 | - | ||
102 | - private static final int DEFAULT_REST_TIMEOUT_MS = 2000; | ||
103 | - private static final int DEFAULT_PRIORITY = 500; | ||
104 | - private static final short DEFAULT_MCAST_VLAN = 4000; | ||
105 | - private static final String DEFAULT_SYNC_HOST = "10.90.0.8:8181"; | ||
106 | - private static final String DEFAULT_USER = "karaf"; | ||
107 | - private static final String DEFAULT_PASSWORD = "karaf"; | ||
108 | - private static final boolean DEFAULT_VLAN_ENABLED = true; | ||
109 | - | ||
110 | - private final Logger log = getLogger(getClass()); | ||
111 | - | ||
112 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
113 | - protected MulticastRouteService mcastService; | ||
114 | - | ||
115 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
116 | - protected FlowObjectiveService flowObjectiveService; | ||
117 | - | ||
118 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
119 | - protected CoreService coreService; | ||
120 | - | ||
121 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
122 | - protected CodecService codecService; | ||
123 | - | ||
124 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
125 | - protected ComponentConfigService componentConfigService; | ||
126 | - | ||
127 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
128 | - protected NetworkConfigRegistry networkConfig; | ||
129 | - | ||
130 | - protected McastListener listener = new InternalMulticastListener(); | ||
131 | - private InternalNetworkConfigListener configListener = | ||
132 | - new InternalNetworkConfigListener(); | ||
133 | - | ||
134 | - //TODO: move this to a ec map | ||
135 | - private Map<IpAddress, Integer> groups = Maps.newConcurrentMap(); | ||
136 | - | ||
137 | - private ApplicationId appId; | ||
138 | - | ||
139 | - @Property(name = "mcastVlan", intValue = DEFAULT_MCAST_VLAN, | ||
140 | - label = "VLAN for multicast traffic") | ||
141 | - private int mcastVlan = DEFAULT_MCAST_VLAN; | ||
142 | - | ||
143 | - @Property(name = "vlanEnabled", boolValue = DEFAULT_VLAN_ENABLED, | ||
144 | - label = "Use vlan for multicast traffic?") | ||
145 | - private boolean vlanEnabled = DEFAULT_VLAN_ENABLED; | ||
146 | - | ||
147 | - @Property(name = "priority", intValue = DEFAULT_PRIORITY, | ||
148 | - label = "Priority for multicast rules") | ||
149 | - private int priority = DEFAULT_PRIORITY; | ||
150 | - | ||
151 | - @Property(name = "syncHost", value = DEFAULT_SYNC_HOST, | ||
152 | - label = "host:port to synchronize routes to") | ||
153 | - private String syncHost = DEFAULT_SYNC_HOST; | ||
154 | - | ||
155 | - @Property(name = "username", value = DEFAULT_USER, | ||
156 | - label = "Username for REST password authentication") | ||
157 | - private String user = DEFAULT_USER; | ||
158 | - | ||
159 | - @Property(name = "password", value = DEFAULT_PASSWORD, | ||
160 | - label = "Password for REST authentication") | ||
161 | - private String password = DEFAULT_PASSWORD; | ||
162 | - | ||
163 | - private String fabricOnosUrl; | ||
164 | - | ||
165 | - private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>(); | ||
166 | - | ||
167 | - private static final Class<AccessDeviceConfig> CONFIG_CLASS = | ||
168 | - AccessDeviceConfig.class; | ||
169 | - | ||
170 | - private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = | ||
171 | - new ConfigFactory<DeviceId, AccessDeviceConfig>( | ||
172 | - SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { | ||
173 | - @Override | ||
174 | - public AccessDeviceConfig createConfig() { | ||
175 | - return new AccessDeviceConfig(); | ||
176 | - } | ||
177 | - }; | ||
178 | - | ||
179 | - @Activate | ||
180 | - public void activate(ComponentContext context) { | ||
181 | - componentConfigService.registerProperties(getClass()); | ||
182 | - modified(context); | ||
183 | - | ||
184 | - appId = coreService.registerApplication("org.onosproject.cordmcast"); | ||
185 | - | ||
186 | - | ||
187 | - clearRemoteRoutes(); | ||
188 | - | ||
189 | - networkConfig.registerConfigFactory(configFactory); | ||
190 | - networkConfig.addListener(configListener); | ||
191 | - | ||
192 | - networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( | ||
193 | - subject -> { | ||
194 | - AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); | ||
195 | - if (config != null) { | ||
196 | - AccessDeviceData data = config.getOlt(); | ||
197 | - oltData.put(data.deviceId(), data); | ||
198 | - } | ||
199 | - } | ||
200 | - ); | ||
201 | - | ||
202 | - | ||
203 | - mcastService.addListener(listener); | ||
204 | - | ||
205 | - mcastService.getRoutes().stream() | ||
206 | - .map(r -> new ImmutablePair<>(r, mcastService.fetchSinks(r))) | ||
207 | - .filter(pair -> pair.getRight() != null && !pair.getRight().isEmpty()) | ||
208 | - .forEach(pair -> pair.getRight().forEach(sink -> provisionGroup(pair.getLeft(), | ||
209 | - sink))); | ||
210 | - | ||
211 | - log.info("Started"); | ||
212 | - } | ||
213 | - | ||
214 | - @Deactivate | ||
215 | - public void deactivate() { | ||
216 | - componentConfigService.unregisterProperties(getClass(), false); | ||
217 | - mcastService.removeListener(listener); | ||
218 | - networkConfig.unregisterConfigFactory(configFactory); | ||
219 | - networkConfig.removeListener(configListener); | ||
220 | - log.info("Stopped"); | ||
221 | - } | ||
222 | - | ||
223 | - @Modified | ||
224 | - public void modified(ComponentContext context) { | ||
225 | - Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); | ||
226 | - | ||
227 | - try { | ||
228 | - String s = get(properties, "username"); | ||
229 | - user = isNullOrEmpty(s) ? DEFAULT_USER : s.trim(); | ||
230 | - | ||
231 | - s = get(properties, "password"); | ||
232 | - password = isNullOrEmpty(s) ? DEFAULT_PASSWORD : s.trim(); | ||
233 | - | ||
234 | - s = get(properties, "mcastVlan"); | ||
235 | - mcastVlan = isNullOrEmpty(s) ? DEFAULT_MCAST_VLAN : Short.parseShort(s.trim()); | ||
236 | - | ||
237 | - s = get(properties, "vlanEnabled"); | ||
238 | - vlanEnabled = isNullOrEmpty(s) ? DEFAULT_VLAN_ENABLED : Boolean.parseBoolean(s.trim()); | ||
239 | - | ||
240 | - s = get(properties, "priority"); | ||
241 | - priority = isNullOrEmpty(s) ? DEFAULT_PRIORITY : Integer.parseInt(s.trim()); | ||
242 | - | ||
243 | - s = get(properties, "syncHost"); | ||
244 | - syncHost = isNullOrEmpty(s) ? DEFAULT_SYNC_HOST : s.trim(); | ||
245 | - } catch (Exception e) { | ||
246 | - user = DEFAULT_USER; | ||
247 | - password = DEFAULT_PASSWORD; | ||
248 | - syncHost = DEFAULT_SYNC_HOST; | ||
249 | - mcastVlan = DEFAULT_MCAST_VLAN; | ||
250 | - vlanEnabled = false; | ||
251 | - priority = DEFAULT_PRIORITY; | ||
252 | - } | ||
253 | - fabricOnosUrl = createRemoteUrl(syncHost); | ||
254 | - } | ||
255 | - | ||
256 | - private static String createRemoteUrl(String remoteHost) { | ||
257 | - return "http://" + remoteHost + "/onos/v1/mcast"; | ||
258 | - } | ||
259 | - | ||
260 | - private class InternalMulticastListener implements McastListener { | ||
261 | - @Override | ||
262 | - public void event(McastEvent event) { | ||
263 | - McastRouteInfo info = event.subject(); | ||
264 | - switch (event.type()) { | ||
265 | - case ROUTE_ADDED: | ||
266 | - break; | ||
267 | - case ROUTE_REMOVED: | ||
268 | - break; | ||
269 | - case SOURCE_ADDED: | ||
270 | - break; | ||
271 | - case SINK_ADDED: | ||
272 | - if (!info.sink().isPresent()) { | ||
273 | - log.warn("No sink given after sink added event: {}", info); | ||
274 | - return; | ||
275 | - } | ||
276 | - provisionGroup(info.route(), info.sink().get()); | ||
277 | - break; | ||
278 | - case SINK_REMOVED: | ||
279 | - unprovisionGroup(event.subject()); | ||
280 | - break; | ||
281 | - default: | ||
282 | - log.warn("Unknown mcast event {}", event.type()); | ||
283 | - } | ||
284 | - } | ||
285 | - } | ||
286 | - | ||
287 | - private void unprovisionGroup(McastRouteInfo info) { | ||
288 | - if (info.sinks().isEmpty()) { | ||
289 | - removeRemoteRoute(info.route()); | ||
290 | - } | ||
291 | - | ||
292 | - if (!info.sink().isPresent()) { | ||
293 | - log.warn("No sink given after sink removed event: {}", info); | ||
294 | - return; | ||
295 | - } | ||
296 | - ConnectPoint loc = info.sink().get(); | ||
297 | - | ||
298 | - NextObjective next = DefaultNextObjective.builder() | ||
299 | - .fromApp(appId) | ||
300 | - .addTreatment(DefaultTrafficTreatment.builder().setOutput(loc.port()).build()) | ||
301 | - .withType(NextObjective.Type.BROADCAST) | ||
302 | - .withId(groups.get(info.route().group())) | ||
303 | - .removeFromExisting(new ObjectiveContext() { | ||
304 | - @Override | ||
305 | - public void onSuccess(Objective objective) { | ||
306 | - //TODO: change to debug | ||
307 | - log.info("Next Objective {} installed", objective.id()); | ||
308 | - } | ||
309 | - | ||
310 | - @Override | ||
311 | - public void onError(Objective objective, ObjectiveError error) { | ||
312 | - //TODO: change to debug | ||
313 | - log.info("Next Objective {} failed, because {}", | ||
314 | - objective.id(), | ||
315 | - error); | ||
316 | - } | ||
317 | - }); | ||
318 | - | ||
319 | - flowObjectiveService.next(loc.deviceId(), next); | ||
320 | - } | ||
321 | - | ||
322 | - private void provisionGroup(McastRoute route, ConnectPoint sink) { | ||
323 | - checkNotNull(route, "Route cannot be null"); | ||
324 | - checkNotNull(sink, "Sink cannot be null"); | ||
325 | - | ||
326 | - AccessDeviceData oltInfo = oltData.get(sink.deviceId()); | ||
327 | - | ||
328 | - if (oltInfo == null) { | ||
329 | - log.warn("Unknown OLT device : {}", sink.deviceId()); | ||
330 | - return; | ||
331 | - } | ||
332 | - | ||
333 | - final AtomicBoolean sync = new AtomicBoolean(false); | ||
334 | - | ||
335 | - Integer nextId = groups.computeIfAbsent(route.group(), (g) -> { | ||
336 | - Integer id = flowObjectiveService.allocateNextId(); | ||
337 | - | ||
338 | - NextObjective next = DefaultNextObjective.builder() | ||
339 | - .fromApp(appId) | ||
340 | - .addTreatment(DefaultTrafficTreatment.builder().setOutput(sink.port()).build()) | ||
341 | - .withType(NextObjective.Type.BROADCAST) | ||
342 | - .withId(id) | ||
343 | - .add(new ObjectiveContext() { | ||
344 | - @Override | ||
345 | - public void onSuccess(Objective objective) { | ||
346 | - //TODO: change to debug | ||
347 | - log.info("Next Objective {} installed", objective.id()); | ||
348 | - } | ||
349 | - | ||
350 | - @Override | ||
351 | - public void onError(Objective objective, ObjectiveError error) { | ||
352 | - //TODO: change to debug | ||
353 | - log.info("Next Objective {} failed, because {}", | ||
354 | - objective.id(), | ||
355 | - error); | ||
356 | - } | ||
357 | - }); | ||
358 | - | ||
359 | - flowObjectiveService.next(sink.deviceId(), next); | ||
360 | - | ||
361 | - TrafficSelector.Builder mcast = DefaultTrafficSelector.builder() | ||
362 | - .matchInPort(oltInfo.uplink()) | ||
363 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
364 | - .matchIPDst(g.toIpPrefix()); | ||
365 | - | ||
366 | - if (vlanEnabled) { | ||
367 | - mcast.matchVlanId(VlanId.vlanId((short) mcastVlan)); | ||
368 | - } | ||
369 | - | ||
370 | - ForwardingObjective fwd = DefaultForwardingObjective.builder() | ||
371 | - .fromApp(appId) | ||
372 | - .nextStep(id) | ||
373 | - .makePermanent() | ||
374 | - .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
375 | - .withPriority(priority) | ||
376 | - .withSelector(mcast.build()) | ||
377 | - .add(new ObjectiveContext() { | ||
378 | - @Override | ||
379 | - public void onSuccess(Objective objective) { | ||
380 | - //TODO: change to debug | ||
381 | - log.info("Forwarding objective installed {}", objective); | ||
382 | - } | ||
383 | - | ||
384 | - @Override | ||
385 | - public void onError(Objective objective, ObjectiveError error) { | ||
386 | - //TODO: change to debug | ||
387 | - log.info("Forwarding objective failed {}", objective); | ||
388 | - } | ||
389 | - }); | ||
390 | - | ||
391 | - flowObjectiveService.forward(sink.deviceId(), fwd); | ||
392 | - | ||
393 | - sync.set(true); | ||
394 | - | ||
395 | - return id; | ||
396 | - }); | ||
397 | - | ||
398 | - if (!sync.get()) { | ||
399 | - NextObjective next = DefaultNextObjective.builder() | ||
400 | - .fromApp(appId) | ||
401 | - .addTreatment(DefaultTrafficTreatment.builder().setOutput(sink.port()).build()) | ||
402 | - .withType(NextObjective.Type.BROADCAST) | ||
403 | - .withId(nextId) | ||
404 | - .addToExisting(new ObjectiveContext() { | ||
405 | - @Override | ||
406 | - public void onSuccess(Objective objective) { | ||
407 | - //TODO: change to debug | ||
408 | - log.info("Next Objective {} installed", objective.id()); | ||
409 | - } | ||
410 | - | ||
411 | - @Override | ||
412 | - public void onError(Objective objective, ObjectiveError error) { | ||
413 | - //TODO: change to debug | ||
414 | - log.info("Next Objective {} failed, because {}", | ||
415 | - objective.id(), | ||
416 | - error); | ||
417 | - } | ||
418 | - }); | ||
419 | - | ||
420 | - flowObjectiveService.next(sink.deviceId(), next); | ||
421 | - } | ||
422 | - | ||
423 | - | ||
424 | - addRemoteRoute(route); | ||
425 | - } | ||
426 | - | ||
427 | - private void addRemoteRoute(McastRoute route) { | ||
428 | - checkNotNull(route); | ||
429 | - if (syncHost == null) { | ||
430 | - log.warn("No host configured for synchronization; route will be dropped"); | ||
431 | - return; | ||
432 | - } | ||
433 | - | ||
434 | - log.debug("Sending route {} to other ONOS {}", route, fabricOnosUrl); | ||
435 | - | ||
436 | - Invocation.Builder builder = getClientBuilder(fabricOnosUrl); | ||
437 | - | ||
438 | - ObjectNode json = codecService.getCodec(McastRoute.class) | ||
439 | - .encode(route, new AbstractWebResource()); | ||
440 | - | ||
441 | - try { | ||
442 | - builder.post(Entity.json(json.toString())); | ||
443 | - } catch (ProcessingException e) { | ||
444 | - log.warn("Unable to send route to remote controller: {}", e.getMessage()); | ||
445 | - } | ||
446 | - } | ||
447 | - | ||
448 | - private void removeRemoteRoute(McastRoute route) { | ||
449 | - if (syncHost == null) { | ||
450 | - log.warn("No host configured for synchronization; route will be dropped"); | ||
451 | - return; | ||
452 | - } | ||
453 | - | ||
454 | - log.debug("Removing route {} from other ONOS {}", route, fabricOnosUrl); | ||
455 | - | ||
456 | - Invocation.Builder builder = getClientBuilder(fabricOnosUrl) | ||
457 | - .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); | ||
458 | - | ||
459 | - ObjectNode json = codecService.getCodec(McastRoute.class) | ||
460 | - .encode(route, new AbstractWebResource()); | ||
461 | - | ||
462 | - builder.method("DELETE", Entity.entity(json.asText(), | ||
463 | - MediaType.APPLICATION_OCTET_STREAM)); | ||
464 | - } | ||
465 | - | ||
466 | - private void clearRemoteRoutes() { | ||
467 | - if (syncHost == null) { | ||
468 | - log.warn("No host configured for synchronization"); | ||
469 | - return; | ||
470 | - } | ||
471 | - | ||
472 | - log.debug("Clearing remote multicast routes from {}", fabricOnosUrl); | ||
473 | - | ||
474 | - Invocation.Builder builder = getClientBuilder(fabricOnosUrl); | ||
475 | - List<McastRoute> mcastRoutes = Lists.newArrayList(); | ||
476 | - | ||
477 | - try { | ||
478 | - String response = builder | ||
479 | - .accept(MediaType.APPLICATION_JSON_TYPE) | ||
480 | - .get(String.class); | ||
481 | - | ||
482 | - JsonCodec<McastRoute> routeCodec = codecService.getCodec(McastRoute.class); | ||
483 | - ObjectMapper mapper = new ObjectMapper(); | ||
484 | - | ||
485 | - | ||
486 | - ObjectNode node = (ObjectNode) mapper.readTree(response); | ||
487 | - ArrayNode list = (ArrayNode) node.path("routes"); | ||
488 | - | ||
489 | - list.forEach(n -> mcastRoutes.add( | ||
490 | - routeCodec.decode((ObjectNode) n, new AbstractWebResource()))); | ||
491 | - | ||
492 | - } catch (IOException e) { | ||
493 | - log.warn("Error clearing remote routes", e); | ||
494 | - } | ||
495 | - | ||
496 | - mcastRoutes.forEach(this::removeRemoteRoute); | ||
497 | - } | ||
498 | - | ||
499 | - private Invocation.Builder getClientBuilder(String uri) { | ||
500 | - ClientConfig config = new ClientConfig(); | ||
501 | - Client client = ClientBuilder.newClient(config); | ||
502 | - | ||
503 | - client.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_REST_TIMEOUT_MS); | ||
504 | - client.property(ClientProperties.READ_TIMEOUT, DEFAULT_REST_TIMEOUT_MS); | ||
505 | - client.register(HttpAuthenticationFeature.basic(user, password)); | ||
506 | - | ||
507 | - WebTarget wt = client.target(uri); | ||
508 | - return wt.request(JSON_UTF_8.toString()); | ||
509 | - } | ||
510 | - | ||
511 | - private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
512 | - @Override | ||
513 | - public void event(NetworkConfigEvent event) { | ||
514 | - switch (event.type()) { | ||
515 | - | ||
516 | - case CONFIG_ADDED: | ||
517 | - case CONFIG_UPDATED: | ||
518 | - AccessDeviceConfig config = | ||
519 | - networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS); | ||
520 | - if (config != null) { | ||
521 | - oltData.put(config.getOlt().deviceId(), config.getOlt()); | ||
522 | - } | ||
523 | - | ||
524 | - break; | ||
525 | - case CONFIG_REGISTERED: | ||
526 | - case CONFIG_UNREGISTERED: | ||
527 | - break; | ||
528 | - case CONFIG_REMOVED: | ||
529 | - oltData.remove(event.subject()); | ||
530 | - break; | ||
531 | - default: | ||
532 | - break; | ||
533 | - } | ||
534 | - } | ||
535 | - | ||
536 | - @Override | ||
537 | - public boolean isRelevant(NetworkConfigEvent event) { | ||
538 | - return event.configClass().equals(CONFIG_CLASS); | ||
539 | - } | ||
540 | - } | ||
541 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * Application for provisioning multicast streams in the context of cord. | ||
19 | - */ | ||
20 | -package org.onosproject.cordmcast; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/cordvtn/BUCK
deleted
100644 → 0
1 | -# app builds but is currently non functional. It needs transitive runtime | ||
2 | -# dependencies. | ||
3 | - | ||
4 | -COMPILE_DEPS = [ | ||
5 | - '//lib:CORE_DEPS', | ||
6 | - '//lib:org.apache.karaf.shell.console', | ||
7 | - '//lib:javax.ws.rs-api', | ||
8 | - '//lib:jsch', | ||
9 | - '//utils/rest:onlab-rest', | ||
10 | - '//cli:onos-cli', | ||
11 | - '//core/store/serializers:onos-core-serializers', | ||
12 | - '//apps/dhcp/api:onos-apps-dhcp-api', | ||
13 | - '//apps/xosclient:onos-apps-xosclient', | ||
14 | - '//apps/cordconfig:onos-apps-cordconfig', | ||
15 | - '//protocols/ovsdb/api:onos-protocols-ovsdb-api', | ||
16 | - '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc', | ||
17 | -] | ||
18 | - | ||
19 | -BUNDLES = [ | ||
20 | - '//apps/cordvtn:onos-apps-cordvtn', | ||
21 | -] | ||
22 | - | ||
23 | -EXCLUDED_BUNDLES = [ | ||
24 | - '//lib:jsch', | ||
25 | -] | ||
26 | - | ||
27 | -osgi_jar_with_tests ( | ||
28 | - deps = COMPILE_DEPS, | ||
29 | - web_context = '/onos/cordvtn', | ||
30 | -) | ||
31 | - | ||
32 | -onos_app ( | ||
33 | - title = 'CORD VTN REST API', | ||
34 | - category = 'Traffic Steering', | ||
35 | - url = 'http://onosproject.org', | ||
36 | - included_bundles = BUNDLES, | ||
37 | - excluded_bundles = EXCLUDED_BUNDLES, | ||
38 | - description = 'APIs for interacting with the CORD VTN application.', | ||
39 | - required_apps = [ 'org.onosproject.cord-config', 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ], | ||
40 | -) |
apps/cordvtn/app.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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 | -<app name="org.onosproject.cordvtn" origin="ON.Lab" version="${project.version}" | ||
18 | - category="Traffic Steering" url="http://onosproject.org" title="CORD Virtual Tenant Network" | ||
19 | - featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" | ||
20 | - features="${project.artifactId}" | ||
21 | - apps="org.onosproject.ovsdb-base,org.onosproject.dhcp,org.onosproject.xosclient,org.onosproject.cord-config"> | ||
22 | - <description>${project.description}</description> | ||
23 | - <artifact>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</artifact> | ||
24 | -</app> |
apps/cordvtn/features.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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 | -<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> | ||
18 | - <feature name="${project.artifactId}" version="${project.version}" description="${project.description}"> | ||
19 | - <feature>onos-api</feature> | ||
20 | - <bundle>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</bundle> | ||
21 | - <bundle>wrap:mvn:com.jcraft/jsch/0.1.53$Bundle-SymbolicName=jsch&Bundle-Version=0.1.53</bundle> | ||
22 | - </feature> | ||
23 | -</features> |
apps/cordvtn/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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/xsd/maven-4.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.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-app-cordvtn</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <description>Virtual tenant network service for CORD</description> | ||
33 | - | ||
34 | - <properties> | ||
35 | - <web.context>/onos/cordvtn</web.context> | ||
36 | - <api.version>1.0.0</api.version> | ||
37 | - <api.title>CORD VTN REST API</api.title> | ||
38 | - <api.description> | ||
39 | - APIs for interacting with the CORD VTN application. | ||
40 | - </api.description> | ||
41 | - <api.package>org.onosproject.cordvtn.rest</api.package> | ||
42 | - </properties> | ||
43 | - | ||
44 | - <dependencies> | ||
45 | - <dependency> | ||
46 | - <groupId>org.osgi</groupId> | ||
47 | - <artifactId>org.osgi.compendium</artifactId> | ||
48 | - </dependency> | ||
49 | - <dependency> | ||
50 | - <groupId>org.onosproject</groupId> | ||
51 | - <artifactId>onos-api</artifactId> | ||
52 | - </dependency> | ||
53 | - <dependency> | ||
54 | - <groupId>org.onosproject</groupId> | ||
55 | - <artifactId>onos-core-serializers</artifactId> | ||
56 | - <version>${project.version}</version> | ||
57 | - </dependency> | ||
58 | - <dependency> | ||
59 | - <groupId>org.onosproject</groupId> | ||
60 | - <artifactId>onos-ovsdb-api</artifactId> | ||
61 | - <version>${project.version}</version> | ||
62 | - </dependency> | ||
63 | - <dependency> | ||
64 | - <groupId>org.onosproject</groupId> | ||
65 | - <artifactId>onos-cli</artifactId> | ||
66 | - <version>${project.version}</version> | ||
67 | - </dependency> | ||
68 | - <dependency> | ||
69 | - <groupId>org.apache.karaf.shell</groupId> | ||
70 | - <artifactId>org.apache.karaf.shell.console</artifactId> | ||
71 | - <version>3.0.5</version> | ||
72 | - </dependency> | ||
73 | - <dependency> | ||
74 | - <groupId>org.onosproject</groupId> | ||
75 | - <artifactId>onos-rest</artifactId> | ||
76 | - <version>${project.version}</version> | ||
77 | - </dependency> | ||
78 | - <dependency> | ||
79 | - <groupId>org.onosproject</groupId> | ||
80 | - <artifactId>onlab-rest</artifactId> | ||
81 | - <version>${project.version}</version> | ||
82 | - </dependency> | ||
83 | - <dependency> | ||
84 | - <groupId>javax.ws.rs</groupId> | ||
85 | - <artifactId>javax.ws.rs-api</artifactId> | ||
86 | - <version>2.0.1</version> | ||
87 | - </dependency> | ||
88 | - <dependency> | ||
89 | - <groupId>org.glassfish.jersey.containers</groupId> | ||
90 | - <artifactId>jersey-container-servlet</artifactId> | ||
91 | - </dependency> | ||
92 | - <dependency> | ||
93 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
94 | - <artifactId>jackson-databind</artifactId> | ||
95 | - </dependency> | ||
96 | - <dependency> | ||
97 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
98 | - <artifactId>jackson-annotations</artifactId> | ||
99 | - </dependency> | ||
100 | - <dependency> | ||
101 | - <groupId>org.onosproject</groupId> | ||
102 | - <artifactId>onos-app-dhcp-api</artifactId> | ||
103 | - <version>${project.version}</version> | ||
104 | - </dependency> | ||
105 | - <dependency> | ||
106 | - <groupId>org.onosproject</groupId> | ||
107 | - <artifactId>onos-app-xos-client</artifactId> | ||
108 | - <version>${project.version}</version> | ||
109 | - </dependency> | ||
110 | - <dependency> | ||
111 | - <groupId>org.onosproject</groupId> | ||
112 | - <artifactId>onos-cord-config</artifactId> | ||
113 | - <version>${project.version}</version> | ||
114 | - </dependency> | ||
115 | - <dependency> | ||
116 | - <groupId>com.jcraft</groupId> | ||
117 | - <artifactId>jsch</artifactId> | ||
118 | - <version>0.1.53</version> | ||
119 | - </dependency> | ||
120 | - </dependencies> | ||
121 | - | ||
122 | - <build> | ||
123 | - <plugins> | ||
124 | - <plugin> | ||
125 | - <groupId>org.apache.felix</groupId> | ||
126 | - <artifactId>maven-bundle-plugin</artifactId> | ||
127 | - <extensions>true</extensions> | ||
128 | - <configuration> | ||
129 | - <instructions> | ||
130 | - <_wab>src/main/webapp/</_wab> | ||
131 | - <Include-Resource> | ||
132 | - WEB-INF/classes/apidoc/swagger.json=target/swagger.json, | ||
133 | - {maven-resources} | ||
134 | - </Include-Resource> | ||
135 | - <Bundle-SymbolicName> | ||
136 | - ${project.groupId}.${project.artifactId} | ||
137 | - </Bundle-SymbolicName> | ||
138 | - <Import-Package> | ||
139 | - *,org.glassfish.jersey.servlet | ||
140 | - </Import-Package> | ||
141 | - <Web-ContextPath>${web.context}</Web-ContextPath> | ||
142 | - </instructions> | ||
143 | - </configuration> | ||
144 | - </plugin> | ||
145 | - </plugins> | ||
146 | - </build> | ||
147 | - | ||
148 | -</project> |
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.api; | ||
17 | - | ||
18 | -/** | ||
19 | - * Entity capable of handling a subject connected and disconnected situation. | ||
20 | - */ | ||
21 | -public interface ConnectionHandler<T> { | ||
22 | - | ||
23 | - /** | ||
24 | - * Processes the connected subject. | ||
25 | - * | ||
26 | - * @param subject subject | ||
27 | - */ | ||
28 | - void connected(T subject); | ||
29 | - | ||
30 | - /** | ||
31 | - * Processes the disconnected subject. | ||
32 | - * | ||
33 | - * @param subject subject. | ||
34 | - */ | ||
35 | - void disconnected(T subject); | ||
36 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import com.fasterxml.jackson.databind.JsonNode; | ||
19 | -import com.google.common.collect.Maps; | ||
20 | -import com.google.common.collect.Sets; | ||
21 | -import org.onlab.packet.Ip4Address; | ||
22 | -import org.onlab.packet.IpAddress; | ||
23 | -import org.onlab.packet.IpPrefix; | ||
24 | -import org.onlab.packet.MacAddress; | ||
25 | -import org.onlab.packet.TpPort; | ||
26 | -import org.onosproject.core.ApplicationId; | ||
27 | -import org.onosproject.net.DeviceId; | ||
28 | -import org.onosproject.net.config.Config; | ||
29 | -import org.onosproject.xosclient.api.OpenStackAccess; | ||
30 | -import org.onosproject.xosclient.api.XosAccess; | ||
31 | -import org.slf4j.Logger; | ||
32 | - | ||
33 | -import java.util.Map; | ||
34 | -import java.util.Set; | ||
35 | - | ||
36 | -import static org.slf4j.LoggerFactory.getLogger; | ||
37 | - | ||
38 | -/** | ||
39 | - * Configuration object for CordVtn service. | ||
40 | - */ | ||
41 | -public class CordVtnConfig extends Config<ApplicationId> { | ||
42 | - | ||
43 | - protected final Logger log = getLogger(getClass()); | ||
44 | - | ||
45 | - public static final String PRIVATE_GATEWAY_MAC = "privateGatewayMac"; | ||
46 | - public static final String PUBLIC_GATEWAYS = "publicGateways"; | ||
47 | - public static final String GATEWAY_IP = "gatewayIp"; | ||
48 | - public static final String GATEWAY_MAC = "gatewayMac"; | ||
49 | - public static final String LOCAL_MANAGEMENT_IP = "localManagementIp"; | ||
50 | - public static final String MANAGEMENT_IP = "managementIpRange"; | ||
51 | - public static final String OVSDB_PORT = "ovsdbPort"; | ||
52 | - | ||
53 | - public static final String CORDVTN_NODES = "nodes"; | ||
54 | - public static final String HOSTNAME = "hostname"; | ||
55 | - public static final String HOST_MANAGEMENT_IP = "hostManagementIp"; | ||
56 | - public static final String DATA_PLANE_IP = "dataPlaneIp"; | ||
57 | - public static final String DATA_PLANE_INTF = "dataPlaneIntf"; | ||
58 | - public static final String BRIDGE_ID = "bridgeId"; | ||
59 | - | ||
60 | - public static final String SSH = "ssh"; | ||
61 | - public static final String SSH_PORT = "sshPort"; | ||
62 | - public static final String SSH_USER = "sshUser"; | ||
63 | - public static final String SSH_KEY_FILE = "sshKeyFile"; | ||
64 | - | ||
65 | - public static final String OPENSTACK = "openstack"; | ||
66 | - public static final String XOS = "xos"; | ||
67 | - | ||
68 | - public static final String ENDPOINT = "endpoint"; | ||
69 | - public static final String TENANT = "tenant"; | ||
70 | - public static final String USER = "user"; | ||
71 | - public static final String PASSWORD = "password"; | ||
72 | - | ||
73 | - /** | ||
74 | - * Returns the set of nodes read from network config. | ||
75 | - * | ||
76 | - * @return set of CordVtnNodeConfig or empty set | ||
77 | - */ | ||
78 | - public Set<CordVtnNode> cordVtnNodes() { | ||
79 | - | ||
80 | - Set<CordVtnNode> nodes = Sets.newHashSet(); | ||
81 | - | ||
82 | - JsonNode cordvtnNodes = object.get(CORDVTN_NODES); | ||
83 | - if (cordvtnNodes == null) { | ||
84 | - log.debug("No CORD VTN nodes found"); | ||
85 | - return nodes; | ||
86 | - } | ||
87 | - | ||
88 | - JsonNode sshNode = object.get(SSH); | ||
89 | - if (sshNode == null) { | ||
90 | - log.warn("SSH information not found"); | ||
91 | - return nodes; | ||
92 | - } | ||
93 | - | ||
94 | - for (JsonNode cordvtnNode : cordvtnNodes) { | ||
95 | - try { | ||
96 | - NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(cordvtnNode, HOST_MANAGEMENT_IP)); | ||
97 | - NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP)); | ||
98 | - if (hostMgmt.prefix().contains(localMgmt.prefix()) || | ||
99 | - localMgmt.prefix().contains(hostMgmt.prefix())) { | ||
100 | - log.error("hostMamt and localMgmt cannot be overlapped, skip this node"); | ||
101 | - continue; | ||
102 | - } | ||
103 | - | ||
104 | - Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address(); | ||
105 | - SshAccessInfo sshInfo = new SshAccessInfo( | ||
106 | - hostMgmtIp, | ||
107 | - TpPort.tpPort(Integer.parseInt(getConfig(sshNode, SSH_PORT))), | ||
108 | - getConfig(sshNode, SSH_USER), getConfig(sshNode, SSH_KEY_FILE)); | ||
109 | - | ||
110 | - String hostname = getConfig(cordvtnNode, HOSTNAME); | ||
111 | - CordVtnNode newNode = new CordVtnNode( | ||
112 | - hostname, hostMgmt, localMgmt, | ||
113 | - NetworkAddress.valueOf(getConfig(cordvtnNode, DATA_PLANE_IP)), | ||
114 | - TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))), | ||
115 | - sshInfo, | ||
116 | - DeviceId.deviceId(getConfig(cordvtnNode, BRIDGE_ID)), | ||
117 | - getConfig(cordvtnNode, DATA_PLANE_INTF), | ||
118 | - CordVtnNodeState.noState()); | ||
119 | - | ||
120 | - nodes.add(newNode); | ||
121 | - } catch (IllegalArgumentException | NullPointerException e) { | ||
122 | - log.error("{}", e); | ||
123 | - } | ||
124 | - } | ||
125 | - | ||
126 | - return nodes; | ||
127 | - } | ||
128 | - | ||
129 | - /** | ||
130 | - * Returns value of a given path. If the path is missing, show log and return | ||
131 | - * null. | ||
132 | - * | ||
133 | - * @param path path | ||
134 | - * @return value or null | ||
135 | - */ | ||
136 | - private String getConfig(JsonNode jsonNode, String path) { | ||
137 | - jsonNode = jsonNode.path(path); | ||
138 | - | ||
139 | - if (jsonNode.isMissingNode()) { | ||
140 | - log.error("{} is not configured", path); | ||
141 | - return null; | ||
142 | - } else { | ||
143 | - return jsonNode.asText(); | ||
144 | - } | ||
145 | - } | ||
146 | - | ||
147 | - /** | ||
148 | - * Returns private network gateway MAC address. | ||
149 | - * | ||
150 | - * @return mac address, or null | ||
151 | - */ | ||
152 | - public MacAddress privateGatewayMac() { | ||
153 | - JsonNode jsonNode = object.get(PRIVATE_GATEWAY_MAC); | ||
154 | - if (jsonNode == null) { | ||
155 | - return null; | ||
156 | - } | ||
157 | - | ||
158 | - try { | ||
159 | - return MacAddress.valueOf(jsonNode.asText()); | ||
160 | - } catch (IllegalArgumentException e) { | ||
161 | - log.error("Wrong MAC address format {}", jsonNode.asText()); | ||
162 | - return null; | ||
163 | - } | ||
164 | - } | ||
165 | - | ||
166 | - /** | ||
167 | - * Returns public network gateway IP and MAC address pairs. | ||
168 | - * | ||
169 | - * @return map of ip and mac address | ||
170 | - */ | ||
171 | - public Map<IpAddress, MacAddress> publicGateways() { | ||
172 | - JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS); | ||
173 | - if (jsonNodes == null) { | ||
174 | - return Maps.newHashMap(); | ||
175 | - } | ||
176 | - | ||
177 | - Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap(); | ||
178 | - jsonNodes.forEach(jsonNode -> { | ||
179 | - try { | ||
180 | - publicGateways.put( | ||
181 | - IpAddress.valueOf(jsonNode.path(GATEWAY_IP).asText()), | ||
182 | - MacAddress.valueOf(jsonNode.path(GATEWAY_MAC).asText())); | ||
183 | - } catch (IllegalArgumentException | NullPointerException e) { | ||
184 | - log.error("Wrong address format {}", e.toString()); | ||
185 | - } | ||
186 | - }); | ||
187 | - | ||
188 | - return publicGateways; | ||
189 | - } | ||
190 | - | ||
191 | - /** | ||
192 | - * Returns management IP address range. | ||
193 | - * | ||
194 | - * @return management network ip prefix, or null | ||
195 | - */ | ||
196 | - public IpPrefix managementIpRange() { | ||
197 | - JsonNode jsonNode = object.get(MANAGEMENT_IP); | ||
198 | - if (jsonNode == null) { | ||
199 | - return null; | ||
200 | - } | ||
201 | - | ||
202 | - try { | ||
203 | - return IpPrefix.valueOf(jsonNode.asText()); | ||
204 | - } catch (IllegalArgumentException e) { | ||
205 | - log.error("{}:{} wrong address format", MANAGEMENT_IP, jsonNode); | ||
206 | - return null; | ||
207 | - } | ||
208 | - } | ||
209 | - | ||
210 | - /** | ||
211 | - * Returns XOS access information. | ||
212 | - * | ||
213 | - * @return XOS access, or null | ||
214 | - */ | ||
215 | - public XosAccess xosAccess() { | ||
216 | - JsonNode jsonNode = object.get(XOS); | ||
217 | - if (jsonNode == null) { | ||
218 | - return null; | ||
219 | - } | ||
220 | - | ||
221 | - try { | ||
222 | - return new XosAccess(getConfig(jsonNode, ENDPOINT), | ||
223 | - getConfig(jsonNode, USER), | ||
224 | - getConfig(jsonNode, PASSWORD)); | ||
225 | - } catch (NullPointerException e) { | ||
226 | - log.error("Failed to get XOS access"); | ||
227 | - return null; | ||
228 | - } | ||
229 | - } | ||
230 | - | ||
231 | - /** | ||
232 | - * Returns OpenStack API access information. | ||
233 | - * | ||
234 | - * @return openstack access | ||
235 | - */ | ||
236 | - public OpenStackAccess openstackAccess() { | ||
237 | - JsonNode jsonNode = object.get(OPENSTACK); | ||
238 | - if (jsonNode == null) { | ||
239 | - log.error("Failed to get OpenStack configurations"); | ||
240 | - return null; | ||
241 | - } | ||
242 | - | ||
243 | - try { | ||
244 | - return new OpenStackAccess( | ||
245 | - jsonNode.path(ENDPOINT).asText(), | ||
246 | - jsonNode.path(TENANT).asText(), | ||
247 | - jsonNode.path(USER).asText(), | ||
248 | - jsonNode.path(PASSWORD).asText()); | ||
249 | - } catch (IllegalArgumentException | NullPointerException e) { | ||
250 | - log.error("Failed to get OpenStack configurations"); | ||
251 | - return null; | ||
252 | - } | ||
253 | - } | ||
254 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | -import org.onlab.packet.TpPort; | ||
20 | -import org.onosproject.net.DeviceId; | ||
21 | - | ||
22 | -import java.util.Comparator; | ||
23 | -import java.util.Objects; | ||
24 | - | ||
25 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
26 | - | ||
27 | -/** | ||
28 | - * Representation of a compute infrastructure node for CORD VTN service. | ||
29 | - */ | ||
30 | -public final class CordVtnNode { | ||
31 | - | ||
32 | - private final String hostname; | ||
33 | - private final NetworkAddress hostMgmtIp; | ||
34 | - private final NetworkAddress localMgmtIp; | ||
35 | - private final NetworkAddress dpIp; | ||
36 | - private final TpPort ovsdbPort; | ||
37 | - private final SshAccessInfo sshInfo; | ||
38 | - private final DeviceId bridgeId; | ||
39 | - private final String dpIntf; | ||
40 | - private final CordVtnNodeState state; | ||
41 | - | ||
42 | - public static final Comparator<CordVtnNode> CORDVTN_NODE_COMPARATOR = | ||
43 | - (node1, node2) -> node1.hostname().compareTo(node2.hostname()); | ||
44 | - | ||
45 | - /** | ||
46 | - * Creates a new node. | ||
47 | - * | ||
48 | - * @param hostname hostname | ||
49 | - * @param hostMgmtIp host management network address | ||
50 | - * @param localMgmtIp local management network address | ||
51 | - * @param dpIp data plane network address | ||
52 | - * @param ovsdbPort port number for OVSDB connection | ||
53 | - * @param sshInfo SSH access information | ||
54 | - * @param bridgeId integration bridge identifier | ||
55 | - * @param dpIntf data plane interface name | ||
56 | - * @param state cordvtn node state | ||
57 | - */ | ||
58 | - public CordVtnNode(String hostname, NetworkAddress hostMgmtIp, NetworkAddress localMgmtIp, | ||
59 | - NetworkAddress dpIp, TpPort ovsdbPort, SshAccessInfo sshInfo, | ||
60 | - DeviceId bridgeId, String dpIntf, CordVtnNodeState state) { | ||
61 | - this.hostname = checkNotNull(hostname, "hostname cannot be null"); | ||
62 | - this.hostMgmtIp = checkNotNull(hostMgmtIp, "hostMgmtIp cannot be null"); | ||
63 | - this.localMgmtIp = checkNotNull(localMgmtIp, "localMgmtIp cannot be null"); | ||
64 | - this.dpIp = checkNotNull(dpIp, "dpIp cannot be null"); | ||
65 | - this.ovsdbPort = checkNotNull(ovsdbPort, "ovsdbPort cannot be null"); | ||
66 | - this.sshInfo = checkNotNull(sshInfo, "sshInfo cannot be null"); | ||
67 | - this.bridgeId = checkNotNull(bridgeId, "bridgeId cannot be null"); | ||
68 | - this.dpIntf = checkNotNull(dpIntf, "dpIntf cannot be null"); | ||
69 | - this.state = state; | ||
70 | - } | ||
71 | - | ||
72 | - /** | ||
73 | - * Returns cordvtn node with new state. | ||
74 | - * | ||
75 | - * @param node cordvtn node | ||
76 | - * @param state cordvtn node init state | ||
77 | - * @return cordvtn node | ||
78 | - */ | ||
79 | - public static CordVtnNode getUpdatedNode(CordVtnNode node, CordVtnNodeState state) { | ||
80 | - return new CordVtnNode(node.hostname, | ||
81 | - node.hostMgmtIp, node.localMgmtIp, node.dpIp, | ||
82 | - node.ovsdbPort, | ||
83 | - node.sshInfo, | ||
84 | - node.bridgeId, | ||
85 | - node.dpIntf, state); | ||
86 | - } | ||
87 | - | ||
88 | - /** | ||
89 | - * Returns the hostname. | ||
90 | - * | ||
91 | - * @return hostname | ||
92 | - */ | ||
93 | - public String hostname() { | ||
94 | - return this.hostname; | ||
95 | - } | ||
96 | - | ||
97 | - /** | ||
98 | - * Returns the host management network address. | ||
99 | - * | ||
100 | - * @return network address | ||
101 | - */ | ||
102 | - public NetworkAddress hostMgmtIp() { | ||
103 | - return this.hostMgmtIp; | ||
104 | - } | ||
105 | - | ||
106 | - /** | ||
107 | - * Returns the local management network address. | ||
108 | - * | ||
109 | - * @return network address | ||
110 | - */ | ||
111 | - public NetworkAddress localMgmtIp() { | ||
112 | - return this.localMgmtIp; | ||
113 | - } | ||
114 | - | ||
115 | - /** | ||
116 | - * Returns the data plane network address. | ||
117 | - * | ||
118 | - * @return network address | ||
119 | - */ | ||
120 | - public NetworkAddress dpIp() { | ||
121 | - return this.dpIp; | ||
122 | - } | ||
123 | - | ||
124 | - /** | ||
125 | - * Returns the port number used for OVSDB connection. | ||
126 | - * | ||
127 | - * @return port number | ||
128 | - */ | ||
129 | - public TpPort ovsdbPort() { | ||
130 | - return this.ovsdbPort; | ||
131 | - } | ||
132 | - | ||
133 | - /** | ||
134 | - * Returns the SSH access information. | ||
135 | - * | ||
136 | - * @return ssh access information | ||
137 | - */ | ||
138 | - public SshAccessInfo sshInfo() { | ||
139 | - return this.sshInfo; | ||
140 | - } | ||
141 | - | ||
142 | - /** | ||
143 | - * Returns the identifier of the integration bridge. | ||
144 | - * | ||
145 | - * @return device id | ||
146 | - */ | ||
147 | - public DeviceId intBrId() { | ||
148 | - return this.bridgeId; | ||
149 | - } | ||
150 | - | ||
151 | - /** | ||
152 | - * Returns the identifier of the OVSDB device. | ||
153 | - * | ||
154 | - * @return device id | ||
155 | - */ | ||
156 | - public DeviceId ovsdbId() { | ||
157 | - return DeviceId.deviceId("ovsdb:" + this.hostMgmtIp.ip().toString()); | ||
158 | - } | ||
159 | - | ||
160 | - /** | ||
161 | - * Returns data plane interface name. | ||
162 | - * | ||
163 | - * @return data plane interface name | ||
164 | - */ | ||
165 | - public String dpIntf() { | ||
166 | - return this.dpIntf; | ||
167 | - } | ||
168 | - | ||
169 | - /** | ||
170 | - * Returns the state of the node. | ||
171 | - * | ||
172 | - * @return state | ||
173 | - */ | ||
174 | - public CordVtnNodeState state() { | ||
175 | - return this.state; | ||
176 | - } | ||
177 | - | ||
178 | - @Override | ||
179 | - public boolean equals(Object obj) { | ||
180 | - if (this == obj) { | ||
181 | - return true; | ||
182 | - } | ||
183 | - | ||
184 | - if (obj instanceof CordVtnNode) { | ||
185 | - CordVtnNode that = (CordVtnNode) obj; | ||
186 | - if (Objects.equals(hostname, that.hostname) && | ||
187 | - Objects.equals(hostMgmtIp, that.hostMgmtIp) && | ||
188 | - Objects.equals(localMgmtIp, that.localMgmtIp) && | ||
189 | - Objects.equals(dpIp, that.dpIp) && | ||
190 | - Objects.equals(ovsdbPort, that.ovsdbPort) && | ||
191 | - Objects.equals(sshInfo, that.sshInfo) && | ||
192 | - Objects.equals(bridgeId, that.bridgeId) && | ||
193 | - Objects.equals(dpIntf, that.dpIntf)) { | ||
194 | - return true; | ||
195 | - } | ||
196 | - } | ||
197 | - return false; | ||
198 | - } | ||
199 | - | ||
200 | - @Override | ||
201 | - public int hashCode() { | ||
202 | - return Objects.hash(hostname, hostMgmtIp, localMgmtIp, dpIp, | ||
203 | - ovsdbPort, sshInfo, bridgeId, dpIntf); | ||
204 | - } | ||
205 | - | ||
206 | - @Override | ||
207 | - public String toString() { | ||
208 | - return MoreObjects.toStringHelper(getClass()) | ||
209 | - .add("hostname", hostname) | ||
210 | - .add("hostMgmtIp", hostMgmtIp) | ||
211 | - .add("localMgmtIp", localMgmtIp) | ||
212 | - .add("dpIp", dpIp) | ||
213 | - .add("port", ovsdbPort) | ||
214 | - .add("sshInfo", sshInfo) | ||
215 | - .add("bridgeId", bridgeId) | ||
216 | - .add("dpIntf", dpIntf) | ||
217 | - .add("state", state) | ||
218 | - .toString(); | ||
219 | - } | ||
220 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.api; | ||
17 | - | ||
18 | -/** | ||
19 | - * Entity that defines possible init state of the cordvtn node. | ||
20 | - */ | ||
21 | -public interface CordVtnNodeState { | ||
22 | - /** | ||
23 | - * Returns null for no state. | ||
24 | - * | ||
25 | - * @return null | ||
26 | - */ | ||
27 | - static CordVtnNodeState noState() { | ||
28 | - return null; | ||
29 | - } | ||
30 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
19 | - | ||
20 | -/** | ||
21 | - * Service for provisioning overlay virtual networks on compute nodes. | ||
22 | - */ | ||
23 | -public interface CordVtnService { | ||
24 | - | ||
25 | - String CORDVTN_APP_ID = "org.onosproject.cordvtn"; | ||
26 | - | ||
27 | - /** | ||
28 | - * Creates dependencies for a given tenant service. | ||
29 | - * | ||
30 | - * @param tServiceId id of the service which has a dependency | ||
31 | - * @param pServiceId id of the service which provide dependency | ||
32 | - * @param isBidirectional true to enable bidirectional connectivity between two services | ||
33 | - */ | ||
34 | - void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId, | ||
35 | - boolean isBidirectional); | ||
36 | - | ||
37 | - /** | ||
38 | - * Removes all dependencies from a given tenant service. | ||
39 | - * | ||
40 | - * @param tServiceId id of the service which has a dependency | ||
41 | - * @param pServiceId id of the service which provide dependency | ||
42 | - */ | ||
43 | - void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId); | ||
44 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import com.google.common.base.Strings; | ||
19 | -import org.onlab.packet.Ip4Address; | ||
20 | -import org.onlab.packet.MacAddress; | ||
21 | -import org.onosproject.net.DeviceId; | ||
22 | -import org.onosproject.net.Host; | ||
23 | -import org.onosproject.net.PortNumber; | ||
24 | -import org.onosproject.xosclient.api.VtnPortId; | ||
25 | -import org.onosproject.xosclient.api.VtnService; | ||
26 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
27 | - | ||
28 | -import static com.google.common.base.Preconditions.checkArgument; | ||
29 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
30 | - | ||
31 | -/** | ||
32 | - * Provides methods to help to handle network service instance. | ||
33 | - */ | ||
34 | -public final class Instance { | ||
35 | - | ||
36 | - public static final String SERVICE_ID = "serviceId"; | ||
37 | - public static final String SERVICE_TYPE = "serviceType"; | ||
38 | - public static final String PORT_ID = "vtnPortId"; | ||
39 | - public static final String CREATE_TIME = "createTime"; | ||
40 | - public static final String NESTED_INSTANCE = "nestedInstance"; | ||
41 | - public static final String TRUE = "true"; | ||
42 | - | ||
43 | - private final Host host; | ||
44 | - | ||
45 | - /** | ||
46 | - * Default constructor. | ||
47 | - * | ||
48 | - * @param instance host object of this instance | ||
49 | - */ | ||
50 | - private Instance(Host instance) { | ||
51 | - this.host = instance; | ||
52 | - } | ||
53 | - | ||
54 | - /** | ||
55 | - * Returns host object of this instance. | ||
56 | - * | ||
57 | - * @return host | ||
58 | - */ | ||
59 | - public Host host() { | ||
60 | - return this.host; | ||
61 | - } | ||
62 | - | ||
63 | - /** | ||
64 | - * Returns new instance. | ||
65 | - * | ||
66 | - * @param host host object of this instance | ||
67 | - * @return instance | ||
68 | - */ | ||
69 | - public static Instance of(Host host) { | ||
70 | - checkNotNull(host); | ||
71 | - checkArgument(!Strings.isNullOrEmpty(host.annotations().value(SERVICE_ID))); | ||
72 | - checkArgument(!Strings.isNullOrEmpty(host.annotations().value(SERVICE_TYPE))); | ||
73 | - checkArgument(!Strings.isNullOrEmpty(host.annotations().value(PORT_ID))); | ||
74 | - checkArgument(!Strings.isNullOrEmpty(host.annotations().value(CREATE_TIME))); | ||
75 | - | ||
76 | - return new Instance(host); | ||
77 | - } | ||
78 | - | ||
79 | - /** | ||
80 | - * Returns service ID of a given host. | ||
81 | - * | ||
82 | - * @return vtn service id | ||
83 | - */ | ||
84 | - public VtnServiceId serviceId() { | ||
85 | - String serviceId = host.annotations().value(SERVICE_ID); | ||
86 | - return VtnServiceId.of(serviceId); | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * Returns service type of a given host. | ||
91 | - * | ||
92 | - * @return vtn service type | ||
93 | - */ | ||
94 | - public VtnService.ServiceType serviceType() { | ||
95 | - String serviceType = host.annotations().value(SERVICE_TYPE); | ||
96 | - return VtnService.ServiceType.valueOf(serviceType); | ||
97 | - } | ||
98 | - | ||
99 | - /** | ||
100 | - * Returns port ID of a given host. | ||
101 | - * | ||
102 | - * @return vtn port id | ||
103 | - */ | ||
104 | - public VtnPortId portId() { | ||
105 | - String portId = host.annotations().value(PORT_ID); | ||
106 | - return VtnPortId.of(portId); | ||
107 | - } | ||
108 | - | ||
109 | - /** | ||
110 | - * Returns if the instance is nested container or not. | ||
111 | - * | ||
112 | - * @return true if it's nested container; false otherwise | ||
113 | - */ | ||
114 | - public boolean isNestedInstance() { | ||
115 | - return host.annotations().value(NESTED_INSTANCE) != null; | ||
116 | - } | ||
117 | - | ||
118 | - /** | ||
119 | - * Returns MAC address of this instance. | ||
120 | - * | ||
121 | - * @return mac address | ||
122 | - */ | ||
123 | - public MacAddress mac() { | ||
124 | - return host.mac(); | ||
125 | - } | ||
126 | - | ||
127 | - /** | ||
128 | - * Returns IP address of this instance. | ||
129 | - * | ||
130 | - * @return ip address | ||
131 | - */ | ||
132 | - public Ip4Address ipAddress() { | ||
133 | - // assume all instance has only one IP address, and only IP4 is supported now | ||
134 | - return host.ipAddresses().stream().findFirst().get().getIp4Address(); | ||
135 | - } | ||
136 | - | ||
137 | - /** | ||
138 | - * Returns device ID of this host. | ||
139 | - * | ||
140 | - * @return device id | ||
141 | - */ | ||
142 | - public DeviceId deviceId() { | ||
143 | - return host.location().deviceId(); | ||
144 | - } | ||
145 | - | ||
146 | - /** | ||
147 | - * Returns the port number where this host is. | ||
148 | - * | ||
149 | - * @return port number | ||
150 | - */ | ||
151 | - public PortNumber portNumber() { | ||
152 | - return host.location().port(); | ||
153 | - } | ||
154 | - | ||
155 | - /** | ||
156 | - * Returns annotation value with a given key. | ||
157 | - * | ||
158 | - * @param annotationKey annotation key | ||
159 | - * @return annotation value | ||
160 | - */ | ||
161 | - public String getAnnotation(String annotationKey) { | ||
162 | - return host.annotations().value(annotationKey); | ||
163 | - } | ||
164 | - | ||
165 | - @Override | ||
166 | - public String toString() { | ||
167 | - return host.toString(); | ||
168 | - } | ||
169 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.api; | ||
17 | - | ||
18 | -/** | ||
19 | - * Handles service instance detection and removal. | ||
20 | - */ | ||
21 | -public interface InstanceHandler { | ||
22 | - | ||
23 | - /** | ||
24 | - * Handles newly detected instance. | ||
25 | - * | ||
26 | - * @param instance instance | ||
27 | - */ | ||
28 | - void instanceDetected(Instance instance); | ||
29 | - | ||
30 | - /** | ||
31 | - * Handles removed instance. | ||
32 | - * | ||
33 | - * @param instance instance | ||
34 | - */ | ||
35 | - void instanceRemoved(Instance instance); | ||
36 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | -import org.onlab.packet.IpAddress; | ||
20 | -import org.onlab.packet.IpPrefix; | ||
21 | - | ||
22 | -import java.util.Objects; | ||
23 | - | ||
24 | -import static com.google.common.base.Preconditions.checkArgument; | ||
25 | - | ||
26 | -/** | ||
27 | - * Representation of a network address, which consists of IP address and prefix. | ||
28 | - */ | ||
29 | -public final class NetworkAddress { | ||
30 | - private final IpAddress ip; | ||
31 | - private final IpPrefix prefix; | ||
32 | - | ||
33 | - /** | ||
34 | - * Constructor for a given IP address and prefix. | ||
35 | - * | ||
36 | - * @param ip ip address | ||
37 | - * @param prefix ip prefix | ||
38 | - */ | ||
39 | - public NetworkAddress(IpAddress ip, IpPrefix prefix) { | ||
40 | - this.ip = ip; | ||
41 | - this.prefix = prefix; | ||
42 | - } | ||
43 | - | ||
44 | - /** | ||
45 | - * Converts a CIDR notation string into a network address. | ||
46 | - * | ||
47 | - * @param cidr cidr | ||
48 | - * @return network address | ||
49 | - * @throws IllegalArgumentException if the cidr is not valid | ||
50 | - */ | ||
51 | - public static NetworkAddress valueOf(String cidr) { | ||
52 | - checkArgument(cidr.contains("/")); | ||
53 | - | ||
54 | - IpAddress ipAddress = IpAddress.valueOf(cidr.split("/")[0]); | ||
55 | - IpPrefix ipPrefix = IpPrefix.valueOf(cidr); | ||
56 | - | ||
57 | - return new NetworkAddress(ipAddress, ipPrefix); | ||
58 | - } | ||
59 | - | ||
60 | - /** | ||
61 | - * Returns the IP address value of the network address. | ||
62 | - * | ||
63 | - * @return ip address | ||
64 | - */ | ||
65 | - public IpAddress ip() { | ||
66 | - return this.ip; | ||
67 | - } | ||
68 | - | ||
69 | - /** | ||
70 | - * Returns the IP prefix value of the network address. | ||
71 | - * | ||
72 | - * @return ip prefix | ||
73 | - */ | ||
74 | - public IpPrefix prefix() { | ||
75 | - return this.prefix; | ||
76 | - } | ||
77 | - | ||
78 | - /** | ||
79 | - * Converts a network address to a CIDR notation. | ||
80 | - * | ||
81 | - * @return cidr notation string | ||
82 | - */ | ||
83 | - public String cidr() { | ||
84 | - return ip.toString() + "/" + prefix.prefixLength(); | ||
85 | - } | ||
86 | - | ||
87 | - @Override | ||
88 | - public boolean equals(Object obj) { | ||
89 | - if (this == obj) { | ||
90 | - return true; | ||
91 | - } | ||
92 | - | ||
93 | - if (obj instanceof NetworkAddress) { | ||
94 | - NetworkAddress that = (NetworkAddress) obj; | ||
95 | - if (Objects.equals(ip, that.ip) && Objects.equals(prefix, that.prefix)) { | ||
96 | - return true; | ||
97 | - } | ||
98 | - } | ||
99 | - return false; | ||
100 | - } | ||
101 | - | ||
102 | - @Override | ||
103 | - public int hashCode() { | ||
104 | - return Objects.hash(ip, prefix); | ||
105 | - } | ||
106 | - | ||
107 | - @Override | ||
108 | - public String toString() { | ||
109 | - return MoreObjects.toStringHelper(getClass()) | ||
110 | - .add("IpAddress", ip) | ||
111 | - .add("IpPrefix", prefix) | ||
112 | - .toString(); | ||
113 | - } | ||
114 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.api; | ||
17 | - | ||
18 | -import com.google.common.base.MoreObjects; | ||
19 | -import org.onlab.packet.Ip4Address; | ||
20 | -import org.onlab.packet.TpPort; | ||
21 | - | ||
22 | -import java.util.Objects; | ||
23 | - | ||
24 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
25 | - | ||
26 | -/** | ||
27 | - * Representation of SSH access information. | ||
28 | - */ | ||
29 | -public final class SshAccessInfo { | ||
30 | - | ||
31 | - private final Ip4Address remoteIp; | ||
32 | - private final TpPort port; | ||
33 | - private final String user; | ||
34 | - private final String privateKey; | ||
35 | - | ||
36 | - /** | ||
37 | - * Creates a new SSH access information. | ||
38 | - * | ||
39 | - * @param remoteIp ssh remote ip address | ||
40 | - * @param port ssh port number | ||
41 | - * @param user user name | ||
42 | - * @param privateKey path of ssh private key | ||
43 | - */ | ||
44 | - public SshAccessInfo(Ip4Address remoteIp, TpPort port, String user, String privateKey) { | ||
45 | - this.remoteIp = checkNotNull(remoteIp); | ||
46 | - this.port = checkNotNull(port); | ||
47 | - this.user = checkNotNull(user); | ||
48 | - this.privateKey = checkNotNull(privateKey); | ||
49 | - } | ||
50 | - | ||
51 | - /** | ||
52 | - * Returns the remote IP address. | ||
53 | - * | ||
54 | - * @return ip address | ||
55 | - */ | ||
56 | - public Ip4Address remoteIp() { | ||
57 | - return this.remoteIp; | ||
58 | - } | ||
59 | - | ||
60 | - /** | ||
61 | - * Returns the port number. | ||
62 | - * | ||
63 | - * @return ssh port | ||
64 | - */ | ||
65 | - public TpPort port() { | ||
66 | - return this.port; | ||
67 | - } | ||
68 | - | ||
69 | - /** | ||
70 | - * Returns the user name. | ||
71 | - * | ||
72 | - * @return user name | ||
73 | - */ | ||
74 | - public String user() { | ||
75 | - return this.user; | ||
76 | - } | ||
77 | - | ||
78 | - /** | ||
79 | - * Returns the private key path. | ||
80 | - * | ||
81 | - * @return privateKey | ||
82 | - */ | ||
83 | - public String privateKey() { | ||
84 | - return privateKey; | ||
85 | - } | ||
86 | - | ||
87 | - @Override | ||
88 | - public boolean equals(Object obj) { | ||
89 | - if (this == obj) { | ||
90 | - return true; | ||
91 | - } | ||
92 | - | ||
93 | - if (obj instanceof SshAccessInfo) { | ||
94 | - SshAccessInfo that = (SshAccessInfo) obj; | ||
95 | - if (Objects.equals(remoteIp, that.remoteIp) && | ||
96 | - Objects.equals(port, that.port) && | ||
97 | - Objects.equals(user, that.user) && | ||
98 | - Objects.equals(privateKey, that.privateKey)) { | ||
99 | - return true; | ||
100 | - } | ||
101 | - } | ||
102 | - return false; | ||
103 | - } | ||
104 | - | ||
105 | - @Override | ||
106 | - public int hashCode() { | ||
107 | - return Objects.hash(remoteIp, port, user, privateKey); | ||
108 | - } | ||
109 | - | ||
110 | - @Override | ||
111 | - public String toString() { | ||
112 | - return MoreObjects.toStringHelper(getClass()) | ||
113 | - .add("remoteIp", remoteIp) | ||
114 | - .add("port", port) | ||
115 | - .add("user", user) | ||
116 | - .add("privateKey", privateKey) | ||
117 | - .toString(); | ||
118 | - } | ||
119 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * API for CORD VTN application. | ||
19 | - */ | ||
20 | -package org.onosproject.cordvtn.api; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Command; | ||
20 | -import org.onosproject.cli.AbstractShellCommand; | ||
21 | -import org.onosproject.cordvtn.impl.CordVtnPipeline; | ||
22 | - | ||
23 | -/** | ||
24 | - * Deletes nodes from the service. | ||
25 | - */ | ||
26 | -@Command(scope = "onos", name = "cordvtn-flush-rules", | ||
27 | - description = "Flush flow rules installed by CORD VTN") | ||
28 | -public class CordVtnFlushRules extends AbstractShellCommand { | ||
29 | - | ||
30 | - @Override | ||
31 | - protected void execute() { | ||
32 | - CordVtnPipeline pipeline = AbstractShellCommand.get(CordVtnPipeline.class); | ||
33 | - pipeline.flushRules(); | ||
34 | - print("Successfully flushed"); | ||
35 | - } | ||
36 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeCheckCommand.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
23 | -import org.onosproject.cordvtn.impl.CordVtnNodeManager; | ||
24 | -import org.onosproject.net.Device; | ||
25 | -import org.onosproject.net.device.DeviceService; | ||
26 | -import org.onosproject.net.driver.DriverService; | ||
27 | - | ||
28 | -/** | ||
29 | - * Checks detailed node init state. | ||
30 | - */ | ||
31 | -@Command(scope = "onos", name = "cordvtn-node-check", | ||
32 | - description = "Shows detailed node init state") | ||
33 | -public class CordVtnNodeCheckCommand extends AbstractShellCommand { | ||
34 | - | ||
35 | - @Argument(index = 0, name = "hostname", description = "Hostname", | ||
36 | - required = true, multiValued = false) | ||
37 | - private String hostname = null; | ||
38 | - | ||
39 | - @Override | ||
40 | - protected void execute() { | ||
41 | - CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class); | ||
42 | - DeviceService deviceService = AbstractShellCommand.get(DeviceService.class); | ||
43 | - | ||
44 | - CordVtnNode node = nodeManager.getNodes() | ||
45 | - .stream() | ||
46 | - .filter(n -> n.hostname().equals(hostname)) | ||
47 | - .findFirst() | ||
48 | - .orElse(null); | ||
49 | - | ||
50 | - if (node == null) { | ||
51 | - print("Cannot find %s from registered nodes", hostname); | ||
52 | - return; | ||
53 | - } | ||
54 | - | ||
55 | - print(nodeManager.checkNodeInitState(node)); | ||
56 | - | ||
57 | - print("%n[DEBUG]"); | ||
58 | - Device device = deviceService.getDevice(node.intBrId()); | ||
59 | - String driver = get(DriverService.class).getDriver(device.id()).name(); | ||
60 | - print("%s available=%s driver=%s %s", | ||
61 | - device.id(), | ||
62 | - deviceService.isAvailable(device.id()), | ||
63 | - driver, | ||
64 | - device.annotations()); | ||
65 | - | ||
66 | - deviceService.getPorts(node.intBrId()).forEach(port -> { | ||
67 | - Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled"; | ||
68 | - print("port=%s state=%s %s", | ||
69 | - port.number(), | ||
70 | - portIsEnabled, | ||
71 | - port.annotations()); | ||
72 | - }); | ||
73 | - } | ||
74 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.cordvtn.impl.CordVtnNodeManager; | ||
23 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
24 | - | ||
25 | -import java.util.NoSuchElementException; | ||
26 | - | ||
27 | -/** | ||
28 | - * Deletes nodes from the service. | ||
29 | - */ | ||
30 | -@Command(scope = "onos", name = "cordvtn-node-delete", | ||
31 | - description = "Deletes nodes from CORD VTN service") | ||
32 | -public class CordVtnNodeDeleteCommand extends AbstractShellCommand { | ||
33 | - | ||
34 | - @Argument(index = 0, name = "hostnames", description = "Hostname(s)", | ||
35 | - required = true, multiValued = true) | ||
36 | - private String[] hostnames = null; | ||
37 | - | ||
38 | - @Override | ||
39 | - protected void execute() { | ||
40 | - CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class); | ||
41 | - | ||
42 | - for (String hostname : hostnames) { | ||
43 | - CordVtnNode node; | ||
44 | - try { | ||
45 | - node = nodeManager.getNodes() | ||
46 | - .stream() | ||
47 | - .filter(n -> n.hostname().equals(hostname)) | ||
48 | - .findFirst().get(); | ||
49 | - } catch (NoSuchElementException e) { | ||
50 | - print("Unable to find %s", hostname); | ||
51 | - continue; | ||
52 | - } | ||
53 | - | ||
54 | - nodeManager.deleteNode(node); | ||
55 | - } | ||
56 | - } | ||
57 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.cordvtn.impl.CordVtnNodeManager; | ||
23 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
24 | - | ||
25 | -import java.util.NoSuchElementException; | ||
26 | - | ||
27 | -/** | ||
28 | - * Initializes nodes for CordVtn service. | ||
29 | - */ | ||
30 | -@Command(scope = "onos", name = "cordvtn-node-init", | ||
31 | - description = "Initializes nodes for CORD VTN service") | ||
32 | -public class CordVtnNodeInitCommand extends AbstractShellCommand { | ||
33 | - | ||
34 | - @Argument(index = 0, name = "hostnames", description = "Hostname(s)", | ||
35 | - required = true, multiValued = true) | ||
36 | - private String[] hostnames = null; | ||
37 | - | ||
38 | - @Override | ||
39 | - protected void execute() { | ||
40 | - CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class); | ||
41 | - | ||
42 | - for (String hostname : hostnames) { | ||
43 | - CordVtnNode node; | ||
44 | - try { | ||
45 | - node = nodeManager.getNodes() | ||
46 | - .stream() | ||
47 | - .filter(n -> n.hostname().equals(hostname)) | ||
48 | - .findFirst().get(); | ||
49 | - } catch (NoSuchElementException e) { | ||
50 | - print("Unable to find %s", hostname); | ||
51 | - continue; | ||
52 | - } | ||
53 | - | ||
54 | - nodeManager.addOrUpdateNode(node); | ||
55 | - } | ||
56 | - } | ||
57 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.cli; | ||
18 | - | ||
19 | -import com.fasterxml.jackson.databind.JsonNode; | ||
20 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
21 | -import com.fasterxml.jackson.databind.node.ArrayNode; | ||
22 | -import org.apache.karaf.shell.commands.Command; | ||
23 | -import org.onosproject.cli.AbstractShellCommand; | ||
24 | -import org.onosproject.cordvtn.impl.CordVtnNodeManager; | ||
25 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
26 | - | ||
27 | -import java.util.Collections; | ||
28 | -import java.util.List; | ||
29 | - | ||
30 | -/** | ||
31 | - * Lists all nodes registered to the service. | ||
32 | - */ | ||
33 | -@Command(scope = "onos", name = "cordvtn-nodes", | ||
34 | - description = "Lists all nodes registered in CORD VTN service") | ||
35 | -public class CordVtnNodeListCommand extends AbstractShellCommand { | ||
36 | - | ||
37 | - private static final String COMPLETE = "COMPLETE"; | ||
38 | - private static final String INCOMPLETE = "INCOMPLETE"; | ||
39 | - | ||
40 | - @Override | ||
41 | - protected void execute() { | ||
42 | - CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class); | ||
43 | - List<CordVtnNode> nodes = nodeManager.getNodes(); | ||
44 | - Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR); | ||
45 | - | ||
46 | - if (outputJson()) { | ||
47 | - print("%s", json(nodeManager, nodes)); | ||
48 | - } else { | ||
49 | - for (CordVtnNode node : nodes) { | ||
50 | - print("hostname=%s, hostMgmtIp=%s, dpIp=%s, br-int=%s, dpIntf=%s, init=%s", | ||
51 | - node.hostname(), | ||
52 | - node.hostMgmtIp().cidr(), | ||
53 | - node.dpIp().cidr(), | ||
54 | - node.intBrId().toString(), | ||
55 | - node.dpIntf(), | ||
56 | - getState(nodeManager, node)); | ||
57 | - } | ||
58 | - print("Total %s nodes", nodeManager.getNodeCount()); | ||
59 | - } | ||
60 | - } | ||
61 | - | ||
62 | - private JsonNode json(CordVtnNodeManager nodeManager, List<CordVtnNode> nodes) { | ||
63 | - ObjectMapper mapper = new ObjectMapper(); | ||
64 | - ArrayNode result = mapper.createArrayNode(); | ||
65 | - for (CordVtnNode node : nodes) { | ||
66 | - result.add(mapper.createObjectNode() | ||
67 | - .put("hostname", node.hostname()) | ||
68 | - .put("hostManagementIp", node.hostMgmtIp().cidr()) | ||
69 | - .put("dataPlaneIp", node.dpIp().cidr()) | ||
70 | - .put("bridgeId", node.intBrId().toString()) | ||
71 | - .put("dataPlaneInterface", node.dpIntf()) | ||
72 | - .put("init", getState(nodeManager, node))); | ||
73 | - } | ||
74 | - return result; | ||
75 | - } | ||
76 | - | ||
77 | - private String getState(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
78 | - return nodeManager.isNodeInitComplete(node) ? COMPLETE : INCOMPLETE; | ||
79 | - } | ||
80 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -/** | ||
18 | - * Console commands to manage OVSDB nodes for cordvtn. | ||
19 | - */ | ||
20 | -package org.onosproject.cordvtn.cli; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Lists; | ||
19 | -import com.google.common.collect.Maps; | ||
20 | -import com.google.common.collect.Sets; | ||
21 | -import org.apache.felix.scr.annotations.Activate; | ||
22 | -import org.apache.felix.scr.annotations.Component; | ||
23 | -import org.apache.felix.scr.annotations.Deactivate; | ||
24 | -import org.apache.felix.scr.annotations.Reference; | ||
25 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
26 | -import org.apache.felix.scr.annotations.Service; | ||
27 | -import org.onlab.packet.Ethernet; | ||
28 | -import org.onlab.packet.Ip4Address; | ||
29 | -import org.onlab.packet.Ip4Prefix; | ||
30 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
31 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
32 | -import org.onosproject.cordvtn.api.Instance; | ||
33 | -import org.onosproject.core.DefaultGroupId; | ||
34 | -import org.onosproject.core.GroupId; | ||
35 | -import org.onosproject.net.DeviceId; | ||
36 | -import org.onosproject.net.Host; | ||
37 | -import org.onosproject.net.PortNumber; | ||
38 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
39 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
40 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
41 | -import org.onosproject.net.flow.FlowRule; | ||
42 | -import org.onosproject.net.flow.TrafficSelector; | ||
43 | -import org.onosproject.net.flow.TrafficTreatment; | ||
44 | -import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
45 | -import org.onosproject.net.group.DefaultGroupDescription; | ||
46 | -import org.onosproject.net.group.DefaultGroupKey; | ||
47 | -import org.onosproject.net.group.Group; | ||
48 | -import org.onosproject.net.group.GroupBucket; | ||
49 | -import org.onosproject.net.group.GroupBuckets; | ||
50 | -import org.onosproject.net.group.GroupDescription; | ||
51 | -import org.onosproject.net.group.GroupKey; | ||
52 | -import org.onosproject.net.group.GroupService; | ||
53 | -import org.onosproject.net.host.HostEvent; | ||
54 | -import org.onosproject.net.host.HostListener; | ||
55 | -import org.onosproject.xosclient.api.VtnService; | ||
56 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
57 | -import org.slf4j.Logger; | ||
58 | - | ||
59 | -import java.util.List; | ||
60 | -import java.util.Map; | ||
61 | -import java.util.Objects; | ||
62 | -import java.util.Set; | ||
63 | -import java.util.stream.Collectors; | ||
64 | - | ||
65 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
66 | -import static org.onlab.util.Tools.groupedThreads; | ||
67 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.*; | ||
68 | -import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket; | ||
69 | -import static org.slf4j.LoggerFactory.getLogger; | ||
70 | - | ||
71 | -/** | ||
72 | - * Provisions service dependency capabilities between network services. | ||
73 | - */ | ||
74 | -@Component(immediate = true) | ||
75 | -@Service | ||
76 | -public class CordVtn extends CordVtnInstanceHandler implements CordVtnService { | ||
77 | - | ||
78 | - protected final Logger log = getLogger(getClass()); | ||
79 | - | ||
80 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
81 | - protected GroupService groupService; | ||
82 | - | ||
83 | - @Activate | ||
84 | - protected void activate() { | ||
85 | - eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "event-handler")); | ||
86 | - hostListener = new InternalHostListener(); | ||
87 | - super.activate(); | ||
88 | - } | ||
89 | - | ||
90 | - @Deactivate | ||
91 | - protected void deactivate() { | ||
92 | - super.deactivate(); | ||
93 | - } | ||
94 | - | ||
95 | - @Override | ||
96 | - public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId, | ||
97 | - boolean isBidirectional) { | ||
98 | - VtnService tService = getVtnService(tServiceId); | ||
99 | - VtnService pService = getVtnService(pServiceId); | ||
100 | - | ||
101 | - if (tService == null || pService == null) { | ||
102 | - log.error("Failed to create dependency between {} and {}", | ||
103 | - tServiceId, pServiceId); | ||
104 | - return; | ||
105 | - } | ||
106 | - | ||
107 | - log.info("Created dependency between {} and {}", tService.name(), pService.name()); | ||
108 | - serviceDependencyRules(tService, pService, isBidirectional, true); | ||
109 | - } | ||
110 | - | ||
111 | - @Override | ||
112 | - public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) { | ||
113 | - VtnService tService = getVtnService(tServiceId); | ||
114 | - VtnService pService = getVtnService(pServiceId); | ||
115 | - | ||
116 | - if (tService == null || pService == null) { | ||
117 | - log.error("Failed to remove dependency between {} and {}", | ||
118 | - tServiceId, pServiceId); | ||
119 | - return; | ||
120 | - } | ||
121 | - | ||
122 | - log.info("Removed dependency between {} and {}", tService.name(), pService.name()); | ||
123 | - serviceDependencyRules(tService, pService, true, false); | ||
124 | - } | ||
125 | - | ||
126 | - @Override | ||
127 | - public void instanceDetected(Instance instance) { | ||
128 | - VtnService service = getVtnService(instance.serviceId()); | ||
129 | - if (service == null) { | ||
130 | - return; | ||
131 | - } | ||
132 | - | ||
133 | - // TODO get bidirectional information from XOS once XOS supports | ||
134 | - service.tenantServices().stream().forEach( | ||
135 | - tServiceId -> createServiceDependency(tServiceId, service.id(), true)); | ||
136 | - service.providerServices().stream().forEach( | ||
137 | - pServiceId -> createServiceDependency(service.id(), pServiceId, true)); | ||
138 | - | ||
139 | - updateProviderServiceInstances(service); | ||
140 | - } | ||
141 | - | ||
142 | - @Override | ||
143 | - public void instanceRemoved(Instance instance) { | ||
144 | - VtnService service = getVtnService(instance.serviceId()); | ||
145 | - if (service == null) { | ||
146 | - return; | ||
147 | - } | ||
148 | - | ||
149 | - if (!service.providerServices().isEmpty()) { | ||
150 | - removeInstanceFromTenantService(instance, service); | ||
151 | - } | ||
152 | - if (!service.tenantServices().isEmpty()) { | ||
153 | - updateProviderServiceInstances(service); | ||
154 | - } | ||
155 | - } | ||
156 | - | ||
157 | - private void updateProviderServiceInstances(VtnService service) { | ||
158 | - GroupKey groupKey = getGroupKey(service.id()); | ||
159 | - | ||
160 | - Set<DeviceId> devices = nodeManager.completeNodes().stream() | ||
161 | - .map(CordVtnNode::intBrId) | ||
162 | - .collect(Collectors.toSet()); | ||
163 | - | ||
164 | - for (DeviceId deviceId : devices) { | ||
165 | - Group group = groupService.getGroup(deviceId, groupKey); | ||
166 | - if (group == null) { | ||
167 | - log.trace("No group exists for service {} in {}", service.id(), deviceId); | ||
168 | - continue; | ||
169 | - } | ||
170 | - | ||
171 | - List<GroupBucket> oldBuckets = group.buckets().buckets(); | ||
172 | - List<GroupBucket> newBuckets = getServiceGroupBuckets( | ||
173 | - deviceId, service.vni(), getInstances(service.id())).buckets(); | ||
174 | - | ||
175 | - if (oldBuckets.equals(newBuckets)) { | ||
176 | - continue; | ||
177 | - } | ||
178 | - | ||
179 | - List<GroupBucket> bucketsToRemove = Lists.newArrayList(oldBuckets); | ||
180 | - bucketsToRemove.removeAll(newBuckets); | ||
181 | - if (!bucketsToRemove.isEmpty()) { | ||
182 | - groupService.removeBucketsFromGroup( | ||
183 | - deviceId, | ||
184 | - groupKey, | ||
185 | - new GroupBuckets(bucketsToRemove), | ||
186 | - groupKey, appId); | ||
187 | - } | ||
188 | - | ||
189 | - List<GroupBucket> bucketsToAdd = Lists.newArrayList(newBuckets); | ||
190 | - bucketsToAdd.removeAll(oldBuckets); | ||
191 | - if (!bucketsToAdd.isEmpty()) { | ||
192 | - groupService.addBucketsToGroup( | ||
193 | - deviceId, | ||
194 | - groupKey, | ||
195 | - new GroupBuckets(bucketsToAdd), | ||
196 | - groupKey, appId); | ||
197 | - } | ||
198 | - } | ||
199 | - } | ||
200 | - | ||
201 | - private void removeInstanceFromTenantService(Instance instance, VtnService service) { | ||
202 | - service.providerServices().stream().forEach(pServiceId -> { | ||
203 | - Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap(); | ||
204 | - Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); | ||
205 | - | ||
206 | - inPorts.put(instance.deviceId(), Sets.newHashSet(instance.portNumber())); | ||
207 | - outGroups.put(instance.deviceId(), getGroupId(pServiceId, instance.deviceId())); | ||
208 | - | ||
209 | - inServiceRule(inPorts, outGroups, false); | ||
210 | - }); | ||
211 | - } | ||
212 | - | ||
213 | - private void serviceDependencyRules(VtnService tService, VtnService pService, | ||
214 | - boolean isBidirectional, boolean install) { | ||
215 | - Map<DeviceId, GroupId> outGroups = Maps.newHashMap(); | ||
216 | - Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap(); | ||
217 | - | ||
218 | - nodeManager.completeNodes().stream().forEach(node -> { | ||
219 | - DeviceId deviceId = node.intBrId(); | ||
220 | - GroupId groupId = createServiceGroup(deviceId, pService); | ||
221 | - outGroups.put(deviceId, groupId); | ||
222 | - | ||
223 | - Set<PortNumber> tServiceInstances = getInstances(tService.id()) | ||
224 | - .stream() | ||
225 | - .filter(instance -> instance.deviceId().equals(deviceId)) | ||
226 | - .map(Instance::portNumber) | ||
227 | - .collect(Collectors.toSet()); | ||
228 | - inPorts.put(deviceId, tServiceInstances); | ||
229 | - }); | ||
230 | - | ||
231 | - Ip4Prefix srcRange = tService.subnet().getIp4Prefix(); | ||
232 | - Ip4Prefix dstRange = pService.subnet().getIp4Prefix(); | ||
233 | - | ||
234 | - indirectAccessRule(srcRange, pService.serviceIp().getIp4Address(), outGroups, install); | ||
235 | - directAccessRule(srcRange, dstRange, install); | ||
236 | - if (isBidirectional) { | ||
237 | - directAccessRule(dstRange, srcRange, install); | ||
238 | - } | ||
239 | - inServiceRule(inPorts, outGroups, install); | ||
240 | - } | ||
241 | - | ||
242 | - private void indirectAccessRule(Ip4Prefix srcRange, Ip4Address serviceIp, | ||
243 | - Map<DeviceId, GroupId> outGroups, boolean install) { | ||
244 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
245 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
246 | - .matchIPSrc(srcRange) | ||
247 | - .matchIPDst(serviceIp.toIpPrefix()) | ||
248 | - .build(); | ||
249 | - | ||
250 | - for (Map.Entry<DeviceId, GroupId> outGroup : outGroups.entrySet()) { | ||
251 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
252 | - .group(outGroup.getValue()) | ||
253 | - .build(); | ||
254 | - | ||
255 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
256 | - .fromApp(appId) | ||
257 | - .withSelector(selector) | ||
258 | - .withTreatment(treatment) | ||
259 | - .withPriority(PRIORITY_HIGH) | ||
260 | - .forDevice(outGroup.getKey()) | ||
261 | - .forTable(TABLE_ACCESS_TYPE) | ||
262 | - .makePermanent() | ||
263 | - .build(); | ||
264 | - | ||
265 | - pipeline.processFlowRule(install, flowRule); | ||
266 | - } | ||
267 | - } | ||
268 | - | ||
269 | - private void directAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) { | ||
270 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
271 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
272 | - .matchIPSrc(srcRange) | ||
273 | - .matchIPDst(dstRange) | ||
274 | - .build(); | ||
275 | - | ||
276 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
277 | - .transition(TABLE_DST_IP) | ||
278 | - .build(); | ||
279 | - | ||
280 | - nodeManager.completeNodes().stream().forEach(node -> { | ||
281 | - DeviceId deviceId = node.intBrId(); | ||
282 | - FlowRule flowRuleDirect = DefaultFlowRule.builder() | ||
283 | - .fromApp(appId) | ||
284 | - .withSelector(selector) | ||
285 | - .withTreatment(treatment) | ||
286 | - .withPriority(PRIORITY_DEFAULT) | ||
287 | - .forDevice(deviceId) | ||
288 | - .forTable(TABLE_ACCESS_TYPE) | ||
289 | - .makePermanent() | ||
290 | - .build(); | ||
291 | - | ||
292 | - pipeline.processFlowRule(install, flowRuleDirect); | ||
293 | - }); | ||
294 | - } | ||
295 | - | ||
296 | - private void inServiceRule(Map<DeviceId, Set<PortNumber>> inPorts, | ||
297 | - Map<DeviceId, GroupId> outGroups, boolean install) { | ||
298 | - for (Map.Entry<DeviceId, Set<PortNumber>> entry : inPorts.entrySet()) { | ||
299 | - Set<PortNumber> ports = entry.getValue(); | ||
300 | - DeviceId deviceId = entry.getKey(); | ||
301 | - | ||
302 | - GroupId groupId = outGroups.get(deviceId); | ||
303 | - if (groupId == null) { | ||
304 | - continue; | ||
305 | - } | ||
306 | - | ||
307 | - ports.stream().forEach(port -> { | ||
308 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
309 | - .matchInPort(port) | ||
310 | - .build(); | ||
311 | - | ||
312 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
313 | - .group(groupId) | ||
314 | - .build(); | ||
315 | - | ||
316 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
317 | - .fromApp(appId) | ||
318 | - .withSelector(selector) | ||
319 | - .withTreatment(treatment) | ||
320 | - .withPriority(PRIORITY_DEFAULT) | ||
321 | - .forDevice(deviceId) | ||
322 | - .forTable(TABLE_IN_SERVICE) | ||
323 | - .makePermanent() | ||
324 | - .build(); | ||
325 | - | ||
326 | - pipeline.processFlowRule(install, flowRule); | ||
327 | - }); | ||
328 | - } | ||
329 | - } | ||
330 | - | ||
331 | - private GroupId getGroupId(VtnServiceId serviceId, DeviceId deviceId) { | ||
332 | - return new DefaultGroupId(Objects.hash(serviceId, deviceId)); | ||
333 | - } | ||
334 | - | ||
335 | - private GroupKey getGroupKey(VtnServiceId serviceId) { | ||
336 | - return new DefaultGroupKey(serviceId.id().getBytes()); | ||
337 | - } | ||
338 | - | ||
339 | - private GroupId createServiceGroup(DeviceId deviceId, VtnService service) { | ||
340 | - GroupKey groupKey = getGroupKey(service.id()); | ||
341 | - Group group = groupService.getGroup(deviceId, groupKey); | ||
342 | - GroupId groupId = getGroupId(service.id(), deviceId); | ||
343 | - | ||
344 | - if (group != null) { | ||
345 | - log.debug("Group {} is already exist in {}", service.id(), deviceId); | ||
346 | - return groupId; | ||
347 | - } | ||
348 | - | ||
349 | - GroupBuckets buckets = getServiceGroupBuckets( | ||
350 | - deviceId, service.vni(), getInstances(service.id())); | ||
351 | - GroupDescription groupDescription = new DefaultGroupDescription( | ||
352 | - deviceId, | ||
353 | - GroupDescription.Type.SELECT, | ||
354 | - buckets, | ||
355 | - groupKey, | ||
356 | - groupId.id(), | ||
357 | - appId); | ||
358 | - | ||
359 | - groupService.addGroup(groupDescription); | ||
360 | - return groupId; | ||
361 | - } | ||
362 | - | ||
363 | - private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId, | ||
364 | - Set<Instance> instances) { | ||
365 | - List<GroupBucket> buckets = Lists.newArrayList(); | ||
366 | - instances.stream().forEach(instance -> { | ||
367 | - Ip4Address tunnelIp = nodeManager.dpIp(instance.deviceId()).getIp4Address(); | ||
368 | - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
369 | - | ||
370 | - if (deviceId.equals(instance.deviceId())) { | ||
371 | - tBuilder.setEthDst(instance.mac()) | ||
372 | - .setOutput(instance.portNumber()); | ||
373 | - } else { | ||
374 | - ExtensionTreatment tunnelDst = | ||
375 | - pipeline.tunnelDstTreatment(deviceId, tunnelIp); | ||
376 | - tBuilder.setEthDst(instance.mac()) | ||
377 | - .extension(tunnelDst, deviceId) | ||
378 | - .setTunnelId(tunnelId) | ||
379 | - .setOutput(nodeManager.tunnelPort(instance.deviceId())); | ||
380 | - } | ||
381 | - buckets.add(createSelectGroupBucket(tBuilder.build())); | ||
382 | - }); | ||
383 | - return new GroupBuckets(buckets); | ||
384 | - } | ||
385 | - | ||
386 | - private class InternalHostListener implements HostListener { | ||
387 | - | ||
388 | - @Override | ||
389 | - public void event(HostEvent event) { | ||
390 | - Host host = event.subject(); | ||
391 | - if (!mastershipService.isLocalMaster(host.location().deviceId())) { | ||
392 | - // do not allow to proceed without mastership | ||
393 | - return; | ||
394 | - } | ||
395 | - | ||
396 | - Instance instance = Instance.of(host); | ||
397 | - switch (event.type()) { | ||
398 | - case HOST_UPDATED: | ||
399 | - case HOST_ADDED: | ||
400 | - eventExecutor.execute(() -> instanceDetected(instance)); | ||
401 | - break; | ||
402 | - case HOST_REMOVED: | ||
403 | - eventExecutor.execute(() -> instanceRemoved(instance)); | ||
404 | - break; | ||
405 | - default: | ||
406 | - break; | ||
407 | - } | ||
408 | - } | ||
409 | - } | ||
410 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Maps; | ||
19 | -import org.onlab.packet.ARP; | ||
20 | -import org.onlab.packet.EthType; | ||
21 | -import org.onlab.packet.Ethernet; | ||
22 | -import org.onlab.packet.Ip4Address; | ||
23 | -import org.onlab.packet.IpAddress; | ||
24 | -import org.onlab.packet.MacAddress; | ||
25 | -import org.onosproject.cordvtn.api.Instance; | ||
26 | -import org.onosproject.core.ApplicationId; | ||
27 | -import org.onosproject.net.Host; | ||
28 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
29 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
30 | -import org.onosproject.net.flow.TrafficSelector; | ||
31 | -import org.onosproject.net.flow.TrafficTreatment; | ||
32 | -import org.onosproject.net.host.HostService; | ||
33 | -import org.onosproject.net.packet.DefaultOutboundPacket; | ||
34 | -import org.onosproject.net.packet.PacketContext; | ||
35 | -import org.onosproject.net.packet.PacketPriority; | ||
36 | -import org.onosproject.net.packet.PacketService; | ||
37 | -import org.slf4j.Logger; | ||
38 | - | ||
39 | -import java.nio.ByteBuffer; | ||
40 | -import java.util.Map; | ||
41 | -import java.util.Optional; | ||
42 | -import java.util.Set; | ||
43 | - | ||
44 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
45 | -import static org.slf4j.LoggerFactory.getLogger; | ||
46 | - | ||
47 | -/** | ||
48 | - * Handles ARP requests for virtual network service IPs. | ||
49 | - */ | ||
50 | -public class CordVtnArpProxy { | ||
51 | - protected final Logger log = getLogger(getClass()); | ||
52 | - | ||
53 | - private final ApplicationId appId; | ||
54 | - private final PacketService packetService; | ||
55 | - private final HostService hostService; | ||
56 | - | ||
57 | - private final Map<Ip4Address, MacAddress> gateways = Maps.newConcurrentMap(); | ||
58 | - | ||
59 | - /** | ||
60 | - * Default constructor. | ||
61 | - * | ||
62 | - * @param appId application id | ||
63 | - * @param packetService packet service | ||
64 | - * @param hostService host service reference | ||
65 | - */ | ||
66 | - public CordVtnArpProxy(ApplicationId appId, PacketService packetService, HostService hostService) { | ||
67 | - this.appId = appId; | ||
68 | - this.packetService = packetService; | ||
69 | - this.hostService = hostService; | ||
70 | - } | ||
71 | - | ||
72 | - /** | ||
73 | - * Requests ARP packet. | ||
74 | - */ | ||
75 | - public void requestPacket() { | ||
76 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
77 | - .matchEthType(EthType.EtherType.ARP.ethType().toShort()) | ||
78 | - .build(); | ||
79 | - | ||
80 | - packetService.requestPackets(selector, | ||
81 | - PacketPriority.CONTROL, | ||
82 | - appId, | ||
83 | - Optional.empty()); | ||
84 | - } | ||
85 | - | ||
86 | - /** | ||
87 | - * Cancels ARP packet. | ||
88 | - */ | ||
89 | - public void cancelPacket() { | ||
90 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
91 | - .matchEthType(EthType.EtherType.ARP.ethType().toShort()) | ||
92 | - .build(); | ||
93 | - | ||
94 | - packetService.cancelPackets(selector, | ||
95 | - PacketPriority.CONTROL, | ||
96 | - appId, | ||
97 | - Optional.empty()); | ||
98 | - } | ||
99 | - | ||
100 | - /** | ||
101 | - * Adds a given gateway IP and MAC address to this ARP proxy. | ||
102 | - * | ||
103 | - * @param gatewayIp gateway ip address | ||
104 | - * @param gatewayMac gateway mac address | ||
105 | - */ | ||
106 | - public void addGateway(IpAddress gatewayIp, MacAddress gatewayMac) { | ||
107 | - checkNotNull(gatewayIp); | ||
108 | - checkNotNull(gatewayMac); | ||
109 | - gateways.put(gatewayIp.getIp4Address(), gatewayMac); | ||
110 | - } | ||
111 | - | ||
112 | - /** | ||
113 | - * Removes a given service IP address from this ARP proxy. | ||
114 | - * | ||
115 | - * @param gatewayIp gateway ip address | ||
116 | - */ | ||
117 | - public void removeGateway(IpAddress gatewayIp) { | ||
118 | - checkNotNull(gatewayIp); | ||
119 | - gateways.remove(gatewayIp.getIp4Address()); | ||
120 | - } | ||
121 | - | ||
122 | - /** | ||
123 | - * Emits ARP reply with fake MAC address for a given ARP request. | ||
124 | - * It only handles requests for the registered service IPs, and the other | ||
125 | - * requests can be handled by other ARP handlers like openstackSwitching or | ||
126 | - * proxyArp, for example. | ||
127 | - * | ||
128 | - * @param context packet context | ||
129 | - * @param ethPacket ethernet packet | ||
130 | - */ | ||
131 | - public void processArpPacket(PacketContext context, Ethernet ethPacket) { | ||
132 | - ARP arpPacket = (ARP) ethPacket.getPayload(); | ||
133 | - if (arpPacket.getOpCode() != ARP.OP_REQUEST) { | ||
134 | - return; | ||
135 | - } | ||
136 | - | ||
137 | - Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()); | ||
138 | - | ||
139 | - MacAddress gatewayMac = gateways.get(targetIp); | ||
140 | - MacAddress replyMac = gatewayMac != null ? gatewayMac : getMacFromHostService(targetIp); | ||
141 | - | ||
142 | - if (replyMac.equals(MacAddress.NONE)) { | ||
143 | - log.debug("Failed to find MAC for {}", targetIp.toString()); | ||
144 | - context.block(); | ||
145 | - return; | ||
146 | - } | ||
147 | - | ||
148 | - log.trace("Send ARP reply for {} with {}", targetIp.toString(), replyMac.toString()); | ||
149 | - Ethernet ethReply = ARP.buildArpReply( | ||
150 | - targetIp, | ||
151 | - replyMac, | ||
152 | - ethPacket); | ||
153 | - | ||
154 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
155 | - .setOutput(context.inPacket().receivedFrom().port()) | ||
156 | - .build(); | ||
157 | - | ||
158 | - packetService.emit(new DefaultOutboundPacket( | ||
159 | - context.inPacket().receivedFrom().deviceId(), | ||
160 | - treatment, | ||
161 | - ByteBuffer.wrap(ethReply.serialize()))); | ||
162 | - | ||
163 | - context.block(); | ||
164 | - } | ||
165 | - | ||
166 | - /** | ||
167 | - * Emits gratuitous ARP when a gateway mac address has been changed. | ||
168 | - * | ||
169 | - * @param gatewayIp gateway ip address to update MAC | ||
170 | - * @param instances set of instances to send gratuitous ARP packet | ||
171 | - */ | ||
172 | - public void sendGratuitousArpForGateway(IpAddress gatewayIp, Set<Instance> instances) { | ||
173 | - MacAddress gatewayMac = gateways.get(gatewayIp.getIp4Address()); | ||
174 | - if (gatewayMac == null) { | ||
175 | - log.debug("Gateway {} is not registered to ARP proxy", gatewayIp.toString()); | ||
176 | - return; | ||
177 | - } | ||
178 | - | ||
179 | - Ethernet ethArp = buildGratuitousArp(gatewayIp.getIp4Address(), gatewayMac); | ||
180 | - instances.stream().forEach(instance -> { | ||
181 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
182 | - .setOutput(instance.portNumber()) | ||
183 | - .build(); | ||
184 | - | ||
185 | - packetService.emit(new DefaultOutboundPacket( | ||
186 | - instance.deviceId(), | ||
187 | - treatment, | ||
188 | - ByteBuffer.wrap(ethArp.serialize()))); | ||
189 | - }); | ||
190 | - } | ||
191 | - | ||
192 | - /** | ||
193 | - * Builds gratuitous ARP packet with a given IP and MAC address. | ||
194 | - * | ||
195 | - * @param ip ip address for TPA and SPA | ||
196 | - * @param mac new mac address | ||
197 | - * @return ethernet packet | ||
198 | - */ | ||
199 | - private Ethernet buildGratuitousArp(IpAddress ip, MacAddress mac) { | ||
200 | - Ethernet eth = new Ethernet(); | ||
201 | - | ||
202 | - eth.setEtherType(Ethernet.TYPE_ARP); | ||
203 | - eth.setSourceMACAddress(mac); | ||
204 | - eth.setDestinationMACAddress(MacAddress.BROADCAST); | ||
205 | - | ||
206 | - ARP arp = new ARP(); | ||
207 | - arp.setOpCode(ARP.OP_REQUEST); | ||
208 | - arp.setHardwareType(ARP.HW_TYPE_ETHERNET); | ||
209 | - arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH); | ||
210 | - arp.setProtocolType(ARP.PROTO_TYPE_IP); | ||
211 | - arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH); | ||
212 | - | ||
213 | - arp.setSenderHardwareAddress(mac.toBytes()); | ||
214 | - arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes()); | ||
215 | - arp.setSenderProtocolAddress(ip.getIp4Address().toOctets()); | ||
216 | - arp.setTargetProtocolAddress(ip.getIp4Address().toOctets()); | ||
217 | - | ||
218 | - eth.setPayload(arp); | ||
219 | - return eth; | ||
220 | - } | ||
221 | - | ||
222 | - /** | ||
223 | - * Returns MAC address of a host with a given target IP address by asking to | ||
224 | - * host service. It does not support overlapping IP. | ||
225 | - * | ||
226 | - * @param targetIp target ip | ||
227 | - * @return mac address, or NONE mac address if it fails to find the mac | ||
228 | - */ | ||
229 | - private MacAddress getMacFromHostService(IpAddress targetIp) { | ||
230 | - checkNotNull(targetIp); | ||
231 | - | ||
232 | - Host host = hostService.getHostsByIp(targetIp) | ||
233 | - .stream() | ||
234 | - .findFirst() | ||
235 | - .orElse(null); | ||
236 | - | ||
237 | - if (host != null) { | ||
238 | - log.trace("Found MAC from host service for {}", targetIp.toString()); | ||
239 | - return host.mac(); | ||
240 | - } else { | ||
241 | - return MacAddress.NONE; | ||
242 | - } | ||
243 | - } | ||
244 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceHandler.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import org.apache.felix.scr.annotations.Component; | ||
19 | -import org.apache.felix.scr.annotations.Reference; | ||
20 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
21 | -import org.onlab.packet.Ethernet; | ||
22 | -import org.onlab.packet.Ip4Address; | ||
23 | -import org.onlab.packet.Ip4Prefix; | ||
24 | -import org.onosproject.cordvtn.api.CordVtnConfig; | ||
25 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
26 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
27 | -import org.onosproject.cordvtn.api.Instance; | ||
28 | -import org.onosproject.cordvtn.api.InstanceHandler; | ||
29 | -import org.onosproject.core.ApplicationId; | ||
30 | -import org.onosproject.core.CoreService; | ||
31 | -import org.onosproject.mastership.MastershipService; | ||
32 | -import org.onosproject.net.Host; | ||
33 | -import org.onosproject.net.PortNumber; | ||
34 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
35 | -import org.onosproject.net.config.NetworkConfigListener; | ||
36 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
37 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
38 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
39 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
40 | -import org.onosproject.net.flow.FlowRule; | ||
41 | -import org.onosproject.net.flow.TrafficSelector; | ||
42 | -import org.onosproject.net.flow.TrafficTreatment; | ||
43 | -import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
44 | -import org.onosproject.net.host.HostEvent; | ||
45 | -import org.onosproject.net.host.HostListener; | ||
46 | -import org.onosproject.net.host.HostService; | ||
47 | -import org.onosproject.xosclient.api.OpenStackAccess; | ||
48 | -import org.onosproject.xosclient.api.VtnService; | ||
49 | -import org.onosproject.xosclient.api.VtnServiceApi; | ||
50 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
51 | -import org.onosproject.xosclient.api.XosAccess; | ||
52 | -import org.onosproject.xosclient.api.XosClientService; | ||
53 | -import org.slf4j.Logger; | ||
54 | - | ||
55 | -import java.util.Objects; | ||
56 | -import java.util.Set; | ||
57 | -import java.util.concurrent.ExecutorService; | ||
58 | -import java.util.stream.Collectors; | ||
59 | -import java.util.stream.StreamSupport; | ||
60 | - | ||
61 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
62 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.*; | ||
63 | -import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT; | ||
64 | -import static org.slf4j.LoggerFactory.getLogger; | ||
65 | - | ||
66 | -/** | ||
67 | - * Provides default virtual network connectivity for service instances. | ||
68 | - */ | ||
69 | -@Component(immediate = true) | ||
70 | -public abstract class CordVtnInstanceHandler implements InstanceHandler { | ||
71 | - | ||
72 | - protected final Logger log = getLogger(getClass()); | ||
73 | - | ||
74 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
75 | - protected CoreService coreService; | ||
76 | - | ||
77 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
78 | - protected MastershipService mastershipService; | ||
79 | - | ||
80 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
81 | - protected NetworkConfigRegistry configRegistry; | ||
82 | - | ||
83 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
84 | - protected HostService hostService; | ||
85 | - | ||
86 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
87 | - protected XosClientService xosClient; | ||
88 | - | ||
89 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
90 | - protected CordVtnNodeManager nodeManager; | ||
91 | - | ||
92 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
93 | - protected CordVtnPipeline pipeline; | ||
94 | - | ||
95 | - protected static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured"; | ||
96 | - protected static final String XOS_ACCESS_ERROR = "XOS access is not configured"; | ||
97 | - | ||
98 | - protected XosAccess xosAccess = null; | ||
99 | - protected OpenStackAccess osAccess = null; | ||
100 | - protected ApplicationId appId; | ||
101 | - protected VtnService.ServiceType serviceType; | ||
102 | - protected ExecutorService eventExecutor; | ||
103 | - | ||
104 | - protected HostListener hostListener = new InternalHostListener(); | ||
105 | - protected NetworkConfigListener configListener = new InternalConfigListener(); | ||
106 | - | ||
107 | - protected void activate() { | ||
108 | - // sub class should set service type and event executor in its activate method | ||
109 | - appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID); | ||
110 | - | ||
111 | - hostService.addListener(hostListener); | ||
112 | - configRegistry.addListener(configListener); | ||
113 | - | ||
114 | - log.info("Started"); | ||
115 | - } | ||
116 | - | ||
117 | - protected void deactivate() { | ||
118 | - hostService.removeListener(hostListener); | ||
119 | - configRegistry.removeListener(configListener); | ||
120 | - eventExecutor.shutdown(); | ||
121 | - | ||
122 | - log.info("Stopped"); | ||
123 | - } | ||
124 | - | ||
125 | - @Override | ||
126 | - public void instanceDetected(Instance instance) { | ||
127 | - log.info("Instance is detected {}", instance); | ||
128 | - | ||
129 | - VtnService service = getVtnService(instance.serviceId()); | ||
130 | - if (service == null) { | ||
131 | - log.warn("Failed to get VtnService for {}", instance); | ||
132 | - return; | ||
133 | - } | ||
134 | - | ||
135 | - if (service.networkType().equals(MANAGEMENT)) { | ||
136 | - managementNetworkRules(instance, service, true); | ||
137 | - } | ||
138 | - | ||
139 | - defaultConnectionRules(instance, service, true); | ||
140 | - } | ||
141 | - | ||
142 | - @Override | ||
143 | - public void instanceRemoved(Instance instance) { | ||
144 | - log.info("Instance is removed {}", instance); | ||
145 | - | ||
146 | - VtnService service = getVtnService(instance.serviceId()); | ||
147 | - if (service == null) { | ||
148 | - log.warn("Failed to get VtnService for {}", instance); | ||
149 | - return; | ||
150 | - } | ||
151 | - | ||
152 | - if (service.networkType().equals(MANAGEMENT)) { | ||
153 | - managementNetworkRules(instance, service, false); | ||
154 | - } | ||
155 | - | ||
156 | - // TODO check if any stale management network rules are | ||
157 | - defaultConnectionRules(instance, service, false); | ||
158 | - } | ||
159 | - | ||
160 | - protected VtnService getVtnService(VtnServiceId serviceId) { | ||
161 | - checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); | ||
162 | - checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
163 | - | ||
164 | - // TODO remove openstack access when XOS provides all information | ||
165 | - VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService(); | ||
166 | - VtnService service = serviceApi.service(serviceId, osAccess); | ||
167 | - if (service == null) { | ||
168 | - log.warn("Failed to get VtnService for {}", serviceId); | ||
169 | - } | ||
170 | - return service; | ||
171 | - } | ||
172 | - | ||
173 | - protected Set<Instance> getInstances(VtnServiceId serviceId) { | ||
174 | - return StreamSupport.stream(hostService.getHosts().spliterator(), false) | ||
175 | - .filter(host -> Objects.equals( | ||
176 | - serviceId.id(), | ||
177 | - host.annotations().value(Instance.SERVICE_ID))) | ||
178 | - .map(Instance::of) | ||
179 | - .collect(Collectors.toSet()); | ||
180 | - } | ||
181 | - | ||
182 | - private void defaultConnectionRules(Instance instance, VtnService service, boolean install) { | ||
183 | - long vni = service.vni(); | ||
184 | - Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix(); | ||
185 | - | ||
186 | - inPortRule(instance, install); | ||
187 | - dstIpRule(instance, vni, install); | ||
188 | - tunnelInRule(instance, vni, install); | ||
189 | - | ||
190 | - if (install) { | ||
191 | - directAccessRule(serviceIpRange, serviceIpRange, true); | ||
192 | - serviceIsolationRule(serviceIpRange, true); | ||
193 | - } else if (getInstances(service.id()).isEmpty()) { | ||
194 | - directAccessRule(serviceIpRange, serviceIpRange, false); | ||
195 | - serviceIsolationRule(serviceIpRange, false); | ||
196 | - } | ||
197 | - } | ||
198 | - | ||
199 | - private void managementNetworkRules(Instance instance, VtnService service, boolean install) { | ||
200 | - | ||
201 | - managementPerInstanceRule(instance, install); | ||
202 | - if (install) { | ||
203 | - managementBaseRule(instance, service, true); | ||
204 | - } else if (!hostService.getConnectedHosts(instance.deviceId()).stream() | ||
205 | - .filter(host -> Instance.of(host).serviceId().equals(service.id())) | ||
206 | - .findAny() | ||
207 | - .isPresent()) { | ||
208 | - managementBaseRule(instance, service, false); | ||
209 | - } | ||
210 | - } | ||
211 | - | ||
212 | - private void managementBaseRule(Instance instance, VtnService service, boolean install) { | ||
213 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
214 | - .matchEthType(Ethernet.TYPE_ARP) | ||
215 | - .matchArpTpa(service.serviceIp().getIp4Address()) | ||
216 | - .build(); | ||
217 | - | ||
218 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
219 | - .setOutput(PortNumber.LOCAL) | ||
220 | - .build(); | ||
221 | - | ||
222 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
223 | - .fromApp(appId) | ||
224 | - .withSelector(selector) | ||
225 | - .withTreatment(treatment) | ||
226 | - .withPriority(PRIORITY_MANAGEMENT) | ||
227 | - .forDevice(instance.deviceId()) | ||
228 | - .forTable(TABLE_ZERO) | ||
229 | - .makePermanent() | ||
230 | - .build(); | ||
231 | - | ||
232 | - pipeline.processFlowRule(install, flowRule); | ||
233 | - | ||
234 | - selector = DefaultTrafficSelector.builder() | ||
235 | - .matchInPort(PortNumber.LOCAL) | ||
236 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
237 | - .matchIPDst(service.subnet()) | ||
238 | - .build(); | ||
239 | - | ||
240 | - treatment = DefaultTrafficTreatment.builder() | ||
241 | - .transition(TABLE_DST_IP) | ||
242 | - .build(); | ||
243 | - | ||
244 | - flowRule = DefaultFlowRule.builder() | ||
245 | - .fromApp(appId) | ||
246 | - .withSelector(selector) | ||
247 | - .withTreatment(treatment) | ||
248 | - .withPriority(PRIORITY_MANAGEMENT) | ||
249 | - .forDevice(instance.deviceId()) | ||
250 | - .forTable(TABLE_ZERO) | ||
251 | - .makePermanent() | ||
252 | - .build(); | ||
253 | - | ||
254 | - pipeline.processFlowRule(install, flowRule); | ||
255 | - | ||
256 | - selector = DefaultTrafficSelector.builder() | ||
257 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
258 | - .matchIPDst(service.serviceIp().toIpPrefix()) | ||
259 | - .build(); | ||
260 | - | ||
261 | - treatment = DefaultTrafficTreatment.builder() | ||
262 | - .setOutput(PortNumber.LOCAL) | ||
263 | - .build(); | ||
264 | - | ||
265 | - flowRule = DefaultFlowRule.builder() | ||
266 | - .fromApp(appId) | ||
267 | - .withSelector(selector) | ||
268 | - .withTreatment(treatment) | ||
269 | - .withPriority(PRIORITY_MANAGEMENT) | ||
270 | - .forDevice(instance.deviceId()) | ||
271 | - .forTable(TABLE_ACCESS_TYPE) | ||
272 | - .makePermanent() | ||
273 | - .build(); | ||
274 | - | ||
275 | - pipeline.processFlowRule(install, flowRule); | ||
276 | - } | ||
277 | - | ||
278 | - private void managementPerInstanceRule(Instance instance, boolean install) { | ||
279 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
280 | - .matchInPort(PortNumber.LOCAL) | ||
281 | - .matchEthType(Ethernet.TYPE_ARP) | ||
282 | - .matchArpTpa(instance.ipAddress().getIp4Address()) | ||
283 | - .build(); | ||
284 | - | ||
285 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
286 | - .setOutput(instance.portNumber()) | ||
287 | - .build(); | ||
288 | - | ||
289 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
290 | - .fromApp(appId) | ||
291 | - .withSelector(selector) | ||
292 | - .withTreatment(treatment) | ||
293 | - .withPriority(PRIORITY_MANAGEMENT) | ||
294 | - .forDevice(instance.deviceId()) | ||
295 | - .forTable(TABLE_ZERO) | ||
296 | - .makePermanent() | ||
297 | - .build(); | ||
298 | - | ||
299 | - pipeline.processFlowRule(install, flowRule); | ||
300 | - } | ||
301 | - | ||
302 | - private void inPortRule(Instance instance, boolean install) { | ||
303 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
304 | - .matchInPort(instance.portNumber()) | ||
305 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
306 | - .matchIPSrc(instance.ipAddress().toIpPrefix()) | ||
307 | - .build(); | ||
308 | - | ||
309 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
310 | - .transition(TABLE_ACCESS_TYPE) | ||
311 | - .build(); | ||
312 | - | ||
313 | - | ||
314 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
315 | - .fromApp(appId) | ||
316 | - .withSelector(selector) | ||
317 | - .withTreatment(treatment) | ||
318 | - .withPriority(PRIORITY_DEFAULT) | ||
319 | - .forDevice(instance.deviceId()) | ||
320 | - .forTable(TABLE_IN_PORT) | ||
321 | - .makePermanent() | ||
322 | - .build(); | ||
323 | - | ||
324 | - pipeline.processFlowRule(install, flowRule); | ||
325 | - | ||
326 | - selector = DefaultTrafficSelector.builder() | ||
327 | - .matchInPort(instance.portNumber()) | ||
328 | - .build(); | ||
329 | - | ||
330 | - treatment = DefaultTrafficTreatment.builder() | ||
331 | - .transition(TABLE_IN_SERVICE) | ||
332 | - .build(); | ||
333 | - | ||
334 | - flowRule = DefaultFlowRule.builder() | ||
335 | - .fromApp(appId) | ||
336 | - .withSelector(selector) | ||
337 | - .withTreatment(treatment) | ||
338 | - .withPriority(PRIORITY_LOW) | ||
339 | - .forDevice(instance.deviceId()) | ||
340 | - .forTable(TABLE_IN_PORT) | ||
341 | - .makePermanent() | ||
342 | - .build(); | ||
343 | - | ||
344 | - pipeline.processFlowRule(install, flowRule); | ||
345 | - } | ||
346 | - | ||
347 | - private void dstIpRule(Instance instance, long vni, boolean install) { | ||
348 | - Ip4Address tunnelIp = nodeManager.dpIp(instance.deviceId()).getIp4Address(); | ||
349 | - | ||
350 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
351 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
352 | - .matchIPDst(instance.ipAddress().toIpPrefix()) | ||
353 | - .build(); | ||
354 | - | ||
355 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
356 | - .setEthDst(instance.mac()) | ||
357 | - .setOutput(instance.portNumber()) | ||
358 | - .build(); | ||
359 | - | ||
360 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
361 | - .fromApp(appId) | ||
362 | - .withSelector(selector) | ||
363 | - .withTreatment(treatment) | ||
364 | - .withPriority(PRIORITY_DEFAULT) | ||
365 | - .forDevice(instance.deviceId()) | ||
366 | - .forTable(TABLE_DST_IP) | ||
367 | - .makePermanent() | ||
368 | - .build(); | ||
369 | - | ||
370 | - pipeline.processFlowRule(install, flowRule); | ||
371 | - | ||
372 | - for (CordVtnNode node : nodeManager.completeNodes()) { | ||
373 | - if (node.intBrId().equals(instance.deviceId())) { | ||
374 | - continue; | ||
375 | - } | ||
376 | - | ||
377 | - ExtensionTreatment tunnelDst = pipeline.tunnelDstTreatment(node.intBrId(), tunnelIp); | ||
378 | - if (tunnelDst == null) { | ||
379 | - continue; | ||
380 | - } | ||
381 | - | ||
382 | - treatment = DefaultTrafficTreatment.builder() | ||
383 | - .setEthDst(instance.mac()) | ||
384 | - .setTunnelId(vni) | ||
385 | - .extension(tunnelDst, node.intBrId()) | ||
386 | - .setOutput(nodeManager.tunnelPort(node.intBrId())) | ||
387 | - .build(); | ||
388 | - | ||
389 | - flowRule = DefaultFlowRule.builder() | ||
390 | - .fromApp(appId) | ||
391 | - .withSelector(selector) | ||
392 | - .withTreatment(treatment) | ||
393 | - .withPriority(PRIORITY_DEFAULT) | ||
394 | - .forDevice(node.intBrId()) | ||
395 | - .forTable(TABLE_DST_IP) | ||
396 | - .makePermanent() | ||
397 | - .build(); | ||
398 | - | ||
399 | - pipeline.processFlowRule(install, flowRule); | ||
400 | - } | ||
401 | - } | ||
402 | - | ||
403 | - private void tunnelInRule(Instance instance, long vni, boolean install) { | ||
404 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
405 | - .matchTunnelId(vni) | ||
406 | - .matchEthDst(instance.mac()) | ||
407 | - .build(); | ||
408 | - | ||
409 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
410 | - .setOutput(instance.portNumber()) | ||
411 | - .build(); | ||
412 | - | ||
413 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
414 | - .fromApp(appId) | ||
415 | - .withSelector(selector) | ||
416 | - .withTreatment(treatment) | ||
417 | - .withPriority(PRIORITY_DEFAULT) | ||
418 | - .forDevice(instance.deviceId()) | ||
419 | - .forTable(TABLE_TUNNEL_IN) | ||
420 | - .makePermanent() | ||
421 | - .build(); | ||
422 | - | ||
423 | - pipeline.processFlowRule(install, flowRule); | ||
424 | - } | ||
425 | - | ||
426 | - private void directAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) { | ||
427 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
428 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
429 | - .matchIPSrc(srcRange) | ||
430 | - .matchIPDst(dstRange) | ||
431 | - .build(); | ||
432 | - | ||
433 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
434 | - .transition(TABLE_DST_IP) | ||
435 | - .build(); | ||
436 | - | ||
437 | - | ||
438 | - nodeManager.completeNodes().stream().forEach(node -> { | ||
439 | - FlowRule flowRuleDirect = DefaultFlowRule.builder() | ||
440 | - .fromApp(appId) | ||
441 | - .withSelector(selector) | ||
442 | - .withTreatment(treatment) | ||
443 | - .withPriority(PRIORITY_DEFAULT) | ||
444 | - .forDevice(node.intBrId()) | ||
445 | - .forTable(TABLE_ACCESS_TYPE) | ||
446 | - .makePermanent() | ||
447 | - .build(); | ||
448 | - | ||
449 | - pipeline.processFlowRule(install, flowRuleDirect); | ||
450 | - }); | ||
451 | - } | ||
452 | - | ||
453 | - private void serviceIsolationRule(Ip4Prefix dstRange, boolean install) { | ||
454 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
455 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
456 | - .matchIPDst(dstRange) | ||
457 | - .build(); | ||
458 | - | ||
459 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
460 | - .drop() | ||
461 | - .build(); | ||
462 | - | ||
463 | - nodeManager.completeNodes().stream().forEach(node -> { | ||
464 | - FlowRule flowRuleDirect = DefaultFlowRule.builder() | ||
465 | - .fromApp(appId) | ||
466 | - .withSelector(selector) | ||
467 | - .withTreatment(treatment) | ||
468 | - .withPriority(PRIORITY_LOW) | ||
469 | - .forDevice(node.intBrId()) | ||
470 | - .forTable(TABLE_ACCESS_TYPE) | ||
471 | - .makePermanent() | ||
472 | - .build(); | ||
473 | - | ||
474 | - pipeline.processFlowRule(install, flowRuleDirect); | ||
475 | - }); | ||
476 | - } | ||
477 | - | ||
478 | - protected void readConfiguration() { | ||
479 | - CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | ||
480 | - if (config == null) { | ||
481 | - log.debug("No configuration found"); | ||
482 | - return; | ||
483 | - } | ||
484 | - osAccess = config.openstackAccess(); | ||
485 | - xosAccess = config.xosAccess(); | ||
486 | - } | ||
487 | - | ||
488 | - public class InternalHostListener implements HostListener { | ||
489 | - | ||
490 | - @Override | ||
491 | - public void event(HostEvent event) { | ||
492 | - Host host = event.subject(); | ||
493 | - if (!mastershipService.isLocalMaster(host.location().deviceId())) { | ||
494 | - // do not allow to proceed without mastership | ||
495 | - return; | ||
496 | - } | ||
497 | - | ||
498 | - Instance instance = Instance.of(host); | ||
499 | - if (!Objects.equals(instance.serviceType(), serviceType)) { | ||
500 | - // not my service instance, do nothing | ||
501 | - return; | ||
502 | - } | ||
503 | - | ||
504 | - switch (event.type()) { | ||
505 | - case HOST_UPDATED: | ||
506 | - case HOST_ADDED: | ||
507 | - eventExecutor.execute(() -> instanceDetected(instance)); | ||
508 | - break; | ||
509 | - case HOST_REMOVED: | ||
510 | - eventExecutor.execute(() -> instanceRemoved(instance)); | ||
511 | - break; | ||
512 | - default: | ||
513 | - break; | ||
514 | - } | ||
515 | - } | ||
516 | - } | ||
517 | - | ||
518 | - public class InternalConfigListener implements NetworkConfigListener { | ||
519 | - | ||
520 | - @Override | ||
521 | - public void event(NetworkConfigEvent event) { | ||
522 | - if (!event.configClass().equals(CordVtnConfig.class)) { | ||
523 | - return; | ||
524 | - } | ||
525 | - | ||
526 | - switch (event.type()) { | ||
527 | - case CONFIG_ADDED: | ||
528 | - case CONFIG_UPDATED: | ||
529 | - readConfiguration(); | ||
530 | - break; | ||
531 | - default: | ||
532 | - break; | ||
533 | - } | ||
534 | - } | ||
535 | - } | ||
536 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Sets; | ||
19 | -import org.apache.felix.scr.annotations.Activate; | ||
20 | -import org.apache.felix.scr.annotations.Component; | ||
21 | -import org.apache.felix.scr.annotations.Deactivate; | ||
22 | -import org.apache.felix.scr.annotations.Reference; | ||
23 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
24 | -import org.apache.felix.scr.annotations.Service; | ||
25 | -import org.onlab.packet.Ethernet; | ||
26 | -import org.onlab.packet.Ip4Address; | ||
27 | -import org.onlab.packet.IpAddress; | ||
28 | -import org.onlab.packet.MacAddress; | ||
29 | -import org.onlab.packet.VlanId; | ||
30 | -import org.onosproject.cordvtn.api.CordVtnConfig; | ||
31 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
32 | -import org.onosproject.cordvtn.api.Instance; | ||
33 | -import org.onosproject.core.ApplicationId; | ||
34 | -import org.onosproject.core.CoreService; | ||
35 | -import org.onosproject.dhcp.DhcpService; | ||
36 | -import org.onosproject.dhcp.IpAssignment; | ||
37 | -import org.onosproject.mastership.MastershipService; | ||
38 | -import org.onosproject.net.ConnectPoint; | ||
39 | -import org.onosproject.net.DefaultAnnotations; | ||
40 | -import org.onosproject.net.Host; | ||
41 | -import org.onosproject.net.HostId; | ||
42 | -import org.onosproject.net.HostLocation; | ||
43 | -import org.onosproject.net.Port; | ||
44 | -import org.onosproject.net.config.ConfigFactory; | ||
45 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
46 | -import org.onosproject.net.config.NetworkConfigListener; | ||
47 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
48 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
49 | -import org.onosproject.net.device.DeviceService; | ||
50 | -import org.onosproject.net.host.DefaultHostDescription; | ||
51 | -import org.onosproject.net.host.HostDescription; | ||
52 | -import org.onosproject.net.host.HostEvent; | ||
53 | -import org.onosproject.net.host.HostListener; | ||
54 | -import org.onosproject.net.host.HostProvider; | ||
55 | -import org.onosproject.net.host.HostProviderRegistry; | ||
56 | -import org.onosproject.net.host.HostProviderService; | ||
57 | -import org.onosproject.net.host.HostService; | ||
58 | -import org.onosproject.net.packet.PacketContext; | ||
59 | -import org.onosproject.net.packet.PacketProcessor; | ||
60 | -import org.onosproject.net.packet.PacketService; | ||
61 | -import org.onosproject.net.provider.AbstractProvider; | ||
62 | -import org.onosproject.net.provider.ProviderId; | ||
63 | -import org.onosproject.xosclient.api.OpenStackAccess; | ||
64 | -import org.onosproject.xosclient.api.VtnPort; | ||
65 | -import org.onosproject.xosclient.api.VtnPortApi; | ||
66 | -import org.onosproject.xosclient.api.VtnService; | ||
67 | -import org.onosproject.xosclient.api.VtnServiceApi; | ||
68 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
69 | -import org.onosproject.xosclient.api.XosAccess; | ||
70 | -import org.onosproject.xosclient.api.XosClientService; | ||
71 | -import org.slf4j.Logger; | ||
72 | - | ||
73 | -import java.util.Date; | ||
74 | -import java.util.Map; | ||
75 | -import java.util.Objects; | ||
76 | -import java.util.Set; | ||
77 | -import java.util.concurrent.ExecutorService; | ||
78 | -import java.util.stream.Collectors; | ||
79 | -import java.util.stream.StreamSupport; | ||
80 | - | ||
81 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
82 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
83 | -import static org.onlab.util.Tools.groupedThreads; | ||
84 | -import static org.onosproject.cordvtn.api.Instance.*; | ||
85 | -import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced; | ||
86 | -import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT; | ||
87 | -import static org.onosproject.xosclient.api.VtnService.NetworkType.PRIVATE; | ||
88 | -import static org.slf4j.LoggerFactory.getLogger; | ||
89 | - | ||
90 | -/** | ||
91 | - * Adds or removes instances to network services. | ||
92 | - */ | ||
93 | -@Component(immediate = true) | ||
94 | -@Service(value = CordVtnInstanceManager.class) | ||
95 | -public class CordVtnInstanceManager extends AbstractProvider implements HostProvider { | ||
96 | - | ||
97 | - protected final Logger log = getLogger(getClass()); | ||
98 | - | ||
99 | - private static final String XOS_ACCESS_ERROR = "XOS access is not configured"; | ||
100 | - private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured"; | ||
101 | - private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8"); | ||
102 | - private static final int DHCP_INFINITE_LEASE = -1; | ||
103 | - | ||
104 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
105 | - protected CoreService coreService; | ||
106 | - | ||
107 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
108 | - protected NetworkConfigRegistry configRegistry; | ||
109 | - | ||
110 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
111 | - protected HostProviderRegistry hostProviderRegistry; | ||
112 | - | ||
113 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
114 | - protected DeviceService deviceService; | ||
115 | - | ||
116 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
117 | - protected HostService hostService; | ||
118 | - | ||
119 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
120 | - protected PacketService packetService; | ||
121 | - | ||
122 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
123 | - protected DhcpService dhcpService; | ||
124 | - | ||
125 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
126 | - protected MastershipService mastershipService; | ||
127 | - | ||
128 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
129 | - protected XosClientService xosClient; | ||
130 | - | ||
131 | - private final ConfigFactory configFactory = | ||
132 | - new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") { | ||
133 | - @Override | ||
134 | - public CordVtnConfig createConfig() { | ||
135 | - return new CordVtnConfig(); | ||
136 | - } | ||
137 | - }; | ||
138 | - | ||
139 | - private final ExecutorService eventExecutor = | ||
140 | - newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-instance", "event-handler")); | ||
141 | - private final PacketProcessor packetProcessor = new InternalPacketProcessor(); | ||
142 | - private final HostListener hostListener = new InternalHostListener(); | ||
143 | - private final NetworkConfigListener configListener = new InternalConfigListener(); | ||
144 | - | ||
145 | - private ApplicationId appId; | ||
146 | - private HostProviderService hostProvider; | ||
147 | - private CordVtnArpProxy arpProxy; // TODO make it a component service | ||
148 | - private MacAddress privateGatewayMac = MacAddress.NONE; | ||
149 | - private XosAccess xosAccess = null; | ||
150 | - private OpenStackAccess osAccess = null; | ||
151 | - | ||
152 | - /** | ||
153 | - * Creates an cordvtn host location provider. | ||
154 | - */ | ||
155 | - public CordVtnInstanceManager() { | ||
156 | - super(new ProviderId("host", CordVtnService.CORDVTN_APP_ID)); | ||
157 | - } | ||
158 | - | ||
159 | - @Activate | ||
160 | - protected void activate() { | ||
161 | - appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID); | ||
162 | - | ||
163 | - arpProxy = new CordVtnArpProxy(appId, packetService, hostService); | ||
164 | - packetService.addProcessor(packetProcessor, PacketProcessor.director(0)); | ||
165 | - arpProxy.requestPacket(); | ||
166 | - | ||
167 | - hostService.addListener(hostListener); | ||
168 | - hostProvider = hostProviderRegistry.register(this); | ||
169 | - | ||
170 | - configRegistry.registerConfigFactory(configFactory); | ||
171 | - configRegistry.addListener(configListener); | ||
172 | - | ||
173 | - log.info("Started"); | ||
174 | - } | ||
175 | - | ||
176 | - @Deactivate | ||
177 | - protected void deactivate() { | ||
178 | - hostProviderRegistry.unregister(this); | ||
179 | - hostService.removeListener(hostListener); | ||
180 | - | ||
181 | - packetService.removeProcessor(packetProcessor); | ||
182 | - | ||
183 | - configRegistry.unregisterConfigFactory(configFactory); | ||
184 | - configRegistry.removeListener(configListener); | ||
185 | - | ||
186 | - eventExecutor.shutdown(); | ||
187 | - log.info("Stopped"); | ||
188 | - } | ||
189 | - | ||
190 | - @Override | ||
191 | - public void triggerProbe(Host host) { | ||
192 | - /* | ||
193 | - * Note: In CORD deployment, we assume that all hosts are configured. | ||
194 | - * Therefore no probe is required. | ||
195 | - */ | ||
196 | - } | ||
197 | - | ||
198 | - /** | ||
199 | - * Adds a service instance at a given connect point. | ||
200 | - * | ||
201 | - * @param connectPoint connect point of the instance | ||
202 | - */ | ||
203 | - public void addInstance(ConnectPoint connectPoint) { | ||
204 | - Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port()); | ||
205 | - if (port == null) { | ||
206 | - log.debug("No port found from {}", connectPoint); | ||
207 | - return; | ||
208 | - } | ||
209 | - | ||
210 | - VtnPort vtnPort = getVtnPort(port.annotations().value("portName")); | ||
211 | - if (vtnPort == null) { | ||
212 | - return; | ||
213 | - } | ||
214 | - | ||
215 | - VtnService vtnService = getVtnService(vtnPort.serviceId()); | ||
216 | - if (vtnService == null) { | ||
217 | - return; | ||
218 | - } | ||
219 | - | ||
220 | - // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the | ||
221 | - // existing instances. | ||
222 | - DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | ||
223 | - .set(SERVICE_TYPE, vtnService.serviceType().toString()) | ||
224 | - .set(SERVICE_ID, vtnPort.serviceId().id()) | ||
225 | - .set(PORT_ID, vtnPort.id().id()) | ||
226 | - .set(CREATE_TIME, String.valueOf(System.currentTimeMillis())); | ||
227 | - | ||
228 | - HostDescription hostDesc = new DefaultHostDescription( | ||
229 | - vtnPort.mac(), | ||
230 | - VlanId.NONE, | ||
231 | - new HostLocation(connectPoint, System.currentTimeMillis()), | ||
232 | - Sets.newHashSet(vtnPort.ip()), | ||
233 | - annotations.build()); | ||
234 | - | ||
235 | - HostId hostId = HostId.hostId(vtnPort.mac()); | ||
236 | - hostProvider.hostDetected(hostId, hostDesc, false); | ||
237 | - } | ||
238 | - | ||
239 | - /** | ||
240 | - * Adds a service instance with given host ID and host description. | ||
241 | - * | ||
242 | - * @param hostId host id | ||
243 | - * @param description host description | ||
244 | - */ | ||
245 | - public void addInstance(HostId hostId, HostDescription description) { | ||
246 | - hostProvider.hostDetected(hostId, description, false); | ||
247 | - } | ||
248 | - | ||
249 | - /** | ||
250 | - * Removes a service instance from a given connect point. | ||
251 | - * | ||
252 | - * @param connectPoint connect point | ||
253 | - */ | ||
254 | - public void removeInstance(ConnectPoint connectPoint) { | ||
255 | - hostService.getConnectedHosts(connectPoint) | ||
256 | - .stream() | ||
257 | - .forEach(host -> hostProvider.hostVanished(host.id())); | ||
258 | - } | ||
259 | - | ||
260 | - /** | ||
261 | - * Removes service instance with given host ID. | ||
262 | - * | ||
263 | - * @param hostId host id | ||
264 | - */ | ||
265 | - public void removeInstance(HostId hostId) { | ||
266 | - hostProvider.hostVanished(hostId); | ||
267 | - } | ||
268 | - | ||
269 | - private void instanceDetected(Instance instance) { | ||
270 | - VtnService service = getVtnService(instance.serviceId()); | ||
271 | - if (service == null) { | ||
272 | - return; | ||
273 | - } | ||
274 | - | ||
275 | - if (service.networkType().equals(PRIVATE)) { | ||
276 | - arpProxy.addGateway(service.serviceIp(), privateGatewayMac); | ||
277 | - arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(instance)); | ||
278 | - } | ||
279 | - if (!instance.isNestedInstance()) { | ||
280 | - registerDhcpLease(instance, service); | ||
281 | - } | ||
282 | - } | ||
283 | - | ||
284 | - private void instanceRemoved(Instance instance) { | ||
285 | - VtnService service = getVtnService(instance.serviceId()); | ||
286 | - if (service == null) { | ||
287 | - return; | ||
288 | - } | ||
289 | - | ||
290 | - if (service.networkType().equals(PRIVATE) && getInstances(service.id()).isEmpty()) { | ||
291 | - arpProxy.removeGateway(service.serviceIp()); | ||
292 | - } | ||
293 | - | ||
294 | - if (!instance.isNestedInstance()) { | ||
295 | - dhcpService.removeStaticMapping(instance.mac()); | ||
296 | - } | ||
297 | - } | ||
298 | - | ||
299 | - private void registerDhcpLease(Instance instance, VtnService service) { | ||
300 | - Ip4Address broadcast = Ip4Address.makeMaskedAddress( | ||
301 | - instance.ipAddress(), | ||
302 | - service.subnet().prefixLength()); | ||
303 | - | ||
304 | - IpAssignment.Builder ipBuilder = IpAssignment.builder() | ||
305 | - .ipAddress(instance.ipAddress()) | ||
306 | - .leasePeriod(DHCP_INFINITE_LEASE) | ||
307 | - .timestamp(new Date()) | ||
308 | - .subnetMask(Ip4Address.makeMaskPrefix(service.subnet().prefixLength())) | ||
309 | - .broadcast(broadcast) | ||
310 | - .domainServer(DEFAULT_DNS) | ||
311 | - .assignmentStatus(Option_RangeNotEnforced); | ||
312 | - | ||
313 | - if (service.networkType() != MANAGEMENT) { | ||
314 | - ipBuilder = ipBuilder.routerAddress(service.serviceIp().getIp4Address()); | ||
315 | - } | ||
316 | - | ||
317 | - log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress()); | ||
318 | - dhcpService.setStaticMapping(instance.mac(), ipBuilder.build()); | ||
319 | - } | ||
320 | - | ||
321 | - private VtnService getVtnService(VtnServiceId serviceId) { | ||
322 | - checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); | ||
323 | - checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
324 | - | ||
325 | - // TODO remove openstack access when XOS provides all information | ||
326 | - VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService(); | ||
327 | - VtnService service = serviceApi.service(serviceId, osAccess); | ||
328 | - if (service == null) { | ||
329 | - log.warn("Failed to get VtnService for {}", serviceId); | ||
330 | - } | ||
331 | - return service; | ||
332 | - } | ||
333 | - | ||
334 | - private VtnPort getVtnPort(String portName) { | ||
335 | - checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); | ||
336 | - checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
337 | - | ||
338 | - // TODO remove openstack access when XOS provides all information | ||
339 | - VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort(); | ||
340 | - VtnPort vtnPort = portApi.vtnPort(portName, osAccess); | ||
341 | - if (vtnPort == null) { | ||
342 | - log.warn("Failed to get port information of {}", portName); | ||
343 | - } | ||
344 | - return vtnPort; | ||
345 | - } | ||
346 | - | ||
347 | - private Set<Instance> getInstances(VtnServiceId serviceId) { | ||
348 | - return StreamSupport.stream(hostService.getHosts().spliterator(), false) | ||
349 | - .filter(host -> Objects.equals( | ||
350 | - serviceId.id(), | ||
351 | - host.annotations().value(Instance.SERVICE_ID))) | ||
352 | - .map(Instance::of) | ||
353 | - .collect(Collectors.toSet()); | ||
354 | - } | ||
355 | - | ||
356 | - private void readConfiguration() { | ||
357 | - CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | ||
358 | - if (config == null) { | ||
359 | - log.debug("No configuration found"); | ||
360 | - return; | ||
361 | - } | ||
362 | - | ||
363 | - log.info("Load CORD-VTN configurations"); | ||
364 | - | ||
365 | - xosAccess = config.xosAccess(); | ||
366 | - osAccess = config.openstackAccess(); | ||
367 | - privateGatewayMac = config.privateGatewayMac(); | ||
368 | - | ||
369 | - Map<IpAddress, MacAddress> publicGateways = config.publicGateways(); | ||
370 | - publicGateways.entrySet() | ||
371 | - .stream() | ||
372 | - .forEach(entry -> { | ||
373 | - arpProxy.addGateway(entry.getKey(), entry.getValue()); | ||
374 | - log.debug("Added public gateway IP {}, MAC {}", | ||
375 | - entry.getKey(), entry.getValue()); | ||
376 | - }); | ||
377 | - // TODO notice gateway MAC change to VMs holds this gateway IP | ||
378 | - } | ||
379 | - | ||
380 | - private class InternalHostListener implements HostListener { | ||
381 | - | ||
382 | - @Override | ||
383 | - public void event(HostEvent event) { | ||
384 | - Host host = event.subject(); | ||
385 | - if (!mastershipService.isLocalMaster(host.location().deviceId())) { | ||
386 | - // do not allow to proceed without mastership | ||
387 | - return; | ||
388 | - } | ||
389 | - | ||
390 | - Instance instance = Instance.of(host); | ||
391 | - switch (event.type()) { | ||
392 | - case HOST_UPDATED: | ||
393 | - case HOST_ADDED: | ||
394 | - eventExecutor.execute(() -> instanceDetected(instance)); | ||
395 | - break; | ||
396 | - case HOST_REMOVED: | ||
397 | - eventExecutor.execute(() -> instanceRemoved(instance)); | ||
398 | - break; | ||
399 | - default: | ||
400 | - break; | ||
401 | - } | ||
402 | - } | ||
403 | - } | ||
404 | - | ||
405 | - private class InternalPacketProcessor implements PacketProcessor { | ||
406 | - | ||
407 | - @Override | ||
408 | - public void process(PacketContext context) { | ||
409 | - if (context.isHandled()) { | ||
410 | - return; | ||
411 | - } | ||
412 | - Ethernet ethPacket = context.inPacket().parsed(); | ||
413 | - if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) { | ||
414 | - return; | ||
415 | - } | ||
416 | - arpProxy.processArpPacket(context, ethPacket); | ||
417 | - } | ||
418 | - } | ||
419 | - | ||
420 | - private class InternalConfigListener implements NetworkConfigListener { | ||
421 | - | ||
422 | - @Override | ||
423 | - public void event(NetworkConfigEvent event) { | ||
424 | - if (!event.configClass().equals(CordVtnConfig.class)) { | ||
425 | - return; | ||
426 | - } | ||
427 | - | ||
428 | - switch (event.type()) { | ||
429 | - case CONFIG_ADDED: | ||
430 | - case CONFIG_UPDATED: | ||
431 | - readConfiguration(); | ||
432 | - break; | ||
433 | - default: | ||
434 | - break; | ||
435 | - } | ||
436 | - } | ||
437 | - } | ||
438 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Sets; | ||
19 | -import com.jcraft.jsch.Session; | ||
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.IpAddress; | ||
27 | -import org.onlab.util.ItemNotFoundException; | ||
28 | -import org.onlab.util.KryoNamespace; | ||
29 | -import org.onosproject.cluster.ClusterService; | ||
30 | -import org.onosproject.cluster.LeadershipService; | ||
31 | -import org.onosproject.cluster.NodeId; | ||
32 | -import org.onosproject.cordvtn.api.ConnectionHandler; | ||
33 | -import org.onosproject.cordvtn.api.CordVtnConfig; | ||
34 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
35 | -import org.onosproject.cordvtn.api.CordVtnNodeState; | ||
36 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
37 | -import org.onosproject.cordvtn.api.NetworkAddress; | ||
38 | -import org.onosproject.cordvtn.api.SshAccessInfo; | ||
39 | -import org.onosproject.core.ApplicationId; | ||
40 | -import org.onosproject.core.CoreService; | ||
41 | -import org.onosproject.net.ConnectPoint; | ||
42 | -import org.onosproject.net.DefaultAnnotations; | ||
43 | -import org.onosproject.net.Device; | ||
44 | -import org.onosproject.net.DeviceId; | ||
45 | -import org.onosproject.net.Host; | ||
46 | -import org.onosproject.net.Port; | ||
47 | -import org.onosproject.net.PortNumber; | ||
48 | -import org.onosproject.net.behaviour.BridgeConfig; | ||
49 | -import org.onosproject.net.behaviour.BridgeName; | ||
50 | -import org.onosproject.net.behaviour.ControllerInfo; | ||
51 | -import org.onosproject.net.behaviour.DefaultTunnelDescription; | ||
52 | -import org.onosproject.net.behaviour.TunnelConfig; | ||
53 | -import org.onosproject.net.behaviour.TunnelDescription; | ||
54 | -import org.onosproject.net.behaviour.TunnelName; | ||
55 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
56 | -import org.onosproject.net.config.NetworkConfigListener; | ||
57 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
58 | -import org.onosproject.net.config.NetworkConfigService; | ||
59 | -import org.onosproject.net.device.DeviceAdminService; | ||
60 | -import org.onosproject.net.device.DeviceEvent; | ||
61 | -import org.onosproject.net.device.DeviceListener; | ||
62 | -import org.onosproject.net.device.DeviceService; | ||
63 | -import org.onosproject.net.host.HostService; | ||
64 | -import org.onosproject.ovsdb.controller.OvsdbClientService; | ||
65 | -import org.onosproject.ovsdb.controller.OvsdbController; | ||
66 | -import org.onosproject.ovsdb.controller.OvsdbNodeId; | ||
67 | -import org.onosproject.store.serializers.KryoNamespaces; | ||
68 | -import org.onosproject.store.service.ConsistentMap; | ||
69 | -import org.onosproject.store.service.MapEvent; | ||
70 | -import org.onosproject.store.service.MapEventListener; | ||
71 | -import org.onosproject.store.service.Serializer; | ||
72 | -import org.onosproject.store.service.StorageService; | ||
73 | -import org.onosproject.store.service.Versioned; | ||
74 | -import org.slf4j.Logger; | ||
75 | - | ||
76 | -import java.util.ArrayList; | ||
77 | -import java.util.HashMap; | ||
78 | -import java.util.List; | ||
79 | -import java.util.Map; | ||
80 | -import java.util.Objects; | ||
81 | -import java.util.Set; | ||
82 | -import java.util.concurrent.ExecutorService; | ||
83 | -import java.util.stream.Collectors; | ||
84 | - | ||
85 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
86 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
87 | -import static org.onlab.util.Tools.groupedThreads; | ||
88 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.DEFAULT_TUNNEL; | ||
89 | -import static org.onosproject.cordvtn.impl.RemoteIpCommandUtil.*; | ||
90 | -import static org.onosproject.net.Device.Type.SWITCH; | ||
91 | -import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN; | ||
92 | -import static org.slf4j.LoggerFactory.getLogger; | ||
93 | - | ||
94 | -/** | ||
95 | - * Reads node information from the network config file and handles the config | ||
96 | - * update events. | ||
97 | - * Only a leader controller performs the node addition or deletion. | ||
98 | - */ | ||
99 | -@Component(immediate = true) | ||
100 | -@Service(value = CordVtnNodeManager.class) | ||
101 | -public class CordVtnNodeManager { | ||
102 | - | ||
103 | - protected final Logger log = getLogger(getClass()); | ||
104 | - | ||
105 | - private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder() | ||
106 | - .register(KryoNamespaces.API) | ||
107 | - .register(CordVtnNode.class) | ||
108 | - .register(NodeState.class) | ||
109 | - .register(SshAccessInfo.class) | ||
110 | - .register(NetworkAddress.class); | ||
111 | - | ||
112 | - private static final String DEFAULT_BRIDGE = "br-int"; | ||
113 | - private static final String VPORT_PREFIX = "tap"; | ||
114 | - private static final String OK = "OK"; | ||
115 | - private static final String NO = "NO"; | ||
116 | - | ||
117 | - private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() { | ||
118 | - { | ||
119 | - put("key", "flow"); | ||
120 | - put("remote_ip", "flow"); | ||
121 | - } | ||
122 | - }; | ||
123 | - private static final int DPID_BEGIN = 3; | ||
124 | - private static final int OFPORT = 6653; | ||
125 | - | ||
126 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
127 | - protected CoreService coreService; | ||
128 | - | ||
129 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
130 | - protected NetworkConfigRegistry configRegistry; | ||
131 | - | ||
132 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
133 | - protected NetworkConfigService configService; | ||
134 | - | ||
135 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
136 | - protected StorageService storageService; | ||
137 | - | ||
138 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
139 | - protected DeviceAdminService adminService; | ||
140 | - | ||
141 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
142 | - protected OvsdbController controller; | ||
143 | - | ||
144 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
145 | - protected ClusterService clusterService; | ||
146 | - | ||
147 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
148 | - protected DeviceService deviceService; | ||
149 | - | ||
150 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
151 | - protected HostService hostService; | ||
152 | - | ||
153 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
154 | - protected LeadershipService leadershipService; | ||
155 | - | ||
156 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
157 | - protected CordVtnInstanceManager instanceManager; | ||
158 | - | ||
159 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
160 | - protected CordVtnPipeline pipeline; | ||
161 | - | ||
162 | - private final ExecutorService eventExecutor = | ||
163 | - newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-node", "event-handler")); | ||
164 | - | ||
165 | - private final NetworkConfigListener configListener = new InternalConfigListener(); | ||
166 | - private final DeviceListener deviceListener = new InternalDeviceListener(); | ||
167 | - private final MapEventListener<String, CordVtnNode> nodeStoreListener = new InternalMapListener(); | ||
168 | - | ||
169 | - private final OvsdbHandler ovsdbHandler = new OvsdbHandler(); | ||
170 | - private final BridgeHandler bridgeHandler = new BridgeHandler(); | ||
171 | - | ||
172 | - private ConsistentMap<String, CordVtnNode> nodeStore; | ||
173 | - private ApplicationId appId; | ||
174 | - private NodeId localNodeId; | ||
175 | - | ||
176 | - private enum NodeState implements CordVtnNodeState { | ||
177 | - | ||
178 | - INIT { | ||
179 | - @Override | ||
180 | - public void process(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
181 | - if (!nodeManager.isOvsdbConnected(node)) { | ||
182 | - nodeManager.connectOvsdb(node); | ||
183 | - } else { | ||
184 | - nodeManager.createIntegrationBridge(node); | ||
185 | - } | ||
186 | - } | ||
187 | - }, | ||
188 | - BRIDGE_CREATED { | ||
189 | - @Override | ||
190 | - public void process(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
191 | - if (!nodeManager.isOvsdbConnected(node)) { | ||
192 | - nodeManager.connectOvsdb(node); | ||
193 | - } else { | ||
194 | - nodeManager.createTunnelInterface(node); | ||
195 | - nodeManager.addDataPlaneInterface(node); | ||
196 | - } | ||
197 | - } | ||
198 | - }, | ||
199 | - PORTS_ADDED { | ||
200 | - @Override | ||
201 | - public void process(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
202 | - nodeManager.setIpAddress(node); | ||
203 | - } | ||
204 | - }, | ||
205 | - COMPLETE { | ||
206 | - @Override | ||
207 | - public void process(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
208 | - nodeManager.postInit(node); | ||
209 | - } | ||
210 | - }, | ||
211 | - INCOMPLETE { | ||
212 | - @Override | ||
213 | - public void process(CordVtnNodeManager nodeManager, CordVtnNode node) { | ||
214 | - } | ||
215 | - }; | ||
216 | - | ||
217 | - public abstract void process(CordVtnNodeManager nodeManager, CordVtnNode node); | ||
218 | - } | ||
219 | - | ||
220 | - @Activate | ||
221 | - protected void activate() { | ||
222 | - appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID); | ||
223 | - | ||
224 | - localNodeId = clusterService.getLocalNode().id(); | ||
225 | - leadershipService.runForLeadership(appId.name()); | ||
226 | - | ||
227 | - nodeStore = storageService.<String, CordVtnNode>consistentMapBuilder() | ||
228 | - .withSerializer(Serializer.using(NODE_SERIALIZER.build())) | ||
229 | - .withName("cordvtn-nodestore") | ||
230 | - .withApplicationId(appId) | ||
231 | - .build(); | ||
232 | - | ||
233 | - nodeStore.addListener(nodeStoreListener); | ||
234 | - deviceService.addListener(deviceListener); | ||
235 | - configService.addListener(configListener); | ||
236 | - | ||
237 | - log.info("Started"); | ||
238 | - } | ||
239 | - | ||
240 | - @Deactivate | ||
241 | - protected void deactivate() { | ||
242 | - configService.removeListener(configListener); | ||
243 | - deviceService.removeListener(deviceListener); | ||
244 | - nodeStore.removeListener(nodeStoreListener); | ||
245 | - | ||
246 | - leadershipService.withdraw(appId.name()); | ||
247 | - eventExecutor.shutdown(); | ||
248 | - | ||
249 | - log.info("Stopped"); | ||
250 | - } | ||
251 | - | ||
252 | - /** | ||
253 | - * Adds or updates a new node to the service. | ||
254 | - * | ||
255 | - * @param node cordvtn node | ||
256 | - */ | ||
257 | - public void addOrUpdateNode(CordVtnNode node) { | ||
258 | - checkNotNull(node); | ||
259 | - nodeStore.put(node.hostname(), CordVtnNode.getUpdatedNode(node, getNodeState(node))); | ||
260 | - } | ||
261 | - | ||
262 | - /** | ||
263 | - * Deletes a node from the service. | ||
264 | - * | ||
265 | - * @param node cordvtn node | ||
266 | - */ | ||
267 | - public void deleteNode(CordVtnNode node) { | ||
268 | - checkNotNull(node); | ||
269 | - | ||
270 | - if (isOvsdbConnected(node)) { | ||
271 | - disconnectOvsdb(node); | ||
272 | - } | ||
273 | - | ||
274 | - nodeStore.remove(node.hostname()); | ||
275 | - } | ||
276 | - | ||
277 | - /** | ||
278 | - * Returns node initialization state. | ||
279 | - * | ||
280 | - * @param node cordvtn node | ||
281 | - * @return true if initial node setup is completed, otherwise false | ||
282 | - */ | ||
283 | - public boolean isNodeInitComplete(CordVtnNode node) { | ||
284 | - checkNotNull(node); | ||
285 | - return nodeStore.containsKey(node.hostname()) && getNodeState(node).equals(NodeState.COMPLETE); | ||
286 | - } | ||
287 | - | ||
288 | - /** | ||
289 | - * Returns detailed node initialization state. | ||
290 | - * | ||
291 | - * @param node cordvtn node | ||
292 | - * @return string including detailed node init state | ||
293 | - */ | ||
294 | - public String checkNodeInitState(CordVtnNode node) { | ||
295 | - checkNotNull(node); | ||
296 | - | ||
297 | - if (!nodeStore.containsKey(node.hostname())) { | ||
298 | - log.warn("Node {} does not exist, add node first", node.hostname()); | ||
299 | - return null; | ||
300 | - } | ||
301 | - | ||
302 | - Session session = connect(node.sshInfo()); | ||
303 | - if (session == null) { | ||
304 | - log.debug("Failed to SSH to {}", node.hostname()); | ||
305 | - return null; | ||
306 | - } | ||
307 | - | ||
308 | - Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE); | ||
309 | - String result = String.format( | ||
310 | - "Current state : %s%n" + | ||
311 | - "br-int created and connected to ONOS : %s (%s)%n" + | ||
312 | - "VXLAN interface added to br-int : %s%n" + | ||
313 | - "Data plane interface is added to br-int and enabled : %s (%s)%n" + | ||
314 | - "IP flushed from data plane interface : %s (%s)%n" + | ||
315 | - "Data plane IP added to br-int : %s (%s)%n" + | ||
316 | - "Local management IP added to br-int : %s (%s)", | ||
317 | - node.state(), | ||
318 | - isBrIntCreated(node) ? OK : NO, node.intBrId(), | ||
319 | - isTunnelIntfCreated(node) ? OK : NO, | ||
320 | - isDataPlaneIntfAdded(node) ? OK : NO, node.dpIntf(), | ||
321 | - isInterfaceUp(session, node.dpIntf()) && | ||
322 | - getCurrentIps(session, node.dpIntf()).isEmpty() ? OK : NO, node.dpIntf(), | ||
323 | - intBrIps.contains(node.dpIp().ip()) ? OK : NO, node.dpIp().cidr(), | ||
324 | - intBrIps.contains(node.localMgmtIp().ip()) ? OK : NO, node.localMgmtIp().cidr()); | ||
325 | - | ||
326 | - disconnect(session); | ||
327 | - | ||
328 | - return result; | ||
329 | - } | ||
330 | - | ||
331 | - /** | ||
332 | - * Returns the number of the nodes known to the service. | ||
333 | - * | ||
334 | - * @return number of nodes | ||
335 | - */ | ||
336 | - public int getNodeCount() { | ||
337 | - return nodeStore.size(); | ||
338 | - } | ||
339 | - | ||
340 | - /** | ||
341 | - * Returns all nodes known to the service. | ||
342 | - * | ||
343 | - * @return list of nodes | ||
344 | - */ | ||
345 | - public List<CordVtnNode> getNodes() { | ||
346 | - return nodeStore.values().stream().map(Versioned::value).collect(Collectors.toList()); | ||
347 | - } | ||
348 | - | ||
349 | - /** | ||
350 | - * Returns all nodes in complete state. | ||
351 | - * | ||
352 | - * @return set of nodes | ||
353 | - */ | ||
354 | - public Set<CordVtnNode> completeNodes() { | ||
355 | - return getNodes().stream().filter(this::isNodeInitComplete).collect(Collectors.toSet()); | ||
356 | - } | ||
357 | - | ||
358 | - /** | ||
359 | - * Returns physical data plane port number of a given device. | ||
360 | - * | ||
361 | - * @param deviceId integration bridge device id | ||
362 | - * @return port number; null otherwise | ||
363 | - */ | ||
364 | - public PortNumber dpPort(DeviceId deviceId) { | ||
365 | - CordVtnNode node = nodeByBridgeId(deviceId); | ||
366 | - if (node == null) { | ||
367 | - log.warn("Failed to get node for {}", deviceId); | ||
368 | - return null; | ||
369 | - } | ||
370 | - Port port = deviceService.getPorts(deviceId).stream() | ||
371 | - .filter(p -> portName(p).contains(node.dpIntf()) && | ||
372 | - p.isEnabled()) | ||
373 | - .findFirst().orElse(null); | ||
374 | - | ||
375 | - return port == null ? null : port.number(); | ||
376 | - } | ||
377 | - | ||
378 | - /** | ||
379 | - * Returns physical data plane IP address of a given device. | ||
380 | - * | ||
381 | - * @param deviceId integration bridge device id | ||
382 | - * @return ip address; null otherwise | ||
383 | - */ | ||
384 | - public IpAddress dpIp(DeviceId deviceId) { | ||
385 | - CordVtnNode node = nodeByBridgeId(deviceId); | ||
386 | - if (node == null) { | ||
387 | - log.warn("Failed to get node for {}", deviceId); | ||
388 | - return null; | ||
389 | - } | ||
390 | - return node.dpIp().ip(); | ||
391 | - } | ||
392 | - | ||
393 | - /** | ||
394 | - * Returns tunnel port number of a given device. | ||
395 | - * | ||
396 | - * @param deviceId integration bridge device id | ||
397 | - * @return port number | ||
398 | - */ | ||
399 | - public PortNumber tunnelPort(DeviceId deviceId) { | ||
400 | - Port port = deviceService.getPorts(deviceId).stream() | ||
401 | - .filter(p -> portName(p).contains(DEFAULT_TUNNEL)) | ||
402 | - .findFirst().orElse(null); | ||
403 | - | ||
404 | - return port == null ? null : port.number(); | ||
405 | - } | ||
406 | - | ||
407 | - /** | ||
408 | - * Returns if current node state saved in nodeStore is COMPLETE or not. | ||
409 | - * | ||
410 | - * @param node cordvtn node | ||
411 | - * @return true if it's complete state, otherwise false | ||
412 | - */ | ||
413 | - private boolean isNodeStateComplete(CordVtnNode node) { | ||
414 | - checkNotNull(node); | ||
415 | - | ||
416 | - // the state saved in nodeStore can be wrong if IP address settings are changed | ||
417 | - // after the node init has been completed since there's no way to detect it | ||
418 | - // getNodeState and checkNodeInitState always return correct answer but can be slow | ||
419 | - Versioned<CordVtnNode> versionedNode = nodeStore.get(node.hostname()); | ||
420 | - CordVtnNodeState state = versionedNode.value().state(); | ||
421 | - return state != null && state.equals(NodeState.COMPLETE); | ||
422 | - } | ||
423 | - | ||
424 | - /** | ||
425 | - * Initiates node to serve virtual tenant network. | ||
426 | - * | ||
427 | - * @param node cordvtn node | ||
428 | - */ | ||
429 | - private void initNode(CordVtnNode node) { | ||
430 | - checkNotNull(node); | ||
431 | - | ||
432 | - NodeState state = (NodeState) node.state(); | ||
433 | - log.debug("Processing node: {} state: {}", node.hostname(), state); | ||
434 | - | ||
435 | - state.process(this, node); | ||
436 | - } | ||
437 | - | ||
438 | - /** | ||
439 | - * Performs tasks after node initialization. | ||
440 | - * It disconnects unnecessary OVSDB connection and installs initial flow | ||
441 | - * rules on the device. | ||
442 | - * | ||
443 | - * @param node cordvtn node | ||
444 | - */ | ||
445 | - private void postInit(CordVtnNode node) { | ||
446 | - disconnectOvsdb(node); | ||
447 | - pipeline.initPipeline(node, dpPort(node.intBrId()), tunnelPort(node.intBrId())); | ||
448 | - | ||
449 | - deviceService.getPorts(node.intBrId()).stream() | ||
450 | - .filter(port -> portName(port).startsWith(VPORT_PREFIX) && | ||
451 | - port.isEnabled()) | ||
452 | - .forEach(port -> instanceManager.addInstance(connectPoint(port))); | ||
453 | - | ||
454 | - hostService.getHosts().forEach(host -> { | ||
455 | - if (deviceService.getPort(host.location().deviceId(), | ||
456 | - host.location().port()) == null) { | ||
457 | - instanceManager.removeInstance(connectPoint(host)); | ||
458 | - } | ||
459 | - }); | ||
460 | - | ||
461 | - log.info("Finished init {}", node.hostname()); | ||
462 | - } | ||
463 | - | ||
464 | - /** | ||
465 | - * Sets a new state for a given cordvtn node. | ||
466 | - * | ||
467 | - * @param node cordvtn node | ||
468 | - * @param newState new node state | ||
469 | - */ | ||
470 | - private void setNodeState(CordVtnNode node, NodeState newState) { | ||
471 | - checkNotNull(node); | ||
472 | - | ||
473 | - log.debug("Changed {} state: {}", node.hostname(), newState); | ||
474 | - nodeStore.put(node.hostname(), CordVtnNode.getUpdatedNode(node, newState)); | ||
475 | - } | ||
476 | - | ||
477 | - /** | ||
478 | - * Checks current state of a given cordvtn node and returns it. | ||
479 | - * | ||
480 | - * @param node cordvtn node | ||
481 | - * @return node state | ||
482 | - */ | ||
483 | - private NodeState getNodeState(CordVtnNode node) { | ||
484 | - checkNotNull(node); | ||
485 | - | ||
486 | - if (isBrIntCreated(node) && isTunnelIntfCreated(node) && | ||
487 | - isDataPlaneIntfAdded(node) && isIpAddressSet(node)) { | ||
488 | - return NodeState.COMPLETE; | ||
489 | - } else if (isDataPlaneIntfAdded(node) && isTunnelIntfCreated(node)) { | ||
490 | - return NodeState.PORTS_ADDED; | ||
491 | - } else if (isBrIntCreated(node)) { | ||
492 | - return NodeState.BRIDGE_CREATED; | ||
493 | - } else { | ||
494 | - return NodeState.INIT; | ||
495 | - } | ||
496 | - } | ||
497 | - | ||
498 | - /** | ||
499 | - * Returns connection state of OVSDB server for a given node. | ||
500 | - * | ||
501 | - * @param node cordvtn node | ||
502 | - * @return true if it is connected, false otherwise | ||
503 | - */ | ||
504 | - private boolean isOvsdbConnected(CordVtnNode node) { | ||
505 | - checkNotNull(node); | ||
506 | - | ||
507 | - OvsdbClientService ovsdbClient = getOvsdbClient(node); | ||
508 | - return deviceService.isAvailable(node.ovsdbId()) && | ||
509 | - ovsdbClient != null && ovsdbClient.isConnected(); | ||
510 | - } | ||
511 | - | ||
512 | - /** | ||
513 | - * Connects to OVSDB server for a given node. | ||
514 | - * | ||
515 | - * @param node cordvtn node | ||
516 | - */ | ||
517 | - private void connectOvsdb(CordVtnNode node) { | ||
518 | - checkNotNull(node); | ||
519 | - | ||
520 | - if (!nodeStore.containsKey(node.hostname())) { | ||
521 | - log.warn("Node {} does not exist", node.hostname()); | ||
522 | - return; | ||
523 | - } | ||
524 | - | ||
525 | - if (!isOvsdbConnected(node)) { | ||
526 | - controller.connect(node.hostMgmtIp().ip(), node.ovsdbPort()); | ||
527 | - } | ||
528 | - } | ||
529 | - | ||
530 | - /** | ||
531 | - * Disconnects OVSDB server for a given node. | ||
532 | - * | ||
533 | - * @param node cordvtn node | ||
534 | - */ | ||
535 | - private void disconnectOvsdb(CordVtnNode node) { | ||
536 | - checkNotNull(node); | ||
537 | - | ||
538 | - if (!nodeStore.containsKey(node.hostname())) { | ||
539 | - log.warn("Node {} does not exist", node.hostname()); | ||
540 | - return; | ||
541 | - } | ||
542 | - | ||
543 | - if (isOvsdbConnected(node)) { | ||
544 | - OvsdbClientService ovsdbClient = getOvsdbClient(node); | ||
545 | - ovsdbClient.disconnect(); | ||
546 | - } | ||
547 | - } | ||
548 | - | ||
549 | - /** | ||
550 | - * Returns OVSDB client for a given node. | ||
551 | - * | ||
552 | - * @param node cordvtn node | ||
553 | - * @return OVSDB client, or null if it fails to get OVSDB client | ||
554 | - */ | ||
555 | - private OvsdbClientService getOvsdbClient(CordVtnNode node) { | ||
556 | - checkNotNull(node); | ||
557 | - | ||
558 | - OvsdbClientService ovsdbClient = controller.getOvsdbClient( | ||
559 | - new OvsdbNodeId(node.hostMgmtIp().ip(), node.ovsdbPort().toInt())); | ||
560 | - if (ovsdbClient == null) { | ||
561 | - log.trace("Couldn't find OVSDB client for {}", node.hostname()); | ||
562 | - } | ||
563 | - return ovsdbClient; | ||
564 | - } | ||
565 | - | ||
566 | - /** | ||
567 | - * Creates an integration bridge for a given node. | ||
568 | - * | ||
569 | - * @param node cordvtn node | ||
570 | - */ | ||
571 | - private void createIntegrationBridge(CordVtnNode node) { | ||
572 | - if (isBrIntCreated(node)) { | ||
573 | - return; | ||
574 | - } | ||
575 | - | ||
576 | - List<ControllerInfo> controllers = new ArrayList<>(); | ||
577 | - Sets.newHashSet(clusterService.getNodes()).stream() | ||
578 | - .forEach(controller -> { | ||
579 | - ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp"); | ||
580 | - controllers.add(ctrlInfo); | ||
581 | - }); | ||
582 | - | ||
583 | - String dpid = node.intBrId().toString().substring(DPID_BEGIN); | ||
584 | - | ||
585 | - try { | ||
586 | - Device device = deviceService.getDevice(node.ovsdbId()); | ||
587 | - if (device.is(BridgeConfig.class)) { | ||
588 | - BridgeConfig bridgeConfig = device.as(BridgeConfig.class); | ||
589 | - bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE), dpid, controllers); | ||
590 | - } else { | ||
591 | - log.warn("The bridging behaviour is not supported in device {}", device.id()); | ||
592 | - } | ||
593 | - } catch (ItemNotFoundException e) { | ||
594 | - log.warn("Failed to create integration bridge on {}", node.hostname()); | ||
595 | - } | ||
596 | - } | ||
597 | - | ||
598 | - /** | ||
599 | - * Creates tunnel interface to the integration bridge for a given node. | ||
600 | - * | ||
601 | - * @param node cordvtn node | ||
602 | - */ | ||
603 | - private void createTunnelInterface(CordVtnNode node) { | ||
604 | - if (isTunnelIntfCreated(node)) { | ||
605 | - return; | ||
606 | - } | ||
607 | - | ||
608 | - DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder(); | ||
609 | - for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) { | ||
610 | - optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key)); | ||
611 | - } | ||
612 | - | ||
613 | - TunnelDescription description = new DefaultTunnelDescription( | ||
614 | - null, null, VXLAN, TunnelName.tunnelName(DEFAULT_TUNNEL), | ||
615 | - optionBuilder.build()); | ||
616 | - | ||
617 | - try { | ||
618 | - Device device = deviceService.getDevice(node.ovsdbId()); | ||
619 | - if (device.is(TunnelConfig.class)) { | ||
620 | - TunnelConfig tunnelConfig = device.as(TunnelConfig.class); | ||
621 | - tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE), description); | ||
622 | - } else { | ||
623 | - log.warn("The tunneling behaviour is not supported in device {}", device.id()); | ||
624 | - } | ||
625 | - } catch (ItemNotFoundException e) { | ||
626 | - log.warn("Failed to create tunnel interface on {}", node.hostname()); | ||
627 | - } | ||
628 | - } | ||
629 | - | ||
630 | - /** | ||
631 | - * Adds data plane interface to a given node. | ||
632 | - * | ||
633 | - * @param node cordvtn node | ||
634 | - */ | ||
635 | - private void addDataPlaneInterface(CordVtnNode node) { | ||
636 | - if (isDataPlaneIntfAdded(node)) { | ||
637 | - return; | ||
638 | - } | ||
639 | - | ||
640 | - Session session = connect(node.sshInfo()); | ||
641 | - if (session == null) { | ||
642 | - log.debug("Failed to SSH to {}", node.hostname()); | ||
643 | - return; | ||
644 | - } | ||
645 | - | ||
646 | - if (!isInterfaceUp(session, node.dpIntf())) { | ||
647 | - log.warn("Interface {} is not available", node.dpIntf()); | ||
648 | - return; | ||
649 | - } | ||
650 | - disconnect(session); | ||
651 | - | ||
652 | - try { | ||
653 | - Device device = deviceService.getDevice(node.ovsdbId()); | ||
654 | - if (device.is(BridgeConfig.class)) { | ||
655 | - BridgeConfig bridgeConfig = device.as(BridgeConfig.class); | ||
656 | - bridgeConfig.addPort(BridgeName.bridgeName(DEFAULT_BRIDGE), node.dpIntf()); | ||
657 | - } else { | ||
658 | - log.warn("The bridging behaviour is not supported in device {}", device.id()); | ||
659 | - } | ||
660 | - } catch (ItemNotFoundException e) { | ||
661 | - log.warn("Failed to add {} on {}", node.dpIntf(), node.hostname()); | ||
662 | - } | ||
663 | - } | ||
664 | - | ||
665 | - /** | ||
666 | - * Flushes IP address from data plane interface and adds data plane IP address | ||
667 | - * to integration bridge. | ||
668 | - * | ||
669 | - * @param node cordvtn node | ||
670 | - */ | ||
671 | - private void setIpAddress(CordVtnNode node) { | ||
672 | - Session session = connect(node.sshInfo()); | ||
673 | - if (session == null) { | ||
674 | - log.debug("Failed to SSH to {}", node.hostname()); | ||
675 | - return; | ||
676 | - } | ||
677 | - | ||
678 | - getCurrentIps(session, DEFAULT_BRIDGE).stream() | ||
679 | - .filter(ip -> !ip.equals(node.localMgmtIp().ip())) | ||
680 | - .filter(ip -> !ip.equals(node.dpIp().ip())) | ||
681 | - .forEach(ip -> deleteIp(session, ip, DEFAULT_BRIDGE)); | ||
682 | - | ||
683 | - boolean result = flushIp(session, node.dpIntf()) && | ||
684 | - setInterfaceUp(session, node.dpIntf()) && | ||
685 | - addIp(session, node.dpIp(), DEFAULT_BRIDGE) && | ||
686 | - addIp(session, node.localMgmtIp(), DEFAULT_BRIDGE) && | ||
687 | - setInterfaceUp(session, DEFAULT_BRIDGE); | ||
688 | - | ||
689 | - disconnect(session); | ||
690 | - | ||
691 | - if (result) { | ||
692 | - setNodeState(node, NodeState.COMPLETE); | ||
693 | - } | ||
694 | - } | ||
695 | - | ||
696 | - /** | ||
697 | - * Checks if integration bridge exists and available. | ||
698 | - * | ||
699 | - * @param node cordvtn node | ||
700 | - * @return true if the bridge is available, false otherwise | ||
701 | - */ | ||
702 | - private boolean isBrIntCreated(CordVtnNode node) { | ||
703 | - return (deviceService.getDevice(node.intBrId()) != null | ||
704 | - && deviceService.isAvailable(node.intBrId())); | ||
705 | - } | ||
706 | - | ||
707 | - /** | ||
708 | - * Checks if tunnel interface exists. | ||
709 | - * | ||
710 | - * @param node cordvtn node | ||
711 | - * @return true if the interface exists, false otherwise | ||
712 | - */ | ||
713 | - private boolean isTunnelIntfCreated(CordVtnNode node) { | ||
714 | - return deviceService.getPorts(node.intBrId()) | ||
715 | - .stream() | ||
716 | - .filter(p -> portName(p).contains(DEFAULT_TUNNEL) && | ||
717 | - p.isEnabled()) | ||
718 | - .findAny().isPresent(); | ||
719 | - } | ||
720 | - | ||
721 | - /** | ||
722 | - * Checks if data plane interface exists. | ||
723 | - * | ||
724 | - * @param node cordvtn node | ||
725 | - * @return true if the interface exists, false otherwise | ||
726 | - */ | ||
727 | - private boolean isDataPlaneIntfAdded(CordVtnNode node) { | ||
728 | - return deviceService.getPorts(node.intBrId()) | ||
729 | - .stream() | ||
730 | - .filter(p -> portName(p).contains(node.dpIntf()) && | ||
731 | - p.isEnabled()) | ||
732 | - .findAny().isPresent(); | ||
733 | - } | ||
734 | - | ||
735 | - /** | ||
736 | - * Checks if the IP addresses are correctly set. | ||
737 | - * | ||
738 | - * @param node cordvtn node | ||
739 | - * @return true if the IP is set, false otherwise | ||
740 | - */ | ||
741 | - private boolean isIpAddressSet(CordVtnNode node) { | ||
742 | - Session session = connect(node.sshInfo()); | ||
743 | - if (session == null) { | ||
744 | - log.debug("Failed to SSH to {}", node.hostname()); | ||
745 | - return false; | ||
746 | - } | ||
747 | - | ||
748 | - Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE); | ||
749 | - boolean result = getCurrentIps(session, node.dpIntf()).isEmpty() && | ||
750 | - isInterfaceUp(session, node.dpIntf()) && | ||
751 | - intBrIps.contains(node.dpIp().ip()) && | ||
752 | - intBrIps.contains(node.localMgmtIp().ip()) && | ||
753 | - isInterfaceUp(session, DEFAULT_BRIDGE); | ||
754 | - | ||
755 | - disconnect(session); | ||
756 | - return result; | ||
757 | - } | ||
758 | - | ||
759 | - /** | ||
760 | - * Returns connect point of a given port. | ||
761 | - * | ||
762 | - * @param port port | ||
763 | - * @return connect point | ||
764 | - */ | ||
765 | - private ConnectPoint connectPoint(Port port) { | ||
766 | - return new ConnectPoint(port.element().id(), port.number()); | ||
767 | - } | ||
768 | - | ||
769 | - /** | ||
770 | - * Returns connect point of a given host. | ||
771 | - * | ||
772 | - * @param host host | ||
773 | - * @return connect point | ||
774 | - */ | ||
775 | - private ConnectPoint connectPoint(Host host) { | ||
776 | - return new ConnectPoint(host.location().deviceId(), host.location().port()); | ||
777 | - } | ||
778 | - | ||
779 | - /** | ||
780 | - * Returns cordvtn node associated with a given OVSDB device. | ||
781 | - * | ||
782 | - * @param ovsdbId OVSDB device id | ||
783 | - * @return cordvtn node, null if it fails to find the node | ||
784 | - */ | ||
785 | - private CordVtnNode nodeByOvsdbId(DeviceId ovsdbId) { | ||
786 | - return getNodes().stream() | ||
787 | - .filter(node -> node.ovsdbId().equals(ovsdbId)) | ||
788 | - .findFirst().orElse(null); | ||
789 | - } | ||
790 | - | ||
791 | - /** | ||
792 | - * Returns cordvtn node associated with a given integration bridge. | ||
793 | - * | ||
794 | - * @param bridgeId device id of integration bridge | ||
795 | - * @return cordvtn node, null if it fails to find the node | ||
796 | - */ | ||
797 | - private CordVtnNode nodeByBridgeId(DeviceId bridgeId) { | ||
798 | - return getNodes().stream() | ||
799 | - .filter(node -> node.intBrId().equals(bridgeId)) | ||
800 | - .findFirst().orElse(null); | ||
801 | - } | ||
802 | - | ||
803 | - /** | ||
804 | - * Returns port name. | ||
805 | - * | ||
806 | - * @param port port | ||
807 | - * @return port name | ||
808 | - */ | ||
809 | - private String portName(Port port) { | ||
810 | - return port.annotations().value("portName"); | ||
811 | - } | ||
812 | - | ||
813 | - private class OvsdbHandler implements ConnectionHandler<Device> { | ||
814 | - | ||
815 | - @Override | ||
816 | - public void connected(Device device) { | ||
817 | - CordVtnNode node = nodeByOvsdbId(device.id()); | ||
818 | - if (node != null) { | ||
819 | - setNodeState(node, getNodeState(node)); | ||
820 | - } else { | ||
821 | - log.debug("{} is detected on unregistered node, ignore it.", device.id()); | ||
822 | - } | ||
823 | - } | ||
824 | - | ||
825 | - @Override | ||
826 | - public void disconnected(Device device) { | ||
827 | - if (!deviceService.isAvailable(device.id())) { | ||
828 | - log.debug("Device {} is disconnected", device.id()); | ||
829 | - adminService.removeDevice(device.id()); | ||
830 | - } | ||
831 | - } | ||
832 | - } | ||
833 | - | ||
834 | - private class BridgeHandler implements ConnectionHandler<Device> { | ||
835 | - | ||
836 | - @Override | ||
837 | - public void connected(Device device) { | ||
838 | - CordVtnNode node = nodeByBridgeId(device.id()); | ||
839 | - if (node != null) { | ||
840 | - setNodeState(node, getNodeState(node)); | ||
841 | - } else { | ||
842 | - log.debug("{} is detected on unregistered node, ignore it.", device.id()); | ||
843 | - } | ||
844 | - } | ||
845 | - | ||
846 | - @Override | ||
847 | - public void disconnected(Device device) { | ||
848 | - CordVtnNode node = nodeByBridgeId(device.id()); | ||
849 | - if (node != null) { | ||
850 | - log.debug("Integration Bridge is disconnected from {}", node.hostname()); | ||
851 | - setNodeState(node, NodeState.INCOMPLETE); | ||
852 | - } | ||
853 | - } | ||
854 | - | ||
855 | - /** | ||
856 | - * Handles port added situation. | ||
857 | - * If the added port is tunnel or data plane interface, proceed to the remaining | ||
858 | - * node initialization. Otherwise, do nothing. | ||
859 | - * | ||
860 | - * @param port port | ||
861 | - */ | ||
862 | - public void portAdded(Port port) { | ||
863 | - CordVtnNode node = nodeByBridgeId((DeviceId) port.element().id()); | ||
864 | - String portName = portName(port); | ||
865 | - | ||
866 | - if (node == null) { | ||
867 | - log.debug("{} is added to unregistered node, ignore it.", portName); | ||
868 | - return; | ||
869 | - } | ||
870 | - | ||
871 | - log.info("Port {} is added to {}", portName, node.hostname()); | ||
872 | - | ||
873 | - if (portName.startsWith(VPORT_PREFIX)) { | ||
874 | - if (isNodeStateComplete(node)) { | ||
875 | - instanceManager.addInstance(connectPoint(port)); | ||
876 | - } else { | ||
877 | - log.debug("VM is detected on incomplete node, ignore it.", portName); | ||
878 | - } | ||
879 | - } else if (portName.contains(DEFAULT_TUNNEL) || portName.equals(node.dpIntf())) { | ||
880 | - setNodeState(node, getNodeState(node)); | ||
881 | - } | ||
882 | - } | ||
883 | - | ||
884 | - /** | ||
885 | - * Handles port removed situation. | ||
886 | - * If the removed port is tunnel or data plane interface, proceed to the remaining | ||
887 | - * node initialization.Others, do nothing. | ||
888 | - * | ||
889 | - * @param port port | ||
890 | - */ | ||
891 | - public void portRemoved(Port port) { | ||
892 | - CordVtnNode node = nodeByBridgeId((DeviceId) port.element().id()); | ||
893 | - String portName = portName(port); | ||
894 | - | ||
895 | - if (node == null) { | ||
896 | - return; | ||
897 | - } | ||
898 | - | ||
899 | - log.info("Port {} is removed from {}", portName, node.hostname()); | ||
900 | - | ||
901 | - if (portName.startsWith(VPORT_PREFIX)) { | ||
902 | - if (isNodeStateComplete(node)) { | ||
903 | - instanceManager.removeInstance(connectPoint(port)); | ||
904 | - } else { | ||
905 | - log.debug("VM is vanished from incomplete node, ignore it.", portName); | ||
906 | - } | ||
907 | - } else if (portName.contains(DEFAULT_TUNNEL) || portName.equals(node.dpIntf())) { | ||
908 | - setNodeState(node, NodeState.INCOMPLETE); | ||
909 | - } | ||
910 | - } | ||
911 | - } | ||
912 | - | ||
913 | - private class InternalDeviceListener implements DeviceListener { | ||
914 | - | ||
915 | - @Override | ||
916 | - public void event(DeviceEvent event) { | ||
917 | - | ||
918 | - NodeId leaderNodeId = leadershipService.getLeader(appId.name()); | ||
919 | - if (!Objects.equals(localNodeId, leaderNodeId)) { | ||
920 | - // do not allow to proceed without leadership | ||
921 | - return; | ||
922 | - } | ||
923 | - | ||
924 | - Device device = event.subject(); | ||
925 | - ConnectionHandler<Device> handler = | ||
926 | - (device.type().equals(SWITCH) ? bridgeHandler : ovsdbHandler); | ||
927 | - | ||
928 | - switch (event.type()) { | ||
929 | - case PORT_ADDED: | ||
930 | - eventExecutor.execute(() -> bridgeHandler.portAdded(event.port())); | ||
931 | - break; | ||
932 | - case PORT_UPDATED: | ||
933 | - if (!event.port().isEnabled()) { | ||
934 | - eventExecutor.execute(() -> bridgeHandler.portRemoved(event.port())); | ||
935 | - } | ||
936 | - break; | ||
937 | - case DEVICE_ADDED: | ||
938 | - case DEVICE_AVAILABILITY_CHANGED: | ||
939 | - if (deviceService.isAvailable(device.id())) { | ||
940 | - eventExecutor.execute(() -> handler.connected(device)); | ||
941 | - } else { | ||
942 | - eventExecutor.execute(() -> handler.disconnected(device)); | ||
943 | - } | ||
944 | - break; | ||
945 | - default: | ||
946 | - break; | ||
947 | - } | ||
948 | - } | ||
949 | - } | ||
950 | - | ||
951 | - /** | ||
952 | - * Reads cordvtn nodes from config file. | ||
953 | - */ | ||
954 | - private void readConfiguration() { | ||
955 | - CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | ||
956 | - if (config == null) { | ||
957 | - log.debug("No configuration found"); | ||
958 | - return; | ||
959 | - } | ||
960 | - config.cordVtnNodes().forEach(this::addOrUpdateNode); | ||
961 | - } | ||
962 | - | ||
963 | - private class InternalConfigListener implements NetworkConfigListener { | ||
964 | - | ||
965 | - @Override | ||
966 | - public void event(NetworkConfigEvent event) { | ||
967 | - NodeId leaderNodeId = leadershipService.getLeader(appId.name()); | ||
968 | - if (!Objects.equals(localNodeId, leaderNodeId)) { | ||
969 | - // do not allow to proceed without leadership | ||
970 | - return; | ||
971 | - } | ||
972 | - | ||
973 | - if (!event.configClass().equals(CordVtnConfig.class)) { | ||
974 | - return; | ||
975 | - } | ||
976 | - | ||
977 | - switch (event.type()) { | ||
978 | - case CONFIG_ADDED: | ||
979 | - case CONFIG_UPDATED: | ||
980 | - eventExecutor.execute(CordVtnNodeManager.this::readConfiguration); | ||
981 | - break; | ||
982 | - default: | ||
983 | - break; | ||
984 | - } | ||
985 | - } | ||
986 | - } | ||
987 | - | ||
988 | - private class InternalMapListener implements MapEventListener<String, CordVtnNode> { | ||
989 | - | ||
990 | - @Override | ||
991 | - public void event(MapEvent<String, CordVtnNode> event) { | ||
992 | - NodeId leaderNodeId = leadershipService.getLeader(appId.name()); | ||
993 | - if (!Objects.equals(localNodeId, leaderNodeId)) { | ||
994 | - // do not allow to proceed without leadership | ||
995 | - return; | ||
996 | - } | ||
997 | - | ||
998 | - CordVtnNode oldNode; | ||
999 | - CordVtnNode newNode; | ||
1000 | - | ||
1001 | - switch (event.type()) { | ||
1002 | - case UPDATE: | ||
1003 | - oldNode = event.oldValue().value(); | ||
1004 | - newNode = event.newValue().value(); | ||
1005 | - | ||
1006 | - log.info("Reloaded {}", newNode.hostname()); | ||
1007 | - if (!newNode.equals(oldNode)) { | ||
1008 | - log.debug("New node: {}", newNode); | ||
1009 | - } | ||
1010 | - // performs init procedure even if the node is not changed | ||
1011 | - // for robustness since it's no harm to run init procedure | ||
1012 | - // multiple times | ||
1013 | - eventExecutor.execute(() -> initNode(newNode)); | ||
1014 | - break; | ||
1015 | - case INSERT: | ||
1016 | - newNode = event.newValue().value(); | ||
1017 | - log.info("Added {}", newNode.hostname()); | ||
1018 | - eventExecutor.execute(() -> initNode(newNode)); | ||
1019 | - break; | ||
1020 | - case REMOVE: | ||
1021 | - oldNode = event.oldValue().value(); | ||
1022 | - log.info("Removed {}", oldNode.hostname()); | ||
1023 | - break; | ||
1024 | - default: | ||
1025 | - break; | ||
1026 | - } | ||
1027 | - } | ||
1028 | - } | ||
1029 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import org.apache.felix.scr.annotations.Activate; | ||
19 | -import org.apache.felix.scr.annotations.Component; | ||
20 | -import org.apache.felix.scr.annotations.Deactivate; | ||
21 | -import org.apache.felix.scr.annotations.Reference; | ||
22 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
23 | -import org.apache.felix.scr.annotations.Service; | ||
24 | -import org.onlab.packet.Ethernet; | ||
25 | -import org.onlab.packet.IPv4; | ||
26 | -import org.onlab.packet.Ip4Address; | ||
27 | -import org.onlab.packet.IpAddress; | ||
28 | -import org.onlab.packet.TpPort; | ||
29 | -import org.onlab.packet.VlanId; | ||
30 | -import org.onlab.util.ItemNotFoundException; | ||
31 | -import org.onosproject.cordvtn.api.CordVtnNode; | ||
32 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
33 | -import org.onosproject.core.ApplicationId; | ||
34 | -import org.onosproject.core.CoreService; | ||
35 | -import org.onosproject.net.Device; | ||
36 | -import org.onosproject.net.DeviceId; | ||
37 | -import org.onosproject.net.PortNumber; | ||
38 | -import org.onosproject.net.behaviour.ExtensionTreatmentResolver; | ||
39 | -import org.onosproject.net.device.DeviceService; | ||
40 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
41 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
42 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
43 | -import org.onosproject.net.flow.FlowRule; | ||
44 | -import org.onosproject.net.flow.FlowRuleOperations; | ||
45 | -import org.onosproject.net.flow.FlowRuleOperationsContext; | ||
46 | -import org.onosproject.net.flow.FlowRuleService; | ||
47 | -import org.onosproject.net.flow.TrafficSelector; | ||
48 | -import org.onosproject.net.flow.TrafficTreatment; | ||
49 | -import org.onosproject.net.flow.instructions.ExtensionPropertyException; | ||
50 | -import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
51 | -import org.slf4j.Logger; | ||
52 | - | ||
53 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
54 | -import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; | ||
55 | -import static org.slf4j.LoggerFactory.getLogger; | ||
56 | - | ||
57 | -/** | ||
58 | - * Provides CORD VTN pipeline. | ||
59 | - */ | ||
60 | -@Component(immediate = true) | ||
61 | -@Service(value = CordVtnPipeline.class) | ||
62 | -public final class CordVtnPipeline { | ||
63 | - | ||
64 | - protected final Logger log = getLogger(getClass()); | ||
65 | - | ||
66 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
67 | - protected CoreService coreService; | ||
68 | - | ||
69 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
70 | - protected FlowRuleService flowRuleService; | ||
71 | - | ||
72 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
73 | - protected DeviceService deviceService; | ||
74 | - | ||
75 | - // tables | ||
76 | - public static final int TABLE_ZERO = 0; | ||
77 | - public static final int TABLE_IN_PORT = 1; | ||
78 | - public static final int TABLE_ACCESS_TYPE = 2; | ||
79 | - public static final int TABLE_IN_SERVICE = 3; | ||
80 | - public static final int TABLE_DST_IP = 4; | ||
81 | - public static final int TABLE_TUNNEL_IN = 5; | ||
82 | - public static final int TABLE_VLAN = 6; | ||
83 | - | ||
84 | - // priorities | ||
85 | - public static final int PRIORITY_MANAGEMENT = 55000; | ||
86 | - public static final int PRIORITY_HIGH = 50000; | ||
87 | - public static final int PRIORITY_DEFAULT = 5000; | ||
88 | - public static final int PRIORITY_LOW = 4000; | ||
89 | - public static final int PRIORITY_ZERO = 0; | ||
90 | - | ||
91 | - public static final int VXLAN_UDP_PORT = 4789; | ||
92 | - public static final VlanId VLAN_WAN = VlanId.vlanId((short) 500); | ||
93 | - public static final String DEFAULT_TUNNEL = "vxlan"; | ||
94 | - private static final String PORT_NAME = "portName"; | ||
95 | - | ||
96 | - private ApplicationId appId; | ||
97 | - | ||
98 | - @Activate | ||
99 | - protected void activate() { | ||
100 | - appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID); | ||
101 | - log.info("Started"); | ||
102 | - } | ||
103 | - | ||
104 | - @Deactivate | ||
105 | - protected void deactivate() { | ||
106 | - log.info("Stopped"); | ||
107 | - } | ||
108 | - | ||
109 | - /** | ||
110 | - * Flush flows installed by this application. | ||
111 | - */ | ||
112 | - public void flushRules() { | ||
113 | - flowRuleService.getFlowRulesById(appId).forEach(flowRule -> processFlowRule(false, flowRule)); | ||
114 | - } | ||
115 | - | ||
116 | - /** | ||
117 | - * Installs table miss rule to a give device. | ||
118 | - * | ||
119 | - * @param node cordvtn node | ||
120 | - * @param dpPort data plane port number | ||
121 | - * @param tunnelPort tunnel port number | ||
122 | - */ | ||
123 | - public void initPipeline(CordVtnNode node, PortNumber dpPort, PortNumber tunnelPort) { | ||
124 | - checkNotNull(node); | ||
125 | - | ||
126 | - processTableZero(node.intBrId(), dpPort, node.dpIp().ip()); | ||
127 | - processInPortTable(node.intBrId(), tunnelPort, dpPort); | ||
128 | - processAccessTypeTable(node.intBrId(), dpPort); | ||
129 | - processVlanTable(node.intBrId(), dpPort); | ||
130 | - } | ||
131 | - | ||
132 | - private void processTableZero(DeviceId deviceId, PortNumber dpPort, IpAddress dpIp) { | ||
133 | - // take vxlan packet out onto the physical port | ||
134 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
135 | - .matchInPort(PortNumber.LOCAL) | ||
136 | - .build(); | ||
137 | - | ||
138 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
139 | - .setOutput(dpPort) | ||
140 | - .build(); | ||
141 | - | ||
142 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
143 | - .fromApp(appId) | ||
144 | - .withSelector(selector) | ||
145 | - .withTreatment(treatment) | ||
146 | - .withPriority(PRIORITY_HIGH) | ||
147 | - .forDevice(deviceId) | ||
148 | - .forTable(TABLE_ZERO) | ||
149 | - .makePermanent() | ||
150 | - .build(); | ||
151 | - | ||
152 | - processFlowRule(true, flowRule); | ||
153 | - | ||
154 | - // take a vxlan encap'd packet through the Linux stack | ||
155 | - selector = DefaultTrafficSelector.builder() | ||
156 | - .matchInPort(dpPort) | ||
157 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
158 | - .matchIPProtocol(IPv4.PROTOCOL_UDP) | ||
159 | - .matchUdpDst(TpPort.tpPort(VXLAN_UDP_PORT)) | ||
160 | - .build(); | ||
161 | - | ||
162 | - treatment = DefaultTrafficTreatment.builder() | ||
163 | - .setOutput(PortNumber.LOCAL) | ||
164 | - .build(); | ||
165 | - | ||
166 | - flowRule = DefaultFlowRule.builder() | ||
167 | - .fromApp(appId) | ||
168 | - .withSelector(selector) | ||
169 | - .withTreatment(treatment) | ||
170 | - .withPriority(PRIORITY_HIGH) | ||
171 | - .forDevice(deviceId) | ||
172 | - .forTable(TABLE_ZERO) | ||
173 | - .makePermanent() | ||
174 | - .build(); | ||
175 | - | ||
176 | - processFlowRule(true, flowRule); | ||
177 | - | ||
178 | - // take a packet to the data plane ip through Linux stack | ||
179 | - selector = DefaultTrafficSelector.builder() | ||
180 | - .matchInPort(dpPort) | ||
181 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
182 | - .matchIPDst(dpIp.toIpPrefix()) | ||
183 | - .build(); | ||
184 | - | ||
185 | - treatment = DefaultTrafficTreatment.builder() | ||
186 | - .setOutput(PortNumber.LOCAL) | ||
187 | - .build(); | ||
188 | - | ||
189 | - flowRule = DefaultFlowRule.builder() | ||
190 | - .fromApp(appId) | ||
191 | - .withSelector(selector) | ||
192 | - .withTreatment(treatment) | ||
193 | - .withPriority(PRIORITY_HIGH) | ||
194 | - .forDevice(deviceId) | ||
195 | - .forTable(TABLE_ZERO) | ||
196 | - .makePermanent() | ||
197 | - .build(); | ||
198 | - | ||
199 | - processFlowRule(true, flowRule); | ||
200 | - | ||
201 | - // take an arp packet from physical through Linux stack | ||
202 | - selector = DefaultTrafficSelector.builder() | ||
203 | - .matchInPort(dpPort) | ||
204 | - .matchEthType(Ethernet.TYPE_ARP) | ||
205 | - .matchArpTpa(dpIp.getIp4Address()) | ||
206 | - .build(); | ||
207 | - | ||
208 | - treatment = DefaultTrafficTreatment.builder() | ||
209 | - .setOutput(PortNumber.LOCAL) | ||
210 | - .build(); | ||
211 | - | ||
212 | - flowRule = DefaultFlowRule.builder() | ||
213 | - .fromApp(appId) | ||
214 | - .withSelector(selector) | ||
215 | - .withTreatment(treatment) | ||
216 | - .withPriority(PRIORITY_HIGH) | ||
217 | - .forDevice(deviceId) | ||
218 | - .forTable(TABLE_ZERO) | ||
219 | - .makePermanent() | ||
220 | - .build(); | ||
221 | - | ||
222 | - processFlowRule(true, flowRule); | ||
223 | - | ||
224 | - // take all else to the next table | ||
225 | - selector = DefaultTrafficSelector.builder() | ||
226 | - .build(); | ||
227 | - | ||
228 | - treatment = DefaultTrafficTreatment.builder() | ||
229 | - .transition(TABLE_IN_PORT) | ||
230 | - .build(); | ||
231 | - | ||
232 | - flowRule = DefaultFlowRule.builder() | ||
233 | - .fromApp(appId) | ||
234 | - .withSelector(selector) | ||
235 | - .withTreatment(treatment) | ||
236 | - .withPriority(PRIORITY_ZERO) | ||
237 | - .forDevice(deviceId) | ||
238 | - .forTable(TABLE_ZERO) | ||
239 | - .makePermanent() | ||
240 | - .build(); | ||
241 | - | ||
242 | - processFlowRule(true, flowRule); | ||
243 | - | ||
244 | - // take all vlan tagged packet to the VLAN table | ||
245 | - selector = DefaultTrafficSelector.builder() | ||
246 | - .matchVlanId(VlanId.ANY) | ||
247 | - .build(); | ||
248 | - | ||
249 | - treatment = DefaultTrafficTreatment.builder() | ||
250 | - .transition(TABLE_VLAN) | ||
251 | - .build(); | ||
252 | - | ||
253 | - flowRule = DefaultFlowRule.builder() | ||
254 | - .fromApp(appId) | ||
255 | - .withSelector(selector) | ||
256 | - .withTreatment(treatment) | ||
257 | - .withPriority(PRIORITY_MANAGEMENT) | ||
258 | - .forDevice(deviceId) | ||
259 | - .forTable(TABLE_ZERO) | ||
260 | - .makePermanent() | ||
261 | - .build(); | ||
262 | - | ||
263 | - processFlowRule(true, flowRule); | ||
264 | - } | ||
265 | - | ||
266 | - private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber dpPort) { | ||
267 | - checkNotNull(tunnelPort); | ||
268 | - | ||
269 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
270 | - .matchInPort(tunnelPort) | ||
271 | - .build(); | ||
272 | - | ||
273 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
274 | - .transition(TABLE_TUNNEL_IN) | ||
275 | - .build(); | ||
276 | - | ||
277 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
278 | - .fromApp(appId) | ||
279 | - .withSelector(selector) | ||
280 | - .withTreatment(treatment) | ||
281 | - .withPriority(PRIORITY_DEFAULT) | ||
282 | - .forDevice(deviceId) | ||
283 | - .forTable(TABLE_IN_PORT) | ||
284 | - .makePermanent() | ||
285 | - .build(); | ||
286 | - | ||
287 | - processFlowRule(true, flowRule); | ||
288 | - | ||
289 | - selector = DefaultTrafficSelector.builder() | ||
290 | - .matchInPort(dpPort) | ||
291 | - .build(); | ||
292 | - | ||
293 | - treatment = DefaultTrafficTreatment.builder() | ||
294 | - .transition(TABLE_DST_IP) | ||
295 | - .build(); | ||
296 | - | ||
297 | - flowRule = DefaultFlowRule.builder() | ||
298 | - .fromApp(appId) | ||
299 | - .withSelector(selector) | ||
300 | - .withTreatment(treatment) | ||
301 | - .withPriority(PRIORITY_DEFAULT) | ||
302 | - .forDevice(deviceId) | ||
303 | - .forTable(TABLE_IN_PORT) | ||
304 | - .makePermanent() | ||
305 | - .build(); | ||
306 | - | ||
307 | - processFlowRule(true, flowRule); | ||
308 | - } | ||
309 | - | ||
310 | - private void processAccessTypeTable(DeviceId deviceId, PortNumber dpPort) { | ||
311 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
312 | - .build(); | ||
313 | - | ||
314 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
315 | - .setOutput(dpPort) | ||
316 | - .build(); | ||
317 | - | ||
318 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
319 | - .fromApp(appId) | ||
320 | - .withSelector(selector) | ||
321 | - .withTreatment(treatment) | ||
322 | - .withPriority(PRIORITY_ZERO) | ||
323 | - .forDevice(deviceId) | ||
324 | - .forTable(TABLE_ACCESS_TYPE) | ||
325 | - .makePermanent() | ||
326 | - .build(); | ||
327 | - | ||
328 | - processFlowRule(true, flowRule); | ||
329 | - } | ||
330 | - | ||
331 | - private void processVlanTable(DeviceId deviceId, PortNumber dpPort) { | ||
332 | - // for traffic going out to WAN, strip vid 500 and take through data plane interface | ||
333 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
334 | - .matchVlanId(VLAN_WAN) | ||
335 | - .build(); | ||
336 | - | ||
337 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
338 | - .popVlan() | ||
339 | - .setOutput(dpPort) | ||
340 | - .build(); | ||
341 | - | ||
342 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
343 | - .fromApp(appId) | ||
344 | - .withSelector(selector) | ||
345 | - .withTreatment(treatment) | ||
346 | - .withPriority(PRIORITY_DEFAULT) | ||
347 | - .forDevice(deviceId) | ||
348 | - .forTable(TABLE_VLAN) | ||
349 | - .makePermanent() | ||
350 | - .build(); | ||
351 | - | ||
352 | - processFlowRule(true, flowRule); | ||
353 | - | ||
354 | - selector = DefaultTrafficSelector.builder() | ||
355 | - .matchVlanId(VLAN_WAN) | ||
356 | - .matchEthType(Ethernet.TYPE_ARP) | ||
357 | - .build(); | ||
358 | - | ||
359 | - treatment = DefaultTrafficTreatment.builder() | ||
360 | - .setOutput(PortNumber.CONTROLLER) | ||
361 | - .build(); | ||
362 | - | ||
363 | - flowRule = DefaultFlowRule.builder() | ||
364 | - .fromApp(appId) | ||
365 | - .withSelector(selector) | ||
366 | - .withTreatment(treatment) | ||
367 | - .withPriority(PRIORITY_HIGH) | ||
368 | - .forDevice(deviceId) | ||
369 | - .forTable(TABLE_VLAN) | ||
370 | - .makePermanent() | ||
371 | - .build(); | ||
372 | - | ||
373 | - processFlowRule(true, flowRule); | ||
374 | - } | ||
375 | - | ||
376 | - public void processFlowRule(boolean install, FlowRule rule) { | ||
377 | - FlowRuleOperations.Builder oBuilder = FlowRuleOperations.builder(); | ||
378 | - oBuilder = install ? oBuilder.add(rule) : oBuilder.remove(rule); | ||
379 | - | ||
380 | - flowRuleService.apply(oBuilder.build(new FlowRuleOperationsContext() { | ||
381 | - @Override | ||
382 | - public void onError(FlowRuleOperations ops) { | ||
383 | - log.error(String.format("Failed %s, %s", ops.toString(), rule.toString())); | ||
384 | - } | ||
385 | - })); | ||
386 | - } | ||
387 | - | ||
388 | - public ExtensionTreatment tunnelDstTreatment(DeviceId deviceId, Ip4Address remoteIp) { | ||
389 | - try { | ||
390 | - Device device = deviceService.getDevice(deviceId); | ||
391 | - | ||
392 | - if (device.is(ExtensionTreatmentResolver.class)) { | ||
393 | - ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class); | ||
394 | - ExtensionTreatment treatment = | ||
395 | - resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type()); | ||
396 | - treatment.setPropertyValue("tunnelDst", remoteIp); | ||
397 | - return treatment; | ||
398 | - } else { | ||
399 | - log.warn("The extension treatment resolving behaviour is not supported in device {}", | ||
400 | - device.id().toString()); | ||
401 | - return null; | ||
402 | - } | ||
403 | - } catch (ItemNotFoundException | UnsupportedOperationException | | ||
404 | - ExtensionPropertyException e) { | ||
405 | - log.error("Failed to get extension instruction {}", deviceId); | ||
406 | - return null; | ||
407 | - } | ||
408 | - } | ||
409 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Sets; | ||
19 | -import com.google.common.io.CharStreams; | ||
20 | -import com.jcraft.jsch.Channel; | ||
21 | -import com.jcraft.jsch.ChannelExec; | ||
22 | -import com.jcraft.jsch.JSch; | ||
23 | -import com.jcraft.jsch.JSchException; | ||
24 | -import com.jcraft.jsch.Session; | ||
25 | -import org.onlab.packet.IpAddress; | ||
26 | -import org.onosproject.cordvtn.api.NetworkAddress; | ||
27 | -import org.onosproject.cordvtn.api.SshAccessInfo; | ||
28 | -import org.slf4j.Logger; | ||
29 | - | ||
30 | -import java.io.IOException; | ||
31 | -import java.io.InputStream; | ||
32 | -import java.io.InputStreamReader; | ||
33 | -import java.util.Set; | ||
34 | -import java.util.regex.Pattern; | ||
35 | -import java.util.stream.Collectors; | ||
36 | - | ||
37 | -import static org.slf4j.LoggerFactory.getLogger; | ||
38 | - | ||
39 | -/** | ||
40 | - * {@code RemoteIpCommandUtil} provides methods to help execute Linux IP commands to a remote server. | ||
41 | - * It opens individual exec channels for each command. User can create a session with {@code connect} | ||
42 | - * method and then execute a series commands. After done with all commands, the session must be closed | ||
43 | - * explicitly by calling {@code disconnect}. | ||
44 | - */ | ||
45 | -public final class RemoteIpCommandUtil { | ||
46 | - | ||
47 | - protected static final Logger log = getLogger(RemoteIpCommandUtil.class); | ||
48 | - | ||
49 | - private static final String STRICT_HOST_CHECKING = "StrictHostKeyChecking"; | ||
50 | - private static final String DEFAULT_STRICT_HOST_CHECKING = "no"; | ||
51 | - private static final int DEFAULT_SESSION_TIMEOUT = 60000; // milliseconds | ||
52 | - | ||
53 | - private static final String IP_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | ||
54 | - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | ||
55 | - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + | ||
56 | - "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; | ||
57 | - | ||
58 | - private static final String IP_ADDR_SHOW = "sudo ip addr show %s"; | ||
59 | - private static final String IP_ADDR_FLUSH = "sudo ip addr flush %s"; | ||
60 | - private static final String IP_ADDR_ADD = "sudo ip addr add %s dev %s"; | ||
61 | - private static final String IP_ADDR_DELETE = "sudo ip addr delete %s dev %s"; | ||
62 | - private static final String IP_LINK_SHOW = "sudo ip link show %s"; | ||
63 | - private static final String IP_LINK_UP = "sudo ip link set %s up"; | ||
64 | - | ||
65 | - /** | ||
66 | - * Default constructor. | ||
67 | - */ | ||
68 | - private RemoteIpCommandUtil() { | ||
69 | - } | ||
70 | - | ||
71 | - /** | ||
72 | - * Adds a given IP address to a given device. | ||
73 | - * | ||
74 | - * @param session ssh connection | ||
75 | - * @param ip network address | ||
76 | - * @param device device name to assign the ip address | ||
77 | - * @return true if the command succeeds, or false | ||
78 | - */ | ||
79 | - public static boolean addIp(Session session, NetworkAddress ip, String device) { | ||
80 | - if (session == null || !session.isConnected()) { | ||
81 | - return false; | ||
82 | - } | ||
83 | - | ||
84 | - executeCommand(session, String.format(IP_ADDR_ADD, ip.cidr(), device)); | ||
85 | - Set<IpAddress> result = getCurrentIps(session, device); | ||
86 | - return result.contains(ip.ip()); | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * Removes the IP address from a given device. | ||
91 | - * | ||
92 | - * @param session ssh connection | ||
93 | - * @param ip ip address | ||
94 | - * @param device device name | ||
95 | - * @return true if the command succeeds, or false | ||
96 | - */ | ||
97 | - public static boolean deleteIp(Session session, IpAddress ip, String device) { | ||
98 | - if (session == null || !session.isConnected()) { | ||
99 | - return false; | ||
100 | - } | ||
101 | - | ||
102 | - executeCommand(session, String.format(IP_ADDR_DELETE, ip, device)); | ||
103 | - Set<IpAddress> result = getCurrentIps(session, device); | ||
104 | - return !result.contains(ip); | ||
105 | - } | ||
106 | - | ||
107 | - /** | ||
108 | - * Removes all IP address on a given device. | ||
109 | - * | ||
110 | - * @param session ssh connection | ||
111 | - * @param device device name | ||
112 | - * @return true if the command succeeds, or false | ||
113 | - */ | ||
114 | - public static boolean flushIp(Session session, String device) { | ||
115 | - if (session == null || !session.isConnected()) { | ||
116 | - return false; | ||
117 | - } | ||
118 | - | ||
119 | - executeCommand(session, String.format(IP_ADDR_FLUSH, device)); | ||
120 | - return getCurrentIps(session, device).isEmpty(); | ||
121 | - } | ||
122 | - | ||
123 | - /** | ||
124 | - * Returns a set of IP address that a given device has. | ||
125 | - * | ||
126 | - * @param session ssh connection | ||
127 | - * @param device device name | ||
128 | - * @return set of IP prefix or empty set | ||
129 | - */ | ||
130 | - public static Set<IpAddress> getCurrentIps(Session session, String device) { | ||
131 | - if (session == null || !session.isConnected()) { | ||
132 | - return Sets.newHashSet(); | ||
133 | - } | ||
134 | - | ||
135 | - String output = executeCommand(session, String.format(IP_ADDR_SHOW, device)); | ||
136 | - Set<IpAddress> result = Pattern.compile(" |/") | ||
137 | - .splitAsStream(output) | ||
138 | - .filter(s -> s.matches(IP_PATTERN)) | ||
139 | - .map(IpAddress::valueOf) | ||
140 | - .collect(Collectors.toSet()); | ||
141 | - | ||
142 | - return result; | ||
143 | - } | ||
144 | - | ||
145 | - /** | ||
146 | - * Sets link state up for a given device. | ||
147 | - * | ||
148 | - * @param session ssh connection | ||
149 | - * @param device device name | ||
150 | - * @return true if the command succeeds, or false | ||
151 | - */ | ||
152 | - public static boolean setInterfaceUp(Session session, String device) { | ||
153 | - if (session == null || !session.isConnected()) { | ||
154 | - return false; | ||
155 | - } | ||
156 | - | ||
157 | - executeCommand(session, String.format(IP_LINK_UP, device)); | ||
158 | - return isInterfaceUp(session, device); | ||
159 | - } | ||
160 | - | ||
161 | - /** | ||
162 | - * Checks if a given interface is up or not. | ||
163 | - * | ||
164 | - * @param session ssh connection | ||
165 | - * @param device device name | ||
166 | - * @return true if the interface is up, or false | ||
167 | - */ | ||
168 | - public static boolean isInterfaceUp(Session session, String device) { | ||
169 | - if (session == null || !session.isConnected()) { | ||
170 | - return false; | ||
171 | - } | ||
172 | - | ||
173 | - String output = executeCommand(session, String.format(IP_LINK_SHOW, device)); | ||
174 | - return output != null && output.contains("UP"); | ||
175 | - } | ||
176 | - | ||
177 | - /** | ||
178 | - * Creates a new session with a given access information. | ||
179 | - * | ||
180 | - * @param sshInfo information to ssh to the remove server | ||
181 | - * @return ssh session, or null | ||
182 | - */ | ||
183 | - public static Session connect(SshAccessInfo sshInfo) { | ||
184 | - try { | ||
185 | - JSch jsch = new JSch(); | ||
186 | - jsch.addIdentity(sshInfo.privateKey()); | ||
187 | - | ||
188 | - Session session = jsch.getSession(sshInfo.user(), | ||
189 | - sshInfo.remoteIp().toString(), | ||
190 | - sshInfo.port().toInt()); | ||
191 | - session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING); | ||
192 | - session.connect(DEFAULT_SESSION_TIMEOUT); | ||
193 | - | ||
194 | - return session; | ||
195 | - } catch (JSchException e) { | ||
196 | - log.debug("Failed to connect to {} due to {}", sshInfo.toString(), e.toString()); | ||
197 | - return null; | ||
198 | - } | ||
199 | - } | ||
200 | - | ||
201 | - /** | ||
202 | - * Closes a connection. | ||
203 | - * | ||
204 | - * @param session session | ||
205 | - */ | ||
206 | - public static void disconnect(Session session) { | ||
207 | - if (session.isConnected()) { | ||
208 | - session.disconnect(); | ||
209 | - } | ||
210 | - } | ||
211 | - | ||
212 | - /** | ||
213 | - * Executes a given command. It opens exec channel for the command and closes | ||
214 | - * the channel when it's done. | ||
215 | - * | ||
216 | - * @param session ssh connection to a remote server | ||
217 | - * @param command command to execute | ||
218 | - * @return command output string if the command succeeds, or null | ||
219 | - */ | ||
220 | - private static String executeCommand(Session session, String command) { | ||
221 | - if (session == null || !session.isConnected()) { | ||
222 | - return null; | ||
223 | - } | ||
224 | - | ||
225 | - log.trace("Execute command {} to {}", command, session.getHost()); | ||
226 | - | ||
227 | - try { | ||
228 | - Channel channel = session.openChannel("exec"); | ||
229 | - ((ChannelExec) channel).setCommand(command); | ||
230 | - channel.setInputStream(null); | ||
231 | - InputStream output = channel.getInputStream(); | ||
232 | - | ||
233 | - channel.connect(); | ||
234 | - String result = CharStreams.toString(new InputStreamReader(output)); | ||
235 | - channel.disconnect(); | ||
236 | - | ||
237 | - return result; | ||
238 | - } catch (JSchException | IOException e) { | ||
239 | - log.debug("Failed to execute command {} due to {}", command, e.toString()); | ||
240 | - return null; | ||
241 | - } | ||
242 | - } | ||
243 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * Implementation for CORD VTN application. | ||
19 | - */ | ||
20 | -package org.onosproject.cordvtn.impl; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/service/DummyInstanceHandler.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl.service; | ||
17 | - | ||
18 | -import org.apache.felix.scr.annotations.Activate; | ||
19 | -import org.apache.felix.scr.annotations.Component; | ||
20 | - | ||
21 | -import org.apache.felix.scr.annotations.Deactivate; | ||
22 | -import org.onosproject.cordvtn.api.Instance; | ||
23 | -import org.onosproject.cordvtn.api.InstanceHandler; | ||
24 | -import org.onosproject.cordvtn.impl.CordVtnInstanceHandler; | ||
25 | -import org.onosproject.xosclient.api.VtnService; | ||
26 | - | ||
27 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
28 | -import static org.onlab.util.Tools.groupedThreads; | ||
29 | - | ||
30 | -/** | ||
31 | - * Provides network connectivity for dummy service instances. | ||
32 | - */ | ||
33 | -@Component(immediate = true) | ||
34 | -public class DummyInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler { | ||
35 | - | ||
36 | - @Activate | ||
37 | - protected void activate() { | ||
38 | - serviceType = VtnService.ServiceType.DUMMY; | ||
39 | - eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-dummy", "event-handler")); | ||
40 | - super.activate(); | ||
41 | - } | ||
42 | - | ||
43 | - @Deactivate | ||
44 | - protected void deactivate() { | ||
45 | - super.deactivate(); | ||
46 | - } | ||
47 | - | ||
48 | - @Override | ||
49 | - public void instanceDetected(Instance instance) { | ||
50 | - super.instanceDetected(instance); | ||
51 | - } | ||
52 | - | ||
53 | - @Override | ||
54 | - public void instanceRemoved(Instance instance) { | ||
55 | - super.instanceRemoved(instance); | ||
56 | - } | ||
57 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/service/OltAgentInstanceHandler.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl.service; | ||
17 | - | ||
18 | -import com.google.common.collect.Maps; | ||
19 | -import org.apache.felix.scr.annotations.Activate; | ||
20 | -import org.apache.felix.scr.annotations.Component; | ||
21 | -import org.apache.felix.scr.annotations.Deactivate; | ||
22 | -import org.onlab.packet.Ethernet; | ||
23 | -import org.onlab.packet.IpPrefix; | ||
24 | -import org.onosproject.cordconfig.access.AccessAgentConfig; | ||
25 | -import org.onosproject.cordconfig.access.AccessAgentData; | ||
26 | -import org.onosproject.cordvtn.api.CordVtnConfig; | ||
27 | -import org.onosproject.cordvtn.api.Instance; | ||
28 | -import org.onosproject.cordvtn.api.InstanceHandler; | ||
29 | -import org.onosproject.cordvtn.impl.CordVtnInstanceHandler; | ||
30 | -import org.onosproject.net.DeviceId; | ||
31 | -import org.onosproject.net.PortNumber; | ||
32 | -import org.onosproject.net.config.ConfigFactory; | ||
33 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
34 | -import org.onosproject.net.config.NetworkConfigListener; | ||
35 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
36 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
37 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
38 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
39 | -import org.onosproject.net.flow.FlowRule; | ||
40 | -import org.onosproject.net.flow.TrafficSelector; | ||
41 | -import org.onosproject.net.flow.TrafficTreatment; | ||
42 | -import org.onosproject.xosclient.api.VtnService; | ||
43 | - | ||
44 | -import java.util.Map; | ||
45 | -import java.util.Set; | ||
46 | - | ||
47 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
48 | -import static org.onlab.util.Tools.groupedThreads; | ||
49 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.PRIORITY_MANAGEMENT; | ||
50 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.TABLE_ACCESS_TYPE; | ||
51 | - | ||
52 | -/** | ||
53 | - * Provides network connectivity for OLT agent instances. | ||
54 | - */ | ||
55 | -@Component(immediate = true) | ||
56 | -public class OltAgentInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler { | ||
57 | - | ||
58 | - private static final Class<AccessAgentConfig> CONFIG_CLASS = AccessAgentConfig.class; | ||
59 | - private ConfigFactory<DeviceId, AccessAgentConfig> configFactory = | ||
60 | - new ConfigFactory<DeviceId, AccessAgentConfig>( | ||
61 | - SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessAgent") { | ||
62 | - @Override | ||
63 | - public AccessAgentConfig createConfig() { | ||
64 | - return new AccessAgentConfig(); | ||
65 | - } | ||
66 | - }; | ||
67 | - | ||
68 | - private Map<DeviceId, AccessAgentData> oltAgentData = Maps.newConcurrentMap(); | ||
69 | - private IpPrefix mgmtIpRange = null; | ||
70 | - | ||
71 | - @Activate | ||
72 | - protected void activate() { | ||
73 | - eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-olt", "event-handler")); | ||
74 | - serviceType = VtnService.ServiceType.OLT_AGENT; | ||
75 | - | ||
76 | - configRegistry.registerConfigFactory(configFactory); | ||
77 | - configListener = new InternalConfigListener(); | ||
78 | - | ||
79 | - super.activate(); | ||
80 | - } | ||
81 | - | ||
82 | - @Deactivate | ||
83 | - protected void deactivate() { | ||
84 | - super.deactivate(); | ||
85 | - } | ||
86 | - | ||
87 | - @Override | ||
88 | - public void instanceDetected(Instance instance) { | ||
89 | - log.info("OLT agent instance detected {}", instance); | ||
90 | - | ||
91 | - managementAccessRule(instance.deviceId(), true); | ||
92 | - // TODO implement | ||
93 | - } | ||
94 | - | ||
95 | - @Override | ||
96 | - public void instanceRemoved(Instance instance) { | ||
97 | - log.info("OLT agent instance removed {}", instance); | ||
98 | - | ||
99 | - if (getInstances(instance.serviceId()).isEmpty()) { | ||
100 | - nodeManager.completeNodes().stream().forEach(node -> | ||
101 | - managementAccessRule(node.intBrId(), false)); | ||
102 | - } | ||
103 | - | ||
104 | - // TODO implement | ||
105 | - } | ||
106 | - | ||
107 | - private void managementAccessRule(DeviceId deviceId, boolean install) { | ||
108 | - // TODO remove this rule after long term management network is done | ||
109 | - if (mgmtIpRange != null) { | ||
110 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
111 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
112 | - .matchIPDst(mgmtIpRange) | ||
113 | - .build(); | ||
114 | - | ||
115 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
116 | - .setOutput(PortNumber.LOCAL) | ||
117 | - .build(); | ||
118 | - | ||
119 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
120 | - .fromApp(appId) | ||
121 | - .withSelector(selector) | ||
122 | - .withTreatment(treatment) | ||
123 | - .withPriority(PRIORITY_MANAGEMENT) | ||
124 | - .forDevice(deviceId) | ||
125 | - .forTable(TABLE_ACCESS_TYPE) | ||
126 | - .makePermanent() | ||
127 | - .build(); | ||
128 | - | ||
129 | - pipeline.processFlowRule(install, flowRule); | ||
130 | - } | ||
131 | - } | ||
132 | - | ||
133 | - private void readAccessAgentConfig() { | ||
134 | - | ||
135 | - Set<DeviceId> deviceSubjects = configRegistry.getSubjects(DeviceId.class, CONFIG_CLASS); | ||
136 | - deviceSubjects.stream().forEach(subject -> { | ||
137 | - AccessAgentConfig config = configRegistry.getConfig(subject, CONFIG_CLASS); | ||
138 | - if (config != null) { | ||
139 | - oltAgentData.put(subject, config.getAgent()); | ||
140 | - } | ||
141 | - }); | ||
142 | - } | ||
143 | - | ||
144 | - @Override | ||
145 | - protected void readConfiguration() { | ||
146 | - CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class); | ||
147 | - if (config == null) { | ||
148 | - log.debug("No configuration found"); | ||
149 | - return; | ||
150 | - } | ||
151 | - | ||
152 | - osAccess = config.openstackAccess(); | ||
153 | - xosAccess = config.xosAccess(); | ||
154 | - mgmtIpRange = config.managementIpRange(); | ||
155 | - } | ||
156 | - | ||
157 | - public class InternalConfigListener implements NetworkConfigListener { | ||
158 | - | ||
159 | - @Override | ||
160 | - public void event(NetworkConfigEvent event) { | ||
161 | - | ||
162 | - switch (event.type()) { | ||
163 | - case CONFIG_UPDATED: | ||
164 | - case CONFIG_ADDED: | ||
165 | - if (event.configClass().equals(CordVtnConfig.class)) { | ||
166 | - readConfiguration(); | ||
167 | - } else if (event.configClass().equals(CONFIG_CLASS)) { | ||
168 | - readAccessAgentConfig(); | ||
169 | - } | ||
170 | - break; | ||
171 | - default: | ||
172 | - break; | ||
173 | - } | ||
174 | - } | ||
175 | - } | ||
176 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/service/VsgInstanceHandler.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.impl.service; | ||
17 | - | ||
18 | -import com.google.common.base.Strings; | ||
19 | -import com.google.common.collect.Sets; | ||
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.IpAddress; | ||
28 | -import org.onlab.packet.IpPrefix; | ||
29 | -import org.onlab.packet.MacAddress; | ||
30 | -import org.onlab.packet.VlanId; | ||
31 | -import org.onosproject.cordvtn.api.Instance; | ||
32 | -import org.onosproject.cordvtn.api.InstanceHandler; | ||
33 | -import org.onosproject.cordvtn.impl.CordVtnInstanceHandler; | ||
34 | -import org.onosproject.cordvtn.impl.CordVtnInstanceManager; | ||
35 | -import org.onosproject.net.DefaultAnnotations; | ||
36 | -import org.onosproject.net.HostId; | ||
37 | -import org.onosproject.net.PortNumber; | ||
38 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
39 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
40 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
41 | -import org.onosproject.net.flow.FlowRule; | ||
42 | -import org.onosproject.net.flow.FlowRuleService; | ||
43 | -import org.onosproject.net.flow.TrafficSelector; | ||
44 | -import org.onosproject.net.flow.TrafficTreatment; | ||
45 | -import org.onosproject.net.flow.criteria.Criterion; | ||
46 | -import org.onosproject.net.flow.criteria.IPCriterion; | ||
47 | -import org.onosproject.net.flow.instructions.Instruction; | ||
48 | -import org.onosproject.net.flow.instructions.Instructions; | ||
49 | -import org.onosproject.net.flow.instructions.L2ModificationInstruction; | ||
50 | -import org.onosproject.net.host.DefaultHostDescription; | ||
51 | -import org.onosproject.net.host.HostDescription; | ||
52 | -import org.onosproject.xosclient.api.VtnPort; | ||
53 | -import org.onosproject.xosclient.api.VtnPortApi; | ||
54 | -import org.onosproject.xosclient.api.VtnPortId; | ||
55 | -import org.onosproject.xosclient.api.VtnService; | ||
56 | - | ||
57 | -import java.util.Map; | ||
58 | -import java.util.Set; | ||
59 | - | ||
60 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
61 | -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | ||
62 | -import static org.onlab.util.Tools.groupedThreads; | ||
63 | -import static org.onosproject.cordvtn.api.Instance.*; | ||
64 | -import static org.onosproject.cordvtn.impl.CordVtnPipeline.*; | ||
65 | -import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST; | ||
66 | -import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH; | ||
67 | - | ||
68 | -/** | ||
69 | - * Provides network connectivity for vSG instances. | ||
70 | - */ | ||
71 | -@Component(immediate = true) | ||
72 | -@Service(value = VsgInstanceHandler.class) | ||
73 | -public final class VsgInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler { | ||
74 | - | ||
75 | - private static final String STAG = "stag"; | ||
76 | - private static final String VSG_VM = "vsgVm"; | ||
77 | - | ||
78 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
79 | - protected FlowRuleService flowRuleService; | ||
80 | - | ||
81 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
82 | - protected CordVtnInstanceManager instanceManager; | ||
83 | - | ||
84 | - @Activate | ||
85 | - protected void activate() { | ||
86 | - serviceType = VtnService.ServiceType.VSG; | ||
87 | - eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-vsg", "event-handler")); | ||
88 | - super.activate(); | ||
89 | - } | ||
90 | - | ||
91 | - @Deactivate | ||
92 | - protected void deactivate() { | ||
93 | - super.deactivate(); | ||
94 | - } | ||
95 | - | ||
96 | - @Override | ||
97 | - public void instanceDetected(Instance instance) { | ||
98 | - if (isVsgContainer(instance)) { | ||
99 | - log.info("vSG container detected {}", instance); | ||
100 | - | ||
101 | - // find vsg vm for this vsg container | ||
102 | - String vsgVmId = instance.getAnnotation(VSG_VM); | ||
103 | - if (Strings.isNullOrEmpty(vsgVmId)) { | ||
104 | - log.warn("Failed to find VSG VM for {}", instance); | ||
105 | - return; | ||
106 | - } | ||
107 | - | ||
108 | - Instance vsgVm = Instance.of(hostService.getHost(HostId.hostId(vsgVmId))); | ||
109 | - VtnPort vtnPort = getVtnPort(vsgVm); | ||
110 | - if (vtnPort == null || getStag(vtnPort) == null) { | ||
111 | - return; | ||
112 | - } | ||
113 | - | ||
114 | - populateVsgRules(vsgVm, getStag(vtnPort), | ||
115 | - nodeManager.dpPort(vsgVm.deviceId()), | ||
116 | - vtnPort.addressPairs().keySet(), | ||
117 | - true); | ||
118 | - | ||
119 | - } else { | ||
120 | - VtnPort vtnPort = getVtnPort(instance); | ||
121 | - if (vtnPort == null || getStag(vtnPort) == null) { | ||
122 | - return; | ||
123 | - } | ||
124 | - | ||
125 | - vtnPort.addressPairs().entrySet().stream() | ||
126 | - .forEach(pair -> addVsgContainer( | ||
127 | - instance, | ||
128 | - pair.getKey(), | ||
129 | - pair.getValue(), | ||
130 | - getStag(vtnPort).toString() | ||
131 | - )); | ||
132 | - super.instanceDetected(instance); | ||
133 | - } | ||
134 | - } | ||
135 | - | ||
136 | - @Override | ||
137 | - public void instanceRemoved(Instance instance) { | ||
138 | - if (isVsgContainer(instance)) { | ||
139 | - log.info("vSG container vanished {}", instance); | ||
140 | - | ||
141 | - // find vsg vm for this vsg container | ||
142 | - String vsgVmId = instance.getAnnotation(VSG_VM); | ||
143 | - if (Strings.isNullOrEmpty(vsgVmId)) { | ||
144 | - log.warn("Failed to find VSG VM for {}", instance); | ||
145 | - return; | ||
146 | - } | ||
147 | - | ||
148 | - Instance vsgVm = Instance.of(hostService.getHost(HostId.hostId(vsgVmId))); | ||
149 | - VtnPort vtnPort = getVtnPort(vsgVm); | ||
150 | - if (vtnPort == null || getStag(vtnPort) == null) { | ||
151 | - return; | ||
152 | - } | ||
153 | - | ||
154 | - populateVsgRules(vsgVm, getStag(vtnPort), | ||
155 | - nodeManager.dpPort(vsgVm.deviceId()), | ||
156 | - vtnPort.addressPairs().keySet(), | ||
157 | - false); | ||
158 | - | ||
159 | - } else { | ||
160 | - // TODO remove vsg vm related rules | ||
161 | - super.instanceRemoved(instance); | ||
162 | - } | ||
163 | - } | ||
164 | - | ||
165 | - /** | ||
166 | - * Updates set of vSGs in a given vSG VM. | ||
167 | - * | ||
168 | - * @param vsgVmId vsg vm host id | ||
169 | - * @param stag stag | ||
170 | - * @param vsgInstances full set of vsg wan ip and mac address pairs in this vsg vm | ||
171 | - */ | ||
172 | - public void updateVsgInstances(HostId vsgVmId, String stag, Map<IpAddress, MacAddress> vsgInstances) { | ||
173 | - if (hostService.getHost(vsgVmId) == null) { | ||
174 | - log.debug("vSG VM {} is not added yet, ignore this update", vsgVmId); | ||
175 | - return; | ||
176 | - } | ||
177 | - | ||
178 | - Instance vsgVm = Instance.of(hostService.getHost(vsgVmId)); | ||
179 | - if (vsgVm == null) { | ||
180 | - log.warn("Failed to find existing vSG VM for STAG: {}", stag); | ||
181 | - return; | ||
182 | - } | ||
183 | - | ||
184 | - log.info("Updates vSGs in {} with STAG: {}", vsgVm, stag); | ||
185 | - | ||
186 | - // adds vSGs in the address pair | ||
187 | - vsgInstances.entrySet().stream() | ||
188 | - .filter(addr -> hostService.getHostsByMac(addr.getValue()).isEmpty()) | ||
189 | - .forEach(addr -> addVsgContainer( | ||
190 | - vsgVm, | ||
191 | - addr.getKey(), | ||
192 | - addr.getValue(), | ||
193 | - stag)); | ||
194 | - | ||
195 | - // removes vSGs not listed in the address pair | ||
196 | - hostService.getConnectedHosts(vsgVm.host().location()).stream() | ||
197 | - .filter(host -> !host.mac().equals(vsgVm.mac())) | ||
198 | - .filter(host -> !vsgInstances.values().contains(host.mac())) | ||
199 | - .forEach(host -> { | ||
200 | - log.info("Removed vSG {}", host.toString()); | ||
201 | - instanceManager.removeInstance(host.id()); | ||
202 | - }); | ||
203 | - } | ||
204 | - | ||
205 | - private boolean isVsgContainer(Instance instance) { | ||
206 | - return !Strings.isNullOrEmpty(instance.host().annotations().value(STAG)); | ||
207 | - } | ||
208 | - | ||
209 | - private void addVsgContainer(Instance vsgVm, IpAddress vsgWanIp, MacAddress vsgMac, | ||
210 | - String stag) { | ||
211 | - HostId hostId = HostId.hostId(vsgMac); | ||
212 | - DefaultAnnotations.Builder annotations = DefaultAnnotations.builder() | ||
213 | - .set(SERVICE_TYPE, vsgVm.serviceType().toString()) | ||
214 | - .set(SERVICE_ID, vsgVm.serviceId().id()) | ||
215 | - .set(PORT_ID, vsgVm.portId().id()) | ||
216 | - .set(NESTED_INSTANCE, TRUE) | ||
217 | - .set(STAG, stag) | ||
218 | - .set(VSG_VM, vsgVm.host().id().toString()) | ||
219 | - .set(CREATE_TIME, String.valueOf(System.currentTimeMillis())); | ||
220 | - | ||
221 | - HostDescription hostDesc = new DefaultHostDescription( | ||
222 | - vsgMac, | ||
223 | - VlanId.NONE, | ||
224 | - vsgVm.host().location(), | ||
225 | - Sets.newHashSet(vsgWanIp), | ||
226 | - annotations.build()); | ||
227 | - | ||
228 | - instanceManager.addInstance(hostId, hostDesc); | ||
229 | - } | ||
230 | - | ||
231 | - private void populateVsgRules(Instance vsgVm, VlanId stag, PortNumber dpPort, | ||
232 | - Set<IpAddress> vsgWanIps, boolean install) { | ||
233 | - // for traffics with s-tag, strip the tag and take through the vSG VM | ||
234 | - TrafficSelector selector = DefaultTrafficSelector.builder() | ||
235 | - .matchInPort(dpPort) | ||
236 | - .matchVlanId(stag) | ||
237 | - .build(); | ||
238 | - | ||
239 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
240 | - .setOutput(vsgVm.portNumber()) | ||
241 | - .build(); | ||
242 | - | ||
243 | - FlowRule flowRule = DefaultFlowRule.builder() | ||
244 | - .fromApp(appId) | ||
245 | - .withSelector(selector) | ||
246 | - .withTreatment(treatment) | ||
247 | - .withPriority(PRIORITY_DEFAULT) | ||
248 | - .forDevice(vsgVm.deviceId()) | ||
249 | - .forTable(TABLE_VLAN) | ||
250 | - .makePermanent() | ||
251 | - .build(); | ||
252 | - | ||
253 | - pipeline.processFlowRule(install, flowRule); | ||
254 | - | ||
255 | - // for traffics with customer vlan, tag with the service vlan based on input port with | ||
256 | - // lower priority to avoid conflict with WAN tag | ||
257 | - selector = DefaultTrafficSelector.builder() | ||
258 | - .matchInPort(vsgVm.portNumber()) | ||
259 | - .matchVlanId(stag) | ||
260 | - .build(); | ||
261 | - | ||
262 | - treatment = DefaultTrafficTreatment.builder() | ||
263 | - .setOutput(dpPort) | ||
264 | - .build(); | ||
265 | - | ||
266 | - flowRule = DefaultFlowRule.builder() | ||
267 | - .fromApp(appId) | ||
268 | - .withSelector(selector) | ||
269 | - .withTreatment(treatment) | ||
270 | - .withPriority(PRIORITY_DEFAULT) | ||
271 | - .forDevice(vsgVm.deviceId()) | ||
272 | - .forTable(TABLE_VLAN) | ||
273 | - .makePermanent() | ||
274 | - .build(); | ||
275 | - | ||
276 | - pipeline.processFlowRule(install, flowRule); | ||
277 | - | ||
278 | - // for traffic coming from WAN, tag 500 and take through the vSG VM | ||
279 | - // based on destination ip | ||
280 | - vsgWanIps.stream().forEach(ip -> { | ||
281 | - TrafficSelector downstream = DefaultTrafficSelector.builder() | ||
282 | - .matchEthType(Ethernet.TYPE_IPV4) | ||
283 | - .matchIPDst(ip.toIpPrefix()) | ||
284 | - .build(); | ||
285 | - | ||
286 | - TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() | ||
287 | - .pushVlan() | ||
288 | - .setVlanId(VLAN_WAN) | ||
289 | - .setEthDst(vsgVm.mac()) | ||
290 | - .setOutput(vsgVm.portNumber()) | ||
291 | - .build(); | ||
292 | - | ||
293 | - FlowRule downstreamFlowRule = DefaultFlowRule.builder() | ||
294 | - .fromApp(appId) | ||
295 | - .withSelector(downstream) | ||
296 | - .withTreatment(downstreamTreatment) | ||
297 | - .withPriority(PRIORITY_DEFAULT) | ||
298 | - .forDevice(vsgVm.deviceId()) | ||
299 | - .forTable(TABLE_DST_IP) | ||
300 | - .makePermanent() | ||
301 | - .build(); | ||
302 | - | ||
303 | - pipeline.processFlowRule(install, downstreamFlowRule); | ||
304 | - }); | ||
305 | - | ||
306 | - // remove downstream flow rules for the vSG not shown in vsgWanIps | ||
307 | - for (FlowRule rule : flowRuleService.getFlowRulesById(appId)) { | ||
308 | - if (!rule.deviceId().equals(vsgVm.deviceId())) { | ||
309 | - continue; | ||
310 | - } | ||
311 | - PortNumber output = getOutputFromTreatment(rule); | ||
312 | - if (output == null || !output.equals(vsgVm.portNumber()) || | ||
313 | - !isVlanPushFromTreatment(rule)) { | ||
314 | - continue; | ||
315 | - } | ||
316 | - | ||
317 | - IpPrefix dstIp = getDstIpFromSelector(rule); | ||
318 | - if (dstIp != null && !vsgWanIps.contains(dstIp.address())) { | ||
319 | - pipeline.processFlowRule(false, rule); | ||
320 | - } | ||
321 | - } | ||
322 | - } | ||
323 | - | ||
324 | - private VtnPort getVtnPort(Instance instance) { | ||
325 | - checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR); | ||
326 | - checkNotNull(xosAccess, XOS_ACCESS_ERROR); | ||
327 | - | ||
328 | - VtnPortId vtnPortId = instance.portId(); | ||
329 | - VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort(); | ||
330 | - VtnPort vtnPort = portApi.vtnPort(vtnPortId, osAccess); | ||
331 | - if (vtnPort == null) { | ||
332 | - log.warn("Failed to get port information of {}", instance); | ||
333 | - return null; | ||
334 | - } | ||
335 | - return vtnPort; | ||
336 | - } | ||
337 | - | ||
338 | - // TODO get stag from XOS when XOS provides it, extract if from port name for now | ||
339 | - private VlanId getStag(VtnPort vtnPort) { | ||
340 | - checkNotNull(vtnPort); | ||
341 | - | ||
342 | - String portName = vtnPort.name(); | ||
343 | - if (portName != null && portName.startsWith(STAG)) { | ||
344 | - return VlanId.vlanId(portName.split("-")[1]); | ||
345 | - } else { | ||
346 | - return null; | ||
347 | - } | ||
348 | - } | ||
349 | - | ||
350 | - private PortNumber getOutputFromTreatment(FlowRule flowRule) { | ||
351 | - Instruction instruction = flowRule.treatment().allInstructions().stream() | ||
352 | - .filter(inst -> inst instanceof Instructions.OutputInstruction) | ||
353 | - .findFirst() | ||
354 | - .orElse(null); | ||
355 | - if (instruction == null) { | ||
356 | - return null; | ||
357 | - } | ||
358 | - return ((Instructions.OutputInstruction) instruction).port(); | ||
359 | - } | ||
360 | - | ||
361 | - private IpPrefix getDstIpFromSelector(FlowRule flowRule) { | ||
362 | - Criterion criterion = flowRule.selector().getCriterion(IPV4_DST); | ||
363 | - if (criterion != null && criterion instanceof IPCriterion) { | ||
364 | - IPCriterion ip = (IPCriterion) criterion; | ||
365 | - return ip.ip(); | ||
366 | - } else { | ||
367 | - return null; | ||
368 | - } | ||
369 | - } | ||
370 | - | ||
371 | - private boolean isVlanPushFromTreatment(FlowRule flowRule) { | ||
372 | - Instruction instruction = flowRule.treatment().allInstructions().stream() | ||
373 | - .filter(inst -> inst instanceof L2ModificationInstruction) | ||
374 | - .filter(inst -> ((L2ModificationInstruction) inst).subtype().equals(VLAN_PUSH)) | ||
375 | - .findAny() | ||
376 | - .orElse(null); | ||
377 | - return instruction != null; | ||
378 | - } | ||
379 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/service/package-info.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * Implementation of instance handlers for various network services. | ||
19 | - */ | ||
20 | -package org.onosproject.cordvtn.impl.service; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.rest; | ||
18 | - | ||
19 | -import org.onlab.rest.AbstractWebApplication; | ||
20 | - | ||
21 | -import java.util.Set; | ||
22 | - | ||
23 | -/** | ||
24 | - * CORD VTN Web application. | ||
25 | - */ | ||
26 | -public class CordVtnWebApplication extends AbstractWebApplication { | ||
27 | - @Override | ||
28 | - public Set<Class<?>> getClasses() { | ||
29 | - return getClasses(ServiceDependencyWebResource.class, | ||
30 | - NeutronMl2NetworksWebResource.class, | ||
31 | - NeutronMl2SubnetsWebResource.class, | ||
32 | - NeutronMl2PortsWebResource.class); | ||
33 | - } | ||
34 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2NetworksWebResource.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.rest; | ||
17 | - | ||
18 | -import org.onosproject.rest.AbstractWebResource; | ||
19 | -import org.slf4j.Logger; | ||
20 | -import org.slf4j.LoggerFactory; | ||
21 | - | ||
22 | -import javax.ws.rs.Consumes; | ||
23 | -import javax.ws.rs.DELETE; | ||
24 | -import javax.ws.rs.POST; | ||
25 | -import javax.ws.rs.PUT; | ||
26 | -import javax.ws.rs.Path; | ||
27 | -import javax.ws.rs.PathParam; | ||
28 | -import javax.ws.rs.Produces; | ||
29 | -import javax.ws.rs.core.MediaType; | ||
30 | -import javax.ws.rs.core.Response; | ||
31 | -import java.io.InputStream; | ||
32 | - | ||
33 | -/** | ||
34 | - * Dummy Neutron ML2 mechanism driver. | ||
35 | - * It just returns OK for networks resource requests. | ||
36 | - */ | ||
37 | -@Path("networks") | ||
38 | -public class NeutronMl2NetworksWebResource extends AbstractWebResource { | ||
39 | - protected final Logger log = LoggerFactory.getLogger(getClass()); | ||
40 | - private static final String NETWORKS_MESSAGE = "Received networks %s"; | ||
41 | - | ||
42 | - @POST | ||
43 | - @Consumes(MediaType.APPLICATION_JSON) | ||
44 | - @Produces(MediaType.APPLICATION_JSON) | ||
45 | - public Response createNetwork(InputStream input) { | ||
46 | - log.trace(String.format(NETWORKS_MESSAGE, "create")); | ||
47 | - return Response.status(Response.Status.OK).build(); | ||
48 | - } | ||
49 | - | ||
50 | - @PUT | ||
51 | - @Path("{id}") | ||
52 | - @Consumes(MediaType.APPLICATION_JSON) | ||
53 | - @Produces(MediaType.APPLICATION_JSON) | ||
54 | - public Response updateNetwork(@PathParam("id") String id, InputStream input) { | ||
55 | - log.trace(String.format(NETWORKS_MESSAGE, "update")); | ||
56 | - return Response.status(Response.Status.OK).build(); | ||
57 | - } | ||
58 | - | ||
59 | - @DELETE | ||
60 | - @Path("{id}") | ||
61 | - public Response deleteNetwork(@PathParam("id") String id) { | ||
62 | - log.trace(String.format(NETWORKS_MESSAGE, "delete")); | ||
63 | - return Response.noContent().build(); | ||
64 | - } | ||
65 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.rest; | ||
17 | - | ||
18 | -import com.fasterxml.jackson.databind.JsonNode; | ||
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | -import com.google.common.collect.Maps; | ||
21 | -import org.onlab.osgi.DefaultServiceDirectory; | ||
22 | -import org.onlab.packet.IpAddress; | ||
23 | -import org.onlab.packet.MacAddress; | ||
24 | -import org.onosproject.cordvtn.impl.service.VsgInstanceHandler; | ||
25 | -import org.onosproject.net.HostId; | ||
26 | -import org.onosproject.rest.AbstractWebResource; | ||
27 | -import org.slf4j.Logger; | ||
28 | -import org.slf4j.LoggerFactory; | ||
29 | - | ||
30 | -import javax.ws.rs.Consumes; | ||
31 | -import javax.ws.rs.DELETE; | ||
32 | -import javax.ws.rs.POST; | ||
33 | -import javax.ws.rs.PUT; | ||
34 | -import javax.ws.rs.Path; | ||
35 | -import javax.ws.rs.PathParam; | ||
36 | -import javax.ws.rs.Produces; | ||
37 | -import javax.ws.rs.core.MediaType; | ||
38 | -import javax.ws.rs.core.Response; | ||
39 | -import java.io.InputStream; | ||
40 | -import java.util.Map; | ||
41 | - | ||
42 | - | ||
43 | -/** | ||
44 | - * Dummy Neutron ML2 mechanism driver. | ||
45 | - * It just returns OK for ports resource requests except for the port update. | ||
46 | - */ | ||
47 | -@Path("ports") | ||
48 | -public class NeutronMl2PortsWebResource extends AbstractWebResource { | ||
49 | - protected final Logger log = LoggerFactory.getLogger(getClass()); | ||
50 | - private static final String PORTS_MESSAGE = "Received ports %s"; | ||
51 | - | ||
52 | - private static final String PORT = "port"; | ||
53 | - private static final String DEVICE_ID = "device_id"; | ||
54 | - private static final String NAME = "name"; | ||
55 | - private static final String MAC_ADDRESS = "mac_address"; | ||
56 | - private static final String ADDRESS_PAIRS = "allowed_address_pairs"; | ||
57 | - private static final String IP_ADDERSS = "ip_address"; | ||
58 | - private static final String STAG_PREFIX = "stag-"; | ||
59 | - private static final int STAG_BEGIN_INDEX = 5; | ||
60 | - | ||
61 | - private final VsgInstanceHandler service = DefaultServiceDirectory.getService(VsgInstanceHandler.class); | ||
62 | - | ||
63 | - @POST | ||
64 | - @Consumes(MediaType.APPLICATION_JSON) | ||
65 | - @Produces(MediaType.APPLICATION_JSON) | ||
66 | - public Response createPorts(InputStream input) { | ||
67 | - log.trace(String.format(PORTS_MESSAGE, "create")); | ||
68 | - return Response.status(Response.Status.OK).build(); | ||
69 | - } | ||
70 | - | ||
71 | - @PUT | ||
72 | - @Path("{id}") | ||
73 | - @Consumes(MediaType.APPLICATION_JSON) | ||
74 | - @Produces(MediaType.APPLICATION_JSON) | ||
75 | - public Response updatePorts(@PathParam("id") String id, InputStream input) { | ||
76 | - log.debug(String.format(PORTS_MESSAGE, "update")); | ||
77 | - | ||
78 | - // TODO get vSG updates from XOS to CORD VTN service directly | ||
79 | - try { | ||
80 | - ObjectMapper mapper = new ObjectMapper(); | ||
81 | - JsonNode jsonNode = mapper.readTree(input).get(PORT); | ||
82 | - log.trace("{}", jsonNode.toString()); | ||
83 | - | ||
84 | - String deviceId = jsonNode.path(DEVICE_ID).asText(); | ||
85 | - String name = jsonNode.path(NAME).asText(); | ||
86 | - if (deviceId.isEmpty() || name.isEmpty() || !name.startsWith(STAG_PREFIX)) { | ||
87 | - // ignore all updates other than allowed address pairs | ||
88 | - return Response.status(Response.Status.OK).build(); | ||
89 | - } | ||
90 | - | ||
91 | - // this is allowed address pairs updates | ||
92 | - MacAddress mac = MacAddress.valueOf(jsonNode.path(MAC_ADDRESS).asText()); | ||
93 | - Map<IpAddress, MacAddress> vsgInstances = Maps.newHashMap(); | ||
94 | - jsonNode.path(ADDRESS_PAIRS).forEach(addrPair -> { | ||
95 | - IpAddress pairIp = IpAddress.valueOf(addrPair.path(IP_ADDERSS).asText()); | ||
96 | - MacAddress pairMac = MacAddress.valueOf(addrPair.path(MAC_ADDRESS).asText()); | ||
97 | - vsgInstances.put(pairIp, pairMac); | ||
98 | - }); | ||
99 | - | ||
100 | - service.updateVsgInstances(HostId.hostId(mac), | ||
101 | - name.substring(STAG_BEGIN_INDEX), | ||
102 | - vsgInstances); | ||
103 | - } catch (Exception e) { | ||
104 | - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); | ||
105 | - } | ||
106 | - | ||
107 | - return Response.status(Response.Status.OK).build(); | ||
108 | - } | ||
109 | - | ||
110 | - @Path("{id}") | ||
111 | - @DELETE | ||
112 | - public Response deletePorts(@PathParam("id") String id) { | ||
113 | - log.trace(String.format(PORTS_MESSAGE, "delete")); | ||
114 | - return Response.noContent().build(); | ||
115 | - } | ||
116 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2SubnetsWebResource.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2016-present 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.cordvtn.rest; | ||
17 | - | ||
18 | -import org.onosproject.rest.AbstractWebResource; | ||
19 | -import org.slf4j.Logger; | ||
20 | -import org.slf4j.LoggerFactory; | ||
21 | - | ||
22 | -import javax.ws.rs.Consumes; | ||
23 | -import javax.ws.rs.DELETE; | ||
24 | -import javax.ws.rs.POST; | ||
25 | -import javax.ws.rs.PUT; | ||
26 | -import javax.ws.rs.Path; | ||
27 | -import javax.ws.rs.PathParam; | ||
28 | -import javax.ws.rs.Produces; | ||
29 | -import javax.ws.rs.core.MediaType; | ||
30 | -import javax.ws.rs.core.Response; | ||
31 | -import java.io.InputStream; | ||
32 | - | ||
33 | -/** | ||
34 | - * Dummy Neutron ML2 mechanism driver. | ||
35 | - * It just returns OK for subnets resource requests. | ||
36 | - */ | ||
37 | -@Path("subnets") | ||
38 | -public class NeutronMl2SubnetsWebResource extends AbstractWebResource { | ||
39 | - protected final Logger log = LoggerFactory.getLogger(getClass()); | ||
40 | - private static final String SUBNETS_MESSAGE = "Received subnets %s"; | ||
41 | - | ||
42 | - @POST | ||
43 | - @Consumes(MediaType.APPLICATION_JSON) | ||
44 | - @Produces(MediaType.APPLICATION_JSON) | ||
45 | - public Response createSubnet(InputStream input) { | ||
46 | - log.trace(String.format(SUBNETS_MESSAGE, "create")); | ||
47 | - return Response.status(Response.Status.OK).build(); | ||
48 | - } | ||
49 | - | ||
50 | - | ||
51 | - @PUT | ||
52 | - @Path("{id}") | ||
53 | - @Produces(MediaType.APPLICATION_JSON) | ||
54 | - @Consumes(MediaType.APPLICATION_JSON) | ||
55 | - public Response updateSubnet(@PathParam("id") String id, InputStream input) { | ||
56 | - log.trace(String.format(SUBNETS_MESSAGE, "update")); | ||
57 | - return Response.status(Response.Status.OK).build(); | ||
58 | - | ||
59 | - } | ||
60 | - | ||
61 | - @DELETE | ||
62 | - @Path("{id}") | ||
63 | - public Response deleteSubnet(@PathParam("id") String id) { | ||
64 | - log.trace(String.format(SUBNETS_MESSAGE, "delete")); | ||
65 | - return Response.noContent().build(); | ||
66 | - } | ||
67 | -} |
apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright 2015-present 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.cordvtn.rest; | ||
17 | - | ||
18 | -import org.onosproject.cordvtn.api.CordVtnService; | ||
19 | -import org.onosproject.rest.AbstractWebResource; | ||
20 | -import org.onosproject.xosclient.api.VtnServiceId; | ||
21 | - | ||
22 | -import javax.ws.rs.DELETE; | ||
23 | -import javax.ws.rs.POST; | ||
24 | -import javax.ws.rs.Path; | ||
25 | -import javax.ws.rs.PathParam; | ||
26 | -import javax.ws.rs.Produces; | ||
27 | -import javax.ws.rs.core.MediaType; | ||
28 | -import javax.ws.rs.core.Response; | ||
29 | - | ||
30 | -/** | ||
31 | - * Manages service dependency. | ||
32 | - */ | ||
33 | -@Path("service-dependency") | ||
34 | -public class ServiceDependencyWebResource extends AbstractWebResource { | ||
35 | - | ||
36 | - private final CordVtnService service = get(CordVtnService.class); | ||
37 | - private static final String BIDIRECTION = "b"; | ||
38 | - | ||
39 | - /** | ||
40 | - * Creates service dependencies with unidirectional access between the services. | ||
41 | - * | ||
42 | - * @param tServiceId tenant service id | ||
43 | - * @param pServiceId provider service id | ||
44 | - * @return 200 OK | ||
45 | - */ | ||
46 | - @POST | ||
47 | - @Path("{tenantServiceId}/{providerServiceId}") | ||
48 | - @Produces(MediaType.APPLICATION_JSON) | ||
49 | - public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, | ||
50 | - @PathParam("providerServiceId") String pServiceId) { | ||
51 | - service.createServiceDependency(VtnServiceId.of(tServiceId), | ||
52 | - VtnServiceId.of(pServiceId), | ||
53 | - false); | ||
54 | - return Response.status(Response.Status.OK).build(); | ||
55 | - } | ||
56 | - | ||
57 | - /** | ||
58 | - * Creates service dependencies with an access type extension between the services. | ||
59 | - * | ||
60 | - * @param tServiceId tenant service id | ||
61 | - * @param pServiceId provider service id | ||
62 | - * @param direction b for bidirectional access, otherwise unidirectional access | ||
63 | - * @return 200 OK | ||
64 | - */ | ||
65 | - @POST | ||
66 | - @Path("{tenantServiceId}/{providerServiceId}/{direction}") | ||
67 | - @Produces(MediaType.APPLICATION_JSON) | ||
68 | - public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId, | ||
69 | - @PathParam("providerServiceId") String pServiceId, | ||
70 | - @PathParam("direction") String direction) { | ||
71 | - service.createServiceDependency(VtnServiceId.of(tServiceId), | ||
72 | - VtnServiceId.of(pServiceId), | ||
73 | - direction.equals(BIDIRECTION)); | ||
74 | - return Response.status(Response.Status.OK).build(); | ||
75 | - } | ||
76 | - | ||
77 | - /** | ||
78 | - * Removes service dependencies. | ||
79 | - * | ||
80 | - * @param tServiceId tenant service id | ||
81 | - * @param pServiceId provider service id | ||
82 | - * @return 204 NO CONTENT | ||
83 | - */ | ||
84 | - @DELETE | ||
85 | - @Path("{tenantServiceId}/{providerServiceId}") | ||
86 | - public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId, | ||
87 | - @PathParam("providerServiceId") String pServiceId) { | ||
88 | - service.removeServiceDependency(VtnServiceId.of(tServiceId), VtnServiceId.of(pServiceId)); | ||
89 | - return Response.noContent().build(); | ||
90 | - } | ||
91 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -/** | ||
18 | - * REST APIs for CORD VTN. | ||
19 | - */ | ||
20 | -package org.onosproject.cordvtn.rest; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -<!-- | ||
2 | - ~ Copyright 2015-present 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 | -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
17 | - | ||
18 | - <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
19 | - <command> | ||
20 | - <action class="org.onosproject.cordvtn.cli.CordVtnNodeListCommand"/> | ||
21 | - </command> | ||
22 | - <command> | ||
23 | - <action class="org.onosproject.cordvtn.cli.CordVtnNodeDeleteCommand"/> | ||
24 | - </command> | ||
25 | - <command> | ||
26 | - <action class="org.onosproject.cordvtn.cli.CordVtnNodeInitCommand"/> | ||
27 | - </command> | ||
28 | - <command> | ||
29 | - <action class="org.onosproject.cordvtn.cli.CordVtnNodeCheckCommand"/> | ||
30 | - </command> | ||
31 | - <command> | ||
32 | - <action class="org.onosproject.cordvtn.cli.CordVtnFlushRules"/> | ||
33 | - </command> | ||
34 | - </command-bundle> | ||
35 | -</blueprint> |
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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" | ||
18 | - xmlns="http://java.sun.com/xml/ns/javaee" | ||
19 | - xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
20 | - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
21 | - id="ONOS" version="2.5"> | ||
22 | - <display-name>CORD VTN REST API v1.0</display-name> | ||
23 | - | ||
24 | - <security-constraint> | ||
25 | - <web-resource-collection> | ||
26 | - <web-resource-name>Secured</web-resource-name> | ||
27 | - <url-pattern>/*</url-pattern> | ||
28 | - </web-resource-collection> | ||
29 | - <auth-constraint> | ||
30 | - <role-name>admin</role-name> | ||
31 | - </auth-constraint> | ||
32 | - </security-constraint> | ||
33 | - | ||
34 | - <security-role> | ||
35 | - <role-name>admin</role-name> | ||
36 | - </security-role> | ||
37 | - | ||
38 | - <login-config> | ||
39 | - <auth-method>BASIC</auth-method> | ||
40 | - <realm-name>karaf</realm-name> | ||
41 | - </login-config> | ||
42 | - | ||
43 | - <servlet> | ||
44 | - <servlet-name>JAX-RS Service</servlet-name> | ||
45 | - <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> | ||
46 | - <init-param> | ||
47 | - <param-name>javax.ws.rs.Application</param-name> | ||
48 | - <param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</param-value> | ||
49 | - </init-param> | ||
50 | - <load-on-startup>1</load-on-startup> | ||
51 | - </servlet> | ||
52 | - | ||
53 | - <servlet-mapping> | ||
54 | - <servlet-name>JAX-RS Service</servlet-name> | ||
55 | - <url-pattern>/*</url-pattern> | ||
56 | - </servlet-mapping> | ||
57 | -</web-app> |
apps/igmp/BUCK
deleted
100644 → 0
1 | -COMPILE_DEPS = [ | ||
2 | - '//lib:CORE_DEPS', | ||
3 | - '//lib:org.apache.karaf.shell.console', | ||
4 | - '//cli:onos-cli', | ||
5 | - '//apps/olt:onos-apps-olt-api', | ||
6 | - '//apps/cordconfig:onos-apps-cordconfig', | ||
7 | -] | ||
8 | - | ||
9 | -BUNDLES = [ | ||
10 | - '//apps/olt:onos-apps-olt-api', | ||
11 | - '//apps/igmp:onos-apps-igmp', | ||
12 | -] | ||
13 | - | ||
14 | -osgi_jar_with_tests ( | ||
15 | - deps = COMPILE_DEPS, | ||
16 | -) | ||
17 | - | ||
18 | -onos_app ( | ||
19 | - title = 'IGMP App', | ||
20 | - category = 'Traffic Steering', | ||
21 | - url = 'http://onosproject.org', | ||
22 | - description = 'Internet Group Message Protocol', | ||
23 | - included_bundles = BUNDLES, | ||
24 | -) |
apps/igmp/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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/xsd/maven-4.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.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-app-igmp</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <description>Internet Group Message Protocol</description> | ||
33 | - | ||
34 | - <properties> | ||
35 | - <onos.app.name>org.onosproject.igmp</onos.app.name> | ||
36 | - <onos.app.title>IGMP App</onos.app.title> | ||
37 | - <onos.app.category>Traffic Steering</onos.app.category> | ||
38 | - <onos.app.url>http://onosproject.org</onos.app.url> | ||
39 | - <onos.app.readme>IGMP implementation.</onos.app.readme> | ||
40 | - <onos.app.requires>org.onosproject.cord-config</onos.app.requires> | ||
41 | - </properties> | ||
42 | - | ||
43 | - <dependencies> | ||
44 | - <dependency> | ||
45 | - <groupId>org.onosproject</groupId> | ||
46 | - <artifactId>onos-api</artifactId> | ||
47 | - <version>${project.version}</version> | ||
48 | - </dependency> | ||
49 | - | ||
50 | - <dependency> | ||
51 | - <groupId>org.onosproject</groupId> | ||
52 | - <artifactId>onos-cli</artifactId> | ||
53 | - <version>${project.version}</version> | ||
54 | - </dependency> | ||
55 | - | ||
56 | - <dependency> | ||
57 | - <groupId>org.onosproject</groupId> | ||
58 | - <artifactId>onos-app-olt-api</artifactId> | ||
59 | - <version>${project.version}</version> | ||
60 | - </dependency> | ||
61 | - | ||
62 | - <dependency> | ||
63 | - <groupId>org.onosproject</groupId> | ||
64 | - <artifactId>onlab-osgi</artifactId> | ||
65 | - <version>${project.version}</version> | ||
66 | - </dependency> | ||
67 | - | ||
68 | - <dependency> | ||
69 | - <groupId>org.onosproject</groupId> | ||
70 | - <artifactId>onos-cord-config</artifactId> | ||
71 | - <version>${project.version}</version> | ||
72 | - </dependency> | ||
73 | - | ||
74 | - <dependency> | ||
75 | - <groupId>org.onosproject</groupId> | ||
76 | - <artifactId>onlab-junit</artifactId> | ||
77 | - <scope>test</scope> | ||
78 | - </dependency> | ||
79 | - | ||
80 | - <!-- This is needed by ComponentContext, used for tunable configuration --> | ||
81 | - <dependency> | ||
82 | - <groupId>org.osgi</groupId> | ||
83 | - <artifactId>org.osgi.compendium</artifactId> | ||
84 | - </dependency> | ||
85 | - | ||
86 | - <dependency> | ||
87 | - <groupId>org.apache.felix</groupId> | ||
88 | - <artifactId>org.apache.felix.scr.annotations</artifactId> | ||
89 | - <scope>provided</scope> | ||
90 | - </dependency> | ||
91 | - | ||
92 | - </dependencies> | ||
93 | - | ||
94 | -</project> |
1 | -/* | ||
2 | - * Copyright 2015-present 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.igmp; | ||
17 | - | ||
18 | -import org.apache.felix.scr.annotations.Activate; | ||
19 | -import org.apache.felix.scr.annotations.Component; | ||
20 | -import org.apache.felix.scr.annotations.Deactivate; | ||
21 | -import org.apache.felix.scr.annotations.Modified; | ||
22 | -import org.apache.felix.scr.annotations.Property; | ||
23 | -import org.apache.felix.scr.annotations.Reference; | ||
24 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
25 | -import org.onlab.packet.EthType; | ||
26 | -import org.onlab.packet.Ethernet; | ||
27 | -import org.onlab.packet.IGMP; | ||
28 | -import org.onlab.packet.IGMPMembership; | ||
29 | -import org.onlab.packet.IGMPQuery; | ||
30 | -import org.onlab.packet.IPv4; | ||
31 | -import org.onlab.packet.Ip4Address; | ||
32 | -import org.onlab.packet.IpAddress; | ||
33 | -import org.onlab.packet.IpPrefix; | ||
34 | -import org.onlab.util.SafeRecurringTask; | ||
35 | -import org.onlab.util.Tools; | ||
36 | -import org.onosproject.cfg.ComponentConfigService; | ||
37 | -import org.onosproject.cordconfig.access.AccessDeviceConfig; | ||
38 | -import org.onosproject.cordconfig.access.AccessDeviceData; | ||
39 | -import org.onosproject.core.ApplicationId; | ||
40 | -import org.onosproject.core.CoreService; | ||
41 | -import org.onosproject.net.ConnectPoint; | ||
42 | -import org.onosproject.net.DeviceId; | ||
43 | -import org.onosproject.net.Port; | ||
44 | -import org.onosproject.net.PortNumber; | ||
45 | -import org.onosproject.net.config.ConfigFactory; | ||
46 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
47 | -import org.onosproject.net.config.NetworkConfigListener; | ||
48 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
49 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
50 | -import org.onosproject.net.device.DeviceEvent; | ||
51 | -import org.onosproject.net.device.DeviceListener; | ||
52 | -import org.onosproject.net.device.DeviceService; | ||
53 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
54 | -import org.onosproject.net.flow.TrafficTreatment; | ||
55 | -import org.onosproject.net.flow.criteria.Criteria; | ||
56 | -import org.onosproject.net.flowobjective.DefaultFilteringObjective; | ||
57 | -import org.onosproject.net.flowobjective.FilteringObjective; | ||
58 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
59 | -import org.onosproject.net.flowobjective.Objective; | ||
60 | -import org.onosproject.net.flowobjective.ObjectiveContext; | ||
61 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
62 | -import org.onosproject.net.mcast.McastRoute; | ||
63 | -import org.onosproject.net.mcast.MulticastRouteService; | ||
64 | -import org.onosproject.net.packet.DefaultOutboundPacket; | ||
65 | -import org.onosproject.net.packet.InboundPacket; | ||
66 | -import org.onosproject.net.packet.PacketContext; | ||
67 | -import org.onosproject.net.packet.PacketProcessor; | ||
68 | -import org.onosproject.net.packet.PacketService; | ||
69 | - | ||
70 | -import org.osgi.service.component.ComponentContext; | ||
71 | -import org.slf4j.Logger; | ||
72 | - | ||
73 | -import java.nio.ByteBuffer; | ||
74 | -import java.util.Collection; | ||
75 | -import java.util.Dictionary; | ||
76 | -import java.util.List; | ||
77 | -import java.util.Map; | ||
78 | -import java.util.Properties; | ||
79 | -import java.util.concurrent.ConcurrentHashMap; | ||
80 | -import java.util.concurrent.Executors; | ||
81 | -import java.util.concurrent.ScheduledExecutorService; | ||
82 | -import java.util.concurrent.ScheduledFuture; | ||
83 | -import java.util.concurrent.TimeUnit; | ||
84 | - | ||
85 | -import static org.onlab.util.Tools.groupedThreads; | ||
86 | -import static org.slf4j.LoggerFactory.getLogger; | ||
87 | - | ||
88 | -/** | ||
89 | - * Internet Group Management Protocol. | ||
90 | - */ | ||
91 | -@Component(immediate = true) | ||
92 | -public class IgmpSnoop { | ||
93 | - | ||
94 | - private final Logger log = getLogger(getClass()); | ||
95 | - | ||
96 | - private static final String DEST_MAC = "01:00:5E:00:00:01"; | ||
97 | - private static final String DEST_IP = "224.0.0.1"; | ||
98 | - | ||
99 | - private static final int DEFAULT_QUERY_PERIOD_SECS = 60; | ||
100 | - private static final byte DEFAULT_IGMP_RESP_CODE = 100; | ||
101 | - | ||
102 | - @Property(name = "multicastAddress", | ||
103 | - label = "Define the multicast base range to listen to") | ||
104 | - private String multicastAddress = IpPrefix.IPV4_MULTICAST_PREFIX.toString(); | ||
105 | - | ||
106 | - @Property(name = "queryPeriod", intValue = DEFAULT_QUERY_PERIOD_SECS, | ||
107 | - label = "Delay in seconds between successive query runs") | ||
108 | - private int queryPeriod = DEFAULT_QUERY_PERIOD_SECS; | ||
109 | - | ||
110 | - @Property(name = "maxRespCode", byteValue = DEFAULT_IGMP_RESP_CODE, | ||
111 | - label = "Maximum time allowed before sending a responding report") | ||
112 | - private byte maxRespCode = DEFAULT_IGMP_RESP_CODE; | ||
113 | - | ||
114 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
115 | - protected FlowObjectiveService flowObjectiveService; | ||
116 | - | ||
117 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
118 | - protected PacketService packetService; | ||
119 | - | ||
120 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
121 | - protected CoreService coreService; | ||
122 | - | ||
123 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
124 | - protected NetworkConfigRegistry networkConfig; | ||
125 | - | ||
126 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
127 | - protected ComponentConfigService componentConfigService; | ||
128 | - | ||
129 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
130 | - protected MulticastRouteService multicastService; | ||
131 | - | ||
132 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
133 | - protected DeviceService deviceService; | ||
134 | - | ||
135 | - | ||
136 | - private ScheduledFuture<?> queryTask; | ||
137 | - private final ScheduledExecutorService queryService = | ||
138 | - Executors.newSingleThreadScheduledExecutor(groupedThreads("onos/igmp-query", | ||
139 | - "membership-query")); | ||
140 | - | ||
141 | - private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>(); | ||
142 | - | ||
143 | - private Map<IpAddress, IpAddress> ssmTranslateTable = new ConcurrentHashMap<>(); | ||
144 | - | ||
145 | - private DeviceListener deviceListener = new InternalDeviceListener(); | ||
146 | - private IgmpPacketProcessor processor = new IgmpPacketProcessor(); | ||
147 | - private static ApplicationId appId; | ||
148 | - | ||
149 | - private InternalNetworkConfigListener configListener = | ||
150 | - new InternalNetworkConfigListener(); | ||
151 | - | ||
152 | - private static final Class<AccessDeviceConfig> CONFIG_CLASS = | ||
153 | - AccessDeviceConfig.class; | ||
154 | - | ||
155 | - private static final Class<IgmpSsmTranslateConfig> SSM_TRANSLATE_CONFIG_CLASS = | ||
156 | - IgmpSsmTranslateConfig.class; | ||
157 | - | ||
158 | - private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = | ||
159 | - new ConfigFactory<DeviceId, AccessDeviceConfig>( | ||
160 | - SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { | ||
161 | - @Override | ||
162 | - public AccessDeviceConfig createConfig() { | ||
163 | - return new AccessDeviceConfig(); | ||
164 | - } | ||
165 | - }; | ||
166 | - | ||
167 | - private ConfigFactory<ApplicationId, IgmpSsmTranslateConfig> ssmTranslateConfigFactory = | ||
168 | - new ConfigFactory<ApplicationId, IgmpSsmTranslateConfig>( | ||
169 | - SubjectFactories.APP_SUBJECT_FACTORY, SSM_TRANSLATE_CONFIG_CLASS, "ssmTranslate", true) { | ||
170 | - @Override | ||
171 | - public IgmpSsmTranslateConfig createConfig() { | ||
172 | - return new IgmpSsmTranslateConfig(); | ||
173 | - } | ||
174 | - }; | ||
175 | - | ||
176 | - | ||
177 | - private ByteBuffer queryPacket; | ||
178 | - | ||
179 | - | ||
180 | - @Activate | ||
181 | - public void activate(ComponentContext context) { | ||
182 | - componentConfigService.registerProperties(getClass()); | ||
183 | - modified(context); | ||
184 | - | ||
185 | - appId = coreService.registerApplication("org.onosproject.igmp"); | ||
186 | - | ||
187 | - packetService.addProcessor(processor, PacketProcessor.director(1)); | ||
188 | - | ||
189 | - networkConfig.registerConfigFactory(configFactory); | ||
190 | - networkConfig.registerConfigFactory(ssmTranslateConfigFactory); | ||
191 | - networkConfig.addListener(configListener); | ||
192 | - | ||
193 | - networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( | ||
194 | - subject -> { | ||
195 | - AccessDeviceConfig config = networkConfig.getConfig(subject, | ||
196 | - AccessDeviceConfig.class); | ||
197 | - if (config != null) { | ||
198 | - AccessDeviceData data = config.getOlt(); | ||
199 | - oltData.put(data.deviceId(), data); | ||
200 | - | ||
201 | - } | ||
202 | - } | ||
203 | - ); | ||
204 | - | ||
205 | - IgmpSsmTranslateConfig ssmTranslateConfig = | ||
206 | - networkConfig.getConfig(appId, IgmpSsmTranslateConfig.class); | ||
207 | - | ||
208 | - if (ssmTranslateConfig != null) { | ||
209 | - Collection<McastRoute> translations = ssmTranslateConfig.getSsmTranslations(); | ||
210 | - for (McastRoute route : translations) { | ||
211 | - ssmTranslateTable.put(route.group(), route.source()); | ||
212 | - } | ||
213 | - } | ||
214 | - | ||
215 | - oltData.keySet().stream() | ||
216 | - .flatMap(did -> deviceService.getPorts(did).stream()) | ||
217 | - .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number())) | ||
218 | - .filter(p -> p.isEnabled()) | ||
219 | - .forEach(p -> processFilterObjective((DeviceId) p.element().id(), p, false)); | ||
220 | - | ||
221 | - deviceService.addListener(deviceListener); | ||
222 | - | ||
223 | - restartQueryTask(); | ||
224 | - | ||
225 | - log.info("Started"); | ||
226 | - } | ||
227 | - | ||
228 | - @Deactivate | ||
229 | - public void deactivate() { | ||
230 | - packetService.removeProcessor(processor); | ||
231 | - processor = null; | ||
232 | - deviceService.removeListener(deviceListener); | ||
233 | - networkConfig.removeListener(configListener); | ||
234 | - networkConfig.unregisterConfigFactory(configFactory); | ||
235 | - networkConfig.unregisterConfigFactory(ssmTranslateConfigFactory); | ||
236 | - queryTask.cancel(true); | ||
237 | - queryService.shutdownNow(); | ||
238 | - componentConfigService.unregisterProperties(getClass(), false); | ||
239 | - log.info("Stopped"); | ||
240 | - } | ||
241 | - | ||
242 | - @Modified | ||
243 | - protected void modified(ComponentContext context) { | ||
244 | - Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); | ||
245 | - | ||
246 | - // TODO read multicastAddress from config | ||
247 | - String strQueryPeriod = Tools.get(properties, "queryPeriod"); | ||
248 | - String strResponseCode = Tools.get(properties, "maxRespCode"); | ||
249 | - try { | ||
250 | - byte newMaxRespCode = Byte.parseByte(strResponseCode); | ||
251 | - if (maxRespCode != newMaxRespCode) { | ||
252 | - maxRespCode = newMaxRespCode; | ||
253 | - queryPacket = buildQueryPacket(); | ||
254 | - } | ||
255 | - | ||
256 | - int newQueryPeriod = Integer.parseInt(strQueryPeriod); | ||
257 | - if (newQueryPeriod != queryPeriod) { | ||
258 | - queryPeriod = newQueryPeriod; | ||
259 | - restartQueryTask(); | ||
260 | - } | ||
261 | - | ||
262 | - } catch (NumberFormatException e) { | ||
263 | - log.warn("Error parsing config input", e); | ||
264 | - } | ||
265 | - | ||
266 | - log.info("queryPeriod set to {}", queryPeriod); | ||
267 | - log.info("maxRespCode set to {}", maxRespCode); | ||
268 | - } | ||
269 | - | ||
270 | - private void restartQueryTask() { | ||
271 | - if (queryTask != null) { | ||
272 | - queryTask.cancel(true); | ||
273 | - } | ||
274 | - queryPacket = buildQueryPacket(); | ||
275 | - queryTask = queryService.scheduleWithFixedDelay( | ||
276 | - SafeRecurringTask.wrap(this::querySubscribers), | ||
277 | - 0, | ||
278 | - queryPeriod, | ||
279 | - TimeUnit.SECONDS); | ||
280 | - } | ||
281 | - | ||
282 | - private void processFilterObjective(DeviceId devId, Port port, boolean remove) { | ||
283 | - | ||
284 | - //TODO migrate to packet requests when packet service uses filtering objectives | ||
285 | - DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder(); | ||
286 | - | ||
287 | - builder = remove ? builder.deny() : builder.permit(); | ||
288 | - | ||
289 | - FilteringObjective igmp = builder | ||
290 | - .withKey(Criteria.matchInPort(port.number())) | ||
291 | - .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType())) | ||
292 | - .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP)) | ||
293 | - .withMeta(DefaultTrafficTreatment.builder() | ||
294 | - .setOutput(PortNumber.CONTROLLER).build()) | ||
295 | - .fromApp(appId) | ||
296 | - .withPriority(10000) | ||
297 | - .add(new ObjectiveContext() { | ||
298 | - @Override | ||
299 | - public void onSuccess(Objective objective) { | ||
300 | - log.info("Igmp filter for {} on {} installed.", | ||
301 | - devId, port); | ||
302 | - } | ||
303 | - | ||
304 | - @Override | ||
305 | - public void onError(Objective objective, ObjectiveError error) { | ||
306 | - log.info("Igmp filter for {} on {} failed because {}.", | ||
307 | - devId, port, error); | ||
308 | - } | ||
309 | - }); | ||
310 | - | ||
311 | - flowObjectiveService.filter(devId, igmp); | ||
312 | - } | ||
313 | - | ||
314 | - private void processMembership(IGMP pkt, ConnectPoint location) { | ||
315 | - pkt.getGroups().forEach(group -> { | ||
316 | - | ||
317 | - if (!(group instanceof IGMPMembership)) { | ||
318 | - log.warn("Wrong group type in IGMP membership"); | ||
319 | - return; | ||
320 | - } | ||
321 | - | ||
322 | - IGMPMembership membership = (IGMPMembership) group; | ||
323 | - | ||
324 | - IpAddress groupAddress = membership.getGaddr(); | ||
325 | - | ||
326 | - if (membership.getRecordType() == IGMPMembership.MODE_IS_INCLUDE || | ||
327 | - membership.getRecordType() == IGMPMembership.CHANGE_TO_INCLUDE_MODE) { | ||
328 | - | ||
329 | - if (membership.getSources().isEmpty()) { | ||
330 | - McastRoute route = ssmTranslateRoute(groupAddress); | ||
331 | - if (route != null) { | ||
332 | - removeRoute(route, location); | ||
333 | - } | ||
334 | - } else { | ||
335 | - membership.getSources().stream() | ||
336 | - .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) | ||
337 | - .forEach(route -> addRoute(route, location)); | ||
338 | - } | ||
339 | - } else if (membership.getRecordType() == IGMPMembership.MODE_IS_EXCLUDE || | ||
340 | - membership.getRecordType() == IGMPMembership.CHANGE_TO_EXCLUDE_MODE) { | ||
341 | - | ||
342 | - if (membership.getSources().isEmpty()) { | ||
343 | - McastRoute route = ssmTranslateRoute(groupAddress); | ||
344 | - if (route != null) { | ||
345 | - addRoute(route, location); | ||
346 | - } | ||
347 | - } else { | ||
348 | - membership.getSources().stream() | ||
349 | - .map(source -> new McastRoute(source, groupAddress, McastRoute.Type.IGMP)) | ||
350 | - .forEach(route -> removeRoute(route, location)); | ||
351 | - } | ||
352 | - } | ||
353 | - }); | ||
354 | - } | ||
355 | - | ||
356 | - private McastRoute ssmTranslateRoute(IpAddress group) { | ||
357 | - IpAddress source = ssmTranslateTable.get(group); | ||
358 | - if (source == null) { | ||
359 | - log.warn("No SSM translate source found for group {}", group); | ||
360 | - return null; | ||
361 | - } | ||
362 | - return new McastRoute(source, group, McastRoute.Type.IGMP); | ||
363 | - } | ||
364 | - | ||
365 | - private void addRoute(McastRoute route, ConnectPoint location) { | ||
366 | - multicastService.add(route); | ||
367 | - multicastService.addSink(route, location); | ||
368 | - } | ||
369 | - | ||
370 | - private void removeRoute(McastRoute route, ConnectPoint location) { | ||
371 | - multicastService.removeSink(route, location); | ||
372 | - // TODO remove route if all sinks are gone | ||
373 | - } | ||
374 | - | ||
375 | - private ByteBuffer buildQueryPacket() { | ||
376 | - IGMP igmp = new IGMP(); | ||
377 | - igmp.setIgmpType(IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY); | ||
378 | - igmp.setMaxRespCode(maxRespCode); | ||
379 | - | ||
380 | - IGMPQuery query = new IGMPQuery(IpAddress.valueOf("0.0.0.0"), 0); | ||
381 | - igmp.addGroup(query); | ||
382 | - | ||
383 | - IPv4 ip = new IPv4(); | ||
384 | - ip.setDestinationAddress(DEST_IP); | ||
385 | - ip.setProtocol(IPv4.PROTOCOL_IGMP); | ||
386 | - ip.setSourceAddress("192.168.1.1"); | ||
387 | - ip.setTtl((byte) 1); | ||
388 | - ip.setPayload(igmp); | ||
389 | - | ||
390 | - Ethernet eth = new Ethernet(); | ||
391 | - eth.setDestinationMACAddress(DEST_MAC); | ||
392 | - eth.setSourceMACAddress("DE:AD:BE:EF:BA:11"); | ||
393 | - eth.setEtherType(Ethernet.TYPE_IPV4); | ||
394 | - | ||
395 | - eth.setPayload(ip); | ||
396 | - | ||
397 | - eth.setPad(true); | ||
398 | - | ||
399 | - return ByteBuffer.wrap(eth.serialize()); | ||
400 | - } | ||
401 | - | ||
402 | - private void querySubscribers() { | ||
403 | - oltData.keySet().stream() | ||
404 | - .flatMap(did -> deviceService.getPorts(did).stream()) | ||
405 | - .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number())) | ||
406 | - .filter(p -> p.isEnabled()) | ||
407 | - .forEach(p -> { | ||
408 | - TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
409 | - .setOutput(p.number()).build(); | ||
410 | - packetService.emit(new DefaultOutboundPacket((DeviceId) p.element().id(), | ||
411 | - treatment, queryPacket)); | ||
412 | - }); | ||
413 | - } | ||
414 | - | ||
415 | - /** | ||
416 | - * Packet processor responsible for handling IGMP packets. | ||
417 | - */ | ||
418 | - private class IgmpPacketProcessor implements PacketProcessor { | ||
419 | - | ||
420 | - @Override | ||
421 | - public void process(PacketContext context) { | ||
422 | - // Stop processing if the packet has been handled, since we | ||
423 | - // can't do any more to it. | ||
424 | - if (context.isHandled()) { | ||
425 | - return; | ||
426 | - } | ||
427 | - | ||
428 | - InboundPacket pkt = context.inPacket(); | ||
429 | - Ethernet ethPkt = pkt.parsed(); | ||
430 | - if (ethPkt == null) { | ||
431 | - return; | ||
432 | - } | ||
433 | - | ||
434 | - | ||
435 | - // IPv6 MLD packets are handled by ICMP6. We'll only deal with IPv4. | ||
436 | - if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) { | ||
437 | - return; | ||
438 | - } | ||
439 | - | ||
440 | - IPv4 ip = (IPv4) ethPkt.getPayload(); | ||
441 | - IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress()); | ||
442 | - IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress()); | ||
443 | - log.trace("Packet ({}, {}) -> ingress port: {}", saddr, gaddr, | ||
444 | - context.inPacket().receivedFrom()); | ||
445 | - | ||
446 | - | ||
447 | - if (ip.getProtocol() != IPv4.PROTOCOL_IGMP || | ||
448 | - !IpPrefix.IPV4_MULTICAST_PREFIX.contains(gaddr)) { | ||
449 | - return; | ||
450 | - } | ||
451 | - | ||
452 | - if (IpPrefix.IPV4_MULTICAST_PREFIX.contains(saddr)) { | ||
453 | - log.debug("IGMP Picked up a packet with a multicast source address."); | ||
454 | - return; | ||
455 | - } | ||
456 | - | ||
457 | - IGMP igmp = (IGMP) ip.getPayload(); | ||
458 | - switch (igmp.getIgmpType()) { | ||
459 | - case IGMP.TYPE_IGMPV3_MEMBERSHIP_REPORT: | ||
460 | - processMembership(igmp, pkt.receivedFrom()); | ||
461 | - break; | ||
462 | - | ||
463 | - case IGMP.TYPE_IGMPV3_MEMBERSHIP_QUERY: | ||
464 | - log.debug("Received a membership query {} from {}", | ||
465 | - igmp, pkt.receivedFrom()); | ||
466 | - break; | ||
467 | - | ||
468 | - case IGMP.TYPE_IGMPV1_MEMBERSHIP_REPORT: | ||
469 | - case IGMP.TYPE_IGMPV2_MEMBERSHIP_REPORT: | ||
470 | - case IGMP.TYPE_IGMPV2_LEAVE_GROUP: | ||
471 | - log.debug("IGMP version 1 & 2 message types are not currently supported. Message type: {}", | ||
472 | - igmp.getIgmpType()); | ||
473 | - break; | ||
474 | - default: | ||
475 | - log.warn("Unknown IGMP message type: {}", igmp.getIgmpType()); | ||
476 | - break; | ||
477 | - } | ||
478 | - } | ||
479 | - } | ||
480 | - | ||
481 | - | ||
482 | - private class InternalDeviceListener implements DeviceListener { | ||
483 | - @Override | ||
484 | - public void event(DeviceEvent event) { | ||
485 | - DeviceId devId = event.subject().id(); | ||
486 | - switch (event.type()) { | ||
487 | - | ||
488 | - case DEVICE_ADDED: | ||
489 | - case DEVICE_UPDATED: | ||
490 | - case DEVICE_REMOVED: | ||
491 | - case DEVICE_SUSPENDED: | ||
492 | - case DEVICE_AVAILABILITY_CHANGED: | ||
493 | - case PORT_STATS_UPDATED: | ||
494 | - break; | ||
495 | - case PORT_ADDED: | ||
496 | - if (!oltData.get(devId).uplink().equals(event.port().number()) && | ||
497 | - event.port().isEnabled()) { | ||
498 | - processFilterObjective(event.subject().id(), event.port(), false); | ||
499 | - } | ||
500 | - break; | ||
501 | - case PORT_UPDATED: | ||
502 | - if (oltData.get(devId).uplink().equals(event.port().number())) { | ||
503 | - break; | ||
504 | - } | ||
505 | - if (event.port().isEnabled()) { | ||
506 | - processFilterObjective(event.subject().id(), event.port(), false); | ||
507 | - } else { | ||
508 | - processFilterObjective(event.subject().id(), event.port(), true); | ||
509 | - } | ||
510 | - break; | ||
511 | - case PORT_REMOVED: | ||
512 | - processFilterObjective(event.subject().id(), event.port(), true); | ||
513 | - break; | ||
514 | - default: | ||
515 | - log.warn("Unknown device event {}", event.type()); | ||
516 | - break; | ||
517 | - } | ||
518 | - } | ||
519 | - | ||
520 | - @Override | ||
521 | - public boolean isRelevant(DeviceEvent event) { | ||
522 | - return oltData.containsKey(event.subject().id()); | ||
523 | - } | ||
524 | - } | ||
525 | - | ||
526 | - private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
527 | - @Override | ||
528 | - public void event(NetworkConfigEvent event) { | ||
529 | - switch (event.type()) { | ||
530 | - | ||
531 | - case CONFIG_ADDED: | ||
532 | - case CONFIG_UPDATED: | ||
533 | - if (event.configClass().equals(CONFIG_CLASS)) { | ||
534 | - AccessDeviceConfig config = | ||
535 | - networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS); | ||
536 | - if (config != null) { | ||
537 | - oltData.put(config.getOlt().deviceId(), config.getOlt()); | ||
538 | - provisionDefaultFlows((DeviceId) event.subject()); | ||
539 | - } | ||
540 | - } | ||
541 | - if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) { | ||
542 | - IgmpSsmTranslateConfig config = | ||
543 | - networkConfig.getConfig((ApplicationId) event.subject(), | ||
544 | - SSM_TRANSLATE_CONFIG_CLASS); | ||
545 | - | ||
546 | - if (config != null) { | ||
547 | - ssmTranslateTable.clear(); | ||
548 | - config.getSsmTranslations().forEach( | ||
549 | - route -> ssmTranslateTable.put(route.group(), route.source())); | ||
550 | - } | ||
551 | - } | ||
552 | - break; | ||
553 | - case CONFIG_REGISTERED: | ||
554 | - case CONFIG_UNREGISTERED: | ||
555 | - break; | ||
556 | - case CONFIG_REMOVED: | ||
557 | - if (event.configClass().equals(SSM_TRANSLATE_CONFIG_CLASS)) { | ||
558 | - ssmTranslateTable.clear(); | ||
559 | - } else if (event.configClass().equals(CONFIG_CLASS)) { | ||
560 | - oltData.remove(event.subject()); | ||
561 | - } | ||
562 | - | ||
563 | - default: | ||
564 | - break; | ||
565 | - } | ||
566 | - } | ||
567 | - } | ||
568 | - | ||
569 | - private void provisionDefaultFlows(DeviceId deviceId) { | ||
570 | - List<Port> ports = deviceService.getPorts(deviceId); | ||
571 | - | ||
572 | - ports.stream() | ||
573 | - .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number())) | ||
574 | - .filter(p -> p.isEnabled()) | ||
575 | - .forEach(p -> processFilterObjective((DeviceId) p.element().id(), p, false)); | ||
576 | - } | ||
577 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.igmp; | ||
18 | - | ||
19 | -import com.fasterxml.jackson.databind.JsonNode; | ||
20 | -import com.fasterxml.jackson.databind.node.ObjectNode; | ||
21 | -import org.onlab.packet.IpAddress; | ||
22 | -import org.onosproject.core.ApplicationId; | ||
23 | -import org.onosproject.net.config.Config; | ||
24 | -import org.onosproject.net.mcast.McastRoute; | ||
25 | - | ||
26 | -import java.util.ArrayList; | ||
27 | -import java.util.List; | ||
28 | - | ||
29 | -/** | ||
30 | - * IGMP SSM translate configuration. | ||
31 | - */ | ||
32 | -public class IgmpSsmTranslateConfig extends Config<ApplicationId> { | ||
33 | - | ||
34 | - private static final String SOURCE = "source"; | ||
35 | - private static final String GROUP = "group"; | ||
36 | - | ||
37 | - @Override | ||
38 | - public boolean isValid() { | ||
39 | - for (JsonNode node : array) { | ||
40 | - if (!hasOnlyFields((ObjectNode) node, SOURCE, GROUP)) { | ||
41 | - return false; | ||
42 | - } | ||
43 | - | ||
44 | - if (!(isIpAddress((ObjectNode) node, SOURCE, FieldPresence.MANDATORY) && | ||
45 | - isIpAddress((ObjectNode) node, GROUP, FieldPresence.MANDATORY))) { | ||
46 | - return false; | ||
47 | - } | ||
48 | - | ||
49 | - } | ||
50 | - return true; | ||
51 | - } | ||
52 | - | ||
53 | - /** | ||
54 | - * Gets the list of SSM translations. | ||
55 | - * | ||
56 | - * @return SSM translations | ||
57 | - */ | ||
58 | - public List<McastRoute> getSsmTranslations() { | ||
59 | - List<McastRoute> translations = new ArrayList(); | ||
60 | - for (JsonNode node : array) { | ||
61 | - translations.add( | ||
62 | - new McastRoute( | ||
63 | - IpAddress.valueOf(node.path(SOURCE).asText().trim()), | ||
64 | - IpAddress.valueOf(node.path(GROUP).asText().trim()), | ||
65 | - McastRoute.Type.STATIC)); | ||
66 | - } | ||
67 | - | ||
68 | - return translations; | ||
69 | - } | ||
70 | -} |
1 | -/* | ||
2 | - * Copyright 2015-present 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 | -/** | ||
18 | - * IGMP implementation. | ||
19 | - */ | ||
20 | -package org.onosproject.igmp; |
apps/olt/BUCK
deleted
100644 → 0
1 | -COMPILE_DEPS = [ | ||
2 | - '//lib:CORE_DEPS', | ||
3 | - '//lib:javax.ws.rs-api', | ||
4 | - '//lib:jersey-client', | ||
5 | - '//lib:org.apache.karaf.shell.console', | ||
6 | - '//utils/rest:onlab-rest', | ||
7 | - '//cli:onos-cli', | ||
8 | - '//core/store/serializers:onos-core-serializers', | ||
9 | - '//apps/cordconfig:onos-apps-cordconfig', | ||
10 | -] | ||
11 | - | ||
12 | -BUNDLES = [ | ||
13 | - ':onos-apps-olt-api', | ||
14 | - ':onos-apps-olt', | ||
15 | -] | ||
16 | - | ||
17 | -osgi_jar_with_tests ( | ||
18 | - name = 'onos-apps-olt-api', | ||
19 | - srcs = glob(['api/' + SRC + '*.java']), | ||
20 | - deps = COMPILE_DEPS, | ||
21 | - visibility = ['PUBLIC'], | ||
22 | -) | ||
23 | - | ||
24 | -osgi_jar_with_tests ( | ||
25 | - srcs = glob(['app/' + SRC + '*.java']), | ||
26 | - deps = COMPILE_DEPS + [':onos-apps-olt-api'], | ||
27 | - visibility = ['PUBLIC'], | ||
28 | -) | ||
29 | - | ||
30 | -onos_app ( | ||
31 | - title = 'ONOS OLT REST API', | ||
32 | - category = 'Security', | ||
33 | - url = 'http://onosproject.org', | ||
34 | - description = 'OLT application for CORD.', | ||
35 | - included_bundles = BUNDLES, | ||
36 | -) |
apps/olt/api/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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/xsd/maven-4.0.0.xsd"> | ||
20 | - <modelVersion>4.0.0</modelVersion> | ||
21 | - | ||
22 | - <parent> | ||
23 | - <artifactId>onos-olt</artifactId> | ||
24 | - <groupId>org.onosproject</groupId> | ||
25 | - <version>1.6.0-SNAPSHOT</version> | ||
26 | - <relativePath>../pom.xml</relativePath> | ||
27 | - </parent> | ||
28 | - | ||
29 | - <artifactId>onos-app-olt-api</artifactId> | ||
30 | - <packaging>bundle</packaging> | ||
31 | - | ||
32 | - <url>http://onosproject.org</url> | ||
33 | - | ||
34 | - <description>CORD OLT application API</description> | ||
35 | - | ||
36 | - <dependencies> | ||
37 | - <dependency> | ||
38 | - <groupId>org.onosproject</groupId> | ||
39 | - <artifactId>onlab-junit</artifactId> | ||
40 | - <scope>test</scope> | ||
41 | - </dependency> | ||
42 | - <dependency> | ||
43 | - <groupId>org.onosproject</groupId> | ||
44 | - <artifactId>onos-core-serializers</artifactId> | ||
45 | - <version>${project.version}</version> | ||
46 | - </dependency> | ||
47 | - | ||
48 | - <dependency> | ||
49 | - <groupId>org.onosproject</groupId> | ||
50 | - <artifactId>onos-api</artifactId> | ||
51 | - <version>${project.version}</version> | ||
52 | - <classifier>tests</classifier> | ||
53 | - <scope>test</scope> | ||
54 | - </dependency> | ||
55 | - <dependency> | ||
56 | - <groupId>org.onosproject</groupId> | ||
57 | - <artifactId>onos-cord-config</artifactId> | ||
58 | - <version>${project.version}</version> | ||
59 | - </dependency> | ||
60 | - | ||
61 | - </dependencies> | ||
62 | - | ||
63 | - <build> | ||
64 | - <plugins> | ||
65 | - <plugin> | ||
66 | - <groupId>org.apache.felix</groupId> | ||
67 | - <artifactId>maven-bundle-plugin</artifactId> | ||
68 | - <extensions>true</extensions> | ||
69 | - <configuration> | ||
70 | - <instructions> | ||
71 | - <Export-Package>org.onosproject.olt</Export-Package> | ||
72 | - </instructions> | ||
73 | - </configuration> | ||
74 | - </plugin> | ||
75 | - </plugins> | ||
76 | - </build> | ||
77 | -</project> |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt; | ||
17 | - | ||
18 | -import org.onlab.packet.VlanId; | ||
19 | -import org.onosproject.event.AbstractEvent; | ||
20 | -import org.onosproject.net.DeviceId; | ||
21 | - | ||
22 | -import java.util.Optional; | ||
23 | - | ||
24 | -/** | ||
25 | - * Describes an access device event. | ||
26 | - */ | ||
27 | -public class AccessDeviceEvent extends AbstractEvent<AccessDeviceEvent.Type, DeviceId> { | ||
28 | - | ||
29 | - private final Optional<VlanId> sVlan; | ||
30 | - private final Optional<VlanId> cVlan; | ||
31 | - | ||
32 | - public enum Type { | ||
33 | - /** | ||
34 | - * A subscriber was registered and provisioned. | ||
35 | - */ | ||
36 | - SUBSCRIBER_REGISTERED, | ||
37 | - | ||
38 | - /** | ||
39 | - * A subscriber was unregistered and deprovisioned. | ||
40 | - */ | ||
41 | - SUBSCRIBER_UNREGISTERED, | ||
42 | - | ||
43 | - /** | ||
44 | - * An access device connected. | ||
45 | - */ | ||
46 | - DEVICE_CONNECTED, | ||
47 | - | ||
48 | - /** | ||
49 | - * An access device disconnected. | ||
50 | - */ | ||
51 | - DEVICE_DISCONNECTED | ||
52 | - | ||
53 | - } | ||
54 | - | ||
55 | - /** | ||
56 | - * | ||
57 | - * Creates an event of a given type and for the specified device, | ||
58 | - * along with the cVlanId and sVlanId. The vlan fields may not be provisioned | ||
59 | - * if the event is related to the access device (dis)connection. | ||
60 | - * | ||
61 | - * @param type the event type | ||
62 | - * @param deviceId the device id | ||
63 | - * @param sVlanId the service vlan | ||
64 | - * @param cVlanId the customer vlan | ||
65 | - */ | ||
66 | - public AccessDeviceEvent(Type type, DeviceId deviceId, | ||
67 | - VlanId sVlanId, | ||
68 | - VlanId cVlanId) { | ||
69 | - super(type, deviceId); | ||
70 | - this.sVlan = Optional.ofNullable(sVlanId); | ||
71 | - this.cVlan = Optional.ofNullable(cVlanId); | ||
72 | - } | ||
73 | - | ||
74 | - /** | ||
75 | - * | ||
76 | - * Creates an event of a given type and for the specified device, and timestamp | ||
77 | - * along with the cVlanId and sVlanId. The vlan fields may not be provisioned | ||
78 | - * if the event is related to the access device (dis)connection. | ||
79 | - * | ||
80 | - * @param type the event type | ||
81 | - * @param deviceId the device id | ||
82 | - * @param time a timestamp | ||
83 | - * @param sVlanId the service vlan | ||
84 | - * @param cVlanId the customer vlan | ||
85 | - */ | ||
86 | - protected AccessDeviceEvent(Type type, DeviceId deviceId, long time, | ||
87 | - VlanId sVlanId, | ||
88 | - VlanId cVlanId) { | ||
89 | - super(type, deviceId, time); | ||
90 | - this.sVlan = Optional.ofNullable(sVlanId); | ||
91 | - this.cVlan = Optional.ofNullable(cVlanId); | ||
92 | - | ||
93 | - } | ||
94 | - | ||
95 | - public Optional<VlanId> sVlanId() { | ||
96 | - return sVlan; | ||
97 | - } | ||
98 | - | ||
99 | - public Optional<VlanId> cVlanId() { | ||
100 | - return cVlan; | ||
101 | - } | ||
102 | - | ||
103 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt; | ||
17 | - | ||
18 | -import org.onosproject.event.EventListener; | ||
19 | - | ||
20 | -/** | ||
21 | - * Entity capable of receiving access device related events. | ||
22 | - */ | ||
23 | -public interface AccessDeviceListener extends EventListener<AccessDeviceEvent> { | ||
24 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt; | ||
18 | - | ||
19 | -import org.onlab.packet.VlanId; | ||
20 | -import org.onosproject.cordconfig.access.AccessDeviceData; | ||
21 | -import org.onosproject.event.ListenerService; | ||
22 | -import org.onosproject.net.ConnectPoint; | ||
23 | -import org.onosproject.net.DeviceId; | ||
24 | - | ||
25 | -import java.util.Collection; | ||
26 | -import java.util.Map; | ||
27 | - | ||
28 | -/** | ||
29 | - * Service for interacting with an access device (OLT). | ||
30 | - */ | ||
31 | -public interface AccessDeviceService | ||
32 | - extends ListenerService<AccessDeviceEvent, AccessDeviceListener> { | ||
33 | - | ||
34 | - /** | ||
35 | - * Provisions connectivity for a subscriber on an access device. | ||
36 | - * | ||
37 | - * @param port subscriber's connection point | ||
38 | - * @param vlan VLAN ID to provision for subscriber | ||
39 | - */ | ||
40 | - void provisionSubscriber(ConnectPoint port, VlanId vlan); | ||
41 | - | ||
42 | - /** | ||
43 | - * Removes provisioned connectivity for a subscriber from an access device. | ||
44 | - * | ||
45 | - * @param port subscriber's connection point | ||
46 | - */ | ||
47 | - void removeSubscriber(ConnectPoint port); | ||
48 | - | ||
49 | - /** | ||
50 | - * Returns information about the provisioned subscribers. | ||
51 | - * | ||
52 | - * @return subscribers | ||
53 | - */ | ||
54 | - Collection<Map.Entry<ConnectPoint, VlanId>> getSubscribers(); | ||
55 | - | ||
56 | - /** | ||
57 | - * Returns the map of configured OLTs. | ||
58 | - * | ||
59 | - * @return a map | ||
60 | - */ | ||
61 | - Map<DeviceId, AccessDeviceData> fetchOlts(); | ||
62 | - | ||
63 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * OLT application api. | ||
19 | - */ | ||
20 | -package org.onosproject.olt; |
apps/olt/app/app.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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 | -<app name="org.onosproject.olt" origin="ON.Lab" version="${project.version}" | ||
18 | - category="Traffic Steering" url="http://onosproject.org" title="Optical Line Terminal App" | ||
19 | - featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" | ||
20 | - features="${project.artifactId}" apps="org.onosproject.cord-config"> | ||
21 | - <description>${project.description}</description> | ||
22 | - <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact> | ||
23 | - <artifact>mvn:${project.groupId}/onos-app-olt-api/${project.version}</artifact> | ||
24 | -</app> |
apps/olt/app/features.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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 | -<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> | ||
18 | - <feature name="${project.artifactId}" version="${project.version}" | ||
19 | - description="${project.description}"> | ||
20 | - <feature>onos-api</feature> | ||
21 | - <bundle>mvn:${project.groupId}/onos-app-olt-api/${project.version}</bundle> | ||
22 | - <bundle>mvn:${project.groupId}/onos-app-olt/${project.version}</bundle> | ||
23 | - </feature> | ||
24 | -</features> |
apps/olt/app/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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/xsd/maven-4.0.0.xsd"> | ||
20 | - <parent> | ||
21 | - <groupId>org.onosproject</groupId> | ||
22 | - <artifactId>onos-olt</artifactId> | ||
23 | - <version>1.6.0-SNAPSHOT</version> | ||
24 | - <relativePath>../pom.xml</relativePath> | ||
25 | - </parent> | ||
26 | - <modelVersion>4.0.0</modelVersion> | ||
27 | - | ||
28 | - <artifactId>onos-app-olt</artifactId> | ||
29 | - | ||
30 | - <packaging>bundle</packaging> | ||
31 | - <description>OLT application for CORD</description> | ||
32 | - | ||
33 | - <properties> | ||
34 | - <web.context>/onos/olt</web.context> | ||
35 | - <api.version>1.0.0</api.version> | ||
36 | - <api.title>ONOS OLT REST API</api.title> | ||
37 | - <api.description> | ||
38 | - APIs for interacting with the CORD OLT application. | ||
39 | - </api.description> | ||
40 | - <api.package>org.onosproject.olt.rest</api.package> | ||
41 | - </properties> | ||
42 | - | ||
43 | - <dependencies> | ||
44 | - <dependency> | ||
45 | - <groupId>org.onosproject</groupId> | ||
46 | - <artifactId>onos-cord-config</artifactId> | ||
47 | - <version>${project.version}</version> | ||
48 | - </dependency> | ||
49 | - <dependency> | ||
50 | - <groupId>org.onosproject</groupId> | ||
51 | - <artifactId>onos-app-olt-api</artifactId> | ||
52 | - <version>${project.version}</version> | ||
53 | - </dependency> | ||
54 | - | ||
55 | - <dependency> | ||
56 | - <groupId>org.onosproject</groupId> | ||
57 | - <artifactId>onos-cli</artifactId> | ||
58 | - <version>${project.version}</version> | ||
59 | - </dependency> | ||
60 | - | ||
61 | - <dependency> | ||
62 | - <groupId>org.apache.karaf.shell</groupId> | ||
63 | - <artifactId>org.apache.karaf.shell.console</artifactId> | ||
64 | - </dependency> | ||
65 | - <dependency> | ||
66 | - <groupId>org.onosproject</groupId> | ||
67 | - <artifactId>onos-rest</artifactId> | ||
68 | - <version>${project.version}</version> | ||
69 | - </dependency> | ||
70 | - <dependency> | ||
71 | - <groupId>org.onosproject</groupId> | ||
72 | - <artifactId>onlab-rest</artifactId> | ||
73 | - <version>${project.version}</version> | ||
74 | - </dependency> | ||
75 | - <dependency> | ||
76 | - <groupId>javax.ws.rs</groupId> | ||
77 | - <artifactId>javax.ws.rs-api</artifactId> | ||
78 | - <version>2.0.1</version> | ||
79 | - </dependency> | ||
80 | - <dependency> | ||
81 | - <groupId>org.glassfish.jersey.containers</groupId> | ||
82 | - <artifactId>jersey-container-servlet</artifactId> | ||
83 | - </dependency> | ||
84 | - <dependency> | ||
85 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
86 | - <artifactId>jackson-databind</artifactId> | ||
87 | - </dependency> | ||
88 | - | ||
89 | - <dependency> | ||
90 | - <groupId>com.fasterxml.jackson.core</groupId> | ||
91 | - <artifactId>jackson-annotations</artifactId> | ||
92 | - </dependency> | ||
93 | - | ||
94 | - <dependency> | ||
95 | - <groupId>org.osgi</groupId> | ||
96 | - <artifactId>org.osgi.compendium</artifactId> | ||
97 | - </dependency> | ||
98 | - <dependency> | ||
99 | - <groupId>org.osgi</groupId> | ||
100 | - <artifactId>org.osgi.core</artifactId> | ||
101 | - </dependency> | ||
102 | - </dependencies> | ||
103 | - | ||
104 | - <build> | ||
105 | - <plugins> | ||
106 | - <plugin> | ||
107 | - <groupId>org.apache.felix</groupId> | ||
108 | - <artifactId>maven-bundle-plugin</artifactId> | ||
109 | - <extensions>true</extensions> | ||
110 | - <configuration> | ||
111 | - <instructions> | ||
112 | - <_wab>src/main/webapp/</_wab> | ||
113 | - <Include-Resource> | ||
114 | - WEB-INF/classes/apidoc/swagger.json=target/swagger.json, | ||
115 | - {maven-resources} | ||
116 | - </Include-Resource> | ||
117 | - <Bundle-SymbolicName> | ||
118 | - ${project.groupId}.${project.artifactId} | ||
119 | - </Bundle-SymbolicName> | ||
120 | - <Import-Package> | ||
121 | - *,org.glassfish.jersey.servlet | ||
122 | - </Import-Package> | ||
123 | - <Web-ContextPath>${web.context}</Web-ContextPath> | ||
124 | - </instructions> | ||
125 | - </configuration> | ||
126 | - </plugin> | ||
127 | - </plugins> | ||
128 | - </build> | ||
129 | -</project> |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.cordconfig.access.AccessDeviceData; | ||
23 | -import org.onosproject.net.DeviceId; | ||
24 | -import org.onosproject.olt.AccessDeviceService; | ||
25 | - | ||
26 | -import java.util.Map; | ||
27 | - | ||
28 | -/** | ||
29 | - * Shows configured OLTs. | ||
30 | - */ | ||
31 | -@Command(scope = "onos", name = "olts", | ||
32 | - description = "Shows configured OLTs") | ||
33 | -public class ShowOltCommand extends AbstractShellCommand { | ||
34 | - | ||
35 | - @Argument(index = 0, name = "deviceId", description = "Access device ID", | ||
36 | - required = false, multiValued = false) | ||
37 | - private String strDeviceId = null; | ||
38 | - | ||
39 | - @Override | ||
40 | - protected void execute() { | ||
41 | - AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class); | ||
42 | - Map<DeviceId, AccessDeviceData> data = service.fetchOlts(); | ||
43 | - if (strDeviceId != null) { | ||
44 | - DeviceId deviceId = DeviceId.deviceId(strDeviceId); | ||
45 | - print("OLT %s:", deviceId); | ||
46 | - display(data.get(deviceId)); | ||
47 | - } else { | ||
48 | - data.keySet().forEach(did -> { | ||
49 | - print("OLT %s:", did); | ||
50 | - display(data.get(did)); | ||
51 | - }); | ||
52 | - } | ||
53 | - } | ||
54 | - | ||
55 | - private void display(AccessDeviceData accessDeviceData) { | ||
56 | - print("\tvlan : %s", accessDeviceData.vlan()); | ||
57 | - print("\tuplink : %s", accessDeviceData.uplink()); | ||
58 | - } | ||
59 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Command; | ||
20 | -import org.onlab.packet.VlanId; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.net.ConnectPoint; | ||
23 | -import org.onosproject.olt.AccessDeviceService; | ||
24 | - | ||
25 | -import java.util.Map; | ||
26 | - | ||
27 | -/** | ||
28 | - * Shows provisioned subscribers. | ||
29 | - */ | ||
30 | -@Command(scope = "onos", name = "subscribers", | ||
31 | - description = "Shows provisioned subscribers") | ||
32 | -public class ShowSubscribersCommand extends AbstractShellCommand { | ||
33 | - | ||
34 | - private static final String FORMAT = "port=%s, cvlan=%s"; | ||
35 | - | ||
36 | - @Override | ||
37 | - protected void execute() { | ||
38 | - AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class); | ||
39 | - service.getSubscribers().forEach(this::display); | ||
40 | - } | ||
41 | - | ||
42 | - private void display(Map.Entry<ConnectPoint, VlanId> subscriber) { | ||
43 | - print(FORMAT, subscriber.getKey(), subscriber.getValue()); | ||
44 | - } | ||
45 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onlab.packet.VlanId; | ||
22 | -import org.onosproject.cli.AbstractShellCommand; | ||
23 | -import org.onosproject.net.ConnectPoint; | ||
24 | -import org.onosproject.net.DeviceId; | ||
25 | -import org.onosproject.net.PortNumber; | ||
26 | -import org.onosproject.olt.AccessDeviceService; | ||
27 | - | ||
28 | -/** | ||
29 | - * Adds a subscriber to an access device. | ||
30 | - */ | ||
31 | -@Command(scope = "onos", name = "add-subscriber-access", | ||
32 | - description = "Adds a subscriber to an access device") | ||
33 | -public class SubscriberAddCommand extends AbstractShellCommand { | ||
34 | - | ||
35 | - @Argument(index = 0, name = "deviceId", description = "Access device ID", | ||
36 | - required = true, multiValued = false) | ||
37 | - private String strDeviceId = null; | ||
38 | - | ||
39 | - @Argument(index = 1, name = "port", description = "Subscriber port number", | ||
40 | - required = true, multiValued = false) | ||
41 | - private String strPort = null; | ||
42 | - | ||
43 | - @Argument(index = 2, name = "vlanId", | ||
44 | - description = "VLAN ID to add", | ||
45 | - required = true, multiValued = false) | ||
46 | - private String strVlanId = null; | ||
47 | - | ||
48 | - @Override | ||
49 | - protected void execute() { | ||
50 | - AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class); | ||
51 | - | ||
52 | - DeviceId deviceId = DeviceId.deviceId(strDeviceId); | ||
53 | - PortNumber port = PortNumber.portNumber(strPort); | ||
54 | - VlanId vlan = VlanId.vlanId(Short.parseShort(strVlanId)); | ||
55 | - ConnectPoint connectPoint = new ConnectPoint(deviceId, port); | ||
56 | - | ||
57 | - service.provisionSubscriber(connectPoint, vlan); | ||
58 | - } | ||
59 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.cli; | ||
18 | - | ||
19 | -import org.apache.karaf.shell.commands.Argument; | ||
20 | -import org.apache.karaf.shell.commands.Command; | ||
21 | -import org.onosproject.cli.AbstractShellCommand; | ||
22 | -import org.onosproject.net.ConnectPoint; | ||
23 | -import org.onosproject.net.DeviceId; | ||
24 | -import org.onosproject.net.PortNumber; | ||
25 | -import org.onosproject.olt.AccessDeviceService; | ||
26 | - | ||
27 | -/** | ||
28 | - * Adds a subscriber to an access device. | ||
29 | - */ | ||
30 | -@Command(scope = "onos", name = "remove-subscriber-access", | ||
31 | - description = "Adds a subscriber to an access device") | ||
32 | -public class SubscriberRemoveCommand extends AbstractShellCommand { | ||
33 | - | ||
34 | - @Argument(index = 0, name = "deviceId", description = "Access device ID", | ||
35 | - required = true, multiValued = false) | ||
36 | - private String strDeviceId = null; | ||
37 | - | ||
38 | - @Argument(index = 1, name = "port", description = "Subscriber port number", | ||
39 | - required = true, multiValued = false) | ||
40 | - private String strPort = null; | ||
41 | - | ||
42 | - @Override | ||
43 | - protected void execute() { | ||
44 | - AccessDeviceService service = AbstractShellCommand.get(AccessDeviceService.class); | ||
45 | - | ||
46 | - DeviceId deviceId = DeviceId.deviceId(strDeviceId); | ||
47 | - PortNumber port = PortNumber.portNumber(strPort); | ||
48 | - ConnectPoint connectPoint = new ConnectPoint(deviceId, port); | ||
49 | - | ||
50 | - service.removeSubscriber(connectPoint); | ||
51 | - | ||
52 | - } | ||
53 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * OLT application handling PMC OLT hardware. | ||
19 | - */ | ||
20 | -package org.onosproject.olt.cli; |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.impl; | ||
17 | - | ||
18 | -import com.google.common.collect.Maps; | ||
19 | -import org.apache.felix.scr.annotations.Activate; | ||
20 | -import org.apache.felix.scr.annotations.Component; | ||
21 | -import org.apache.felix.scr.annotations.Deactivate; | ||
22 | -import org.apache.felix.scr.annotations.Modified; | ||
23 | -import org.apache.felix.scr.annotations.Property; | ||
24 | -import org.apache.felix.scr.annotations.Reference; | ||
25 | -import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
26 | -import org.apache.felix.scr.annotations.Service; | ||
27 | -import org.onlab.packet.EthType; | ||
28 | -import org.onlab.packet.VlanId; | ||
29 | -import org.onosproject.cfg.ComponentConfigService; | ||
30 | -import org.onosproject.cordconfig.access.AccessDeviceConfig; | ||
31 | -import org.onosproject.cordconfig.access.AccessDeviceData; | ||
32 | -import org.onosproject.core.ApplicationId; | ||
33 | -import org.onosproject.core.CoreService; | ||
34 | -import org.onosproject.event.AbstractListenerManager; | ||
35 | -import org.onosproject.mastership.MastershipService; | ||
36 | -import org.onosproject.net.ConnectPoint; | ||
37 | -import org.onosproject.net.DeviceId; | ||
38 | -import org.onosproject.net.Port; | ||
39 | -import org.onosproject.net.PortNumber; | ||
40 | -import org.onosproject.net.config.ConfigFactory; | ||
41 | -import org.onosproject.net.config.NetworkConfigEvent; | ||
42 | -import org.onosproject.net.config.NetworkConfigListener; | ||
43 | -import org.onosproject.net.config.NetworkConfigRegistry; | ||
44 | -import org.onosproject.net.config.basics.SubjectFactories; | ||
45 | -import org.onosproject.net.device.DeviceEvent; | ||
46 | -import org.onosproject.net.device.DeviceListener; | ||
47 | -import org.onosproject.net.device.DeviceService; | ||
48 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
49 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
50 | -import org.onosproject.net.flow.TrafficSelector; | ||
51 | -import org.onosproject.net.flow.TrafficTreatment; | ||
52 | -import org.onosproject.net.flow.criteria.Criteria; | ||
53 | -import org.onosproject.net.flowobjective.DefaultFilteringObjective; | ||
54 | -import org.onosproject.net.flowobjective.DefaultForwardingObjective; | ||
55 | -import org.onosproject.net.flowobjective.FilteringObjective; | ||
56 | -import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
57 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
58 | -import org.onosproject.net.flowobjective.Objective; | ||
59 | -import org.onosproject.net.flowobjective.ObjectiveContext; | ||
60 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
61 | -import org.onosproject.olt.AccessDeviceEvent; | ||
62 | -import org.onosproject.olt.AccessDeviceListener; | ||
63 | -import org.onosproject.olt.AccessDeviceService; | ||
64 | -import org.onosproject.store.serializers.KryoNamespaces; | ||
65 | -import org.onosproject.store.service.Serializer; | ||
66 | -import org.onosproject.store.service.StorageService; | ||
67 | -import org.osgi.service.component.ComponentContext; | ||
68 | -import org.slf4j.Logger; | ||
69 | - | ||
70 | -import java.util.Collection; | ||
71 | -import java.util.Dictionary; | ||
72 | -import java.util.List; | ||
73 | -import java.util.Map; | ||
74 | -import java.util.Optional; | ||
75 | -import java.util.Properties; | ||
76 | -import java.util.concurrent.CompletableFuture; | ||
77 | -import java.util.concurrent.ConcurrentHashMap; | ||
78 | -import java.util.concurrent.ExecutorService; | ||
79 | -import java.util.concurrent.Executors; | ||
80 | - | ||
81 | -import static com.google.common.base.Strings.isNullOrEmpty; | ||
82 | -import static org.onlab.util.Tools.get; | ||
83 | -import static org.onlab.util.Tools.groupedThreads; | ||
84 | -import static org.slf4j.LoggerFactory.getLogger; | ||
85 | - | ||
86 | -/** | ||
87 | - * Provisions rules on access devices. | ||
88 | - */ | ||
89 | -@Service | ||
90 | -@Component(immediate = true) | ||
91 | -public class Olt | ||
92 | - extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener> | ||
93 | - implements AccessDeviceService { | ||
94 | - | ||
95 | - private static final short DEFAULT_VLAN = 0; | ||
96 | - private static final String SUBSCRIBERS = "existing-subscribers"; | ||
97 | - | ||
98 | - private final Logger log = getLogger(getClass()); | ||
99 | - | ||
100 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
101 | - protected FlowObjectiveService flowObjectiveService; | ||
102 | - | ||
103 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
104 | - protected MastershipService mastershipService; | ||
105 | - | ||
106 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
107 | - protected DeviceService deviceService; | ||
108 | - | ||
109 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
110 | - protected CoreService coreService; | ||
111 | - | ||
112 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
113 | - protected NetworkConfigRegistry networkConfig; | ||
114 | - | ||
115 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
116 | - protected ComponentConfigService componentConfigService; | ||
117 | - | ||
118 | - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
119 | - protected StorageService storageService; | ||
120 | - | ||
121 | - @Property(name = "defaultVlan", intValue = DEFAULT_VLAN, | ||
122 | - label = "Default VLAN RG<->ONU traffic") | ||
123 | - private int defaultVlan = DEFAULT_VLAN; | ||
124 | - | ||
125 | - private final DeviceListener deviceListener = new InternalDeviceListener(); | ||
126 | - | ||
127 | - private ApplicationId appId; | ||
128 | - | ||
129 | - private ExecutorService oltInstallers = Executors.newFixedThreadPool(4, | ||
130 | - groupedThreads("onos/olt-service", | ||
131 | - "olt-installer-%d")); | ||
132 | - | ||
133 | - private Map<DeviceId, AccessDeviceData> oltData = new ConcurrentHashMap<>(); | ||
134 | - | ||
135 | - private Map<ConnectPoint, VlanId> subscribers; | ||
136 | - | ||
137 | - private InternalNetworkConfigListener configListener = | ||
138 | - new InternalNetworkConfigListener(); | ||
139 | - private static final Class<AccessDeviceConfig> CONFIG_CLASS = | ||
140 | - AccessDeviceConfig.class; | ||
141 | - | ||
142 | - private ConfigFactory<DeviceId, AccessDeviceConfig> configFactory = | ||
143 | - new ConfigFactory<DeviceId, AccessDeviceConfig>( | ||
144 | - SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessDevice") { | ||
145 | - @Override | ||
146 | - public AccessDeviceConfig createConfig() { | ||
147 | - return new AccessDeviceConfig(); | ||
148 | - } | ||
149 | - }; | ||
150 | - | ||
151 | - | ||
152 | - @Activate | ||
153 | - public void activate(ComponentContext context) { | ||
154 | - modified(context); | ||
155 | - appId = coreService.registerApplication("org.onosproject.olt"); | ||
156 | - componentConfigService.registerProperties(getClass()); | ||
157 | - | ||
158 | - eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry); | ||
159 | - | ||
160 | - networkConfig.registerConfigFactory(configFactory); | ||
161 | - networkConfig.addListener(configListener); | ||
162 | - | ||
163 | - | ||
164 | - networkConfig.getSubjects(DeviceId.class, AccessDeviceConfig.class).forEach( | ||
165 | - subject -> { | ||
166 | - AccessDeviceConfig config = networkConfig.getConfig(subject, AccessDeviceConfig.class); | ||
167 | - if (config != null) { | ||
168 | - AccessDeviceData data = config.getOlt(); | ||
169 | - oltData.put(data.deviceId(), data); | ||
170 | - } | ||
171 | - } | ||
172 | - ); | ||
173 | - | ||
174 | - oltData.keySet().stream() | ||
175 | - .flatMap(did -> deviceService.getPorts(did).stream()) | ||
176 | - .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number())) | ||
177 | - .filter(p -> p.isEnabled()) | ||
178 | - .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(), | ||
179 | - p.number(), true)); | ||
180 | - | ||
181 | - subscribers = storageService.<ConnectPoint, VlanId>consistentMapBuilder() | ||
182 | - .withName(SUBSCRIBERS) | ||
183 | - .withSerializer(Serializer.using(KryoNamespaces.API)) | ||
184 | - .build().asJavaMap(); | ||
185 | - | ||
186 | - deviceService.addListener(deviceListener); | ||
187 | - | ||
188 | - log.info("Started with Application ID {}", appId.id()); | ||
189 | - } | ||
190 | - | ||
191 | - @Deactivate | ||
192 | - public void deactivate() { | ||
193 | - componentConfigService.unregisterProperties(getClass(), false); | ||
194 | - deviceService.removeListener(deviceListener); | ||
195 | - networkConfig.removeListener(configListener); | ||
196 | - networkConfig.unregisterConfigFactory(configFactory); | ||
197 | - log.info("Stopped"); | ||
198 | - } | ||
199 | - | ||
200 | - @Modified | ||
201 | - public void modified(ComponentContext context) { | ||
202 | - Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); | ||
203 | - | ||
204 | - try { | ||
205 | - String s = get(properties, "defaultVlan"); | ||
206 | - defaultVlan = isNullOrEmpty(s) ? DEFAULT_VLAN : Integer.parseInt(s.trim()); | ||
207 | - } catch (Exception e) { | ||
208 | - defaultVlan = DEFAULT_VLAN; | ||
209 | - } | ||
210 | - } | ||
211 | - | ||
212 | - @Override | ||
213 | - public void provisionSubscriber(ConnectPoint port, VlanId vlan) { | ||
214 | - AccessDeviceData olt = oltData.get(port.deviceId()); | ||
215 | - | ||
216 | - if (olt == null) { | ||
217 | - log.warn("No data found for OLT device {}", port.deviceId()); | ||
218 | - return; | ||
219 | - } | ||
220 | - | ||
221 | - provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(), | ||
222 | - olt.defaultVlan()); | ||
223 | - } | ||
224 | - | ||
225 | - @Override | ||
226 | - public void removeSubscriber(ConnectPoint port) { | ||
227 | - AccessDeviceData olt = oltData.get(port.deviceId()); | ||
228 | - | ||
229 | - if (olt == null) { | ||
230 | - log.warn("No data found for OLT device {}", port.deviceId()); | ||
231 | - return; | ||
232 | - } | ||
233 | - | ||
234 | - VlanId subscriberVlan = subscribers.remove(port); | ||
235 | - | ||
236 | - if (subscriberVlan == null) { | ||
237 | - log.warn("Unknown subscriber at location {}", port); | ||
238 | - return; | ||
239 | - } | ||
240 | - | ||
241 | - unprovisionSubscriber(olt.deviceId(), olt.uplink(), port.port(), subscriberVlan, | ||
242 | - olt.vlan(), olt.defaultVlan()); | ||
243 | - | ||
244 | - } | ||
245 | - | ||
246 | - @Override | ||
247 | - public Collection<Map.Entry<ConnectPoint, VlanId>> getSubscribers() { | ||
248 | - return subscribers.entrySet(); | ||
249 | - } | ||
250 | - | ||
251 | - @Override | ||
252 | - public Map<DeviceId, AccessDeviceData> fetchOlts() { | ||
253 | - return Maps.newHashMap(oltData); | ||
254 | - } | ||
255 | - | ||
256 | - private void unprovisionSubscriber(DeviceId deviceId, PortNumber uplink, | ||
257 | - PortNumber subscriberPort, VlanId subscriberVlan, | ||
258 | - VlanId deviceVlan, Optional<VlanId> defaultVlan) { | ||
259 | - | ||
260 | - CompletableFuture<ObjectiveError> downFuture = new CompletableFuture(); | ||
261 | - CompletableFuture<ObjectiveError> upFuture = new CompletableFuture(); | ||
262 | - | ||
263 | - ForwardingObjective.Builder upFwd = upBuilder(uplink, subscriberPort, | ||
264 | - subscriberVlan, deviceVlan, | ||
265 | - defaultVlan); | ||
266 | - ForwardingObjective.Builder downFwd = downBuilder(uplink, subscriberPort, | ||
267 | - subscriberVlan, deviceVlan, | ||
268 | - defaultVlan); | ||
269 | - | ||
270 | - | ||
271 | - flowObjectiveService.forward(deviceId, upFwd.remove(new ObjectiveContext() { | ||
272 | - @Override | ||
273 | - public void onSuccess(Objective objective) { | ||
274 | - upFuture.complete(null); | ||
275 | - } | ||
276 | - | ||
277 | - @Override | ||
278 | - public void onError(Objective objective, ObjectiveError error) { | ||
279 | - upFuture.complete(error); | ||
280 | - } | ||
281 | - })); | ||
282 | - | ||
283 | - flowObjectiveService.forward(deviceId, downFwd.remove(new ObjectiveContext() { | ||
284 | - @Override | ||
285 | - public void onSuccess(Objective objective) { | ||
286 | - downFuture.complete(null); | ||
287 | - } | ||
288 | - | ||
289 | - @Override | ||
290 | - public void onError(Objective objective, ObjectiveError error) { | ||
291 | - downFuture.complete(error); | ||
292 | - } | ||
293 | - })); | ||
294 | - | ||
295 | - upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> { | ||
296 | - if (upStatus == null && downStatus == null) { | ||
297 | - post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_UNREGISTERED, | ||
298 | - deviceId, | ||
299 | - deviceVlan, | ||
300 | - subscriberVlan)); | ||
301 | - } else if (downStatus != null) { | ||
302 | - log.error("Subscriber with vlan {} on device {} " + | ||
303 | - "on port {} failed downstream uninstallation: {}", | ||
304 | - subscriberVlan, deviceId, subscriberPort, downStatus); | ||
305 | - } else if (upStatus != null) { | ||
306 | - log.error("Subscriber with vlan {} on device {} " + | ||
307 | - "on port {} failed upstream uninstallation: {}", | ||
308 | - subscriberVlan, deviceId, subscriberPort, upStatus); | ||
309 | - } | ||
310 | - }, oltInstallers); | ||
311 | - | ||
312 | - } | ||
313 | - | ||
314 | - private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort, | ||
315 | - PortNumber subscriberPort, | ||
316 | - VlanId subscriberVlan, VlanId deviceVlan, | ||
317 | - Optional<VlanId> defaultVlan) { | ||
318 | - | ||
319 | - CompletableFuture<ObjectiveError> downFuture = new CompletableFuture(); | ||
320 | - CompletableFuture<ObjectiveError> upFuture = new CompletableFuture(); | ||
321 | - | ||
322 | - ForwardingObjective.Builder upFwd = upBuilder(uplinkPort, subscriberPort, | ||
323 | - subscriberVlan, deviceVlan, | ||
324 | - defaultVlan); | ||
325 | - | ||
326 | - | ||
327 | - ForwardingObjective.Builder downFwd = downBuilder(uplinkPort, subscriberPort, | ||
328 | - subscriberVlan, deviceVlan, | ||
329 | - defaultVlan); | ||
330 | - | ||
331 | - ConnectPoint cp = new ConnectPoint(deviceId, subscriberPort); | ||
332 | - subscribers.put(cp, subscriberVlan); | ||
333 | - | ||
334 | - flowObjectiveService.forward(deviceId, upFwd.add(new ObjectiveContext() { | ||
335 | - @Override | ||
336 | - public void onSuccess(Objective objective) { | ||
337 | - upFuture.complete(null); | ||
338 | - } | ||
339 | - | ||
340 | - @Override | ||
341 | - public void onError(Objective objective, ObjectiveError error) { | ||
342 | - upFuture.complete(error); | ||
343 | - } | ||
344 | - })); | ||
345 | - | ||
346 | - flowObjectiveService.forward(deviceId, downFwd.add(new ObjectiveContext() { | ||
347 | - @Override | ||
348 | - public void onSuccess(Objective objective) { | ||
349 | - downFuture.complete(null); | ||
350 | - } | ||
351 | - | ||
352 | - @Override | ||
353 | - public void onError(Objective objective, ObjectiveError error) { | ||
354 | - downFuture.complete(error); | ||
355 | - } | ||
356 | - })); | ||
357 | - | ||
358 | - upFuture.thenAcceptBothAsync(downFuture, (upStatus, downStatus) -> { | ||
359 | - if (upStatus == null && downStatus == null) { | ||
360 | - post(new AccessDeviceEvent(AccessDeviceEvent.Type.SUBSCRIBER_REGISTERED, | ||
361 | - deviceId, | ||
362 | - deviceVlan, | ||
363 | - subscriberVlan)); | ||
364 | - | ||
365 | - } else if (downStatus != null) { | ||
366 | - log.error("Subscriber with vlan {} on device {} " + | ||
367 | - "on port {} failed downstream installation: {}", | ||
368 | - subscriberVlan, deviceId, subscriberPort, downStatus); | ||
369 | - } else if (upStatus != null) { | ||
370 | - log.error("Subscriber with vlan {} on device {} " + | ||
371 | - "on port {} failed upstream installation: {}", | ||
372 | - subscriberVlan, deviceId, subscriberPort, upStatus); | ||
373 | - } | ||
374 | - }, oltInstallers); | ||
375 | - | ||
376 | - } | ||
377 | - | ||
378 | - private ForwardingObjective.Builder downBuilder(PortNumber uplinkPort, | ||
379 | - PortNumber subscriberPort, | ||
380 | - VlanId subscriberVlan, | ||
381 | - VlanId deviceVlan, | ||
382 | - Optional<VlanId> defaultVlan) { | ||
383 | - TrafficSelector downstream = DefaultTrafficSelector.builder() | ||
384 | - .matchVlanId(deviceVlan) | ||
385 | - .matchInPort(uplinkPort) | ||
386 | - .matchInnerVlanId(subscriberVlan) | ||
387 | - .build(); | ||
388 | - | ||
389 | - TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() | ||
390 | - .popVlan() | ||
391 | - .setVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan))) | ||
392 | - .setOutput(subscriberPort) | ||
393 | - .build(); | ||
394 | - | ||
395 | - return DefaultForwardingObjective.builder() | ||
396 | - .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
397 | - .withPriority(1000) | ||
398 | - .makePermanent() | ||
399 | - .withSelector(downstream) | ||
400 | - .fromApp(appId) | ||
401 | - .withTreatment(downstreamTreatment); | ||
402 | - } | ||
403 | - | ||
404 | - private ForwardingObjective.Builder upBuilder(PortNumber uplinkPort, | ||
405 | - PortNumber subscriberPort, | ||
406 | - VlanId subscriberVlan, | ||
407 | - VlanId deviceVlan, | ||
408 | - Optional<VlanId> defaultVlan) { | ||
409 | - TrafficSelector upstream = DefaultTrafficSelector.builder() | ||
410 | - .matchVlanId(defaultVlan.orElse(VlanId.vlanId((short) this.defaultVlan))) | ||
411 | - .matchInPort(subscriberPort) | ||
412 | - .build(); | ||
413 | - | ||
414 | - | ||
415 | - TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() | ||
416 | - .pushVlan() | ||
417 | - .setVlanId(subscriberVlan) | ||
418 | - .pushVlan() | ||
419 | - .setVlanId(deviceVlan) | ||
420 | - .setOutput(uplinkPort) | ||
421 | - .build(); | ||
422 | - | ||
423 | - return DefaultForwardingObjective.builder() | ||
424 | - .withFlag(ForwardingObjective.Flag.VERSATILE) | ||
425 | - .withPriority(1000) | ||
426 | - .makePermanent() | ||
427 | - .withSelector(upstream) | ||
428 | - .fromApp(appId) | ||
429 | - .withTreatment(upstreamTreatment); | ||
430 | - } | ||
431 | - | ||
432 | - private void processFilteringObjectives(DeviceId devId, PortNumber port, boolean install) { | ||
433 | - if (!mastershipService.isLocalMaster(devId)) { | ||
434 | - return; | ||
435 | - } | ||
436 | - DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder(); | ||
437 | - | ||
438 | - FilteringObjective eapol = (install ? builder.permit() : builder.deny()) | ||
439 | - .withKey(Criteria.matchInPort(port)) | ||
440 | - .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType())) | ||
441 | - .withMeta(DefaultTrafficTreatment.builder() | ||
442 | - .setOutput(PortNumber.CONTROLLER).build()) | ||
443 | - .fromApp(appId) | ||
444 | - .withPriority(1000) | ||
445 | - .add(new ObjectiveContext() { | ||
446 | - @Override | ||
447 | - public void onSuccess(Objective objective) { | ||
448 | - log.info("Eapol filter for {} on {} installed.", | ||
449 | - devId, port); | ||
450 | - } | ||
451 | - | ||
452 | - @Override | ||
453 | - public void onError(Objective objective, ObjectiveError error) { | ||
454 | - log.info("Eapol filter for {} on {} failed because {}", | ||
455 | - devId, port, error); | ||
456 | - } | ||
457 | - }); | ||
458 | - | ||
459 | - flowObjectiveService.filter(devId, eapol); | ||
460 | - | ||
461 | - } | ||
462 | - | ||
463 | - private class InternalDeviceListener implements DeviceListener { | ||
464 | - @Override | ||
465 | - public void event(DeviceEvent event) { | ||
466 | - DeviceId devId = event.subject().id(); | ||
467 | - if (!oltData.containsKey(devId)) { | ||
468 | - return; | ||
469 | - } | ||
470 | - switch (event.type()) { | ||
471 | - //TODO: Port handling and bookkeeping should be improved once | ||
472 | - // olt firmware handles correct behaviour. | ||
473 | - case PORT_ADDED: | ||
474 | - if (!oltData.get(devId).uplink().equals(event.port().number()) && | ||
475 | - event.port().isEnabled()) { | ||
476 | - processFilteringObjectives(devId, event.port().number(), true); | ||
477 | - } | ||
478 | - break; | ||
479 | - case PORT_REMOVED: | ||
480 | - AccessDeviceData olt = oltData.get(devId); | ||
481 | - VlanId vlan = subscribers.get(new ConnectPoint(devId, | ||
482 | - event.port().number())); | ||
483 | - unprovisionSubscriber(devId, olt.uplink(), | ||
484 | - event.port().number(), | ||
485 | - vlan, olt.vlan(), olt.defaultVlan()); | ||
486 | - if (!oltData.get(devId).uplink().equals(event.port().number()) && | ||
487 | - event.port().isEnabled()) { | ||
488 | - processFilteringObjectives(devId, event.port().number(), false); | ||
489 | - } | ||
490 | - break; | ||
491 | - case PORT_UPDATED: | ||
492 | - if (oltData.get(devId).uplink().equals(event.port().number())) { | ||
493 | - break; | ||
494 | - } | ||
495 | - if (event.port().isEnabled()) { | ||
496 | - processFilteringObjectives(devId, event.port().number(), true); | ||
497 | - } else { | ||
498 | - processFilteringObjectives(devId, event.port().number(), false); | ||
499 | - } | ||
500 | - break; | ||
501 | - case DEVICE_ADDED: | ||
502 | - post(new AccessDeviceEvent( | ||
503 | - AccessDeviceEvent.Type.DEVICE_CONNECTED, devId, | ||
504 | - null, null)); | ||
505 | - provisionDefaultFlows(devId); | ||
506 | - break; | ||
507 | - case DEVICE_REMOVED: | ||
508 | - post(new AccessDeviceEvent( | ||
509 | - AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId, | ||
510 | - null, null)); | ||
511 | - break; | ||
512 | - case DEVICE_AVAILABILITY_CHANGED: | ||
513 | - if (deviceService.isAvailable(devId)) { | ||
514 | - post(new AccessDeviceEvent( | ||
515 | - AccessDeviceEvent.Type.DEVICE_CONNECTED, devId, | ||
516 | - null, null)); | ||
517 | - } else { | ||
518 | - post(new AccessDeviceEvent( | ||
519 | - AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId, | ||
520 | - null, null)); | ||
521 | - } | ||
522 | - break; | ||
523 | - case DEVICE_UPDATED: | ||
524 | - case DEVICE_SUSPENDED: | ||
525 | - case PORT_STATS_UPDATED: | ||
526 | - default: | ||
527 | - return; | ||
528 | - } | ||
529 | - } | ||
530 | - } | ||
531 | - | ||
532 | - private class InternalNetworkConfigListener implements NetworkConfigListener { | ||
533 | - @Override | ||
534 | - public void event(NetworkConfigEvent event) { | ||
535 | - switch (event.type()) { | ||
536 | - | ||
537 | - case CONFIG_ADDED: | ||
538 | - case CONFIG_UPDATED: | ||
539 | - | ||
540 | - AccessDeviceConfig config = | ||
541 | - networkConfig.getConfig((DeviceId) event.subject(), CONFIG_CLASS); | ||
542 | - if (config != null) { | ||
543 | - oltData.put(config.getOlt().deviceId(), config.getOlt()); | ||
544 | - provisionDefaultFlows((DeviceId) event.subject()); | ||
545 | - } | ||
546 | - | ||
547 | - break; | ||
548 | - case CONFIG_REGISTERED: | ||
549 | - case CONFIG_UNREGISTERED: | ||
550 | - break; | ||
551 | - case CONFIG_REMOVED: | ||
552 | - oltData.remove(event.subject()); | ||
553 | - default: | ||
554 | - break; | ||
555 | - } | ||
556 | - } | ||
557 | - | ||
558 | - @Override | ||
559 | - public boolean isRelevant(NetworkConfigEvent event) { | ||
560 | - return event.configClass().equals(CONFIG_CLASS); | ||
561 | - } | ||
562 | - } | ||
563 | - | ||
564 | - private void provisionDefaultFlows(DeviceId deviceId) { | ||
565 | - if (!mastershipService.isLocalMaster(deviceId)) { | ||
566 | - return; | ||
567 | - } | ||
568 | - List<Port> ports = deviceService.getPorts(deviceId); | ||
569 | - | ||
570 | - ports.stream() | ||
571 | - .filter(p -> !oltData.get(p.element().id()).uplink().equals(p.number())) | ||
572 | - .filter(p -> p.isEnabled()) | ||
573 | - .forEach(p -> processFilteringObjectives((DeviceId) p.element().id(), | ||
574 | - p.number(), true)); | ||
575 | - | ||
576 | - } | ||
577 | - | ||
578 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * OLT application handling PMC OLT hardware. | ||
19 | - */ | ||
20 | -package org.onosproject.olt.impl; |
1 | -/* | ||
2 | - * Copyright 2016-present 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.olt.rest; | ||
17 | - | ||
18 | -import javax.ws.rs.DELETE; | ||
19 | -import javax.ws.rs.POST; | ||
20 | -import javax.ws.rs.Path; | ||
21 | -import javax.ws.rs.PathParam; | ||
22 | -import javax.ws.rs.Produces; | ||
23 | -import javax.ws.rs.core.MediaType; | ||
24 | -import javax.ws.rs.core.Response; | ||
25 | - | ||
26 | -import org.onlab.packet.VlanId; | ||
27 | -import org.onosproject.net.ConnectPoint; | ||
28 | -import org.onosproject.net.DeviceId; | ||
29 | -import org.onosproject.net.PortNumber; | ||
30 | -import org.onosproject.olt.AccessDeviceService; | ||
31 | -import org.onosproject.rest.AbstractWebResource; | ||
32 | - | ||
33 | -/** | ||
34 | - * OLT REST APIs. | ||
35 | - */ | ||
36 | - | ||
37 | -@Path("oltapp") | ||
38 | -public class OltWebResource extends AbstractWebResource { | ||
39 | - | ||
40 | - /** | ||
41 | - * Provision a subscriber. | ||
42 | - * | ||
43 | - * @param device device id | ||
44 | - * @param port port number | ||
45 | - * @param vlan vlan id | ||
46 | - * @return 200 OK | ||
47 | - */ | ||
48 | - @POST | ||
49 | - @Produces(MediaType.APPLICATION_JSON) | ||
50 | - @Path("{device}/{port}/{vlan}") | ||
51 | - public Response provisionSubscriber( | ||
52 | - @PathParam("device")String device, | ||
53 | - @PathParam("port")long port, | ||
54 | - @PathParam("vlan")short vlan) { | ||
55 | - AccessDeviceService service = get(AccessDeviceService.class); | ||
56 | - DeviceId deviceId = DeviceId.deviceId(device); | ||
57 | - PortNumber portNumber = PortNumber.portNumber(port); | ||
58 | - VlanId vlanId = VlanId.vlanId(vlan); | ||
59 | - ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber); | ||
60 | - service.provisionSubscriber(connectPoint, vlanId); | ||
61 | - return ok("").build(); | ||
62 | - } | ||
63 | - | ||
64 | - /** | ||
65 | - * Remove the provisioning for a subscriber. | ||
66 | - * | ||
67 | - * @param device device id | ||
68 | - * @param port port number | ||
69 | - * @return 204 NO CONTENT | ||
70 | - */ | ||
71 | - @DELETE | ||
72 | - @Path("{device}/{port}") | ||
73 | - public Response removeSubscriber( | ||
74 | - @PathParam("device")String device, | ||
75 | - @PathParam("port")long port) { | ||
76 | - AccessDeviceService service = get(AccessDeviceService.class); | ||
77 | - DeviceId deviceId = DeviceId.deviceId(device); | ||
78 | - PortNumber portNumber = PortNumber.portNumber(port); | ||
79 | - ConnectPoint connectPoint = new ConnectPoint(deviceId, portNumber); | ||
80 | - service.removeSubscriber(connectPoint); | ||
81 | - return Response.noContent().build(); | ||
82 | - } | ||
83 | -} |
1 | -/* | ||
2 | - * Copyright 2016-present 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 | -/** | ||
18 | - * REST APIs for the OLT application. | ||
19 | - */ | ||
20 | -package org.onosproject.olt.rest; |
1 | -<!-- | ||
2 | - ~ Copyright 2016-present 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 | -<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
17 | - | ||
18 | - <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
19 | - <command> | ||
20 | - <action class="org.onosproject.olt.cli.SubscriberAddCommand"/> | ||
21 | - <completers> | ||
22 | - <ref component-id="deviceIdCompleter"/> | ||
23 | - <null/> | ||
24 | - </completers> | ||
25 | - </command> | ||
26 | - <command> | ||
27 | - <action class="org.onosproject.olt.cli.SubscriberRemoveCommand"/> | ||
28 | - <completers> | ||
29 | - <ref component-id="deviceIdCompleter"/> | ||
30 | - <null/> | ||
31 | - </completers> | ||
32 | - </command> | ||
33 | - <command> | ||
34 | - <action class="org.onosproject.olt.cli.ShowOltCommand"/> | ||
35 | - <completers> | ||
36 | - <ref component-id="deviceIdCompleter"/> | ||
37 | - <null/> | ||
38 | - </completers> | ||
39 | - </command> | ||
40 | - <command> | ||
41 | - <action class="org.onosproject.olt.cli.ShowSubscribersCommand"/> | ||
42 | - </command> | ||
43 | - </command-bundle> | ||
44 | - | ||
45 | - <bean id="deviceIdCompleter" class="org.onosproject.cli.net.DeviceIdCompleter"/> | ||
46 | -</blueprint> |
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2016-present 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>OLT REST API v1.0</display-name> | ||
22 | - | ||
23 | - <servlet> | ||
24 | - <servlet-name>JAX-RS Service</servlet-name> | ||
25 | - <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> | ||
26 | - <init-param> | ||
27 | - <param-name>jersey.config.server.provider.classnames</param-name> | ||
28 | - <param-value> | ||
29 | - org.onosproject.olt.rest.OltWebResource | ||
30 | - </param-value> | ||
31 | - </init-param> | ||
32 | - <load-on-startup>1</load-on-startup> | ||
33 | - </servlet> | ||
34 | - | ||
35 | - <servlet-mapping> | ||
36 | - <servlet-name>JAX-RS Service</servlet-name> | ||
37 | - <url-pattern>/*</url-pattern> | ||
38 | - </servlet-mapping> | ||
39 | -</web-app> |
apps/olt/pom.xml
deleted
100644 → 0
1 | -<?xml version="1.0" encoding="UTF-8"?> | ||
2 | -<!-- | ||
3 | - ~ Copyright 2015-present 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/xsd/maven-4.0.0.xsd"> | ||
20 | - <parent> | ||
21 | - <groupId>org.onosproject</groupId> | ||
22 | - <artifactId>onos-apps</artifactId> | ||
23 | - <version>1.6.0-SNAPSHOT</version> | ||
24 | - <relativePath>../pom.xml</relativePath> | ||
25 | - </parent> | ||
26 | - <modelVersion>4.0.0</modelVersion> | ||
27 | - | ||
28 | - <artifactId>onos-olt</artifactId> | ||
29 | - | ||
30 | - <packaging>pom</packaging> | ||
31 | - <description>OLT application for CORD</description> | ||
32 | - | ||
33 | - <modules> | ||
34 | - <module>api</module> | ||
35 | - <module>app</module> | ||
36 | - </modules> | ||
37 | - | ||
38 | -</project> |
... | @@ -29,7 +29,6 @@ | ... | @@ -29,7 +29,6 @@ |
29 | <description>ONOS sample applications</description> | 29 | <description>ONOS sample applications</description> |
30 | 30 | ||
31 | <modules> | 31 | <modules> |
32 | - <module>aaa</module> | ||
33 | <module>acl</module> | 32 | <module>acl</module> |
34 | <module>faultmanagement</module> | 33 | <module>faultmanagement</module> |
35 | <module>fwd</module> | 34 | <module>fwd</module> |
... | @@ -51,14 +50,11 @@ | ... | @@ -51,14 +50,11 @@ |
51 | <module>pcep-api</module> | 50 | <module>pcep-api</module> |
52 | <module>iptopology-api</module> | 51 | <module>iptopology-api</module> |
53 | <module>pce</module> | 52 | <module>pce</module> |
54 | - <module>olt</module> | ||
55 | <module>cip</module> | 53 | <module>cip</module> |
56 | <module>flowanalyzer</module> | 54 | <module>flowanalyzer</module> |
57 | <module>vtn</module> | 55 | <module>vtn</module> |
58 | <module>dhcp</module> | 56 | <module>dhcp</module> |
59 | - <module>cordvtn</module> | ||
60 | <module>mfwd</module> | 57 | <module>mfwd</module> |
61 | - <module>igmp</module> | ||
62 | <module>pim</module> | 58 | <module>pim</module> |
63 | <module>mlb</module> | 59 | <module>mlb</module> |
64 | <module>pathpainter</module> | 60 | <module>pathpainter</module> |
... | @@ -66,7 +62,6 @@ | ... | @@ -66,7 +62,6 @@ |
66 | <module>cpman</module> | 62 | <module>cpman</module> |
67 | <module>events</module> | 63 | <module>events</module> |
68 | <module>vrouter</module> | 64 | <module>vrouter</module> |
69 | - <module>cordmcast</module> | ||
70 | <module>vpls</module> | 65 | <module>vpls</module> |
71 | <module>openstacknode</module> | 66 | <module>openstacknode</module> |
72 | <module>openstacknetworking</module> | 67 | <module>openstacknetworking</module> |
... | @@ -75,7 +70,6 @@ | ... | @@ -75,7 +70,6 @@ |
75 | <module>gangliametrics</module> | 70 | <module>gangliametrics</module> |
76 | <module>graphitemetrics</module> | 71 | <module>graphitemetrics</module> |
77 | <module>xosclient</module> | 72 | <module>xosclient</module> |
78 | - <module>cordconfig</module> | ||
79 | <module>scalablegateway</module> | 73 | <module>scalablegateway</module> |
80 | </modules> | 74 | </modules> |
81 | 75 | ... | ... |
... | @@ -40,16 +40,12 @@ APPS = [ | ... | @@ -40,16 +40,12 @@ APPS = [ |
40 | # Apps | 40 | # Apps |
41 | '//apps/dhcp:onos-apps-dhcp-oar', | 41 | '//apps/dhcp:onos-apps-dhcp-oar', |
42 | '//apps/fwd:onos-apps-fwd-oar', | 42 | '//apps/fwd:onos-apps-fwd-oar', |
43 | - '//apps/aaa:onos-apps-aaa-oar', | ||
44 | '//apps/acl:onos-apps-acl-oar', | 43 | '//apps/acl:onos-apps-acl-oar', |
45 | '//apps/bgprouter:onos-apps-bgprouter-oar', | 44 | '//apps/bgprouter:onos-apps-bgprouter-oar', |
46 | '//apps/proxyarp:onos-apps-proxyarp-oar', | 45 | '//apps/proxyarp:onos-apps-proxyarp-oar', |
47 | '//apps/segmentrouting:onos-apps-segmentrouting-oar', | 46 | '//apps/segmentrouting:onos-apps-segmentrouting-oar', |
48 | '//apps/gangliametrics:onos-apps-gangliametrics-oar', | 47 | '//apps/gangliametrics:onos-apps-gangliametrics-oar', |
49 | '//apps/graphitemetrics:onos-apps-graphitemetrics-oar', | 48 | '//apps/graphitemetrics:onos-apps-graphitemetrics-oar', |
50 | - '//apps/igmp:onos-apps-igmp-oar', | ||
51 | - '//apps/cordmcast:onos-apps-cordmcast-oar', | ||
52 | - '//apps/olt:onos-apps-olt-oar', | ||
53 | '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar', | 49 | '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar', |
54 | '//apps/metrics:onos-apps-metrics-oar', | 50 | '//apps/metrics:onos-apps-metrics-oar', |
55 | '//apps/mfwd:onos-apps-mfwd-oar', | 51 | '//apps/mfwd:onos-apps-mfwd-oar', |
... | @@ -66,7 +62,6 @@ APPS = [ | ... | @@ -66,7 +62,6 @@ APPS = [ |
66 | '//apps/reactive-routing:onos-apps-reactive-routing-oar', | 62 | '//apps/reactive-routing:onos-apps-reactive-routing-oar', |
67 | '//apps/sdnip:onos-apps-sdnip-oar', | 63 | '//apps/sdnip:onos-apps-sdnip-oar', |
68 | '//apps/virtualbng:onos-apps-virtualbng-oar', | 64 | '//apps/virtualbng:onos-apps-virtualbng-oar', |
69 | - '//apps/cordvtn:onos-apps-cordvtn-oar', | ||
70 | '//apps/vpls:onos-apps-vpls-oar', | 65 | '//apps/vpls:onos-apps-vpls-oar', |
71 | '//apps/vrouter:onos-apps-vrouter-oar', | 66 | '//apps/vrouter:onos-apps-vrouter-oar', |
72 | '//apps/vtn:onos-apps-vtn-oar', | 67 | '//apps/vtn:onos-apps-vtn-oar', | ... | ... |
-
Please register or login to post a comment