/* * 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()); } }