blob: 7520843bcdbd6b89e15c589a385a214fa07a1802 [file] [log] [blame]
/*
* Copyright 2018-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.t3.impl;
import com.google.common.collect.ImmutableSet;
import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.mcast.api.McastRouteData;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.t3.api.MulticastRouteNib;
import org.onosproject.t3.api.StaticPacketTrace;
import org.slf4j.Logger;
import java.util.Set;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of the generator class that yields a set of Packet Traces.
*/
public class McastGenerator extends Generator<Set<StaticPacketTrace>> {
private static final Logger log = getLogger(McastGenerator.class);
protected static final MacAddress IPV4_ADDRESS = MacAddress.valueOf("01:00:5E:00:00:00");
protected static final MacAddress IPV6_ADDRESS = MacAddress.valueOf("33:33:00:00:00:00");
private static final String NO_SINK = "There is no sink for this mcast route";
private static final String GENERATOR_ERROR =
"Generator for mcast route trace has benn interrupted. The trace result may be incomplete.";
private final MulticastRouteNib mcastRouteNib;
private final TroubleshootManager manager;
private final VlanId vlanId;
/**
* Creates a generator for obtaining traces of all configured multicast routes.
*
* @param mcastRouteNib the multicast route NIB
* @param manager the troubleshoot manager issuing the request.
* @param vlanId the multicast configured VlanId.
*/
McastGenerator(MulticastRouteNib mcastRouteNib, TroubleshootManager manager, VlanId vlanId) {
this.mcastRouteNib = mcastRouteNib;
this.manager = manager;
this.vlanId = vlanId;
}
@Override
protected void run() {
mcastRouteNib.getRoutes().forEach(route -> {
McastRouteData routeData = mcastRouteNib.routeData(route);
IpAddress group = route.group();
routeData.sources().forEach((host, sources) -> {
sources.forEach(source -> {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
.matchVlanId(vlanId)
.matchInPort(source.port());
if (group.isIp4()) {
selector.matchEthDst(IPV4_ADDRESS)
.matchIPDst(group.toIpPrefix())
.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
} else {
selector.matchEthDst(IPV6_ADDRESS)
.matchIPv6Dst(group.toIpPrefix())
.matchEthType(EthType.EtherType.IPV6.ethType().toShort());
}
StaticPacketTrace trace;
// check this mcast route has no sink
if (routeData.allSinks().size() == 0) {
trace = new StaticPacketTrace(selector.build(), source);
trace.addResultMessage(NO_SINK);
// tracing mcast route with no sink is not a failure
trace.setSuccess(true);
} else {
trace = manager.trace(selector.build(), source);
}
try {
yield(ImmutableSet.of(trace));
} catch (InterruptedException e) {
log.warn("Interrupted generator", e.getMessage());
log.debug("exception", e);
trace.setSuccess(false);
trace.addResultMessage(GENERATOR_ERROR);
}
});
});
});
}
}