blob: eae4a671fa6315256425c62c7ac03fa722230b81 [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* 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.sdxl2;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.PointToPointIntent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkState;
/**
* Manages Virtual Circuits using MAC addresses.
*/
public class SdxL2MacVCManager extends SdxL2VCManager {
private static final int PRIORITY_OFFSET = 2000;
private static Logger log = LoggerFactory.getLogger(SdxL2MacVCManager.class);
private static String errorMacNull = "VC cannot be %s: the mac address of %s is null";
private static String errorMacEqual = "VC cannot be %s: same mac addresses on both sides";
/**
* Creates a SDX-L2 MAC-based VC Manager.
*
* @param sdxl2id application ID
* @param store reference to the SDX-L2 store
* @param intentService reference to the Intent service
*/
public SdxL2MacVCManager(ApplicationId sdxl2id,
SdxL2Store store,
IntentService intentService) {
super(sdxl2id, store, intentService);
log.info("Started");
}
@Override
public Collection<Intent> buildIntents(String sdxl2, SdxL2ConnectionPoint ingress, SdxL2ConnectionPoint egress) {
List<Intent> intents = null;
TrafficSelector selector;
TrafficTreatment treatment;
Key key;
if (ingress.vlanIds().size() == egress.vlanIds().size()) {
intents = new ArrayList<>();
if (ingress.vlanIds().size() == 0) {
selector = buildSelector(ingress.macAddress(),
egress.macAddress(),
null,
null);
treatment = DefaultTrafficTreatment.emptyTreatment();
key = generateIntentKey(sdxl2, ingress, egress, "1");
intents.add(PointToPointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.treatment(treatment)
.ingressPoint(ingress.connectPoint())
.egressPoint(egress.connectPoint())
.priority(PRIORITY_OFFSET)
.build());
} else {
Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
Iterator<VlanId> egressTags = egress.vlanIds().iterator();
int index = 1;
while (ingressTags.hasNext()) {
selector = buildSelector(ingress.macAddress(),
egress.macAddress(),
null,
ingressTags.next());
treatment = buildTreatment(egressTags.next(),
null,
false);
key = generateIntentKey(sdxl2, ingress, egress, String.valueOf(index));
intents.add(PointToPointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.treatment(treatment)
.ingressPoint(ingress.connectPoint())
.egressPoint(egress.connectPoint())
.priority(PRIORITY_OFFSET)
.build());
index += 1;
}
}
return intents;
}
if (ingress.vlanIds().size() == 1 && egress.vlanIds().size() == 0) {
Iterator<VlanId> ingressTags = ingress.vlanIds().iterator();
intents = new ArrayList<>();
selector = buildSelector(ingress.macAddress(),
egress.macAddress(),
null,
ingressTags.next());
treatment = buildTreatment(null,
null,
true);
key = generateIntentKey(sdxl2, ingress, egress, "1");
intents.add(PointToPointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.treatment(treatment)
.ingressPoint(ingress.connectPoint())
.egressPoint(egress.connectPoint())
.priority(PRIORITY_OFFSET)
.build());
return intents;
}
if (ingress.vlanIds().size() == 0 && egress.vlanIds().size() == 1) {
Iterator<VlanId> egressTags = egress.vlanIds().iterator();
intents = new ArrayList<>();
selector = buildSelector(ingress.macAddress(),
egress.macAddress(),
null,
null);
treatment = buildTreatment(null,
egressTags.next(),
false);
key = generateIntentKey(sdxl2, ingress, egress, "1");
intents.add(PointToPointIntent.builder()
.appId(appId)
.key(key)
.selector(selector)
.treatment(treatment)
.ingressPoint(ingress.connectPoint())
.egressPoint(egress.connectPoint())
.priority(PRIORITY_OFFSET)
.build());
return intents;
}
log.warn(String.format(ERROR_CREATE_INTENTS, ingress.name(), egress.name()));
return intents;
}
@Override
public void addVC(String sdxl2, SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
String action = "created";
checkState(!(isNullMac(sdxl2cplhs.macAddress()) && isNullMac(sdxl2cprhs.macAddress())),
errorMacNull, action, sdxl2cplhs.name() + " and " + sdxl2cprhs.name());
checkState(!isNullMac(sdxl2cprhs.macAddress()), errorMacNull, action, sdxl2cplhs.name());
checkState(!isNullMac(sdxl2cprhs.macAddress()), errorMacNull, action, sdxl2cprhs.name());
checkState(!sdxl2cplhs.macAddress().equals(sdxl2cprhs.macAddress()), errorMacEqual, action);
super.addVC(sdxl2, sdxl2cplhs, sdxl2cprhs);
}
@Override
public void removeVC(SdxL2ConnectionPoint sdxl2cplhs, SdxL2ConnectionPoint sdxl2cprhs) {
String action = "deleted";
checkState(!(isNullMac(sdxl2cplhs.macAddress()) && isNullMac(sdxl2cprhs.macAddress())),
errorMacNull, action, sdxl2cplhs.name() + " and " + sdxl2cprhs.name());
checkState(!sdxl2cplhs.macAddress().equals(MacAddress.ZERO), errorMacNull, action, sdxl2cplhs.name());
checkState(!sdxl2cprhs.macAddress().equals(MacAddress.ZERO), errorMacNull, action, sdxl2cprhs.name());
checkState(!sdxl2cplhs.macAddress().equals(sdxl2cprhs.macAddress()), errorMacEqual, action);
super.removeVC(sdxl2cplhs, sdxl2cprhs);
}
@Override
public void removeVC(SdxL2ConnectionPoint cp) {
checkState(!cp.macAddress().equals(MacAddress.ZERO), errorMacNull, "deleted", cp.name());
super.removeVC(cp);
}
/**
* Determines whether a MAC address is empty or not.
*
* @param mac MacAddress object
* @return boolean indicating whether MAC is empty (true) or not
*/
private boolean isNullMac(MacAddress mac) {
return mac.equals(MacAddress.ZERO);
}
/**
* Returns the traffic selector, used in the definition of the intents.
*
* @param ingressMac Input MAC address
* @param egressMac Output MAC address
* @param etherType name of the Ethernet type used (e.g. of SDX-L2)
* @param ingressTag VLAN id used at the ingress
* @return TrafficSelector object
*/
protected TrafficSelector buildSelector(MacAddress ingressMac,
MacAddress egressMac,
Short etherType,
VlanId ingressTag) {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
selectorBuilder.matchEthSrc(ingressMac);
selectorBuilder.matchEthDst(egressMac);
if (etherType != null) {
selectorBuilder.matchEthType(etherType);
}
if (ingressTag != null) {
selectorBuilder.matchVlanId(ingressTag);
}
return selectorBuilder.build();
}
}