Committed by
Gerrit Code Review
[ONOS-3953] Implements Security Group of Openstack
Change-Id: I30766097a2894a26e46a7a399176d99e95af6abf
Showing
8 changed files
with
623 additions
and
37 deletions
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.openstackinterface; | 16 | package org.onosproject.openstackinterface; |
17 | 17 | ||
18 | +import org.onlab.packet.IpPrefix; | ||
19 | + | ||
18 | import java.util.Objects; | 20 | import java.util.Objects; |
19 | 21 | ||
20 | import static com.google.common.base.Preconditions.checkNotNull; | 22 | import static com.google.common.base.Preconditions.checkNotNull; |
... | @@ -24,25 +26,34 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -24,25 +26,34 @@ import static com.google.common.base.Preconditions.checkNotNull; |
24 | */ | 26 | */ |
25 | public final class OpenstackSecurityGroupRule { | 27 | public final class OpenstackSecurityGroupRule { |
26 | 28 | ||
27 | - private final String direction; | 29 | + private final Direction direction; |
28 | private final String ethertype; | 30 | private final String ethertype; |
29 | private final String id; | 31 | private final String id; |
30 | - private final String portRangeMax; | 32 | + private final int portRangeMax; |
31 | - private final String portRangeMin; | 33 | + private final int portRangeMin; |
32 | private final String protocol; | 34 | private final String protocol; |
33 | private final String remoteGroupId; | 35 | private final String remoteGroupId; |
34 | - private final String remoteIpPrefix; | 36 | + private final IpPrefix remoteIpPrefix; |
35 | private final String secuityGroupId; | 37 | private final String secuityGroupId; |
36 | private final String tenantId; | 38 | private final String tenantId; |
37 | 39 | ||
38 | - private OpenstackSecurityGroupRule(String direction, | 40 | + /** |
41 | + * Direction of the Security Group. | ||
42 | + * | ||
43 | + */ | ||
44 | + public enum Direction { | ||
45 | + INGRESS, | ||
46 | + EGRESS | ||
47 | + } | ||
48 | + | ||
49 | + private OpenstackSecurityGroupRule(Direction direction, | ||
39 | String ethertype, | 50 | String ethertype, |
40 | String id, | 51 | String id, |
41 | - String portRangeMax, | 52 | + int portRangeMax, |
42 | - String portRangeMin, | 53 | + int portRangeMin, |
43 | String protocol, | 54 | String protocol, |
44 | String remoteGroupId, | 55 | String remoteGroupId, |
45 | - String remoteIpPrefix, | 56 | + IpPrefix remoteIpPrefix, |
46 | String securityGroupId, | 57 | String securityGroupId, |
47 | String tenantId) { | 58 | String tenantId) { |
48 | this.direction = direction; | 59 | this.direction = direction; |
... | @@ -57,6 +68,105 @@ public final class OpenstackSecurityGroupRule { | ... | @@ -57,6 +68,105 @@ public final class OpenstackSecurityGroupRule { |
57 | this.tenantId = tenantId; | 68 | this.tenantId = tenantId; |
58 | } | 69 | } |
59 | 70 | ||
71 | + /** | ||
72 | + * Returns the builder object for the OpenstackSecurityGroupRule. | ||
73 | + * | ||
74 | + * @return OpenstackSecurityGroupRule builder object | ||
75 | + */ | ||
76 | + public static OpenstackSecurityGroupRule.Builder builder() { | ||
77 | + return new Builder(); | ||
78 | + } | ||
79 | + | ||
80 | + /** | ||
81 | + * Returns the direction. | ||
82 | + * | ||
83 | + * @return direction | ||
84 | + */ | ||
85 | + public Direction direction() { | ||
86 | + return direction; | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * Returns the Ethernet type. | ||
91 | + * | ||
92 | + * @return Ethernet type | ||
93 | + */ | ||
94 | + public String ethertype() { | ||
95 | + return ethertype; | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * Returns the Security Group ID. | ||
100 | + * | ||
101 | + * @return Security Group ID | ||
102 | + */ | ||
103 | + public String id() { | ||
104 | + return id; | ||
105 | + } | ||
106 | + | ||
107 | + /** | ||
108 | + * Returns the max of the port range. | ||
109 | + * | ||
110 | + * @return max of the port range | ||
111 | + */ | ||
112 | + public int portRangeMax() { | ||
113 | + return portRangeMax; | ||
114 | + } | ||
115 | + | ||
116 | + /** | ||
117 | + * Returns the min of the port range. | ||
118 | + * | ||
119 | + * @return min of the port range | ||
120 | + */ | ||
121 | + public int portRangeMin() { | ||
122 | + return portRangeMin; | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + * Returns the IP protocol. | ||
127 | + * | ||
128 | + * @return IP protocol | ||
129 | + */ | ||
130 | + public String protocol() { | ||
131 | + return protocol; | ||
132 | + } | ||
133 | + | ||
134 | + /** | ||
135 | + * Returns the remote group ID. | ||
136 | + * | ||
137 | + * @return remote group ID | ||
138 | + */ | ||
139 | + public String remoteGroupId() { | ||
140 | + return remoteGroupId; | ||
141 | + } | ||
142 | + | ||
143 | + /** | ||
144 | + * Returns the remote IP address. | ||
145 | + * | ||
146 | + * @return remote IP address | ||
147 | + */ | ||
148 | + public IpPrefix remoteIpPrefix() { | ||
149 | + return this.remoteIpPrefix; | ||
150 | + } | ||
151 | + | ||
152 | + /** | ||
153 | + * Returns the Security Group ID. | ||
154 | + * | ||
155 | + * @return security group ID | ||
156 | + */ | ||
157 | + public String secuityGroupId() { | ||
158 | + return secuityGroupId; | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Returns the tenant ID. | ||
163 | + * | ||
164 | + * @return tenant ID | ||
165 | + */ | ||
166 | + public String tenantId() { | ||
167 | + return tenantId; | ||
168 | + } | ||
169 | + | ||
60 | @Override | 170 | @Override |
61 | public String toString() { | 171 | public String toString() { |
62 | return new StringBuilder(" [") | 172 | return new StringBuilder(" [") |
... | @@ -84,8 +194,8 @@ public final class OpenstackSecurityGroupRule { | ... | @@ -84,8 +194,8 @@ public final class OpenstackSecurityGroupRule { |
84 | return this.direction.equals(that.direction) && | 194 | return this.direction.equals(that.direction) && |
85 | this.ethertype.equals(that.direction) && | 195 | this.ethertype.equals(that.direction) && |
86 | this.id.equals(that.id) && | 196 | this.id.equals(that.id) && |
87 | - this.portRangeMax.equals(that.portRangeMax) && | 197 | + this.portRangeMax == that.portRangeMax && |
88 | - this.portRangeMin.equals(that.portRangeMin) && | 198 | + this.portRangeMin == that.portRangeMin && |
89 | this.protocol.equals(that.protocol) && | 199 | this.protocol.equals(that.protocol) && |
90 | this.remoteGroupId.equals(that.remoteGroupId) && | 200 | this.remoteGroupId.equals(that.remoteGroupId) && |
91 | this.secuityGroupId.equals(that.secuityGroupId) && | 201 | this.secuityGroupId.equals(that.secuityGroupId) && |
... | @@ -235,8 +345,16 @@ public final class OpenstackSecurityGroupRule { | ... | @@ -235,8 +345,16 @@ public final class OpenstackSecurityGroupRule { |
235 | * @return OpenstackSecurityGroupRule object | 345 | * @return OpenstackSecurityGroupRule object |
236 | */ | 346 | */ |
237 | public OpenstackSecurityGroupRule build() { | 347 | public OpenstackSecurityGroupRule build() { |
238 | - return new OpenstackSecurityGroupRule(direction, etherType, id, portRangeMax, | 348 | + |
239 | - portRangeMin, protocol, remoteGroupId, remoteIpPrefix, secuityGroupId, tenantId); | 349 | + int portRangeMinInt = (portRangeMin == null || portRangeMin.equals("null")) ? |
350 | + -1 : Integer.parseInt(portRangeMax); | ||
351 | + int portRangeMaxInt = (portRangeMax == null || portRangeMax.equals("null")) ? | ||
352 | + -1 : Integer.parseInt(portRangeMax); | ||
353 | + IpPrefix ipPrefix = (remoteIpPrefix == null || remoteIpPrefix.equals("null")) ? | ||
354 | + null : IpPrefix.valueOf(remoteIpPrefix); | ||
355 | + | ||
356 | + return new OpenstackSecurityGroupRule(Direction.valueOf(direction.toUpperCase()), etherType, id, | ||
357 | + portRangeMaxInt, portRangeMinInt, protocol, remoteGroupId, ipPrefix, secuityGroupId, tenantId); | ||
240 | } | 358 | } |
241 | } | 359 | } |
242 | } | 360 | } | ... | ... |
... | @@ -48,7 +48,7 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou | ... | @@ -48,7 +48,7 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou |
48 | private static final String REMOTE_GROUP_ID = "remote_group_id"; | 48 | private static final String REMOTE_GROUP_ID = "remote_group_id"; |
49 | private static final String REMOTE_IP_PREFIX = "remote_ip_prefix"; | 49 | private static final String REMOTE_IP_PREFIX = "remote_ip_prefix"; |
50 | private static final String SECURITY_GROUP_ID = "security_group_id"; | 50 | private static final String SECURITY_GROUP_ID = "security_group_id"; |
51 | - private static final String TENAN_ID = "tenant_id"; | 51 | + private static final String TENANT_ID = "tenant_id"; |
52 | 52 | ||
53 | @Override | 53 | @Override |
54 | public OpenstackSecurityGroup decode(ObjectNode json, CodecContext context) { | 54 | public OpenstackSecurityGroup decode(ObjectNode json, CodecContext context) { |
... | @@ -75,12 +75,12 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou | ... | @@ -75,12 +75,12 @@ public class OpenstackSecurityGroupCodec extends JsonCodec<OpenstackSecurityGrou |
75 | .remoteGroupId(ruleInfo.path(REMOTE_GROUP_ID).asText()) | 75 | .remoteGroupId(ruleInfo.path(REMOTE_GROUP_ID).asText()) |
76 | .remoteIpPrefix(ruleInfo.path(REMOTE_IP_PREFIX).asText()) | 76 | .remoteIpPrefix(ruleInfo.path(REMOTE_IP_PREFIX).asText()) |
77 | .securityGroupId(ruleInfo.path(SECURITY_GROUP_ID).asText()) | 77 | .securityGroupId(ruleInfo.path(SECURITY_GROUP_ID).asText()) |
78 | - .tenantId(ruleInfo.path(TENAN_ID).asText()) | 78 | + .tenantId(ruleInfo.path(TENANT_ID).asText()) |
79 | .build(); | 79 | .build(); |
80 | 80 | ||
81 | rules.add(openstackSecurityGroupRule); | 81 | rules.add(openstackSecurityGroupRule); |
82 | } | 82 | } |
83 | - String tenantId = securityGroupNode.path(TENAN_ID).asText(); | 83 | + String tenantId = securityGroupNode.path(TENANT_ID).asText(); |
84 | 84 | ||
85 | OpenstackSecurityGroup openstackSecurityGroup = OpenstackSecurityGroup.builder() | 85 | OpenstackSecurityGroup openstackSecurityGroup = OpenstackSecurityGroup.builder() |
86 | .description(description) | 86 | .description(description) | ... | ... |
... | @@ -18,6 +18,10 @@ package org.onosproject.openstacknetworking; | ... | @@ -18,6 +18,10 @@ package org.onosproject.openstacknetworking; |
18 | import org.onlab.packet.Ip4Address; | 18 | import org.onlab.packet.Ip4Address; |
19 | import org.onlab.packet.MacAddress; | 19 | import org.onlab.packet.MacAddress; |
20 | import org.onosproject.net.DeviceId; | 20 | import org.onosproject.net.DeviceId; |
21 | + | ||
22 | +import java.util.Collection; | ||
23 | +import java.util.Collections; | ||
24 | + | ||
21 | import static com.google.common.base.Preconditions.checkNotNull; | 25 | import static com.google.common.base.Preconditions.checkNotNull; |
22 | 26 | ||
23 | /** | 27 | /** |
... | @@ -29,70 +33,174 @@ public class OpenstackPortInfo { | ... | @@ -29,70 +33,174 @@ public class OpenstackPortInfo { |
29 | private final DeviceId deviceId; | 33 | private final DeviceId deviceId; |
30 | private final long vni; | 34 | private final long vni; |
31 | private final Ip4Address gatewayIP; | 35 | private final Ip4Address gatewayIP; |
36 | + private final Collection<String> securityGroups; | ||
32 | 37 | ||
33 | - public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, long vni, Ip4Address gatewayIP) { | 38 | + /** |
39 | + * Returns OpenstackPortInfo reference. | ||
40 | + * | ||
41 | + * @param hostIp host IP address | ||
42 | + * @param hostMac host MAC address | ||
43 | + * @param deviceId device ID | ||
44 | + * @param vni tunnel ID | ||
45 | + * @param gatewayIP gateway IP address | ||
46 | + * @param securityGroups security group list | ||
47 | + */ | ||
48 | + public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, long vni, | ||
49 | + Ip4Address gatewayIP, Collection<String> securityGroups) { | ||
34 | this.hostIp = hostIp; | 50 | this.hostIp = hostIp; |
35 | this.hostMac = hostMac; | 51 | this.hostMac = hostMac; |
36 | this.deviceId = deviceId; | 52 | this.deviceId = deviceId; |
37 | this.vni = vni; | 53 | this.vni = vni; |
38 | this.gatewayIP = gatewayIP; | 54 | this.gatewayIP = gatewayIP; |
55 | + this.securityGroups = securityGroups; | ||
39 | } | 56 | } |
40 | 57 | ||
58 | + /** | ||
59 | + * Returns IP address of the port. | ||
60 | + * | ||
61 | + * @return IP address | ||
62 | + */ | ||
41 | public Ip4Address ip() { | 63 | public Ip4Address ip() { |
42 | return hostIp; | 64 | return hostIp; |
43 | } | 65 | } |
44 | 66 | ||
67 | + /** | ||
68 | + * Returns MAC address of the port. | ||
69 | + * | ||
70 | + * @return MAC address | ||
71 | + */ | ||
45 | public MacAddress mac() { | 72 | public MacAddress mac() { |
46 | return hostMac; | 73 | return hostMac; |
47 | } | 74 | } |
48 | 75 | ||
76 | + /** | ||
77 | + * Returns device ID. | ||
78 | + * | ||
79 | + * @return device ID | ||
80 | + */ | ||
49 | public DeviceId deviceId() { | 81 | public DeviceId deviceId() { |
50 | return deviceId; | 82 | return deviceId; |
51 | } | 83 | } |
52 | 84 | ||
85 | + /** | ||
86 | + * Returns tunnel ID. | ||
87 | + * | ||
88 | + * @return tunnel ID | ||
89 | + */ | ||
53 | public long vni() { | 90 | public long vni() { |
54 | return vni; | 91 | return vni; |
55 | } | 92 | } |
56 | 93 | ||
94 | + /** | ||
95 | + * Returns gateway IP address. | ||
96 | + * | ||
97 | + * @return gateway IP address | ||
98 | + */ | ||
57 | public Ip4Address gatewayIP() { | 99 | public Ip4Address gatewayIP() { |
58 | return gatewayIP; | 100 | return gatewayIP; |
59 | } | 101 | } |
60 | 102 | ||
103 | + /** | ||
104 | + * Returns Security Group ID list. | ||
105 | + * | ||
106 | + * @return list of Security Group ID | ||
107 | + */ | ||
108 | + public Collection<String> securityGroups() { | ||
109 | + return Collections.unmodifiableCollection(securityGroups); | ||
110 | + } | ||
111 | + | ||
112 | + /** | ||
113 | + * Returns the builder of the OpenstackPortInfo. | ||
114 | + * | ||
115 | + * @return OpenstackPortInfo builder reference | ||
116 | + */ | ||
61 | public static OpenstackPortInfo.Builder builder() { | 117 | public static OpenstackPortInfo.Builder builder() { |
62 | return new Builder(); | 118 | return new Builder(); |
63 | } | 119 | } |
64 | 120 | ||
121 | + /** | ||
122 | + * Represents the OpenstackPortInfo Builder. | ||
123 | + * | ||
124 | + */ | ||
65 | public static final class Builder { | 125 | public static final class Builder { |
66 | private Ip4Address hostIp; | 126 | private Ip4Address hostIp; |
67 | private MacAddress hostMac; | 127 | private MacAddress hostMac; |
68 | private DeviceId deviceId; | 128 | private DeviceId deviceId; |
69 | private long vni; | 129 | private long vni; |
70 | private Ip4Address gatewayIP; | 130 | private Ip4Address gatewayIP; |
131 | + private Collection<String> securityGroups; | ||
71 | 132 | ||
133 | + /** | ||
134 | + * Sets the IP address of the port. | ||
135 | + * | ||
136 | + * @param gatewayIP | ||
137 | + * @return Builder reference | ||
138 | + */ | ||
72 | public Builder setGatewayIP(Ip4Address gatewayIP) { | 139 | public Builder setGatewayIP(Ip4Address gatewayIP) { |
73 | this.gatewayIP = checkNotNull(gatewayIP, "gatewayIP cannot be null"); | 140 | this.gatewayIP = checkNotNull(gatewayIP, "gatewayIP cannot be null"); |
74 | return this; | 141 | return this; |
75 | } | 142 | } |
76 | 143 | ||
144 | + /** | ||
145 | + * Sets the host IP address of the port. | ||
146 | + * | ||
147 | + * @param hostIp host IP address | ||
148 | + * @return Builder reference | ||
149 | + */ | ||
77 | public Builder setHostIp(Ip4Address hostIp) { | 150 | public Builder setHostIp(Ip4Address hostIp) { |
78 | this.hostIp = checkNotNull(hostIp, "hostIp cannot be null"); | 151 | this.hostIp = checkNotNull(hostIp, "hostIp cannot be null"); |
79 | return this; | 152 | return this; |
80 | } | 153 | } |
81 | 154 | ||
155 | + /** | ||
156 | + * Sets the host MAC address of the port. | ||
157 | + * | ||
158 | + * @param hostMac host MAC address | ||
159 | + * @return Builder reference | ||
160 | + */ | ||
82 | public Builder setHostMac(MacAddress hostMac) { | 161 | public Builder setHostMac(MacAddress hostMac) { |
83 | this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull"); | 162 | this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull"); |
84 | return this; | 163 | return this; |
85 | } | 164 | } |
86 | 165 | ||
166 | + /** | ||
167 | + * Sets the device ID. | ||
168 | + * | ||
169 | + * @param deviceId device ID | ||
170 | + * @return Builder reference | ||
171 | + */ | ||
87 | public Builder setDeviceId(DeviceId deviceId) { | 172 | public Builder setDeviceId(DeviceId deviceId) { |
88 | this.deviceId = checkNotNull(deviceId, "deviceId cannot be null"); | 173 | this.deviceId = checkNotNull(deviceId, "deviceId cannot be null"); |
89 | return this; | 174 | return this; |
90 | } | 175 | } |
91 | 176 | ||
177 | + /** | ||
178 | + * Sets the tunnel ID. | ||
179 | + * | ||
180 | + * @param vni tunnel ID | ||
181 | + * @return Builder reference | ||
182 | + */ | ||
92 | public Builder setVni(long vni) { | 183 | public Builder setVni(long vni) { |
93 | this.vni = checkNotNull(vni, "vni cannot be null"); | 184 | this.vni = checkNotNull(vni, "vni cannot be null"); |
94 | return this; | 185 | return this; |
95 | } | 186 | } |
187 | + | ||
188 | + /** | ||
189 | + * Sets the security group ID list. | ||
190 | + * | ||
191 | + * @param securityGroups security group ID list | ||
192 | + * @return Builder reference | ||
193 | + */ | ||
194 | + public Builder setSecurityGroups(Collection<String> securityGroups) { | ||
195 | + this.securityGroups = securityGroups; | ||
196 | + return this; | ||
197 | + } | ||
198 | + | ||
199 | + /** | ||
200 | + * Builds the OpenstackPortInfo reference. | ||
201 | + * | ||
202 | + * @return OpenstackPortInfo reference | ||
203 | + */ | ||
96 | public OpenstackPortInfo build() { | 204 | public OpenstackPortInfo build() { |
97 | return new OpenstackPortInfo(this); | 205 | return new OpenstackPortInfo(this); |
98 | } | 206 | } |
... | @@ -104,5 +212,6 @@ public class OpenstackPortInfo { | ... | @@ -104,5 +212,6 @@ public class OpenstackPortInfo { |
104 | deviceId = builder.deviceId; | 212 | deviceId = builder.deviceId; |
105 | vni = builder.vni; | 213 | vni = builder.vni; |
106 | gatewayIP = builder.gatewayIP; | 214 | gatewayIP = builder.gatewayIP; |
215 | + securityGroups = builder.securityGroups; | ||
107 | } | 216 | } |
108 | } | 217 | } | ... | ... |
1 | +/* | ||
2 | +* Copyright 2016 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.openstacknetworking.switching; | ||
18 | + | ||
19 | +import org.onlab.packet.Ethernet; | ||
20 | +import org.onlab.packet.IPv4; | ||
21 | +import org.onlab.packet.Ip4Address; | ||
22 | +import org.onlab.packet.Ip4Prefix; | ||
23 | +import org.onlab.packet.IpAddress; | ||
24 | +import org.onlab.packet.IpPrefix; | ||
25 | +import org.onlab.packet.TpPort; | ||
26 | +import org.onosproject.core.ApplicationId; | ||
27 | +import org.onosproject.net.DeviceId; | ||
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.flowobjective.DefaultForwardingObjective; | ||
33 | +import org.onosproject.net.flowobjective.FlowObjectiveService; | ||
34 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
35 | +import org.onosproject.openstackinterface.OpenstackInterfaceService; | ||
36 | +import org.onosproject.openstackinterface.OpenstackSecurityGroup; | ||
37 | +import org.onosproject.openstackinterface.OpenstackSecurityGroupRule; | ||
38 | +import org.onosproject.openstacknetworking.OpenstackPortInfo; | ||
39 | +import org.slf4j.Logger; | ||
40 | +import org.slf4j.LoggerFactory; | ||
41 | + | ||
42 | +import java.util.Map; | ||
43 | + | ||
44 | +/** | ||
45 | + * Populates flows rules for Security Groups of VMs. | ||
46 | + * | ||
47 | + */ | ||
48 | +public class OpenstackSecurityGroupRulePopulator { | ||
49 | + | ||
50 | + private static Logger log = LoggerFactory | ||
51 | + .getLogger(OpenstackSecurityGroupRulePopulator.class); | ||
52 | + | ||
53 | + private OpenstackInterfaceService openstackService; | ||
54 | + private FlowObjectiveService flowObjectiveService; | ||
55 | + | ||
56 | + private ApplicationId appId; | ||
57 | + | ||
58 | + private static final String PROTO_ICMP = "ICMP"; | ||
59 | + private static final String PROTO_TCP = "TCP"; | ||
60 | + private static final String PROTO_UDP = "UDP"; | ||
61 | + | ||
62 | + private static final String ETHTYPE_IPV4 = "IPV4"; | ||
63 | + | ||
64 | + private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0"); | ||
65 | + | ||
66 | + private static final int ACL_RULE_PRIORITY = 30000; | ||
67 | + | ||
68 | + /** | ||
69 | + * Constructor. | ||
70 | + * | ||
71 | + * @param appId | ||
72 | + * @param openstackService | ||
73 | + * @param flowObjectiveService | ||
74 | + */ | ||
75 | + public OpenstackSecurityGroupRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService, | ||
76 | + FlowObjectiveService flowObjectiveService) { | ||
77 | + this.appId = appId; | ||
78 | + this.openstackService = openstackService; | ||
79 | + this.flowObjectiveService = flowObjectiveService; | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Populates flow rules for security groups. | ||
84 | + * | ||
85 | + * @param id Device ID | ||
86 | + * @param sgId Security Group ID | ||
87 | + * @param vmIp VM IP address | ||
88 | + * @param portInfoMap Port Info map | ||
89 | + */ | ||
90 | + public void populateSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp, | ||
91 | + Map<String, OpenstackPortInfo> portInfoMap) { | ||
92 | + OpenstackSecurityGroup securityGroup = openstackService.getSecurityGroup(sgId); | ||
93 | + if (securityGroup != null) { | ||
94 | + securityGroup.rules().stream().forEach(sgRule -> { | ||
95 | + if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) { | ||
96 | + openstackService.ports().stream() | ||
97 | + .filter(port -> port.securityGroups().contains(sgRule.remoteGroupId())) | ||
98 | + .flatMap(port -> port.fixedIps().values().stream()) | ||
99 | + .forEach(remoteIp -> setSecurityGroupRule(id, sgRule, | ||
100 | + vmIp, IpPrefix.valueOf((IpAddress) remoteIp, 32))); | ||
101 | + } else { | ||
102 | + setSecurityGroupRule(id, sgRule, vmIp, sgRule.remoteIpPrefix()); | ||
103 | + } | ||
104 | + }); | ||
105 | + | ||
106 | + openstackService.ports().stream().forEach(osPort -> | ||
107 | + osPort.securityGroups().stream().forEach(remoteVmSgId -> { | ||
108 | + OpenstackSecurityGroup remoteVmSg = openstackService.getSecurityGroup(remoteVmSgId); | ||
109 | + remoteVmSg.rules().stream() | ||
110 | + .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId)) | ||
111 | + .forEach(remoteVmSgRule -> { | ||
112 | + Ip4Address remoteVmIp = | ||
113 | + (Ip4Address) osPort.fixedIps().values().stream().findAny().orElse(null); | ||
114 | + OpenstackPortInfo osPortInfo = portInfoMap.get(OpenstackSwitchingManager.PORTNAME_PREFIX_VM | ||
115 | + + osPort.id().substring(0, 11)); | ||
116 | + if (osPortInfo != null && remoteVmIp != null) { | ||
117 | + setSecurityGroupRule(osPortInfo.deviceId(), remoteVmSgRule, remoteVmIp, | ||
118 | + IpPrefix.valueOf(vmIp, 32)); | ||
119 | + } | ||
120 | + }); | ||
121 | + })); | ||
122 | + } | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + * Removes flow rules for security groups. | ||
127 | + * | ||
128 | + * @param id Device ID | ||
129 | + * @param sgId Security Group ID to remove | ||
130 | + * @param vmIp VM IP address | ||
131 | + * @param portInfoMap port info map | ||
132 | + * @param securityGroupMap security group info map | ||
133 | + */ | ||
134 | + public void removeSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp, | ||
135 | + Map<String, OpenstackPortInfo> portInfoMap, | ||
136 | + Map<String, OpenstackSecurityGroup> securityGroupMap) { | ||
137 | + OpenstackSecurityGroup securityGroup = securityGroupMap.get(sgId); | ||
138 | + if (securityGroup != null) { | ||
139 | + securityGroup.rules().stream().forEach(sgRule -> { | ||
140 | + if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) { | ||
141 | + portInfoMap.values().stream() | ||
142 | + .filter(portInfo -> portInfo.securityGroups().contains(sgRule.remoteGroupId())) | ||
143 | + .map(OpenstackPortInfo::ip) | ||
144 | + .forEach(remoteIp -> { | ||
145 | + removeSecurityGroupRule(id, sgRule, vmIp, IpPrefix.valueOf(remoteIp, 32)); | ||
146 | + }); | ||
147 | + } else { | ||
148 | + removeSecurityGroupRule(id, sgRule, vmIp, sgRule.remoteIpPrefix()); | ||
149 | + } | ||
150 | + }); | ||
151 | + | ||
152 | + portInfoMap.values().stream() | ||
153 | + .forEach(portInfo -> portInfo.securityGroups() | ||
154 | + .forEach(remoteVmSgId -> { | ||
155 | + OpenstackSecurityGroup remoteVmSg = securityGroupMap.get(remoteVmSgId); | ||
156 | + remoteVmSg.rules().stream() | ||
157 | + .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId)) | ||
158 | + .forEach(remoteVmSgRule -> removeSecurityGroupRule(portInfo.deviceId(), | ||
159 | + remoteVmSgRule, portInfo.ip(), IpPrefix.valueOf(vmIp, 32))); | ||
160 | + })); | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + private void setSecurityGroupRule(DeviceId id, OpenstackSecurityGroupRule sgRule, | ||
165 | + Ip4Address vmIp, IpPrefix remoteIp) { | ||
166 | + ForwardingObjective.Builder foBuilder = buildFlowObjective(id, sgRule, vmIp, remoteIp); | ||
167 | + if (foBuilder != null) { | ||
168 | + flowObjectiveService.forward(id, foBuilder.add()); | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | + private void removeSecurityGroupRule(DeviceId id, OpenstackSecurityGroupRule sgRule, | ||
173 | + Ip4Address vmIp, IpPrefix remoteIp) { | ||
174 | + ForwardingObjective.Builder foBuilder = buildFlowObjective(id, sgRule, vmIp, remoteIp); | ||
175 | + if (foBuilder != null) { | ||
176 | + flowObjectiveService.forward(id, foBuilder.remove()); | ||
177 | + } | ||
178 | + } | ||
179 | + | ||
180 | + ForwardingObjective.Builder buildFlowObjective(DeviceId id, OpenstackSecurityGroupRule sgRule, | ||
181 | + Ip4Address vmIp, IpPrefix remoteIp) { | ||
182 | + if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, 32))) { | ||
183 | + return null; | ||
184 | + } | ||
185 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
186 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
187 | + | ||
188 | + buildMatchs(sBuilder, sgRule, vmIp, remoteIp); | ||
189 | + | ||
190 | + ForwardingObjective.Builder foBuilder = DefaultForwardingObjective.builder() | ||
191 | + .withSelector(sBuilder.build()) | ||
192 | + .withTreatment(tBuilder.build()) | ||
193 | + .withPriority(ACL_RULE_PRIORITY) | ||
194 | + .withFlag(ForwardingObjective.Flag.SPECIFIC) | ||
195 | + .fromApp(appId); | ||
196 | + | ||
197 | + return foBuilder; | ||
198 | + } | ||
199 | + | ||
200 | + private void buildMatchs(TrafficSelector.Builder sBuilder, OpenstackSecurityGroupRule sgRule, | ||
201 | + Ip4Address vmIp, IpPrefix remoteIp) { | ||
202 | + buildMatchEthType(sBuilder, sgRule.ethertype()); | ||
203 | + buildMatchDirection(sBuilder, sgRule.direction(), vmIp); | ||
204 | + buildMatchProto(sBuilder, sgRule.protocol()); | ||
205 | + buildMatchPort(sBuilder, sgRule.protocol(), sgRule.direction(), sgRule.portRangeMax(), sgRule.portRangeMin()); | ||
206 | + buildMatchRemoteIp(sBuilder, remoteIp, sgRule.direction()); | ||
207 | + } | ||
208 | + | ||
209 | + private void buildMatchDirection(TrafficSelector.Builder sBuilder, | ||
210 | + OpenstackSecurityGroupRule.Direction direction, Ip4Address vmIp) { | ||
211 | + if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) { | ||
212 | + sBuilder.matchIPSrc(IpPrefix.valueOf(vmIp, 32)); | ||
213 | + } else { | ||
214 | + sBuilder.matchIPDst(IpPrefix.valueOf(vmIp, 32)); | ||
215 | + } | ||
216 | + } | ||
217 | + | ||
218 | + private void buildMatchEthType(TrafficSelector.Builder sBuilder, String ethertype) { | ||
219 | + // Either IpSrc or IpDst (or both) is set by default, and we need to set EthType as IPv4. | ||
220 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4); | ||
221 | + if (ethertype != null && ethertype != "null" && | ||
222 | + !ethertype.toUpperCase().equals(ETHTYPE_IPV4)) { | ||
223 | + log.error("EthType {} is not supported yet in Security Group", ethertype); | ||
224 | + } | ||
225 | + } | ||
226 | + | ||
227 | + private void buildMatchRemoteIp(TrafficSelector.Builder sBuilder, IpPrefix remoteIpPrefix, | ||
228 | + OpenstackSecurityGroupRule.Direction direction) { | ||
229 | + if (remoteIpPrefix != null && !remoteIpPrefix.getIp4Prefix().equals(IP_PREFIX_ANY)) { | ||
230 | + if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) { | ||
231 | + sBuilder.matchIPDst(remoteIpPrefix); | ||
232 | + } else { | ||
233 | + sBuilder.matchIPSrc(remoteIpPrefix); | ||
234 | + } | ||
235 | + } | ||
236 | + } | ||
237 | + | ||
238 | + private void buildMatchProto(TrafficSelector.Builder sBuilder, String protocol) { | ||
239 | + if (protocol != null) { | ||
240 | + switch (protocol.toUpperCase()) { | ||
241 | + case PROTO_ICMP: | ||
242 | + sBuilder.matchIPProtocol(IPv4.PROTOCOL_ICMP); | ||
243 | + break; | ||
244 | + case PROTO_TCP: | ||
245 | + sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP); | ||
246 | + break; | ||
247 | + case PROTO_UDP: | ||
248 | + sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP); | ||
249 | + break; | ||
250 | + default: | ||
251 | + } | ||
252 | + } | ||
253 | + } | ||
254 | + | ||
255 | + private void buildMatchPort(TrafficSelector.Builder sBuilder, String protocol, | ||
256 | + OpenstackSecurityGroupRule.Direction direction, | ||
257 | + int portMin, int portMax) { | ||
258 | + if (portMin > 0 && portMax > 0 && portMin == portMax) { | ||
259 | + if (protocol.toUpperCase().equals(PROTO_TCP)) { | ||
260 | + if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) { | ||
261 | + sBuilder.matchTcpDst(TpPort.tpPort(portMax)); | ||
262 | + } else { | ||
263 | + sBuilder.matchTcpSrc(TpPort.tpPort(portMax)); | ||
264 | + } | ||
265 | + } else if (protocol.toUpperCase().equals(PROTO_UDP)) { | ||
266 | + if (direction.equals(OpenstackSecurityGroupRule.Direction.EGRESS)) { | ||
267 | + sBuilder.matchUdpDst(TpPort.tpPort(portMax)); | ||
268 | + } else { | ||
269 | + sBuilder.matchUdpSrc(TpPort.tpPort(portMax)); | ||
270 | + } | ||
271 | + } | ||
272 | + } | ||
273 | + } | ||
274 | +} |
... | @@ -104,7 +104,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -104,7 +104,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
104 | public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway"; | 104 | public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway"; |
105 | 105 | ||
106 | private ApplicationId appId; | 106 | private ApplicationId appId; |
107 | - private OpenstackArpHandler arpHandler = new OpenstackArpHandler(openstackService, packetService, hostService); | 107 | + |
108 | + private OpenstackArpHandler arpHandler; | ||
109 | + private OpenstackSecurityGroupRulePopulator sgRulePopulator; | ||
108 | 110 | ||
109 | private ExecutorService deviceEventExcutorService = | 111 | private ExecutorService deviceEventExcutorService = |
110 | Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event")); | 112 | Executors.newSingleThreadExecutor(groupedThreads("onos/openstackswitching", "device-event")); |
... | @@ -114,6 +116,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -114,6 +116,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
114 | private InternalHostListener internalHostListener = new InternalHostListener(); | 116 | private InternalHostListener internalHostListener = new InternalHostListener(); |
115 | 117 | ||
116 | private Map<String, OpenstackPortInfo> openstackPortInfoMap = Maps.newHashMap(); | 118 | private Map<String, OpenstackPortInfo> openstackPortInfoMap = Maps.newHashMap(); |
119 | + private Map<String, OpenstackSecurityGroup> securityGroupMap = Maps.newConcurrentMap(); | ||
117 | 120 | ||
118 | @Activate | 121 | @Activate |
119 | protected void activate() { | 122 | protected void activate() { |
... | @@ -124,6 +127,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -124,6 +127,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
124 | deviceService.addListener(internalDeviceListener); | 127 | deviceService.addListener(internalDeviceListener); |
125 | hostService.addListener(internalHostListener); | 128 | hostService.addListener(internalHostListener); |
126 | 129 | ||
130 | + arpHandler = new OpenstackArpHandler(openstackService, packetService, hostService); | ||
131 | + sgRulePopulator = new OpenstackSecurityGroupRulePopulator(appId, openstackService, flowObjectiveService); | ||
132 | + | ||
127 | initializeFlowRules(); | 133 | initializeFlowRules(); |
128 | 134 | ||
129 | log.info("Started"); | 135 | log.info("Started"); |
... | @@ -148,13 +154,6 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -148,13 +154,6 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
148 | registerDhcpInfo(openstackPort); | 154 | registerDhcpInfo(openstackPort); |
149 | } | 155 | } |
150 | } | 156 | } |
151 | - | ||
152 | - if (!openstackPort.securityGroups().isEmpty()) { | ||
153 | - openstackPort.securityGroups().forEach(sgId -> { | ||
154 | - OpenstackSecurityGroup sg = openstackService.getSecurityGroup(sgId); | ||
155 | - log.debug("SecurityGroup : {}", sg.toString()); | ||
156 | - }); | ||
157 | - } | ||
158 | } | 157 | } |
159 | 158 | ||
160 | @Override | 159 | @Override |
... | @@ -185,6 +184,22 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -185,6 +184,22 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
185 | 184 | ||
186 | @Override | 185 | @Override |
187 | public void updatePort(OpenstackPort openstackPort) { | 186 | public void updatePort(OpenstackPort openstackPort) { |
187 | + if (openstackPort.status().equals(OpenstackPort.PortStatus.ACTIVE)) { | ||
188 | + String portName = PORTNAME_PREFIX_VM + openstackPort.id().substring(0, 11); | ||
189 | + OpenstackPortInfo osPortInfo = openstackPortInfoMap.get(portName); | ||
190 | + if (osPortInfo != null) { | ||
191 | + // Remove all security group rules based on the ones stored in security group map. | ||
192 | + osPortInfo.securityGroups().stream().forEach( | ||
193 | + sgId -> sgRulePopulator.removeSecurityGroupRules(osPortInfo.deviceId(), sgId, | ||
194 | + osPortInfo.ip(), openstackPortInfoMap, securityGroupMap)); | ||
195 | + // Add all security group rules based on the updated security group. | ||
196 | + openstackPort.securityGroups().stream().forEach( | ||
197 | + sgId -> sgRulePopulator.populateSecurityGroupRules(osPortInfo.deviceId(), sgId, | ||
198 | + osPortInfo.ip(), openstackPortInfoMap)); | ||
199 | + updatePortMap(osPortInfo.deviceId(), portName, openstackService.networks(), | ||
200 | + openstackService.subnets(), openstackPort); | ||
201 | + } | ||
202 | + } | ||
188 | } | 203 | } |
189 | 204 | ||
190 | @Override | 205 | @Override |
... | @@ -205,29 +220,40 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -205,29 +220,40 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
205 | } | 220 | } |
206 | 221 | ||
207 | private void processPortUpdated(Device device, Port port) { | 222 | private void processPortUpdated(Device device, Port port) { |
208 | - if (!port.annotations().value(PORTNAME).equals(PORTNAME_PREFIX_TUNNEL)) { | 223 | + String portName = port.annotations().value(PORTNAME); |
209 | - if (port.isEnabled() || port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER)) { | 224 | + synchronized (openstackPortInfoMap) { |
225 | + if (portName.startsWith(PORTNAME_PREFIX_VM)) { | ||
226 | + if (port.isEnabled()) { | ||
210 | OpenstackSwitchingRulePopulator rulePopulator = | 227 | OpenstackSwitchingRulePopulator rulePopulator = |
211 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, | 228 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
212 | deviceService, openstackService, driverService); | 229 | deviceService, openstackService, driverService); |
213 | 230 | ||
214 | rulePopulator.populateSwitchingRules(device, port); | 231 | rulePopulator.populateSwitchingRules(device, port); |
215 | - updatePortMap(device.id(), port, openstackService.networks(), openstackService.subnets(), | 232 | + OpenstackPort openstackPort = rulePopulator.openstackPort(port); |
216 | - rulePopulator.openstackPort(port)); | 233 | + Ip4Address vmIp = (Ip4Address) openstackPort.fixedIps().values().stream() |
234 | + .findAny().orElseGet(null); | ||
235 | + openstackPort.securityGroups().stream().forEach( | ||
236 | + sgId -> sgRulePopulator.populateSecurityGroupRules(device.id(), sgId, vmIp, | ||
237 | + openstackPortInfoMap)); | ||
238 | + updatePortMap(device.id(), port.annotations().value(PORTNAME), | ||
239 | + openstackService.networks(), openstackService.subnets(), openstackPort); | ||
217 | 240 | ||
218 | //In case portupdate event is driven by vm shutoff from openstack | 241 | //In case portupdate event is driven by vm shutoff from openstack |
219 | - } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) { | 242 | + } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(portName)) { |
220 | log.debug("Flowrules according to the port {} were removed", port.number().toString()); | 243 | log.debug("Flowrules according to the port {} were removed", port.number().toString()); |
221 | OpenstackSwitchingRulePopulator rulePopulator = | 244 | OpenstackSwitchingRulePopulator rulePopulator = |
222 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, | 245 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
223 | deviceService, openstackService, driverService); | 246 | deviceService, openstackService, driverService); |
224 | - | ||
225 | rulePopulator.removeSwitchingRules(port, openstackPortInfoMap); | 247 | rulePopulator.removeSwitchingRules(port, openstackPortInfoMap); |
248 | + openstackPortInfoMap.get(portName).securityGroups().stream().forEach( | ||
249 | + sgId -> sgRulePopulator.removeSecurityGroupRules(device.id(), sgId, | ||
250 | + openstackPortInfoMap.get(portName).ip(), openstackPortInfoMap, securityGroupMap)); | ||
226 | dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac()); | 251 | dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac()); |
227 | openstackPortInfoMap.remove(port.annotations().value(PORTNAME)); | 252 | openstackPortInfoMap.remove(port.annotations().value(PORTNAME)); |
228 | } | 253 | } |
229 | } | 254 | } |
230 | } | 255 | } |
256 | + } | ||
231 | 257 | ||
232 | private void processPortRemoved(Device device, Port port) { | 258 | private void processPortRemoved(Device device, Port port) { |
233 | log.debug("port {} is removed", port.toString()); | 259 | log.debug("port {} is removed", port.toString()); |
... | @@ -251,7 +277,13 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -251,7 +277,13 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
251 | OpenstackPort osPort = rulePopulator.openstackPort(vmPort); | 277 | OpenstackPort osPort = rulePopulator.openstackPort(vmPort); |
252 | if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) { | 278 | if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) { |
253 | rulePopulator.populateSwitchingRules(device, vmPort); | 279 | rulePopulator.populateSwitchingRules(device, vmPort); |
254 | - updatePortMap(device.id(), vmPort, networks, subnets, osPort); | 280 | + Ip4Address vmIp = (Ip4Address) osPort.fixedIps().values().stream() |
281 | + .findAny().orElseGet(null); | ||
282 | + osPort.securityGroups().stream().forEach( | ||
283 | + sgId -> sgRulePopulator.populateSecurityGroupRules(device.id(), | ||
284 | + sgId, vmIp, openstackPortInfoMap)); | ||
285 | + updatePortMap(device.id(), vmPort.annotations().value(PORTNAME), networks, | ||
286 | + subnets, osPort); | ||
255 | registerDhcpInfo(osPort); | 287 | registerDhcpInfo(osPort); |
256 | } else { | 288 | } else { |
257 | log.warn("No openstackPort information for port {}", vmPort); | 289 | log.warn("No openstackPort information for port {}", vmPort); |
... | @@ -262,7 +294,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -262,7 +294,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
262 | ); | 294 | ); |
263 | } | 295 | } |
264 | 296 | ||
265 | - private void updatePortMap(DeviceId deviceId, Port port, Collection<OpenstackNetwork> networks, | 297 | + private void updatePortMap(DeviceId deviceId, String portName, Collection<OpenstackNetwork> networks, |
266 | Collection<OpenstackSubnet> subnets, OpenstackPort openstackPort) { | 298 | Collection<OpenstackSubnet> subnets, OpenstackPort openstackPort) { |
267 | long vni = Long.parseLong(networks.stream() | 299 | long vni = Long.parseLong(networks.stream() |
268 | .filter(n -> n.id().equals(openstackPort.networkId())) | 300 | .filter(n -> n.id().equals(openstackPort.networkId())) |
... | @@ -279,10 +311,17 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -279,10 +311,17 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
279 | .setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null)) | 311 | .setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null)) |
280 | .setHostMac(openstackPort.macAddress()) | 312 | .setHostMac(openstackPort.macAddress()) |
281 | .setVni(vni) | 313 | .setVni(vni) |
282 | - .setGatewayIP(gatewayIPAddress); | 314 | + .setGatewayIP(gatewayIPAddress) |
315 | + .setSecurityGroups(openstackPort.securityGroups()); | ||
316 | + | ||
317 | + openstackPortInfoMap.put(portName, portBuilder.build()); | ||
318 | + | ||
319 | + openstackPort.securityGroups().stream().forEach(sgId -> { | ||
320 | + if (!securityGroupMap.containsKey(sgId)) { | ||
321 | + securityGroupMap.put(sgId, openstackService.getSecurityGroup(sgId)); | ||
322 | + } | ||
323 | + }); | ||
283 | 324 | ||
284 | - openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME), | ||
285 | - portBuilder.build()); | ||
286 | } | 325 | } |
287 | 326 | ||
288 | private void processHostRemoved(Host host) { | 327 | private void processHostRemoved(Host host) { | ... | ... |
... | @@ -58,7 +58,6 @@ public class OpenstackSwitchingRulePopulator { | ... | @@ -58,7 +58,6 @@ public class OpenstackSwitchingRulePopulator { |
58 | private static Logger log = LoggerFactory | 58 | private static Logger log = LoggerFactory |
59 | .getLogger(OpenstackSwitchingRulePopulator.class); | 59 | .getLogger(OpenstackSwitchingRulePopulator.class); |
60 | private static final int SWITCHING_RULE_PRIORITY = 30000; | 60 | private static final int SWITCHING_RULE_PRIORITY = 30000; |
61 | - private static final int EAST_WEST_ROUTING_RULE_PRIORITY = 29000; | ||
62 | private static final int TUNNELTAG_RULE_PRIORITY = 30000; | 61 | private static final int TUNNELTAG_RULE_PRIORITY = 30000; |
63 | 62 | ||
64 | private FlowObjectiveService flowObjectiveService; | 63 | private FlowObjectiveService flowObjectiveService; |
... | @@ -490,4 +489,5 @@ public class OpenstackSwitchingRulePopulator { | ... | @@ -490,4 +489,5 @@ public class OpenstackSwitchingRulePopulator { |
490 | } | 489 | } |
491 | return port.number(); | 490 | return port.number(); |
492 | } | 491 | } |
492 | + | ||
493 | } | 493 | } | ... | ... |
... | @@ -84,6 +84,23 @@ public class OpenstackPortWebResource extends AbstractWebResource { | ... | @@ -84,6 +84,23 @@ public class OpenstackPortWebResource extends AbstractWebResource { |
84 | @Consumes(MediaType.APPLICATION_JSON) | 84 | @Consumes(MediaType.APPLICATION_JSON) |
85 | @Produces(MediaType.APPLICATION_JSON) | 85 | @Produces(MediaType.APPLICATION_JSON) |
86 | public Response updatePorts(InputStream input) { | 86 | public Response updatePorts(InputStream input) { |
87 | + try { | ||
88 | + ObjectMapper mapper = new ObjectMapper(); | ||
89 | + ObjectNode portNode = (ObjectNode) mapper.readTree(input); | ||
90 | + | ||
91 | + OpenstackPort openstackPort = PORT_CODEC.decode(portNode, this); | ||
92 | + OpenstackSwitchingService switchingService = | ||
93 | + getService(OpenstackSwitchingService.class); | ||
94 | + switchingService.updatePort(openstackPort); | ||
95 | + | ||
96 | + log.debug("REST API update port is called with {}", portNode.toString()); | ||
87 | return Response.status(Response.Status.OK).build(); | 97 | return Response.status(Response.Status.OK).build(); |
98 | + | ||
99 | + } catch (Exception e) { | ||
100 | + log.error("Update Port failed because of exception {}", | ||
101 | + e.toString()); | ||
102 | + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString()) | ||
103 | + .build(); | ||
104 | + } | ||
88 | } | 105 | } |
89 | } | 106 | } | ... | ... |
... | @@ -64,6 +64,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline | ... | @@ -64,6 +64,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline |
64 | 64 | ||
65 | protected static final int VNI_TABLE = 0; | 65 | protected static final int VNI_TABLE = 0; |
66 | protected static final int FORWARDING_TABLE = 1; | 66 | protected static final int FORWARDING_TABLE = 1; |
67 | + protected static final int ACL_TABLE = 2; | ||
67 | 68 | ||
68 | private static final int DROP_PRIORITY = 0; | 69 | private static final int DROP_PRIORITY = 0; |
69 | private static final int TIME_OUT = 0; | 70 | private static final int TIME_OUT = 0; |
... | @@ -136,6 +137,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline | ... | @@ -136,6 +137,7 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline |
136 | private void initializePipeline() { | 137 | private void initializePipeline() { |
137 | processVniTable(true); | 138 | processVniTable(true); |
138 | processForwardingTable(true); | 139 | processForwardingTable(true); |
140 | + processAclTable(true); | ||
139 | } | 141 | } |
140 | 142 | ||
141 | private void processVniTable(boolean install) { | 143 | private void processVniTable(boolean install) { |
... | @@ -176,6 +178,26 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline | ... | @@ -176,6 +178,26 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline |
176 | applyRules(install, flowRule); | 178 | applyRules(install, flowRule); |
177 | } | 179 | } |
178 | 180 | ||
181 | + private void processAclTable(boolean install) { | ||
182 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
183 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
184 | + | ||
185 | + treatment.wipeDeferred(); | ||
186 | + treatment.drop(); | ||
187 | + | ||
188 | + FlowRule flowRule = DefaultFlowRule.builder() | ||
189 | + .forDevice(deviceId) | ||
190 | + .withSelector(selector.build()) | ||
191 | + .withTreatment(treatment.build()) | ||
192 | + .withPriority(DROP_PRIORITY) | ||
193 | + .fromApp(appId) | ||
194 | + .makePermanent() | ||
195 | + .forTable(ACL_TABLE) | ||
196 | + .build(); | ||
197 | + | ||
198 | + applyRules(install, flowRule); | ||
199 | + } | ||
200 | + | ||
179 | private void applyRules(boolean install, FlowRule flowRule) { | 201 | private void applyRules(boolean install, FlowRule flowRule) { |
180 | FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder(); | 202 | FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder(); |
181 | 203 | ||
... | @@ -264,8 +286,15 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline | ... | @@ -264,8 +286,15 @@ public class OpenstackPipeline extends DefaultSingleTablePipeline |
264 | tBuilder.transition(FORWARDING_TABLE); | 286 | tBuilder.transition(FORWARDING_TABLE); |
265 | ruleBuilder.withTreatment(tBuilder.build()); | 287 | ruleBuilder.withTreatment(tBuilder.build()); |
266 | ruleBuilder.forTable(VNI_TABLE); | 288 | ruleBuilder.forTable(VNI_TABLE); |
267 | - } else { | 289 | + } else if (forwardingObjective.selector().getCriterion(Criterion.Type.TUNNEL_ID) != null) { |
290 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
291 | + tBuilder.deferred(); | ||
292 | + forwardingObjective.treatment().allInstructions().forEach(tBuilder::add); | ||
293 | + tBuilder.transition(ACL_TABLE); | ||
294 | + ruleBuilder.withTreatment(tBuilder.build()); | ||
268 | ruleBuilder.forTable(FORWARDING_TABLE); | 295 | ruleBuilder.forTable(FORWARDING_TABLE); |
296 | + } else { | ||
297 | + ruleBuilder.forTable(ACL_TABLE); | ||
269 | } | 298 | } |
270 | 299 | ||
271 | return Collections.singletonList(ruleBuilder.build()); | 300 | return Collections.singletonList(ruleBuilder.build()); | ... | ... |
-
Please register or login to post a comment