use of org.onosproject.segmentrouting.xconnect.api.XconnectKey in project trellis-control by opennetworkinglab.
the class XconnectManager method populateFilter.
/**
* Populates filtering objectives for given XConnect.
*
* @param key XConnect store key
* @param endpoints XConnect endpoints
*/
private void populateFilter(XconnectKey key, Set<XconnectEndpoint> endpoints) {
// FIXME Improve the logic
// If port load balancer is not involved, use filtered port. Otherwise, use unfiltered port.
// The purpose is to make sure existing XConnect logic can still work on a configured port.
boolean filtered = endpoints.stream().map(ep -> getNextTreatment(key.deviceId(), ep, false)).allMatch(t -> t.type().equals(NextTreatment.Type.TREATMENT));
endpoints.stream().map(ep -> getPhysicalPorts(key.deviceId(), ep)).flatMap(Set::stream).forEach(port -> {
FilteringObjective.Builder filtObjBuilder = filterObjBuilder(key, port, filtered);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("XConnect FilterObj for {} on port {} populated", key, port), (objective, error) -> log.warn("Failed to populate XConnect FilterObj for {} on port {}: {}", key, port, error));
flowObjectiveService.filter(key.deviceId(), filtObjBuilder.add(context));
});
}
use of org.onosproject.segmentrouting.xconnect.api.XconnectKey in project trellis-control by opennetworkinglab.
the class XconnectManager method removeXonnect.
@Override
public void removeXonnect(DeviceId deviceId, VlanId vlanId) {
log.info("Removing xconnect. deviceId={}, vlanId={}", deviceId, vlanId);
final XconnectKey key = new XconnectKey(deviceId, vlanId);
xconnectStore.remove(key);
// Cleanup multicasting support, if any.
srService.getPairDeviceId(deviceId).ifPresent(pairDeviceId -> cleanupL2MulticastRule(pairDeviceId, srService.getPairLocalPort(pairDeviceId).get(), vlanId, true));
}
use of org.onosproject.segmentrouting.xconnect.api.XconnectKey in project trellis-control by opennetworkinglab.
the class XconnectManager method revokeNext.
/**
* Revokes next objectives for given XConnect.
*
* @param key XConnect store key
* @param endpoints XConnect endpoints
* @param nextId next objective id
* @param nextFuture completable future for this next objective operation
*/
private void revokeNext(XconnectKey key, Set<XconnectEndpoint> endpoints, int nextId, CompletableFuture<ObjectiveError> nextFuture) {
ObjectiveContext context = new ObjectiveContext() {
@Override
public void onSuccess(Objective objective) {
log.debug("Previous NextObj for {} removed", key);
if (nextFuture != null) {
nextFuture.complete(null);
}
}
@Override
public void onError(Objective objective, ObjectiveError error) {
log.warn("Failed to remove previous NextObj for {}: {}", key, error);
if (nextFuture != null) {
nextFuture.complete(error);
}
srService.invalidateNextObj(objective.id());
}
};
NextObjective.Builder nextObjBuilder = nextObjBuilder(key, endpoints, nextId);
if (nextObjBuilder == null) {
log.warn("Fail to revokeNext {}: {}", key, ERROR_NEXT_OBJ_BUILDER);
return;
}
// Release the port load balancer if present
endpoints.stream().filter(endpoint -> endpoint.type() == XconnectEndpoint.Type.LOAD_BALANCER).forEach(endpoint -> {
String portLoadBalancerKey = String.valueOf(((XconnectLoadBalancerEndpoint) endpoint).key());
portLoadBalancerService.release(new PortLoadBalancerId(key.deviceId(), Integer.parseInt(portLoadBalancerKey)), appId);
});
flowObjectiveService.next(key.deviceId(), nextObjBuilder.remove(context));
xconnectNextObjStore.remove(key);
}
use of org.onosproject.segmentrouting.xconnect.api.XconnectKey in project trellis-control by opennetworkinglab.
the class XconnectManager method populateNext.
/**
* Populates next objectives for given XConnect.
*
* @param key XConnect store key
* @param endpoints XConnect endpoints
* @return next id
*/
private int populateNext(XconnectKey key, Set<XconnectEndpoint> endpoints) {
int nextId = Versioned.valueOrElse(xconnectNextObjStore.get(key), -1);
if (nextId != -1) {
log.debug("NextObj for {} found, id={}", key, nextId);
return nextId;
} else {
NextObjective.Builder nextObjBuilder = nextObjBuilder(key, endpoints);
if (nextObjBuilder == null) {
log.warn("Fail to populate {}: {}", key, ERROR_NEXT_OBJ_BUILDER);
return -1;
}
ObjectiveContext nextContext = new DefaultObjectiveContext(// To serialize this with kryo
(Serializable & Consumer<Objective>) (objective) -> log.debug("XConnect NextObj for {} added", key), (Serializable & BiConsumer<Objective, ObjectiveError>) (objective, error) -> {
log.warn("Failed to add XConnect NextObj for {}: {}", key, error);
srService.invalidateNextObj(objective.id());
});
NextObjective nextObj = nextObjBuilder.add(nextContext);
flowObjectiveService.next(key.deviceId(), nextObj);
xconnectNextObjStore.put(key, nextObj.id());
log.debug("NextObj for {} not found. Creating new NextObj with id={}", key, nextObj.id());
return nextObj.id();
}
}
use of org.onosproject.segmentrouting.xconnect.api.XconnectKey in project trellis-control by opennetworkinglab.
the class XconnectManager method updateXConnect.
/**
* Updates XConnect groups and flows for given key.
*
* @param key XConnect key
* @param prevEndpoints previous XConnect endpoints
* @param endpoints new XConnect endpoints
*/
private void updateXConnect(XconnectKey key, Set<XconnectEndpoint> prevEndpoints, Set<XconnectEndpoint> endpoints) {
if (!srService.shouldProgram(key.deviceId())) {
log.debug("Abort updating XConnect {}: {}", key, ERROR_NOT_LEADER);
return;
}
// NOTE: ACL flow doesn't include port information. No need to update it.
// Pair port is built-in and thus not going to change. No need to update it.
// remove old filter
prevEndpoints.stream().filter(prevEndpoint -> !endpoints.contains(prevEndpoint)).forEach(prevEndpoint -> revokeFilter(key, ImmutableSet.of(prevEndpoint)));
// install new filter
endpoints.stream().filter(endpoint -> !prevEndpoints.contains(endpoint)).forEach(endpoint -> populateFilter(key, ImmutableSet.of(endpoint)));
CompletableFuture<ObjectiveError> fwdFuture = new CompletableFuture<>();
CompletableFuture<ObjectiveError> nextFuture = new CompletableFuture<>();
int nextId = Versioned.valueOrElse(xconnectNextObjStore.get(key), -1);
if (nextId != -1) {
revokeFwd(key, nextId, fwdFuture);
fwdFuture.thenAcceptAsync(fwdStatus -> {
if (fwdStatus == null) {
log.debug("Fwd removed. Now remove group {}", key);
revokeNext(key, prevEndpoints, nextId, nextFuture);
}
});
nextFuture.thenAcceptAsync(nextStatus -> {
if (nextStatus == null) {
log.debug("Installing new group and flow for {}", key);
int newNextId = populateNext(key, endpoints);
if (newNextId == -1) {
log.warn("Fail to updateXConnect {}: {}", key, ERROR_NEXT_ID);
return;
}
populateFwd(key, newNextId);
}
});
} else {
log.warn("NextObj for {} does not exist in the store.", key);
}
}
Aggregations