blob: 70f197a3a915c0a674e3b944344dee10c34c42e0 [file] [log] [blame]
sangho6a9ff0d2017-03-27 11:23:37 +09001/*
Jian Li26949762018-03-30 15:46:37 +09002 * Copyright 2017-present Open Networking Foundation
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 */
sangho6a9ff0d2017-03-27 11:23:37 +090016
17package org.onosproject.openstacknetworking.impl;
18
19import com.google.common.base.Strings;
sangho2e97be02017-07-03 18:18:27 +090020import com.google.common.collect.Sets;
sangho6a9ff0d2017-03-27 11:23:37 +090021import org.onlab.packet.Ethernet;
22import org.onlab.packet.IPv4;
23import org.onlab.packet.Ip4Address;
24import org.onlab.packet.Ip4Prefix;
25import org.onlab.packet.IpPrefix;
26import org.onlab.packet.TpPort;
Jian Lie8b28db2018-10-17 14:04:09 +090027import org.onlab.packet.VlanId;
Jian Liac30e272018-10-18 23:08:03 +090028import org.onlab.util.KryoNamespace;
sangho0248ca22017-05-31 13:22:47 +090029import org.onlab.util.Tools;
30import org.onosproject.cfg.ComponentConfigService;
Jian Li627e0162020-03-12 17:50:36 +090031import org.onosproject.cfg.ConfigProperty;
sangho1aaa7882017-05-31 13:22:47 +090032import org.onosproject.cluster.ClusterService;
33import org.onosproject.cluster.LeadershipService;
34import org.onosproject.cluster.NodeId;
sangho6a9ff0d2017-03-27 11:23:37 +090035import org.onosproject.core.ApplicationId;
36import org.onosproject.core.CoreService;
37import org.onosproject.mastership.MastershipService;
sangho1aaa7882017-05-31 13:22:47 +090038import org.onosproject.net.DeviceId;
Jian Li857f1b02019-09-20 16:58:19 +090039import org.onosproject.net.device.DeviceService;
sangho1aaa7882017-05-31 13:22:47 +090040import org.onosproject.net.driver.DriverService;
sangho6a9ff0d2017-03-27 11:23:37 +090041import org.onosproject.net.flow.DefaultTrafficSelector;
42import org.onosproject.net.flow.DefaultTrafficTreatment;
43import org.onosproject.net.flow.TrafficSelector;
sangho1aaa7882017-05-31 13:22:47 +090044import org.onosproject.net.flow.TrafficTreatment;
45import org.onosproject.net.flow.criteria.ExtensionSelector;
Jian Li28ec77f2018-10-31 07:07:25 +090046import org.onosproject.net.flow.instructions.ExtensionTreatment;
sangho6a9ff0d2017-03-27 11:23:37 +090047import org.onosproject.openstacknetworking.api.InstancePort;
Jian Li9d35bd62018-10-13 01:43:24 +090048import org.onosproject.openstacknetworking.api.InstancePortAdminService;
sangho6a9ff0d2017-03-27 11:23:37 +090049import org.onosproject.openstacknetworking.api.InstancePortEvent;
50import org.onosproject.openstacknetworking.api.InstancePortListener;
sanghodc375372017-06-08 10:41:30 +090051import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
SONA Project6bc5c4a2018-12-14 23:49:52 +090052import org.onosproject.openstacknetworking.api.OpenstackNetwork.Type;
sangho6a9ff0d2017-03-27 11:23:37 +090053import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
54import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
55import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
56import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupEvent;
57import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupListener;
58import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupService;
Jian Li26949762018-03-30 15:46:37 +090059import org.onosproject.openstacknetworking.util.RulePopulatorUtil;
Jian Li627e0162020-03-12 17:50:36 +090060import org.onosproject.openstacknode.api.OpenstackNode;
sangho1aaa7882017-05-31 13:22:47 +090061import org.onosproject.openstacknode.api.OpenstackNodeEvent;
62import org.onosproject.openstacknode.api.OpenstackNodeListener;
sangho3dd2a8b2017-07-19 15:54:31 +090063import org.onosproject.openstacknode.api.OpenstackNodeService;
Jian Liac30e272018-10-18 23:08:03 +090064import org.onosproject.store.serializers.KryoNamespaces;
65import org.onosproject.store.service.ConsistentMap;
66import org.onosproject.store.service.Serializer;
67import org.onosproject.store.service.StorageService;
Jian Li1e9cb732018-11-25 23:17:21 +090068import org.openstack4j.model.network.Network;
sangho6a9ff0d2017-03-27 11:23:37 +090069import org.openstack4j.model.network.Port;
70import org.openstack4j.model.network.SecurityGroup;
71import org.openstack4j.model.network.SecurityGroupRule;
Jian Liac30e272018-10-18 23:08:03 +090072import org.openstack4j.model.network.State;
73import org.openstack4j.openstack.networking.domain.NeutronAllowedAddressPair;
74import org.openstack4j.openstack.networking.domain.NeutronExtraDhcpOptCreate;
75import org.openstack4j.openstack.networking.domain.NeutronIP;
76import org.openstack4j.openstack.networking.domain.NeutronPort;
sangho6a9ff0d2017-03-27 11:23:37 +090077import org.openstack4j.openstack.networking.domain.NeutronSecurityGroupRule;
sangho0248ca22017-05-31 13:22:47 +090078import org.osgi.service.component.ComponentContext;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070079import org.osgi.service.component.annotations.Activate;
80import org.osgi.service.component.annotations.Component;
81import org.osgi.service.component.annotations.Deactivate;
82import org.osgi.service.component.annotations.Modified;
83import org.osgi.service.component.annotations.Reference;
84import org.osgi.service.component.annotations.ReferenceCardinality;
sangho6a9ff0d2017-03-27 11:23:37 +090085import org.slf4j.Logger;
86
sangho6a9ff0d2017-03-27 11:23:37 +090087import java.util.Collections;
sangho0248ca22017-05-31 13:22:47 +090088import java.util.Dictionary;
Jian Liac30e272018-10-18 23:08:03 +090089import java.util.HashSet;
90import java.util.LinkedHashMap;
Jian Li362f9fd2018-11-28 11:14:40 +090091import java.util.List;
sangho2e97be02017-07-03 18:18:27 +090092import java.util.Map;
sangho6a9ff0d2017-03-27 11:23:37 +090093import java.util.Objects;
94import java.util.Set;
95import java.util.concurrent.ExecutorService;
96import java.util.stream.Collectors;
97
98import static java.util.concurrent.Executors.newSingleThreadExecutor;
99import static org.onlab.util.Tools.groupedThreads;
Jian Li1e9cb732018-11-25 23:17:21 +0900100import static org.onosproject.openstacknetworking.api.Constants.ACL_EGRESS_TABLE;
101import static org.onosproject.openstacknetworking.api.Constants.ACL_INGRESS_TABLE;
102import static org.onosproject.openstacknetworking.api.Constants.ACL_RECIRC_TABLE;
sangho1aaa7882017-05-31 13:22:47 +0900103import static org.onosproject.openstacknetworking.api.Constants.CT_TABLE;
104import static org.onosproject.openstacknetworking.api.Constants.ERROR_TABLE;
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700105import static org.onosproject.openstacknetworking.api.Constants.JUMP_TABLE;
sangho6a9ff0d2017-03-27 11:23:37 +0900106import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
Jian Li1e9cb732018-11-25 23:17:21 +0900107import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ACL_INGRESS_RULE;
sangho6a9ff0d2017-03-27 11:23:37 +0900108import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ACL_RULE;
sangho1aaa7882017-05-31 13:22:47 +0900109import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_DROP_RULE;
110import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_HOOK_RULE;
111import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_RULE;
Jian Li621f73c2018-12-15 01:49:22 +0900112import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GENEVE;
SONA Project6bc5c4a2018-12-14 23:49:52 +0900113import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.GRE;
114import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VLAN;
115import static org.onosproject.openstacknetworking.api.OpenstackNetwork.Type.VXLAN;
Jian Li4d138702018-11-27 17:25:28 +0900116import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
Ray Milkey8e406512018-10-24 15:56:50 -0700117import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_SECURITY_GROUP;
118import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_SECURITY_GROUP_DEFAULT;
Jian Li0f6ef9c2020-07-08 21:37:26 +0900119import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValueAsBoolean;
Jian Lib8cdcc12018-10-23 01:53:10 +0900120import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
Jian Li6d2ffbf2020-11-04 15:58:18 +0900121import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildPortRangeMatches;
Jian Libcc42282018-09-13 20:59:34 +0900122import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.computeCtMaskFlag;
123import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.computeCtStateFlag;
124import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.niciraConnTrackTreatmentBuilder;
sangho1aaa7882017-05-31 13:22:47 +0900125import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
sangho6a9ff0d2017-03-27 11:23:37 +0900126import static org.slf4j.LoggerFactory.getLogger;
127
128/**
129 * Populates flow rules to handle OpenStack SecurityGroups.
130 */
Ray Milkey8e406512018-10-24 15:56:50 -0700131@Component(
132 immediate = true,
133 property = {
134 USE_SECURITY_GROUP + ":Boolean=" + USE_SECURITY_GROUP_DEFAULT
135 }
136)
sangho6a9ff0d2017-03-27 11:23:37 +0900137public class OpenstackSecurityGroupHandler {
138
139 private final Logger log = getLogger(getClass());
140
Jian Li2b9838c2018-10-28 17:09:42 +0900141 private static final int VM_IP_PREFIX = 32;
142
Jian Li4d138702018-11-27 17:25:28 +0900143 private static final String STR_NULL = "null";
Jian Li4d138702018-11-27 17:25:28 +0900144
Jian Li900b7232018-12-14 14:04:51 +0900145 /** Apply OpenStack security group rule for VM traffic. */
Ray Milkey8e406512018-10-24 15:56:50 -0700146 private boolean useSecurityGroup = USE_SECURITY_GROUP_DEFAULT;
sangho0248ca22017-05-31 13:22:47 +0900147
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700148 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +0900149 protected CoreService coreService;
150
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700151 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li9d35bd62018-10-13 01:43:24 +0900152 protected InstancePortAdminService instancePortService;
sangho6a9ff0d2017-03-27 11:23:37 +0900153
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700154 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +0900155 protected MastershipService mastershipService;
156
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700157 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Hyunsun Moonae51e732017-04-25 17:46:21 +0900158 protected OpenstackNetworkService osNetService;
sangho6a9ff0d2017-03-27 11:23:37 +0900159
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700160 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho6a9ff0d2017-03-27 11:23:37 +0900161 protected OpenstackSecurityGroupService securityGroupService;
162
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700163 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sanghodc375372017-06-08 10:41:30 +0900164 protected OpenstackFlowRuleService osFlowRuleService;
sangho6a9ff0d2017-03-27 11:23:37 +0900165
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700166 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho0248ca22017-05-31 13:22:47 +0900167 protected ComponentConfigService configService;
168
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700169 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho3dd2a8b2017-07-19 15:54:31 +0900170 protected OpenstackNodeService osNodeService;
171
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700172 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho1aaa7882017-05-31 13:22:47 +0900173 protected DriverService driverService;
174
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700175 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Li857f1b02019-09-20 16:58:19 +0900176 protected DeviceService deviceService;
177
178 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho1aaa7882017-05-31 13:22:47 +0900179 protected LeadershipService leadershipService;
180
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700181 @Reference(cardinality = ReferenceCardinality.MANDATORY)
sangho1aaa7882017-05-31 13:22:47 +0900182 protected ClusterService clusterService;
183
Ray Milkey0b18b722018-10-16 13:19:15 -0700184 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jian Liac30e272018-10-18 23:08:03 +0900185 protected StorageService storageService;
186
187 private static final KryoNamespace SERIALIZER_PORT = KryoNamespace.newBuilder()
188 .register(KryoNamespaces.API)
189 .register(Port.class)
190 .register(NeutronPort.class)
191 .register(NeutronIP.class)
192 .register(State.class)
193 .register(NeutronAllowedAddressPair.class)
194 .register(NeutronExtraDhcpOptCreate.class)
195 .register(LinkedHashMap.class)
196 .build();
Jian Li9d35bd62018-10-13 01:43:24 +0900197
Jian Libcc42282018-09-13 20:59:34 +0900198 private final InstancePortListener instancePortListener =
Jian Lia70fdb602018-11-05 01:32:22 +0900199 new InternalInstancePortListener();
Jian Libcc42282018-09-13 20:59:34 +0900200 private final OpenstackNetworkListener osNetworkListener =
Jian Lia70fdb602018-11-05 01:32:22 +0900201 new InternalOpenstackNetworkListener();
Jian Libcc42282018-09-13 20:59:34 +0900202 private final OpenstackNetworkListener osPortListener =
Jian Lia70fdb602018-11-05 01:32:22 +0900203 new InternalOpenstackPortListener();
Jian Libcc42282018-09-13 20:59:34 +0900204 private final OpenstackSecurityGroupListener securityGroupListener =
Jian Lia70fdb602018-11-05 01:32:22 +0900205 new InternalSecurityGroupListener();
sangho1aaa7882017-05-31 13:22:47 +0900206 private final OpenstackNodeListener osNodeListener = new InternalNodeListener();
Jian Liac30e272018-10-18 23:08:03 +0900207
208 private ConsistentMap<String, Port> removedOsPortStore;
209
sangho6a9ff0d2017-03-27 11:23:37 +0900210 private ApplicationId appId;
sangho1aaa7882017-05-31 13:22:47 +0900211 private NodeId localNodeId;
sangho6a9ff0d2017-03-27 11:23:37 +0900212
213 private final ExecutorService eventExecutor = newSingleThreadExecutor(
214 groupedThreads(this.getClass().getSimpleName(), "event-handler"));
215
216 private static final String PROTO_ICMP = "ICMP";
Jian Li0f6ef9c2020-07-08 21:37:26 +0900217 private static final String PROTO_ICMP_NUM = "1";
sangho6a9ff0d2017-03-27 11:23:37 +0900218 private static final String PROTO_TCP = "TCP";
Jian Li0f6ef9c2020-07-08 21:37:26 +0900219 private static final String PROTO_TCP_NUM = "6";
sangho6a9ff0d2017-03-27 11:23:37 +0900220 private static final String PROTO_UDP = "UDP";
Jian Li0f6ef9c2020-07-08 21:37:26 +0900221 private static final String PROTO_UDP_NUM = "17";
222 private static final String PROTO_SCTP = "SCTP";
223 private static final String PROTO_SCTP_NUM = "132";
224 private static final byte PROTOCOL_SCTP = (byte) 0x84;
225 private static final String PROTO_ANY = "ANY";
226 private static final String PROTO_ANY_NUM = "0";
sangho6a9ff0d2017-03-27 11:23:37 +0900227 private static final String ETHTYPE_IPV4 = "IPV4";
228 private static final String EGRESS = "EGRESS";
229 private static final String INGRESS = "INGRESS";
230 private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");
231
sangho1aaa7882017-05-31 13:22:47 +0900232 // We expose pipeline structure to SONA application considering removing pipeline soon.
sanghoshinbbeb31a2018-09-11 17:01:01 +0800233 private static final int GOTO_CONNTRACK_TABLE = CT_TABLE;
234 private static final int GOTO_JUMP_TABLE = JUMP_TABLE;
sangho1aaa7882017-05-31 13:22:47 +0900235
236 private static final int CT_COMMIT = 0;
237 private static final int CT_NO_COMMIT = 1;
238 private static final short CT_NO_RECIRC = -1;
239
240 private static final int ACTION_NONE = 0;
241 private static final int ACTION_DROP = -1;
242
sangho6a9ff0d2017-03-27 11:23:37 +0900243 @Activate
244 protected void activate() {
245 appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
sangho1aaa7882017-05-31 13:22:47 +0900246 localNodeId = clusterService.getLocalNode().id();
sangho6a9ff0d2017-03-27 11:23:37 +0900247 instancePortService.addListener(instancePortListener);
248 securityGroupService.addListener(securityGroupListener);
Jian Libcc42282018-09-13 20:59:34 +0900249 osNetService.addListener(osPortListener);
250 osNetService.addListener(osNetworkListener);
sangho0248ca22017-05-31 13:22:47 +0900251 configService.registerProperties(getClass());
sangho1aaa7882017-05-31 13:22:47 +0900252 osNodeService.addListener(osNodeListener);
sangho6a9ff0d2017-03-27 11:23:37 +0900253
Jian Liac30e272018-10-18 23:08:03 +0900254 removedOsPortStore = storageService.<String, Port>consistentMapBuilder()
255 .withSerializer(Serializer.using(SERIALIZER_PORT))
256 .withName("openstack-removed-portstore")
257 .withApplicationId(appId)
258 .build();
259
sangho6a9ff0d2017-03-27 11:23:37 +0900260 log.info("Started");
261 }
262
263 @Deactivate
264 protected void deactivate() {
265 instancePortService.removeListener(instancePortListener);
266 securityGroupService.removeListener(securityGroupListener);
Jian Libcc42282018-09-13 20:59:34 +0900267 osNetService.removeListener(osNetworkListener);
268 osNetService.removeListener(osPortListener);
sangho0248ca22017-05-31 13:22:47 +0900269 configService.unregisterProperties(getClass(), false);
sangho1aaa7882017-05-31 13:22:47 +0900270 osNodeService.removeListener(osNodeListener);
sangho6a9ff0d2017-03-27 11:23:37 +0900271 eventExecutor.shutdown();
272
273 log.info("Stopped");
274 }
275
sangho0248ca22017-05-31 13:22:47 +0900276 @Modified
277 protected void modified(ComponentContext context) {
278 Dictionary<?, ?> properties = context.getProperties();
279 Boolean flag;
280
Ray Milkey8e406512018-10-24 15:56:50 -0700281 flag = Tools.isPropertyEnabled(properties, USE_SECURITY_GROUP);
sangho0248ca22017-05-31 13:22:47 +0900282 if (flag == null) {
283 log.info("useSecurityGroup is not configured, " +
284 "using current value of {}", useSecurityGroup);
285 } else {
286 useSecurityGroup = flag;
287 log.info("Configured. useSecurityGroup is {}",
288 useSecurityGroup ? "enabled" : "disabled");
289 }
290
sanghoe6457a32017-08-24 14:31:19 +0900291 securityGroupService.setSecurityGroupEnabled(useSecurityGroup);
sangho0248ca22017-05-31 13:22:47 +0900292 resetSecurityGroupRules();
293 }
294
Jian Li627e0162020-03-12 17:50:36 +0900295 private boolean getUseSecurityGroupFlag() {
296 Set<ConfigProperty> properties =
297 configService.getProperties(getClass().getName());
298 return getPropertyValueAsBoolean(properties, USE_SECURITY_GROUP);
299 }
300
sangho1aaa7882017-05-31 13:22:47 +0900301 private void initializeConnTrackTable(DeviceId deviceId, boolean install) {
302
303 //table=1,ip,ct_state=-trk, actions=ct(table:2)
Jian Libcc42282018-09-13 20:59:34 +0900304 long ctState = computeCtStateFlag(false, false, false);
305 long ctMask = computeCtMaskFlag(true, false, false);
sangho1aaa7882017-05-31 13:22:47 +0900306 setConnTrackRule(deviceId, ctState, ctMask, CT_NO_COMMIT, (short) GOTO_CONNTRACK_TABLE,
307 ACTION_NONE, PRIORITY_CT_HOOK_RULE, install);
308
309 //table=2,ip,nw_dst=10.10.0.2,ct_state=+trk+est,action=goto_table:3
Jian Libcc42282018-09-13 20:59:34 +0900310 ctState = computeCtStateFlag(true, false, true);
311 ctMask = computeCtMaskFlag(true, false, true);
sangho1aaa7882017-05-31 13:22:47 +0900312 setConnTrackRule(deviceId, ctState, ctMask, CT_NO_COMMIT, CT_NO_RECIRC,
313 GOTO_JUMP_TABLE, PRIORITY_CT_RULE, install);
314
315 //table=2,ip,nw_dst=10.10.0.2,ct_state=+trk+new,action=drop
Jian Libcc42282018-09-13 20:59:34 +0900316 ctState = computeCtStateFlag(true, true, false);
317 ctMask = computeCtMaskFlag(true, true, false);
sangho1aaa7882017-05-31 13:22:47 +0900318 setConnTrackRule(deviceId, ctState, ctMask, CT_NO_COMMIT, CT_NO_RECIRC,
319 ACTION_DROP, PRIORITY_CT_DROP_RULE, install);
320 }
321
Jian Li1e9cb732018-11-25 23:17:21 +0900322 private void initializeAclTable(DeviceId deviceId, boolean install) {
323
324 ExtensionTreatment ctTreatment =
325 niciraConnTrackTreatmentBuilder(driverService, deviceId)
326 .commit(true)
327 .build();
328
329 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
330 sBuilder.matchEthType(Ethernet.TYPE_IPV4);
331
332 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
333 tBuilder.extension(ctTreatment, deviceId)
334 .transition(JUMP_TABLE);
335
336 osFlowRuleService.setRule(appId,
337 deviceId,
338 sBuilder.build(),
339 tBuilder.build(),
340 PRIORITY_ACL_INGRESS_RULE,
341 ACL_RECIRC_TABLE,
342 install);
343 }
344
345 private void initializeIngressTable(DeviceId deviceId, boolean install) {
346 if (install) {
347 osFlowRuleService.setUpTableMissEntry(deviceId, ACL_INGRESS_TABLE);
348 } else {
349 osFlowRuleService.connectTables(deviceId, ACL_INGRESS_TABLE, JUMP_TABLE);
350 }
351 }
352
Jian Libcc42282018-09-13 20:59:34 +0900353 private void updateSecurityGroupRule(InstancePort instPort, Port port,
354 SecurityGroupRule sgRule, boolean install) {
sangho2e97be02017-07-03 18:18:27 +0900355
Daniel Park3a140592018-06-28 18:33:10 +0900356 if (instPort == null || port == null || sgRule == null) {
357 return;
358 }
359
sangho6a9ff0d2017-03-27 11:23:37 +0900360 if (sgRule.getRemoteGroupId() != null && !sgRule.getRemoteGroupId().isEmpty()) {
Jian Lia70fdb602018-11-05 01:32:22 +0900361 getRemoteInstPorts(port, sgRule.getRemoteGroupId(), install)
Jian Libcc42282018-09-13 20:59:34 +0900362 .forEach(rInstPort -> {
Jian Li1e9cb732018-11-25 23:17:21 +0900363 populateSecurityGroupRule(sgRule, instPort,
Jian Libcc42282018-09-13 20:59:34 +0900364 rInstPort.ipAddress().toIpPrefix(), install);
Jian Li1e9cb732018-11-25 23:17:21 +0900365 populateSecurityGroupRule(sgRule, rInstPort,
Jian Libcc42282018-09-13 20:59:34 +0900366 instPort.ipAddress().toIpPrefix(), install);
sangho6a9ff0d2017-03-27 11:23:37 +0900367
Jian Libcc42282018-09-13 20:59:34 +0900368 SecurityGroupRule rSgRule =
369 new NeutronSecurityGroupRule
370 .SecurityGroupRuleConcreteBuilder()
Jian Li28ec77f2018-10-31 07:07:25 +0900371 .from(sgRule)
Jian Li4d138702018-11-27 17:25:28 +0900372 .direction(sgRule.getDirection()
373 .equalsIgnoreCase(EGRESS) ? INGRESS : EGRESS)
Jian Li28ec77f2018-10-31 07:07:25 +0900374 .build();
Jian Li1e9cb732018-11-25 23:17:21 +0900375 populateSecurityGroupRule(rSgRule, instPort,
Jian Libcc42282018-09-13 20:59:34 +0900376 rInstPort.ipAddress().toIpPrefix(), install);
Jian Li1e9cb732018-11-25 23:17:21 +0900377 populateSecurityGroupRule(rSgRule, rInstPort,
Jian Libcc42282018-09-13 20:59:34 +0900378 instPort.ipAddress().toIpPrefix(), install);
379 });
sangho6a9ff0d2017-03-27 11:23:37 +0900380 } else {
Jian Li1e9cb732018-11-25 23:17:21 +0900381 populateSecurityGroupRule(sgRule, instPort,
Jian Libcc42282018-09-13 20:59:34 +0900382 sgRule.getRemoteIpPrefix() == null ? IP_PREFIX_ANY :
Jian Li28ec77f2018-10-31 07:07:25 +0900383 IpPrefix.valueOf(sgRule.getRemoteIpPrefix()), install);
sangho6a9ff0d2017-03-27 11:23:37 +0900384 }
385 }
386
Jian Li0f6ef9c2020-07-08 21:37:26 +0900387 private boolean checkProtocol(String protocol) {
388 if (protocol == null) {
389 log.debug("No protocol was specified, use default IP(v4/v6) protocol.");
390 return true;
391 } else {
392 String protocolUpper = protocol.toUpperCase();
393 if (protocolUpper.equals(PROTO_TCP) ||
394 protocolUpper.equals(PROTO_UDP) ||
395 protocolUpper.equals(PROTO_ICMP) ||
396 protocolUpper.equals(PROTO_SCTP) ||
397 protocolUpper.equals(PROTO_ANY) ||
398 protocol.equals(PROTO_TCP_NUM) ||
399 protocol.equals(PROTO_UDP_NUM) ||
400 protocol.equals(PROTO_ICMP_NUM) ||
401 protocol.equals(PROTO_SCTP_NUM) ||
402 protocol.equals(PROTO_ANY_NUM)) {
403 return true;
404 } else {
405 log.error("Unsupported protocol {}, we only support " +
406 "TCP/UDP/ICMP/SCTP protocols.", protocol);
407 return false;
408 }
409 }
410 }
411
Jian Libcc42282018-09-13 20:59:34 +0900412 private void populateSecurityGroupRule(SecurityGroupRule sgRule,
413 InstancePort instPort,
Jian Lie8b28db2018-10-17 14:04:09 +0900414 IpPrefix remoteIp,
415 boolean install) {
Jian Li0f6ef9c2020-07-08 21:37:26 +0900416 if (!checkProtocol(sgRule.getProtocol())) {
417 return;
418 }
419
sangho2e97be02017-07-03 18:18:27 +0900420 Set<TrafficSelector> selectors = buildSelectors(sgRule,
Jian Li1e9cb732018-11-25 23:17:21 +0900421 Ip4Address.valueOf(instPort.ipAddress().toInetAddress()),
422 remoteIp, instPort.networkId());
sangho2e97be02017-07-03 18:18:27 +0900423 if (selectors == null || selectors.isEmpty()) {
sangho6a9ff0d2017-03-27 11:23:37 +0900424 return;
425 }
426
Jian Li857f1b02019-09-20 16:58:19 +0900427 // if the device is not available we do not perform any action
428 if (instPort.deviceId() == null || !deviceService.isAvailable(instPort.deviceId())) {
429 return;
430 }
431
Jian Li362f9fd2018-11-28 11:14:40 +0900432 // in case a port is bound to multiple security groups, we do NOT remove
433 // egress rules unless all security groups bound to the port to be removed
434 Port osPort = osNetService.port(instPort.portId());
435 if (!install && osPort != null && sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
436 List<String> sgIds = osPort.getSecurityGroups();
437 if (!sgIds.contains(sgRule.getSecurityGroupId()) && !sgIds.isEmpty()) {
438 return;
439 }
440 }
441
Jian Li28ec77f2018-10-31 07:07:25 +0900442 // XXX All egress traffic needs to go through connection tracking module,
443 // which might hurt its performance.
444 ExtensionTreatment ctTreatment =
445 niciraConnTrackTreatmentBuilder(driverService, instPort.deviceId())
446 .commit(true)
447 .build();
448
Jian Li1e9cb732018-11-25 23:17:21 +0900449 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
Jian Li28ec77f2018-10-31 07:07:25 +0900450
Jian Li1e9cb732018-11-25 23:17:21 +0900451 int aclTable;
Jian Li4d138702018-11-27 17:25:28 +0900452 if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
Jian Li1e9cb732018-11-25 23:17:21 +0900453 aclTable = ACL_EGRESS_TABLE;
454 tBuilder.transition(ACL_RECIRC_TABLE);
455 } else {
456 aclTable = ACL_INGRESS_TABLE;
457 tBuilder.extension(ctTreatment, instPort.deviceId())
458 .transition(JUMP_TABLE);
459 }
460
461 int finalAclTable = aclTable;
462 selectors.forEach(selector -> {
463 osFlowRuleService.setRule(appId,
464 instPort.deviceId(),
465 selector, tBuilder.build(),
466 PRIORITY_ACL_RULE,
467 finalAclTable,
468 install);
469 });
sangho6a9ff0d2017-03-27 11:23:37 +0900470 }
471
472 /**
sangho1aaa7882017-05-31 13:22:47 +0900473 * Sets connection tracking rule using OVS extension commands.
Jian Li2b9838c2018-10-28 17:09:42 +0900474 * It is not so graceful, but I don't want to make it more general because
475 * it is going to be used only here.
476 * The following is the usage of the function.
sangho1aaa7882017-05-31 13:22:47 +0900477 *
478 * @param deviceId Device ID
Jian Li2b9838c2018-10-28 17:09:42 +0900479 * @param ctState ctState: please use RulePopulatorUtil.computeCtStateFlag()
480 * to build the value
481 * @param ctMask crMask: please use RulePopulatorUtil.computeCtMaskFlag()
482 * to build the value
sangho1aaa7882017-05-31 13:22:47 +0900483 * @param commit CT_COMMIT for commit action, CT_NO_COMMIT otherwise
Jian Li2b9838c2018-10-28 17:09:42 +0900484 * @param recircTable table number for recirculation after CT actions.
485 * CT_NO_RECIRC with no recirculation
486 * @param action Additional actions. ACTION_DROP, ACTION_NONE,
487 * GOTO_XXX_TABLE are supported.
sangho1aaa7882017-05-31 13:22:47 +0900488 * @param priority priority value for the rule
489 * @param install true for insertion, false for removal
490 */
491 private void setConnTrackRule(DeviceId deviceId, long ctState, long ctMask,
492 int commit, short recircTable,
493 int action, int priority, boolean install) {
494
Jian Libcc42282018-09-13 20:59:34 +0900495 ExtensionSelector esCtSate = RulePopulatorUtil
496 .buildCtExtensionSelector(driverService, deviceId, ctState, ctMask);
sangho1aaa7882017-05-31 13:22:47 +0900497 TrafficSelector selector = DefaultTrafficSelector.builder()
498 .extension(esCtSate, deviceId)
499 .matchEthType(Ethernet.TYPE_IPV4)
500 .build();
501
502 TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
503
504 if (commit == CT_COMMIT || recircTable > 0) {
Jian Li5a26ab32019-03-21 15:20:01 +0900505 RulePopulatorUtil.NiciraConnTrackTreatmentBuilder natTreatmentBuilder =
Jian Libcc42282018-09-13 20:59:34 +0900506 niciraConnTrackTreatmentBuilder(driverService, deviceId);
sangho1aaa7882017-05-31 13:22:47 +0900507 natTreatmentBuilder.natAction(false);
508 if (commit == CT_COMMIT) {
509 natTreatmentBuilder.commit(true);
510 } else {
511 natTreatmentBuilder.commit(false);
512 }
513 if (recircTable > 0) {
514 natTreatmentBuilder.table(recircTable);
515 }
516 tb.extension(natTreatmentBuilder.build(), deviceId);
517 } else if (action == ACTION_DROP) {
518 tb.drop();
519 }
520
sanghoshinbbeb31a2018-09-11 17:01:01 +0800521 if (action != ACTION_NONE && action != ACTION_DROP) {
sangho1aaa7882017-05-31 13:22:47 +0900522 tb.transition(action);
523 }
524
525 int tableType = ERROR_TABLE;
526 if (priority == PRIORITY_CT_RULE || priority == PRIORITY_CT_DROP_RULE) {
527 tableType = CT_TABLE;
528 } else if (priority == PRIORITY_CT_HOOK_RULE) {
Jian Li1e9cb732018-11-25 23:17:21 +0900529 tableType = ACL_INGRESS_TABLE;
sangho1aaa7882017-05-31 13:22:47 +0900530 } else {
531 log.error("Cannot an appropriate table for the conn track rule.");
532 }
533
534 osFlowRuleService.setRule(
535 appId,
536 deviceId,
537 selector,
538 tb.build(),
539 priority,
540 tableType,
541 install);
542 }
543
544 /**
sangho6a9ff0d2017-03-27 11:23:37 +0900545 * Returns a set of host IP addresses engaged with supplied security group ID.
546 * It only searches a VM in the same tenant boundary.
547 *
Jian Lia70fdb602018-11-05 01:32:22 +0900548 * @param srcPort openstack port
sangho6a9ff0d2017-03-27 11:23:37 +0900549 * @param sgId security group id
550 * @return set of ip addresses
551 */
Jian Lia70fdb602018-11-05 01:32:22 +0900552 private Set<InstancePort> getRemoteInstPorts(Port srcPort,
Jian Li2b9838c2018-10-28 17:09:42 +0900553 String sgId, boolean install) {
sangho6a9ff0d2017-03-27 11:23:37 +0900554 Set<InstancePort> remoteInstPorts;
555
Jian Liac30e272018-10-18 23:08:03 +0900556 Set<Port> removedPorts = Sets.newConcurrentHashSet();
557
558 if (!install) {
559 removedPorts = new HashSet<>(removedOsPortStore.asJavaMap().values());
560 }
561
562 remoteInstPorts = Sets.union(osNetService.ports(), removedPorts).stream()
Jian Lia70fdb602018-11-05 01:32:22 +0900563 .filter(port -> !port.getId().equals(srcPort.getId()))
564 .filter(port -> port.getTenantId().equals(srcPort.getTenantId()))
sangho6a9ff0d2017-03-27 11:23:37 +0900565 .filter(port -> port.getSecurityGroups().contains(sgId))
Jian Lia70fdb602018-11-05 01:32:22 +0900566 .filter(port -> port.getNetworkId().equals(srcPort.getNetworkId()))
sangho6a9ff0d2017-03-27 11:23:37 +0900567 .map(port -> instancePortService.instancePort(port.getId()))
568 .filter(instPort -> instPort != null && instPort.ipAddress() != null)
569 .collect(Collectors.toSet());
570
571 return Collections.unmodifiableSet(remoteInstPorts);
572 }
573
sangho2e97be02017-07-03 18:18:27 +0900574 private Set<TrafficSelector> buildSelectors(SecurityGroupRule sgRule,
575 Ip4Address vmIp,
Jian Lie8b28db2018-10-17 14:04:09 +0900576 IpPrefix remoteIp,
Jian Li1e9cb732018-11-25 23:17:21 +0900577 String netId) {
Jian Li2b9838c2018-10-28 17:09:42 +0900578 if (remoteIp != null && remoteIp.equals(IpPrefix.valueOf(vmIp, VM_IP_PREFIX))) {
sangho2e97be02017-07-03 18:18:27 +0900579 // do nothing if the remote IP is my IP
580 return null;
581 }
582
583 Set<TrafficSelector> selectorSet = Sets.newHashSet();
584
sangho2e97be02017-07-03 18:18:27 +0900585 if (sgRule.getPortRangeMax() != null && sgRule.getPortRangeMin() != null &&
586 sgRule.getPortRangeMin() < sgRule.getPortRangeMax()) {
Jian Libcc42282018-09-13 20:59:34 +0900587 Map<TpPort, TpPort> portRangeMatchMap =
588 buildPortRangeMatches(sgRule.getPortRangeMin(),
Jian Li28ec77f2018-10-31 07:07:25 +0900589 sgRule.getPortRangeMax());
Jian Li2b9838c2018-10-28 17:09:42 +0900590 portRangeMatchMap.forEach((key, value) -> {
sangho2e97be02017-07-03 18:18:27 +0900591
Jian Li22ce4672020-05-26 00:31:27 +0900592 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
593 buildMatches(sBuilder, sgRule, vmIp, remoteIp, netId);
594
Jian Li0f6ef9c2020-07-08 21:37:26 +0900595 if (sgRule.getProtocol().equalsIgnoreCase(PROTO_TCP) ||
596 sgRule.getProtocol().equals(PROTO_TCP_NUM)) {
Jian Li4d138702018-11-27 17:25:28 +0900597 if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
Jian Li22ce4672020-05-26 00:31:27 +0900598 if (value.toInt() == TpPort.MAX_PORT) {
599 sBuilder.matchTcpSrc(key);
600 } else {
601 sBuilder.matchTcpSrcMasked(key, value);
602 }
Jian Li2b9838c2018-10-28 17:09:42 +0900603 } else {
Jian Li22ce4672020-05-26 00:31:27 +0900604 if (value.toInt() == TpPort.MAX_PORT) {
605 sBuilder.matchTcpDst(key);
606 } else {
607 sBuilder.matchTcpDstMasked(key, value);
608 }
Jian Libcc42282018-09-13 20:59:34 +0900609 }
Jian Li0f6ef9c2020-07-08 21:37:26 +0900610 } else if (sgRule.getProtocol().equalsIgnoreCase(PROTO_UDP) ||
611 sgRule.getProtocol().equals(PROTO_UDP_NUM)) {
Jian Li4d138702018-11-27 17:25:28 +0900612 if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
Jian Li22ce4672020-05-26 00:31:27 +0900613 if (value.toInt() == TpPort.MAX_PORT) {
614 sBuilder.matchUdpSrc(key);
615 } else {
616 sBuilder.matchUdpSrcMasked(key, value);
617 }
Jian Li2b9838c2018-10-28 17:09:42 +0900618 } else {
Jian Li22ce4672020-05-26 00:31:27 +0900619 if (value.toInt() == TpPort.MAX_PORT) {
620 sBuilder.matchUdpDst(key);
621 } else {
622 sBuilder.matchUdpDstMasked(key, value);
623 }
Jian Li2b9838c2018-10-28 17:09:42 +0900624 }
Jian Li0f6ef9c2020-07-08 21:37:26 +0900625 } else if (sgRule.getProtocol().equalsIgnoreCase(PROTO_SCTP) ||
626 sgRule.getProtocol().equals(PROTO_SCTP_NUM)) {
627 if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
628 if (value.toInt() == TpPort.MAX_PORT) {
629 sBuilder.matchSctpSrc(key);
630 } else {
631 sBuilder.matchSctpSrcMasked(key, value);
632 }
633 } else {
634 if (value.toInt() == TpPort.MAX_PORT) {
635 sBuilder.matchSctpDst(key);
636 } else {
637 sBuilder.matchSctpDstMasked(key, value);
638 }
639 }
Jian Li2b9838c2018-10-28 17:09:42 +0900640 }
641
642 selectorSet.add(sBuilder.build());
643 });
sangho2e97be02017-07-03 18:18:27 +0900644 } else {
Jian Li22ce4672020-05-26 00:31:27 +0900645
646 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
647 buildMatches(sBuilder, sgRule, vmIp, remoteIp, netId);
648
sangho2e97be02017-07-03 18:18:27 +0900649 selectorSet.add(sBuilder.build());
650 }
651
652 return selectorSet;
653 }
654
Jian Libcc42282018-09-13 20:59:34 +0900655 private void buildMatches(TrafficSelector.Builder sBuilder,
Jian Li1e9cb732018-11-25 23:17:21 +0900656 SecurityGroupRule sgRule, Ip4Address vmIp,
657 IpPrefix remoteIp, String netId) {
658 buildTunnelId(sBuilder, netId);
sangho6a9ff0d2017-03-27 11:23:37 +0900659 buildMatchEthType(sBuilder, sgRule.getEtherType());
660 buildMatchDirection(sBuilder, sgRule.getDirection(), vmIp);
661 buildMatchProto(sBuilder, sgRule.getProtocol());
662 buildMatchPort(sBuilder, sgRule.getProtocol(), sgRule.getDirection(),
sangho2e97be02017-07-03 18:18:27 +0900663 sgRule.getPortRangeMin() == null ? 0 : sgRule.getPortRangeMin(),
664 sgRule.getPortRangeMax() == null ? 0 : sgRule.getPortRangeMax());
Jian Li0f6ef9c2020-07-08 21:37:26 +0900665 buildMatchIcmp(sBuilder, sgRule.getProtocol(),
666 sgRule.getPortRangeMin(), sgRule.getPortRangeMax());
sangho6a9ff0d2017-03-27 11:23:37 +0900667 buildMatchRemoteIp(sBuilder, remoteIp, sgRule.getDirection());
sangho6a9ff0d2017-03-27 11:23:37 +0900668 }
669
Jian Li1e9cb732018-11-25 23:17:21 +0900670 private void buildTunnelId(TrafficSelector.Builder sBuilder, String netId) {
671 String segId = osNetService.segmentId(netId);
SONA Project6bc5c4a2018-12-14 23:49:52 +0900672 Type netType = osNetService.networkType(netId);
Jian Lie8b28db2018-10-17 14:04:09 +0900673
SONA Project6bc5c4a2018-12-14 23:49:52 +0900674 if (netType == VLAN) {
Jian Lie8b28db2018-10-17 14:04:09 +0900675 sBuilder.matchVlanId(VlanId.vlanId(segId));
Jian Li621f73c2018-12-15 01:49:22 +0900676 } else if (netType == VXLAN || netType == GRE || netType == GENEVE) {
Jian Lie8b28db2018-10-17 14:04:09 +0900677 sBuilder.matchTunnelId(Long.valueOf(segId));
Jian Li28ec77f2018-10-31 07:07:25 +0900678 } else {
Jian Li2dc37592019-03-14 17:32:15 +0900679 log.debug("Cannot tag the VID due to lack of support of virtual network type {}", netType);
Jian Lie8b28db2018-10-17 14:04:09 +0900680 }
681 }
682
sangho6a9ff0d2017-03-27 11:23:37 +0900683 private void buildMatchDirection(TrafficSelector.Builder sBuilder,
684 String direction,
685 Ip4Address vmIp) {
Jian Li4d138702018-11-27 17:25:28 +0900686 if (direction.equalsIgnoreCase(EGRESS)) {
Jian Li2b9838c2018-10-28 17:09:42 +0900687 sBuilder.matchIPSrc(IpPrefix.valueOf(vmIp, VM_IP_PREFIX));
sangho6a9ff0d2017-03-27 11:23:37 +0900688 } else {
Jian Li2b9838c2018-10-28 17:09:42 +0900689 sBuilder.matchIPDst(IpPrefix.valueOf(vmIp, VM_IP_PREFIX));
sangho6a9ff0d2017-03-27 11:23:37 +0900690 }
691 }
692
693 private void buildMatchEthType(TrafficSelector.Builder sBuilder, String etherType) {
694 // Either IpSrc or IpDst (or both) is set by default, and we need to set EthType as IPv4.
695 sBuilder.matchEthType(Ethernet.TYPE_IPV4);
Jian Li4d138702018-11-27 17:25:28 +0900696 if (etherType != null && !Objects.equals(etherType, STR_NULL) &&
697 !etherType.equalsIgnoreCase(ETHTYPE_IPV4)) {
sangho6a9ff0d2017-03-27 11:23:37 +0900698 log.debug("EthType {} is not supported yet in Security Group", etherType);
699 }
700 }
701
Jian Libcc42282018-09-13 20:59:34 +0900702 private void buildMatchRemoteIp(TrafficSelector.Builder sBuilder,
703 IpPrefix remoteIpPrefix, String direction) {
704 if (remoteIpPrefix != null &&
705 !remoteIpPrefix.getIp4Prefix().equals(IP_PREFIX_ANY)) {
Jian Li4d138702018-11-27 17:25:28 +0900706 if (direction.equalsIgnoreCase(EGRESS)) {
sangho6a9ff0d2017-03-27 11:23:37 +0900707 sBuilder.matchIPDst(remoteIpPrefix);
708 } else {
709 sBuilder.matchIPSrc(remoteIpPrefix);
710 }
711 }
712 }
713
714 private void buildMatchProto(TrafficSelector.Builder sBuilder, String protocol) {
715 if (protocol != null) {
716 switch (protocol.toUpperCase()) {
717 case PROTO_ICMP:
Jian Li0f6ef9c2020-07-08 21:37:26 +0900718 case PROTO_ICMP_NUM:
sangho6a9ff0d2017-03-27 11:23:37 +0900719 sBuilder.matchIPProtocol(IPv4.PROTOCOL_ICMP);
720 break;
721 case PROTO_TCP:
Jian Li0f6ef9c2020-07-08 21:37:26 +0900722 case PROTO_TCP_NUM:
sangho6a9ff0d2017-03-27 11:23:37 +0900723 sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP);
724 break;
725 case PROTO_UDP:
Jian Li0f6ef9c2020-07-08 21:37:26 +0900726 case PROTO_UDP_NUM:
sangho6a9ff0d2017-03-27 11:23:37 +0900727 sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP);
728 break;
Jian Li0f6ef9c2020-07-08 21:37:26 +0900729 case PROTO_SCTP:
730 case PROTO_SCTP_NUM:
731 sBuilder.matchIPProtocol(PROTOCOL_SCTP);
732 break;
sangho6a9ff0d2017-03-27 11:23:37 +0900733 default:
Jian Li0f6ef9c2020-07-08 21:37:26 +0900734 break;
sangho6a9ff0d2017-03-27 11:23:37 +0900735 }
736 }
737 }
738
Jian Libcc42282018-09-13 20:59:34 +0900739 private void buildMatchPort(TrafficSelector.Builder sBuilder,
740 String protocol, String direction,
sangho6a9ff0d2017-03-27 11:23:37 +0900741 int portMin, int portMax) {
Jian Li0f6ef9c2020-07-08 21:37:26 +0900742 if (portMax > 0 && portMin == portMax) {
743 if (protocol.equalsIgnoreCase(PROTO_TCP) ||
744 protocol.equals(PROTO_TCP_NUM)) {
Jian Li4d138702018-11-27 17:25:28 +0900745 if (direction.equalsIgnoreCase(EGRESS)) {
sangho6a9ff0d2017-03-27 11:23:37 +0900746 sBuilder.matchTcpSrc(TpPort.tpPort(portMax));
747 } else {
748 sBuilder.matchTcpDst(TpPort.tpPort(portMax));
749 }
Jian Li0f6ef9c2020-07-08 21:37:26 +0900750 } else if (protocol.equalsIgnoreCase(PROTO_UDP) ||
751 protocol.equals(PROTO_UDP_NUM)) {
Jian Li4d138702018-11-27 17:25:28 +0900752 if (direction.equalsIgnoreCase(EGRESS)) {
sangho6a9ff0d2017-03-27 11:23:37 +0900753 sBuilder.matchUdpSrc(TpPort.tpPort(portMax));
754 } else {
755 sBuilder.matchUdpDst(TpPort.tpPort(portMax));
756 }
Jian Li0f6ef9c2020-07-08 21:37:26 +0900757 } else if (protocol.equalsIgnoreCase(PROTO_SCTP) ||
758 protocol.equals(PROTO_SCTP_NUM)) {
759 if (direction.equalsIgnoreCase(EGRESS)) {
760 sBuilder.matchSctpSrc(TpPort.tpPort(portMax));
761 } else {
762 sBuilder.matchSctpDst(TpPort.tpPort(portMax));
763 }
764 }
765 }
766
767
768 }
769
770 private void buildMatchIcmp(TrafficSelector.Builder sBuilder,
771 String protocol, Integer icmpCode, Integer icmpType) {
772 if (protocol != null) {
773 if (protocol.equalsIgnoreCase(PROTO_ICMP) ||
774 protocol.equals(PROTO_ICMP_NUM)) {
775 if (icmpCode != null && icmpCode >= 0 && icmpCode <= 255) {
776 sBuilder.matchIcmpCode(icmpCode.byteValue());
777 }
778 if (icmpType != null && icmpType >= 0 && icmpType <= 255) {
779 sBuilder.matchIcmpType(icmpType.byteValue());
780 }
sangho6a9ff0d2017-03-27 11:23:37 +0900781 }
782 }
783 }
784
sangho0248ca22017-05-31 13:22:47 +0900785 private void resetSecurityGroupRules() {
786
Jian Li627e0162020-03-12 17:50:36 +0900787 if (getUseSecurityGroupFlag()) {
Jian Lib6969502018-10-30 20:38:07 +0900788 osNodeService.completeNodes(COMPUTE).forEach(node -> {
Jian Li1e9cb732018-11-25 23:17:21 +0900789 osFlowRuleService.setUpTableMissEntry(node.intgBridge(), ACL_EGRESS_TABLE);
Jian Lib6969502018-10-30 20:38:07 +0900790 initializeConnTrackTable(node.intgBridge(), true);
Jian Li1e9cb732018-11-25 23:17:21 +0900791 initializeAclTable(node.intgBridge(), true);
792 initializeIngressTable(node.intgBridge(), true);
Jian Lib6969502018-10-30 20:38:07 +0900793 });
794
sangho0248ca22017-05-31 13:22:47 +0900795 securityGroupService.securityGroups().forEach(securityGroup ->
796 securityGroup.getRules().forEach(this::securityGroupRuleAdded));
797 } else {
Jian Lib6969502018-10-30 20:38:07 +0900798 osNodeService.completeNodes(COMPUTE).forEach(node -> {
Jian Li1e9cb732018-11-25 23:17:21 +0900799 osFlowRuleService.connectTables(node.intgBridge(), ACL_EGRESS_TABLE, JUMP_TABLE);
Jian Lib6969502018-10-30 20:38:07 +0900800 initializeConnTrackTable(node.intgBridge(), false);
Jian Li1e9cb732018-11-25 23:17:21 +0900801 initializeAclTable(node.intgBridge(), false);
802 initializeIngressTable(node.intgBridge(), false);
Jian Lib6969502018-10-30 20:38:07 +0900803 });
804
sangho0248ca22017-05-31 13:22:47 +0900805 securityGroupService.securityGroups().forEach(securityGroup ->
806 securityGroup.getRules().forEach(this::securityGroupRuleRemoved));
807 }
808
Jian Libcc42282018-09-13 20:59:34 +0900809 log.info("Reset security group info " +
Jian Li38c82f72020-04-02 11:15:38 +0900810 (getUseSecurityGroupFlag() ? " with " : " without") + " Security Group");
sangho0248ca22017-05-31 13:22:47 +0900811 }
812
813 private void securityGroupRuleAdded(SecurityGroupRule sgRule) {
814 osNetService.ports().stream()
Jian Libcc42282018-09-13 20:59:34 +0900815 .filter(port -> port.getSecurityGroups()
Jian Li28ec77f2018-10-31 07:07:25 +0900816 .contains(sgRule.getSecurityGroupId()))
sangho0248ca22017-05-31 13:22:47 +0900817 .forEach(port -> {
818 updateSecurityGroupRule(
819 instancePortService.instancePort(port.getId()),
820 port, sgRule, true);
821 log.debug("Applied security group rule {} to port {}",
822 sgRule.getId(), port.getId());
823 });
824 }
825
826 private void securityGroupRuleRemoved(SecurityGroupRule sgRule) {
Jian Liac30e272018-10-18 23:08:03 +0900827 Set<Port> removedPorts = new HashSet<>(removedOsPortStore.asJavaMap().values());
828
829 Sets.union(osNetService.ports(), removedPorts).stream()
Jian Libcc42282018-09-13 20:59:34 +0900830 .filter(port -> port.getSecurityGroups()
Jian Li28ec77f2018-10-31 07:07:25 +0900831 .contains(sgRule.getSecurityGroupId()))
sangho0248ca22017-05-31 13:22:47 +0900832 .forEach(port -> {
833 updateSecurityGroupRule(
834 instancePortService.instancePort(port.getId()),
835 port, sgRule, false);
836 log.debug("Removed security group rule {} from port {}",
837 sgRule.getId(), port.getId());
838 });
839 }
840
sangho6a9ff0d2017-03-27 11:23:37 +0900841 private class InternalInstancePortListener implements InstancePortListener {
842
843 @Override
844 public boolean isRelevant(InstancePortEvent event) {
Jian Li38c82f72020-04-02 11:15:38 +0900845 return getUseSecurityGroupFlag();
Jian Li34220ea2018-11-14 01:30:24 +0900846 }
847
848 private boolean isRelevantHelper(InstancePortEvent event) {
849 return mastershipService.isLocalMaster(event.subject().deviceId());
sangho6a9ff0d2017-03-27 11:23:37 +0900850 }
851
852 @Override
853 public void event(InstancePortEvent event) {
sangho6a9ff0d2017-03-27 11:23:37 +0900854 switch (event.type()) {
Jian Liec5c32b2018-07-13 14:28:58 +0900855 case OPENSTACK_INSTANCE_PORT_UPDATED:
Jian Lie8b28db2018-10-17 14:04:09 +0900856 case OPENSTACK_INSTANCE_PORT_DETECTED:
Jian Liac30e272018-10-18 23:08:03 +0900857 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
Jian Li4d138702018-11-27 17:25:28 +0900858 eventExecutor.execute(() -> processInstanceMigrationStart(event));
Jian Liac30e272018-10-18 23:08:03 +0900859 break;
860 case OPENSTACK_INSTANCE_PORT_VANISHED:
Jian Li4d138702018-11-27 17:25:28 +0900861 eventExecutor.execute(() -> processInstancePortVanish(event));
sangho6a9ff0d2017-03-27 11:23:37 +0900862 break;
Jian Lib8cdcc12018-10-23 01:53:10 +0900863 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
Jian Li4d138702018-11-27 17:25:28 +0900864 eventExecutor.execute(() -> processInstanceMigrationEnd(event));
sangho6a9ff0d2017-03-27 11:23:37 +0900865 break;
sangho6a9ff0d2017-03-27 11:23:37 +0900866 default:
867 break;
868 }
869 }
Jian Liac30e272018-10-18 23:08:03 +0900870
Jian Li4d138702018-11-27 17:25:28 +0900871 private void processInstanceMigrationStart(InstancePortEvent event) {
872 if (!isRelevantHelper(event)) {
873 return;
874 }
875
876 InstancePort instPort = event.subject();
877 installSecurityGroupRules(event, instPort);
878 setAclRecircRules(instPort, true);
879 }
880
881 private void processInstancePortVanish(InstancePortEvent event) {
882 if (!isRelevantHelper(event)) {
883 return;
884 }
885
886 InstancePort instPort = event.subject();
887 Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
888 setSecurityGroupRules(instPort, osPort, false);
889 removedOsPortStore.remove(instPort.portId());
890 setAclRecircRules(instPort, false);
891 }
892
893 private void processInstanceMigrationEnd(InstancePortEvent event) {
894 if (!isRelevantHelper(event)) {
895 return;
896 }
897
898 InstancePort instPort = event.subject();
899 InstancePort revisedInstPort = swapStaleLocation(instPort);
900 Port port = osNetService.port(instPort.portId());
901 setSecurityGroupRules(revisedInstPort, port, false);
902 setAclRecircRules(revisedInstPort, false);
903 }
904
Jian Liac30e272018-10-18 23:08:03 +0900905 private void installSecurityGroupRules(InstancePortEvent event,
906 InstancePort instPort) {
907 log.debug("Instance port detected/updated MAC:{} IP:{}",
908 instPort.macAddress(),
909 instPort.ipAddress());
Jian Li2b9838c2018-10-28 17:09:42 +0900910 eventExecutor.execute(() ->
911 setSecurityGroupRules(instPort,
912 osNetService.port(event.subject().portId()), true));
Jian Liac30e272018-10-18 23:08:03 +0900913 }
Jian Li1e9cb732018-11-25 23:17:21 +0900914
Jian Li4d138702018-11-27 17:25:28 +0900915 private void setSecurityGroupRules(InstancePort instPort,
916 Port port, boolean install) {
917 Port osPort = port;
918
919 if (!install) {
920 Port rmvPort = removedOsPortStore.asJavaMap().get(instPort.portId());
921 if (osPort == null && rmvPort == null) {
922 return;
923 }
924
925 if (port == null) {
926 osPort = rmvPort;
927 }
928 }
929
930 final Port finalPort = osPort;
931
932 osPort.getSecurityGroups().forEach(sgId -> {
933 SecurityGroup sg = securityGroupService.securityGroup(sgId);
934 if (sg == null) {
935 log.error("Security Group {} not found", sgId);
936 return;
937 }
938 sg.getRules().forEach(sgRule ->
939 updateSecurityGroupRule(instPort, finalPort, sgRule, install));
940 final String action = install ? "Installed " : "Removed ";
941 log.debug(action + "Security Group Rule ID : " + sgId);
942 });
943 }
944
Jian Li1e9cb732018-11-25 23:17:21 +0900945 private void setAclRecircRules(InstancePort instPort, boolean install) {
946 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
947
948 Network net = osNetService.network(instPort.networkId());
SONA Project6bc5c4a2018-12-14 23:49:52 +0900949 Type netType = osNetService.networkType(instPort.networkId());
Jian Li1e9cb732018-11-25 23:17:21 +0900950 String segId = net.getProviderSegID();
951
952 switch (netType) {
953 case VXLAN:
Jian Li2d68c192018-12-13 15:52:59 +0900954 case GRE:
Jian Li621f73c2018-12-15 01:49:22 +0900955 case GENEVE:
Jian Li1e9cb732018-11-25 23:17:21 +0900956 sBuilder.matchTunnelId(Long.valueOf(segId));
957 break;
958 case VLAN:
959 sBuilder.matchVlanId(VlanId.vlanId(segId));
960 break;
961 default:
962 break;
963 }
964
965 sBuilder.matchEthType(Ethernet.TYPE_IPV4);
966 sBuilder.matchIPDst(IpPrefix.valueOf(instPort.ipAddress(), VM_IP_PREFIX));
967
968 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
969 tBuilder.transition(ACL_INGRESS_TABLE);
970
971 osFlowRuleService.setRule(
972 appId,
973 instPort.deviceId(),
974 sBuilder.build(),
975 tBuilder.build(),
976 PRIORITY_ACL_RULE,
977 ACL_RECIRC_TABLE,
978 install);
979 }
sangho6a9ff0d2017-03-27 11:23:37 +0900980 }
981
982 private class InternalOpenstackPortListener implements OpenstackNetworkListener {
983
984 @Override
985 public boolean isRelevant(OpenstackNetworkEvent event) {
sanghoshinbbeb31a2018-09-11 17:01:01 +0800986 if (event.port() == null || Strings.isNullOrEmpty(event.port().getId())) {
sangho6a9ff0d2017-03-27 11:23:37 +0900987 return false;
988 }
Jian Libcc42282018-09-13 20:59:34 +0900989
Jian Li38c82f72020-04-02 11:15:38 +0900990 return getUseSecurityGroupFlag();
Jian Li34220ea2018-11-14 01:30:24 +0900991 }
992
993 private boolean isRelevantHelper(OpenstackNetworkEvent event) {
Jian Libcc42282018-09-13 20:59:34 +0900994 InstancePort instPort = instancePortService.instancePort(event.port().getId());
995
996 if (instPort == null) {
997 return false;
998 }
999
Jian Li34220ea2018-11-14 01:30:24 +09001000 return mastershipService.isLocalMaster(instPort.deviceId());
Jian Libcc42282018-09-13 20:59:34 +09001001 }
1002
1003 @Override
1004 public void event(OpenstackNetworkEvent event) {
1005 log.debug("openstack port event received {}", event);
Jian Libcc42282018-09-13 20:59:34 +09001006
Jian Li4d138702018-11-27 17:25:28 +09001007 if (event.type() == OPENSTACK_PORT_PRE_REMOVE) {
1008 eventExecutor.execute(() -> processPortPreRemove(event));
Jian Libcc42282018-09-13 20:59:34 +09001009 }
1010 }
Jian Li4d138702018-11-27 17:25:28 +09001011
1012 private void processPortPreRemove(OpenstackNetworkEvent event) {
1013 if (!isRelevantHelper(event)) {
1014 return;
1015 }
1016
1017 Port osPort = event.port();
1018 removedOsPortStore.put(osPort.getId(), osPort);
1019 }
Jian Libcc42282018-09-13 20:59:34 +09001020 }
1021
Jian Li34220ea2018-11-14 01:30:24 +09001022 private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
Jian Libcc42282018-09-13 20:59:34 +09001023
1024 @Override
1025 public boolean isRelevant(OpenstackNetworkEvent event) {
1026 if (event.port() == null || Strings.isNullOrEmpty(event.port().getId())) {
1027 return false;
1028 }
Jian Li2b9838c2018-10-28 17:09:42 +09001029
Jian Li38c82f72020-04-02 11:15:38 +09001030 return getUseSecurityGroupFlag();
Jian Li34220ea2018-11-14 01:30:24 +09001031 }
1032
1033 private boolean isRelevantHelper(OpenstackNetworkEvent event) {
Hyunsun Moonae51e732017-04-25 17:46:21 +09001034 if (event.securityGroupId() == null ||
1035 securityGroupService.securityGroup(event.securityGroupId()) == null) {
1036 return false;
1037 }
Jian Li2b9838c2018-10-28 17:09:42 +09001038
1039 InstancePort instPort = instancePortService.instancePort(event.port().getId());
1040
1041 if (instPort == null) {
Hyunsun Moonae51e732017-04-25 17:46:21 +09001042 return false;
1043 }
Jian Li2b9838c2018-10-28 17:09:42 +09001044
Jian Li34220ea2018-11-14 01:30:24 +09001045 return mastershipService.isLocalMaster(instPort.deviceId());
sangho6a9ff0d2017-03-27 11:23:37 +09001046 }
1047
1048 @Override
1049 public void event(OpenstackNetworkEvent event) {
sanghoshinbbeb31a2018-09-11 17:01:01 +08001050 log.debug("security group event received {}", event);
Hyunsun Moonae51e732017-04-25 17:46:21 +09001051
sangho6a9ff0d2017-03-27 11:23:37 +09001052 switch (event.type()) {
Hyunsun Moonae51e732017-04-25 17:46:21 +09001053 case OPENSTACK_PORT_SECURITY_GROUP_ADDED:
Jian Li4d138702018-11-27 17:25:28 +09001054 eventExecutor.execute(() -> processPortSgAdd(event));
sangho6a9ff0d2017-03-27 11:23:37 +09001055 break;
Hyunsun Moonae51e732017-04-25 17:46:21 +09001056 case OPENSTACK_PORT_SECURITY_GROUP_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +09001057 eventExecutor.execute(() -> processPortSgRemove(event));
sangho6a9ff0d2017-03-27 11:23:37 +09001058 break;
1059 default:
Hyunsun Moonae51e732017-04-25 17:46:21 +09001060 // do nothing for the other events
sangho6a9ff0d2017-03-27 11:23:37 +09001061 break;
1062 }
1063 }
Jian Li4d138702018-11-27 17:25:28 +09001064
1065 private void processPortSgAdd(OpenstackNetworkEvent event) {
1066 if (!isRelevantHelper(event)) {
1067 return;
1068 }
1069
1070 InstancePort instPort = instancePortService.instancePort(event.port().getId());
1071 SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
1072
1073 osSg.getRules().forEach(sgRule -> {
1074 updateSecurityGroupRule(instPort, event.port(), sgRule, true);
1075 });
1076 log.info("Added security group {} to port {}",
1077 event.securityGroupId(), event.port().getId());
1078 }
1079
1080 private void processPortSgRemove(OpenstackNetworkEvent event) {
1081 if (!isRelevantHelper(event)) {
1082 return;
1083 }
1084
1085 InstancePort instPort = instancePortService.instancePort(event.port().getId());
1086 SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
1087
1088 osSg.getRules().forEach(sgRule -> {
1089 updateSecurityGroupRule(instPort, event.port(), sgRule, false);
1090 });
1091 log.info("Removed security group {} from port {}",
1092 event.securityGroupId(), event.port().getId());
1093 }
sangho6a9ff0d2017-03-27 11:23:37 +09001094 }
1095
Jian Li34220ea2018-11-14 01:30:24 +09001096 private class InternalSecurityGroupListener implements OpenstackSecurityGroupListener {
sangho6a9ff0d2017-03-27 11:23:37 +09001097
1098 @Override
sangho0248ca22017-05-31 13:22:47 +09001099 public boolean isRelevant(OpenstackSecurityGroupEvent event) {
Jian Li38c82f72020-04-02 11:15:38 +09001100 return getUseSecurityGroupFlag();
sangho0248ca22017-05-31 13:22:47 +09001101 }
1102
Jian Li34220ea2018-11-14 01:30:24 +09001103 private boolean isRelevantHelper() {
1104 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1105 }
1106
sangho0248ca22017-05-31 13:22:47 +09001107 @Override
sangho6a9ff0d2017-03-27 11:23:37 +09001108 public void event(OpenstackSecurityGroupEvent event) {
1109 switch (event.type()) {
sangho6a9ff0d2017-03-27 11:23:37 +09001110 case OPENSTACK_SECURITY_GROUP_RULE_CREATED:
Jian Li4d138702018-11-27 17:25:28 +09001111 eventExecutor.execute(() -> processSgRuleCreate(event));
sangho6a9ff0d2017-03-27 11:23:37 +09001112 break;
sangho6a9ff0d2017-03-27 11:23:37 +09001113 case OPENSTACK_SECURITY_GROUP_RULE_REMOVED:
Jian Li4d138702018-11-27 17:25:28 +09001114 eventExecutor.execute(() -> processSgRuleRemove(event));
sangho6a9ff0d2017-03-27 11:23:37 +09001115 break;
Hyunsun Moonae51e732017-04-25 17:46:21 +09001116 case OPENSTACK_SECURITY_GROUP_REMOVED:
Jian Li9d35bd62018-10-13 01:43:24 +09001117 case OPENSTACK_SECURITY_GROUP_CREATED:
sangho6a9ff0d2017-03-27 11:23:37 +09001118 default:
Hyunsun Moonae51e732017-04-25 17:46:21 +09001119 // do nothing
1120 break;
sangho6a9ff0d2017-03-27 11:23:37 +09001121 }
1122 }
Jian Li4d138702018-11-27 17:25:28 +09001123
1124 private void processSgRuleCreate(OpenstackSecurityGroupEvent event) {
1125 if (!isRelevantHelper()) {
1126 return;
1127 }
1128
1129 SecurityGroupRule sgRuleToAdd = event.securityGroupRule();
1130 securityGroupRuleAdded(sgRuleToAdd);
1131 log.info("Applied new security group rule {} to ports", sgRuleToAdd.getId());
1132 }
1133
1134 private void processSgRuleRemove(OpenstackSecurityGroupEvent event) {
1135 if (!isRelevantHelper()) {
1136 return;
1137 }
1138
1139 SecurityGroupRule sgRuleToRemove = event.securityGroupRule();
1140 securityGroupRuleRemoved(sgRuleToRemove);
1141 log.info("Removed security group rule {} from ports", sgRuleToRemove.getId());
1142 }
sangho6a9ff0d2017-03-27 11:23:37 +09001143 }
sangho1aaa7882017-05-31 13:22:47 +09001144
1145 private class InternalNodeListener implements OpenstackNodeListener {
1146
1147 @Override
1148 public boolean isRelevant(OpenstackNodeEvent event) {
Jian Li2dc37592019-03-14 17:32:15 +09001149 return event.subject().type() == COMPUTE;
sangho1aaa7882017-05-31 13:22:47 +09001150 }
1151
Jian Li34220ea2018-11-14 01:30:24 +09001152 private boolean isRelevantHelper() {
1153 return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
1154 }
1155
sangho1aaa7882017-05-31 13:22:47 +09001156 @Override
1157 public void event(OpenstackNodeEvent event) {
sangho1aaa7882017-05-31 13:22:47 +09001158 switch (event.type()) {
1159 case OPENSTACK_NODE_COMPLETE:
Jian Li627e0162020-03-12 17:50:36 +09001160 eventExecutor.execute(() -> processNodeComplete(event.subject()));
sangho1aaa7882017-05-31 13:22:47 +09001161 break;
1162 case OPENSTACK_NODE_CREATED:
1163 case OPENSTACK_NODE_REMOVED:
1164 case OPENSTACK_NODE_UPDATED:
1165 case OPENSTACK_NODE_INCOMPLETE:
1166 default:
1167 break;
1168 }
1169 }
Jian Li4d138702018-11-27 17:25:28 +09001170
Jian Li627e0162020-03-12 17:50:36 +09001171 private void processNodeComplete(OpenstackNode node) {
Jian Li4d138702018-11-27 17:25:28 +09001172 if (!isRelevantHelper()) {
1173 return;
1174 }
1175
Jian Li627e0162020-03-12 17:50:36 +09001176 resetSecurityGroupRulesByNode(node);
1177 }
1178
1179 private void resetSecurityGroupRulesByNode(OpenstackNode node) {
1180 if (getUseSecurityGroupFlag()) {
1181 osFlowRuleService.setUpTableMissEntry(node.intgBridge(), ACL_EGRESS_TABLE);
1182 initializeConnTrackTable(node.intgBridge(), true);
1183 initializeAclTable(node.intgBridge(), true);
1184 initializeIngressTable(node.intgBridge(), true);
1185
1186 securityGroupService.securityGroups().forEach(securityGroup ->
1187 securityGroup.getRules().forEach(
1188 OpenstackSecurityGroupHandler.this::securityGroupRuleAdded));
1189 } else {
1190 osFlowRuleService.connectTables(node.intgBridge(), ACL_EGRESS_TABLE, JUMP_TABLE);
1191 initializeConnTrackTable(node.intgBridge(), false);
1192 initializeAclTable(node.intgBridge(), false);
1193 initializeIngressTable(node.intgBridge(), false);
1194
1195 securityGroupService.securityGroups().forEach(securityGroup ->
1196 securityGroup.getRules().forEach(
1197 OpenstackSecurityGroupHandler.this::securityGroupRuleRemoved));
1198 }
1199
1200 log.info("Reset security group info " +
Jian Li38c82f72020-04-02 11:15:38 +09001201 (getUseSecurityGroupFlag() ? " with " : " without") + " Security Group");
Jian Li4d138702018-11-27 17:25:28 +09001202 }
sangho1aaa7882017-05-31 13:22:47 +09001203 }
Jian Li627e0162020-03-12 17:50:36 +09001204}