blob: f32cd2d9b4fca557321ac508b7c07db09a6c18c8 [file] [log] [blame]
Charles Chan5270ed02016-01-30 23:22:37 -08001package org.onosproject.segmentrouting;
2
3import com.google.common.collect.ImmutableSet;
4import org.onlab.packet.MacAddress;
5import org.onosproject.net.DeviceId;
6import org.onosproject.net.PortNumber;
7import org.onosproject.net.config.NetworkConfigEvent;
8import org.onosproject.net.device.DeviceService;
9import org.onosproject.net.flow.criteria.Criteria;
10import org.onosproject.net.flowobjective.DefaultFilteringObjective;
11import org.onosproject.net.flowobjective.FilteringObjective;
12import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
13import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
14import org.slf4j.Logger;
15import org.slf4j.LoggerFactory;
16
17import java.util.HashSet;
18import java.util.Set;
19
20/**
21 * Handles network config events.
22 */
23public class NetworkConfigEventHandler {
24 private static final Logger log = LoggerFactory.getLogger(NetworkConfigEventHandler.class);
25 private final SegmentRoutingManager srManager;
26 private final DeviceService deviceService;
27
28 /**
29 * Constructs Network Config Event Handler.
30 *
31 * @param srManager instance of {@link SegmentRoutingManager}
32 */
33 public NetworkConfigEventHandler(SegmentRoutingManager srManager) {
34 this.srManager = srManager;
35 this.deviceService = srManager.deviceService;
36 }
37
38 /**
39 * Processes vRouter config added event.
40 *
41 * @param event network config added event
42 */
43 protected void processVRouterConfigAdded(NetworkConfigEvent event) {
44 log.info("Processing vRouter CONFIG_ADDED");
45 SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
46 deviceService.getAvailableDevices().forEach(device -> {
47 populateVRouter(device.id(), getMacAddresses(config));
48 });
49 }
50
51 /**
52 * Processes vRouter config updated event.
53 *
54 * @param event network config updated event
55 */
56 protected void processVRouterConfigUpdated(NetworkConfigEvent event) {
57 log.info("Processing vRouter CONFIG_UPDATED");
58 SegmentRoutingAppConfig config = (SegmentRoutingAppConfig) event.config().get();
59 SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
60 deviceService.getAvailableDevices().forEach(device -> {
61 Set<MacAddress> macAddresses = getMacAddresses(config);
62 Set<MacAddress> prevMacAddresses = getMacAddresses(prevConfig);
63 // Avoid removing and re-adding unchanged MAC addresses since
64 // FlowObjective does not guarantee the execution order.
65 Set<MacAddress> sameMacAddresses = new HashSet<>(macAddresses);
66 sameMacAddresses.retainAll(prevMacAddresses);
67 macAddresses.removeAll(sameMacAddresses);
68 prevMacAddresses.removeAll(sameMacAddresses);
69
70 revokeVRouter(device.id(), prevMacAddresses);
71 populateVRouter(device.id(), macAddresses);
72 });
73
74 }
75
76 /**
77 * Processes vRouter config removed event.
78 *
79 * @param event network config removed event
80 */
81 protected void processVRouterConfigRemoved(NetworkConfigEvent event) {
82 log.info("Processing vRouter CONFIG_REMOVED");
83 SegmentRoutingAppConfig prevConfig = (SegmentRoutingAppConfig) event.prevConfig().get();
84 deviceService.getAvailableDevices().forEach(device -> {
85 revokeVRouter(device.id(), getMacAddresses(prevConfig));
86 });
87 }
88
89 /**
90 * Populates initial vRouter rules.
91 *
92 * @param deviceId device ID
93 */
94 public void initVRouters(DeviceId deviceId) {
95 SegmentRoutingAppConfig config =
96 srManager.cfgService.getConfig(srManager.appId, SegmentRoutingAppConfig.class);
97 populateVRouter(deviceId, getMacAddresses(config));
98 }
99
100 private void populateVRouter(DeviceId deviceId, Set<MacAddress> pendingAdd) {
101 if (!isEdge(deviceId)) {
102 return;
103 }
104 getVRouterFlowObjBuilders(pendingAdd).forEach(foBuilder -> {
105 srManager.flowObjectiveService.
106 filter(deviceId, foBuilder.add(new SRObjectiveContext(deviceId,
107 SRObjectiveContext.ObjectiveType.FILTER)));
108 });
109 }
110
111 private void revokeVRouter(DeviceId deviceId, Set<MacAddress> pendingRemove) {
112 if (!isEdge(deviceId)) {
113 return;
114 }
115 getVRouterFlowObjBuilders(pendingRemove).forEach(foBuilder -> {
116 srManager.flowObjectiveService.
117 filter(deviceId, foBuilder.remove(new SRObjectiveContext(deviceId,
118 SRObjectiveContext.ObjectiveType.FILTER)));
119 });
120 }
121
122 private Set<FilteringObjective.Builder> getVRouterFlowObjBuilders(Set<MacAddress> macAddresses) {
123 ImmutableSet.Builder<FilteringObjective.Builder> setBuilder = ImmutableSet.builder();
124 macAddresses.forEach(macAddress -> {
125 FilteringObjective.Builder fobuilder = DefaultFilteringObjective.builder();
126 fobuilder.withKey(Criteria.matchInPort(PortNumber.ANY))
127 .addCondition(Criteria.matchEthDst(macAddress))
128 .permit()
129 .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
130 .fromApp(srManager.appId);
131 setBuilder.add(fobuilder);
132 });
133 return setBuilder.build();
134 }
135
136 private Set<MacAddress> getMacAddresses(SegmentRoutingAppConfig config) {
137 if (config == null) {
138 return ImmutableSet.of();
139 }
Charles Chan2196a922016-03-07 00:49:33 -0800140 return ImmutableSet.copyOf(config.vRouterMacs());
Charles Chan5270ed02016-01-30 23:22:37 -0800141 }
142
143 private boolean isEdge(DeviceId deviceId) {
144 try {
145 if (srManager.deviceConfiguration.isEdgeDevice(deviceId)) {
146 return true;
147 }
148 } catch (DeviceConfigNotFoundException e) { }
149 return false;
150 }
151}