blob: 9f3ea06313eb2753b88b520f5f20a00dffe3fcd3 [file] [log] [blame]
Yi Tseng28767f02016-09-13 04:27:20 -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 */
16
17package org.onosproject.vpls;
18
19import com.google.common.collect.Maps;
20
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.onosproject.core.ApplicationId;
27import org.onosproject.core.CoreService;
28import org.onosproject.incubator.net.intf.Interface;
29import org.onosproject.incubator.net.intf.InterfaceEvent;
30import org.onosproject.incubator.net.intf.InterfaceListener;
31import org.onosproject.incubator.net.intf.InterfaceService;
32import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
33import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
34import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
35import org.onosproject.net.Host;
36import org.onosproject.net.host.HostService;
37import org.slf4j.Logger;
38
39import java.util.Map;
40
41import static org.slf4j.LoggerFactory.getLogger;
42
43/**
44 * Handles neighbour messages for VPLS use case.
45 * Handlers will be changed automatically by interface or network configuration
46 * events.
47 */
48@Component(immediate = true)
49public class VplsNeighbourHandler {
50
51 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 protected CoreService coreService;
53
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 protected InterfaceService interfaceService;
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected NeighbourResolutionService neighbourService;
59
60 private VplsInterfaceListener interfaceListener
61 = new VplsInterfaceListener();
62
63 private VplsNeighbourMessageHandler neighbourHandler =
64 new VplsNeighbourMessageHandler();
65
66 private final Logger log = getLogger(getClass());
67
68 private Map<Interface, NeighbourMessageHandler> neighbourHandlers =
69 Maps.newHashMap();
70
71 private ApplicationId appId;
72
73
74 @Activate
75 protected void activate() {
76 appId = coreService.registerApplication(Vpls.VPLS_APP);
77 interfaceService.addListener(interfaceListener);
78
79 interfaceService.getInterfaces().forEach(intf -> {
80 neighbourHandlers.put(intf, neighbourHandler);
81
82 neighbourService.registerNeighbourHandler(intf, neighbourHandler, appId);
83 });
84
85 log.debug("Activated");
86 }
87
88 @Deactivate
89 protected void deactivate() {
90 interfaceService.removeListener(interfaceListener);
91 neighbourHandlers.entrySet().forEach(e -> {
92 neighbourService.unregisterNeighbourHandler(e.getKey(), e.getValue(), appId);
93 });
94 log.debug("Deactivated");
95 }
96
97 private void configNeighbourHandler(Interface intf,
98 NeighbourMessageHandler handler,
99 InterfaceEvent.Type eventType) {
100 switch (eventType) {
101 case INTERFACE_ADDED:
102 neighbourHandlers.put(intf, handler);
103 neighbourService.registerNeighbourHandler(intf, handler, appId);
104 break;
105 case INTERFACE_REMOVED:
106 neighbourHandlers.remove(intf, handler);
107 neighbourService.unregisterNeighbourHandler(intf, handler, appId);
108 break;
109 case INTERFACE_UPDATED:
110 break;
111 default:
112 break;
113 }
114 }
115
116 /**
117 * Handler for neighbour messages.
118 */
119 private class VplsNeighbourMessageHandler implements NeighbourMessageHandler {
120
121 @Override
122 public void handleMessage(NeighbourMessageContext context,
123 HostService hostService) {
124
125 switch (context.type()) {
126 case REQUEST:
127 interfaceService.getInterfacesByVlan(context.vlan())
128 .stream()
129 .map(Interface::connectPoint)
130 .forEach(context::proxy);
131 break;
132 case REPLY:
133 hostService.getHostsByMac(context.dstMac())
134 .stream()
135 .filter(host -> host.vlan().equals(context.vlan()))
136 .map(Host::location)
137 .forEach(context::proxy);
138 break;
139
140 default:
141 log.warn("Unknown context type: {}", context.type());
142 break;
143 }
144 }
145 }
146
147 /**
148 * Listener for interface configuration events.
149 */
150 private class VplsInterfaceListener implements InterfaceListener {
151
152 @Override
153 public void event(InterfaceEvent event) {
154 configNeighbourHandler(event.subject(), neighbourHandler, event.type());
155 }
156 }
157
158}