blob: 34f5d1e52fb58083a2150158e16f63723d070c87 [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.segmentrouting;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultHost;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.provider.ProviderId;
import org.opencord.cordconfig.CordConfigEvent;
import org.opencord.cordconfig.access.AccessAgentData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Optional;
/**
* Handles access agent config event which is required for CORD integration.
*/
public class CordConfigHandler {
private static Logger log = LoggerFactory.getLogger(CordConfigHandler.class);
private final SegmentRoutingManager srManager;
/**
* Constructs the CordConfigHandler.
*
* @param srManager Segment Routing manager
*/
public CordConfigHandler(SegmentRoutingManager srManager) {
this.srManager = srManager;
}
/**
* Read initial access agent config for given device.
*
* @param deviceId ID of the device to be initialized
*/
public void init(DeviceId deviceId) {
// Try to read access agent config
Optional<AccessAgentData> accessAgent =
srManager.cordConfigService.getAccessAgent(deviceId);
if (!accessAgent.isPresent()) {
log.debug("No access agent config on {}. Skip.", deviceId);
return;
}
processAccessAgentAdded(accessAgent.get());
}
// TODO javadoc
protected void processAccessAgentAddedEvent(CordConfigEvent event) {
log.debug("processAccessAgentAdded: {}, {}", event.subject(), event.prevSubject());
processAccessAgentAdded((AccessAgentData) event.subject());
}
protected void processAccessAgentUpdatedEvent(CordConfigEvent event) {
log.debug("processAccessAgentUpdated: {}, {}", event.subject(), event.prevSubject());
processAccessAgentRemoved((AccessAgentData) event.prevSubject());
processAccessAgentAdded((AccessAgentData) event.subject());
}
protected void processAccessAgentRemovedEvent(CordConfigEvent event) {
log.debug("processAccessAgentRemoved: {}, {}", event.subject(), event.prevSubject());
processAccessAgentRemoved((AccessAgentData) event.prevSubject());
}
protected void processAccessAgentAdded(AccessAgentData accessAgentData) {
if (!srManager.mastershipService.isLocalMaster(accessAgentData.deviceId())) {
log.debug("Not the master of {}. Abort.", accessAgentData.deviceId());
return;
}
// Do not proceed if vtn location is missing
if (!accessAgentData.getVtnLocation().isPresent()) {
log.warn("accessAgentData does not contain vtn location. Abort.");
return;
}
MacAddress agentMac = accessAgentData.getAgentMac();
ConnectPoint agentLocation = accessAgentData.getVtnLocation().get();
// Do not proceed if agent port doesn't have subnet configured
Ip4Prefix agentSubnet = srManager.deviceConfiguration
.getPortIPv4Subnet(agentLocation.deviceId(), agentLocation.port());
if (agentSubnet == null) {
log.warn("Agent port does not have subnet configuration. Abort.");
return;
}
// Add host information for agent
log.info("push host info for agent {}", agentMac);
srManager.hostHandler.processHostAdded(createHost(agentMac, agentLocation));
accessAgentData.getOltMacInfo().forEach((connectPoint, macAddress) -> {
// Do not proceed if olt port has subnet configured
Ip4Prefix oltSubnet = srManager.deviceConfiguration
.getPortIPv4Subnet(connectPoint.deviceId(), connectPoint.port());
if (oltSubnet != null) {
log.warn("OLT port has subnet configuration. Abort.");
return;
}
// Add olt to the subnet of agent
log.info("push subnet for olt {}", agentSubnet);
srManager.deviceConfiguration.addSubnet(connectPoint, agentSubnet);
srManager.routingRulePopulator.populateVlanMacFilters(connectPoint.deviceId());
// Add host information for olt
log.info("push host info for olt {}", macAddress);
srManager.hostHandler.processHostAdded(createHost(macAddress, connectPoint));
});
}
protected void processAccessAgentRemoved(AccessAgentData accessAgentData) {
if (!srManager.mastershipService.isLocalMaster(accessAgentData.deviceId())) {
log.debug("Not the master of {}. Abort.", accessAgentData.deviceId());
return;
}
// Do not proceed if vtn location is missing
if (!accessAgentData.getVtnLocation().isPresent()) {
log.warn("accessAgentData does not contain vtn location. Abort.");
return;
}
MacAddress agentMac = accessAgentData.getAgentMac();
ConnectPoint agentLocation = accessAgentData.getVtnLocation().get();
// Do not proceed if olt port doesn't have subnet configured
Ip4Prefix agentSubnet = srManager.deviceConfiguration
.getPortIPv4Subnet(agentLocation.deviceId(), agentLocation.port());
if (agentSubnet == null) {
log.warn("Agent port does not have subnet configuration. Abort.");
return;
}
// Remove host information for agent
log.info("delete host info for agent {}", agentMac);
srManager.hostHandler.processHostRemoved(createHost(agentMac, agentLocation));
accessAgentData.getOltMacInfo().forEach((connectPoint, macAddress) -> {
// Do not proceed if agent port doesn't have subnet configured
Ip4Prefix oltSubnet = srManager.deviceConfiguration
.getPortIPv4Subnet(connectPoint.deviceId(), connectPoint.port());
if (oltSubnet == null) {
log.warn("OLT port does not have subnet configuration. Abort.");
return;
}
// Remove host information for olt
log.info("delete host info for olt {}", macAddress);
srManager.hostHandler.processHostRemoved(createHost(macAddress, connectPoint));
// Remove olt to the subnet of agent
log.info("delete subnet for olt {}", agentSubnet);
srManager.deviceConfiguration.removeSubnet(connectPoint, agentSubnet);
srManager.routingRulePopulator.populateVlanMacFilters(connectPoint.deviceId());
});
}
private Host createHost(MacAddress macAddress, ConnectPoint location) {
return new DefaultHost(
new ProviderId("host", "org.onosproject.segmentrouting"),
HostId.hostId(macAddress),
macAddress,
VlanId.NONE,
new HostLocation(location, System.currentTimeMillis()),
ImmutableSet.of());
}
}