blob: a60694bf883d14b416e66d47fe488d0770b3bf60 [file] [log] [blame]
Luca Prete9c2ee072016-02-16 11:00:44 -08001/*
2 * Copyright 2014-2015 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 */
16package org.onosproject.vpls;
17
18import com.google.common.collect.HashMultimap;
19import com.google.common.collect.SetMultimap;
20import javafx.util.Pair;
21import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
28import org.onosproject.app.ApplicationService;
29import org.onosproject.core.ApplicationId;
30import org.onosproject.core.CoreService;
31import org.onosproject.incubator.net.intf.InterfaceService;
32import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.Host;
34import org.onosproject.net.host.HostEvent;
35import org.onosproject.net.host.HostListener;
36import org.onosproject.net.host.HostService;
37import org.onosproject.net.intent.IntentService;
38import org.onosproject.routing.IntentSynchronizationAdminService;
39import org.onosproject.routing.IntentSynchronizationService;
40import org.slf4j.Logger;
41
42import java.util.Map;
43import java.util.Set;
44
45import static org.slf4j.LoggerFactory.getLogger;
46
47/**
48 * Application to create L2 broadcast overlay networks using VLAN.
49 */
50@Component(immediate = true)
51public class Vpls {
52 private static final String VPLS_APP = "org.onosproject.vpls";
53 private final Logger log = getLogger(getClass());
54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected ApplicationService applicationService;
57
58 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 protected CoreService coreService;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 protected HostService hostService;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected IntentService intentService;
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected InterfaceService interfaceService;
69
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected IntentSynchronizationService intentSynchronizer;
72
73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected IntentSynchronizationAdminService intentSynchronizerAdmin;
75
76 private final HostListener hostListener = new InternalHostListener();
77
78 private IntentInstaller intentInstaller;
79
80 private ApplicationId appId;
81
82 @Activate
83 public void activate() {
84 appId = coreService.registerApplication(VPLS_APP);
85
86 intentInstaller = new IntentInstaller(appId,
87 intentService,
88 intentSynchronizer);
89
90 applicationService.registerDeactivateHook(appId,
91 intentSynchronizerAdmin::removeIntents);
92
93 hostService.addListener(hostListener);
94
95 setupConnectivity();
96
97 log.info("Started");
98 }
99
100 @Deactivate
101 public void deactivate() {
102 log.info("Stopped");
103 }
104
105 protected void setupConnectivity() {
106 /*
107 * Parse Configuration and get Connect Point by VlanId.
108 */
109 SetMultimap<VlanId, ConnectPoint> confCPointsByVlan = getConfigCPoints();
110
111 /*
112 * Check that configured Connect Points have hosts attached and
113 * associate their Mac Address to the Connect Points configured.
114 */
115 SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
116 pairAvailableHosts(confCPointsByVlan);
117
118 /*
119 * Create and submit intents between the Connect Points.
120 * Intents for broadcast between all the configured Connect Points.
121 * Intents for unicast between all the configured Connect Points with
122 * hosts attached.
123 */
124 intentInstaller.installIntents(confHostPresentCPoint);
125 }
126
127 /**
128 * Computes the list of configured interfaces with a VLAN Id.
129 *
130 * @return the interfaces grouped by vlan id
131 */
132 protected SetMultimap<VlanId, ConnectPoint> getConfigCPoints() {
133 log.debug("Checking interface configuration");
134
135 SetMultimap<VlanId, ConnectPoint> confCPointsByVlan =
136 HashMultimap.create();
137
138 interfaceService.getInterfaces()
139 .forEach(intf -> confCPointsByVlan.put(intf.vlan(),
140 intf.connectPoint()));
141 return confCPointsByVlan;
142 }
143
144 /**
145 * Checks if for any ConnectPoint configured there's an host present
146 * and in case it associate them together.
147 *
148 * @param confCPointsByVlan the configured ConnectPoints grouped by vlan id
149 * @return the configured ConnectPoints with eventual hosts associated.
150 */
151 protected SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> pairAvailableHosts(
152 SetMultimap<VlanId, ConnectPoint> confCPointsByVlan) {
153 log.debug("Binding connected hosts mac addresses");
154
155 SetMultimap<VlanId, Pair<ConnectPoint, MacAddress>> confHostPresentCPoint =
156 HashMultimap.create();
157
158 confCPointsByVlan.entries()
159 .forEach(e -> bindMacAddr(e, confHostPresentCPoint));
160
161 return confHostPresentCPoint;
162 }
163
164 private void bindMacAddr(Map.Entry<VlanId, ConnectPoint> e,
165 SetMultimap<VlanId, Pair<ConnectPoint,
166 MacAddress>> confHostPresentCPoint) {
167 VlanId vlanId = e.getKey();
168 ConnectPoint cp = e.getValue();
169 Set<Host> connectedHosts = hostService.getConnectedHosts(cp);
170 if (!connectedHosts.isEmpty()) {
171 connectedHosts.forEach(host -> {
172 if (host.vlan().equals(vlanId)) {
173 confHostPresentCPoint.put(vlanId, new Pair<>(cp, host.mac()));
174 } else {
175 confHostPresentCPoint.put(vlanId, new Pair<>(cp, null));
176 }
177 });
178 } else {
179 confHostPresentCPoint.put(vlanId, new Pair<>(cp, null));
180 }
181 }
182
183 /**
184 * Listener for host events.
185 */
186 class InternalHostListener implements HostListener {
187 @Override
188 public void event(HostEvent event) {
189 log.debug("Received HostEvent {}", event);
190 switch (event.type()) {
191 case HOST_ADDED:
192 case HOST_UPDATED:
193 case HOST_REMOVED:
194 setupConnectivity();
195 break;
196 default:
197 break;
198 }
199 }
200 }
201}