blob: 7e9dd5530ad242639dbcac6c2be91409e44d216e [file] [log] [blame]
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Charles Chan5270ed02016-01-30 23:22:37 -080016package org.onosproject.segmentrouting;
17
18import com.google.common.collect.ImmutableSet;
19import org.onlab.packet.MacAddress;
20import org.onosproject.net.DeviceId;
21import org.onosproject.net.PortNumber;
22import org.onosproject.net.config.NetworkConfigEvent;
23import org.onosproject.net.device.DeviceService;
24import org.onosproject.net.flow.criteria.Criteria;
25import org.onosproject.net.flowobjective.DefaultFilteringObjective;
26import org.onosproject.net.flowobjective.FilteringObjective;
27import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
28import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
29import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
31
32import java.util.HashSet;
33import java.util.Set;
34
35/**
36 * Handles network config events.
37 */
38public class NetworkConfigEventHandler {
39 private static final Logger log = LoggerFactory.getLogger(NetworkConfigEventHandler.class);
40 private final SegmentRoutingManager srManager;
41 private final DeviceService deviceService;
42
43 /**
44 * Constructs Network Config Event Handler.
45 *
46 * @param srManager instance of {@link SegmentRoutingManager}
47 */
48 public NetworkConfigEventHandler(SegmentRoutingManager srManager) {
49 this.srManager = srManager;
50 this.deviceService = srManager.deviceService;
51 }
52
53 /**
54 * Processes vRouter config added event.
55 *
56 * @param event network config added event
57 */
58 protected void processVRouterConfigAdded(NetworkConfigEvent event) {
59 log.info("Processing vRouter CONFIG_ADDED");
60 SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
61 deviceService.getAvailableDevices().forEach(device -> {
62 populateVRouter(device.id(), getMacAddresses(config));
63 });
64 }
65
66 /**
67 * Processes vRouter config updated event.
68 *
69 * @param event network config updated event
70 */
71 protected void processVRouterConfigUpdated(NetworkConfigEvent event) {
72 log.info("Processing vRouter CONFIG_UPDATED");
73 SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
74 SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
75 deviceService.getAvailableDevices().forEach(device -> {
76 Set<MacAddress> macAddresses = getMacAddresses(config);
77 Set<MacAddress> prevMacAddresses = getMacAddresses(prevConfig);
78 // Avoid removing and re-adding unchanged MAC addresses since
79 // FlowObjective does not guarantee the execution order.
80 Set<MacAddress> sameMacAddresses = new HashSet<>(macAddresses);
81 sameMacAddresses.retainAll(prevMacAddresses);
82 macAddresses.removeAll(sameMacAddresses);
83 prevMacAddresses.removeAll(sameMacAddresses);
84
85 revokeVRouter(device.id(), prevMacAddresses);
86 populateVRouter(device.id(), macAddresses);
87 });
88
89 }
90
91 /**
92 * Processes vRouter config removed event.
93 *
94 * @param event network config removed event
95 */
96 protected void processVRouterConfigRemoved(NetworkConfigEvent event) {
97 log.info("Processing vRouter CONFIG_REMOVED");
98 SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
99 deviceService.getAvailableDevices().forEach(device -> {
100 revokeVRouter(device.id(), getMacAddresses(prevConfig));
101 });
102 }
103
104 /**
105 * Populates initial vRouter rules.
106 *
107 * @param deviceId device ID
108 */
109 public void initVRouters(DeviceId deviceId) {
110 SegmentRoutingAppConfig config =
111 srManager.cfgService.getConfig(srManager.appId, SegmentRoutingAppConfig.class);
112 populateVRouter(deviceId, getMacAddresses(config));
113 }
114
115 private void populateVRouter(DeviceId deviceId, Set<MacAddress> pendingAdd) {
116 if (!isEdge(deviceId)) {
117 return;
118 }
119 getVRouterFlowObjBuilders(pendingAdd).forEach(foBuilder -> {
120 srManager.flowObjectiveService.
121 filter(deviceId, foBuilder.add(new SRObjectiveContext(deviceId,
122 SRObjectiveContext.ObjectiveType.FILTER)));
123 });
124 }
125
126 private void revokeVRouter(DeviceId deviceId, Set<MacAddress> pendingRemove) {
127 if (!isEdge(deviceId)) {
128 return;
129 }
130 getVRouterFlowObjBuilders(pendingRemove).forEach(foBuilder -> {
131 srManager.flowObjectiveService.
132 filter(deviceId, foBuilder.remove(new SRObjectiveContext(deviceId,
133 SRObjectiveContext.ObjectiveType.FILTER)));
134 });
135 }
136
137 private Set<FilteringObjective.Builder> getVRouterFlowObjBuilders(Set<MacAddress> macAddresses) {
138 ImmutableSet.Builder<FilteringObjective.Builder> setBuilder = ImmutableSet.builder();
139 macAddresses.forEach(macAddress -> {
140 FilteringObjective.Builder fobuilder = DefaultFilteringObjective.builder();
141 fobuilder.withKey(Criteria.matchInPort(PortNumber.ANY))
142 .addCondition(Criteria.matchEthDst(macAddress))
143 .permit()
144 .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
145 .fromApp(srManager.appId);
146 setBuilder.add(fobuilder);
147 });
148 return setBuilder.build();
149 }
150
151 private Set<MacAddress> getMacAddresses(SegmentRoutingAppConfig config) {
152 if (config == null) {
153 return ImmutableSet.of();
154 }
Charles Chan2196a922016-03-07 00:49:33 -0800155 return ImmutableSet.copyOf(config.vRouterMacs());
Charles Chan5270ed02016-01-30 23:22:37 -0800156 }
157
158 private boolean isEdge(DeviceId deviceId) {
159 try {
160 if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) {
161 return true;
162 }
163 } catch (DeviceConfigNotFoundException e) { }
164 return false;
165 }
166}