blob: adb1e8ad4ba6651effd3a279e9d2f4b1a1545e9f [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.drivers.barefoot.pro;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TMultiplexedProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.onosproject.drivers.barefoot.pro.pal.pal;
import org.onosproject.drivers.barefoot.pro.pal.pal_autoneg_policy_t;
import org.onosproject.drivers.barefoot.pro.pal.pal_fec_type_t;
import org.onosproject.drivers.barefoot.pro.pal.pal_port_speed_t;
import org.onosproject.incubator.net.config.basics.PortDescriptionsConfig;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.provider.general.device.api.GeneralProviderDeviceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import static java.lang.Boolean.parseBoolean;
/**
* Class to configure ports on Tofino.
*/
final class TofinoPortConfigurator {
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String P4RUNTIME = "p4runtime";
private static final String PROTOCOL_KEY_IP = "ip";
private static final String DEVICE_ID = "deviceId";
private static final String AUTONEG = "autoneg";
private static final int PAL_MGMT_PORT = 9090;
private static final String PAL_THRIFT_SERVICE = "pal";
private static final pal_fec_type_t DEFAULT_FEC_TYPE =
pal_fec_type_t.BF_FEC_TYP_NONE;
private final NetworkConfigService netcfgService;
TofinoPortConfigurator(NetworkConfigService netcfgService) {
this.netcfgService = netcfgService;
}
// FIXME Currently use thrift, may use gNMI to manage it in the future.
public void setupPorts(DeviceId deviceId) {
GeneralProviderDeviceConfig providerConfig = netcfgService
.getConfig(deviceId, GeneralProviderDeviceConfig.class);
PortDescriptionsConfig portConfig = netcfgService
.getConfig(deviceId, PortDescriptionsConfig.class);
Map<String, String> values = providerConfig.protocolsInfo()
.get(P4RUNTIME).configValues();
String ip = values.get(PROTOCOL_KEY_IP);
byte tofinoDeviceId = Byte.parseByte(values.get(DEVICE_ID));
List<PortDescription> ports = portConfig.portDescriptions();
if (ports == null) {
log.warn("Empty port configuration for {}, won't add any port", deviceId);
return;
}
ports.forEach(port -> {
pal_port_speed_t speed = getPortSpeed(port.portSpeed());
String anString = port.annotations().value(AUTONEG);
pal_autoneg_policy_t an = anString != null && parseBoolean(anString)
? pal_autoneg_policy_t.BF_AN_FORCE_ENABLE
: pal_autoneg_policy_t.BF_AN_FORCE_DISABLE;
addAndEnablePort(deviceId, port.portNumber().name(),
ip, tofinoDeviceId,
(int) port.portNumber().toLong(), speed,
DEFAULT_FEC_TYPE, an);
});
}
private pal_port_speed_t getPortSpeed(long speed) {
// Mbps -> BF_SPEED (1G~100G)
speed = speed / 1000;
if (speed >= 100) {
return pal_port_speed_t.BF_SPEED_100G;
}
if (speed >= 50) {
return pal_port_speed_t.BF_SPEED_50G;
}
if (speed >= 40) {
return pal_port_speed_t.BF_SPEED_40G;
}
if (speed >= 25) {
return pal_port_speed_t.BF_SPEED_25G;
}
if (speed >= 10) {
return pal_port_speed_t.BF_SPEED_10G;
}
return pal_port_speed_t.BF_SPEED_1G;
}
private void addAndEnablePort(DeviceId deviceId, String portName, String ip,
byte tofinoDeviceId,
int dp, pal_port_speed_t speed,
pal_fec_type_t fec,
pal_autoneg_policy_t an) {
log.info("Adding port {} to {}: dp={}, speed={}, an={}, fec={}",
portName, deviceId, dp, speed.name(), an.name(), fec.name());
TTransport transport = new TSocket(ip, PAL_MGMT_PORT);
try {
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
TMultiplexedProtocol mProtocol = new TMultiplexedProtocol(
protocol, PAL_THRIFT_SERVICE);
pal.Client client = new pal.Client(mProtocol);
client.pal_port_add(tofinoDeviceId, dp, speed, fec);
client.pal_port_an_set(tofinoDeviceId, dp, an);
client.pal_port_enable(tofinoDeviceId, dp);
} catch (TException x) {
log.error("Error adding port {} to device {}:\n{}",
dp, tofinoDeviceId, ip, x);
} finally {
if (transport.isOpen()) {
transport.close();
}
}
}
}