| /* |
| * 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.pipelines.fabric.pro; |
| |
| import com.google.common.collect.ImmutableList; |
| import org.apache.felix.scr.annotations.Activate; |
| import org.apache.felix.scr.annotations.Component; |
| import org.apache.felix.scr.annotations.Deactivate; |
| import org.apache.felix.scr.annotations.Reference; |
| import org.apache.felix.scr.annotations.ReferenceCardinality; |
| import org.onosproject.net.behaviour.Pipeliner; |
| import org.onosproject.net.device.PortStatisticsDiscovery; |
| import org.onosproject.net.pi.model.DefaultPiPipeconf; |
| import org.onosproject.net.pi.model.PiPipeconf; |
| import org.onosproject.net.pi.model.PiPipeconfId; |
| import org.onosproject.net.pi.model.PiPipelineInterpreter; |
| import org.onosproject.net.pi.model.PiPipelineModel; |
| import org.onosproject.net.pi.service.PiPipeconfService; |
| import org.onosproject.p4runtime.model.P4InfoParser; |
| import org.onosproject.p4runtime.model.P4InfoParserException; |
| import org.onosproject.pipelines.fabric.FabricInterpreter; |
| import org.onosproject.pipelines.fabric.FabricPortStatisticsDiscovery; |
| import org.onosproject.pipelines.fabric.pipeliner.FabricPipeliner; |
| |
| import java.net.URL; |
| import java.util.Collection; |
| |
| import static java.lang.String.format; |
| import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.P4_INFO_TEXT; |
| import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.TOFINO_BIN; |
| import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.TOFINO_CONTEXT_JSON; |
| import static org.onosproject.pipelines.fabric.PipeconfLoader.FABRIC_PIPECONF_ID; |
| |
| /** |
| * Pipeline config loader for fabric pipeline. |
| */ |
| @Component(immediate = true) |
| public class HwPipeconfLoader { |
| |
| private static final String MAVERICKS = "mavericks"; |
| private static final String MONTARA = "montara"; |
| |
| private static final String PLAIN_FABRIC = ""; |
| private static final String WITH_SPGW = "-spgw"; |
| |
| // TODO: add WITH_SPGW when ready |
| private static final Collection<String> APPENDICES = ImmutableList |
| .of(PLAIN_FABRIC, WITH_SPGW); |
| |
| private static final Collection<String> PLATFORMS = ImmutableList |
| .of(MAVERICKS, MONTARA); |
| |
| private static final String BASE_PATH = "/p4c-out/tofino/fabric%s/%s"; |
| private static final String BASE_TOFINO_BIN_PATH = BASE_PATH + "/tofino.bin"; |
| private static final String BASE_CONTEXT_JSON_PATH = BASE_PATH + "/context.json"; |
| private static final String BASE_P4INFO_PATH = BASE_PATH + "/fabric.p4info"; |
| |
| private static final Collection<PiPipeconf> ALL_PIPECONFS = buildAll(); |
| |
| @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| private PiPipeconfService piPipeconfService; |
| |
| @Activate |
| public void activate() { |
| // Registers all pipeconf at component activation. |
| ALL_PIPECONFS.forEach(piPipeconfService::register); |
| } |
| |
| @Deactivate |
| public void deactivate() { |
| ALL_PIPECONFS.stream().map(PiPipeconf::id).forEach(piPipeconfService::remove); |
| } |
| |
| private static PiPipeconf buildTofinoPipeconf(String platform, String appendix) { |
| final PiPipeconfId pipeconfId = new PiPipeconfId( |
| FABRIC_PIPECONF_ID.id() + appendix + "." + platform); |
| final URL tofinoBinUrl = HwPipeconfLoader.class |
| .getResource(format(BASE_TOFINO_BIN_PATH, appendix, platform)); |
| final URL contextJsonUrl = HwPipeconfLoader.class |
| .getResource(format(BASE_CONTEXT_JSON_PATH, appendix, platform)); |
| final URL p4InfoUrl = HwPipeconfLoader.class |
| .getResource(format(BASE_P4INFO_PATH, appendix, platform)); |
| |
| final PiPipelineModel model = parseP4Info(p4InfoUrl); |
| return DefaultPiPipeconf.builder() |
| .withId(pipeconfId) |
| .withPipelineModel(model) |
| .addBehaviour(PiPipelineInterpreter.class, FabricInterpreter.class) |
| .addBehaviour(Pipeliner.class, FabricPipeliner.class) |
| .addBehaviour(PortStatisticsDiscovery.class, FabricPortStatisticsDiscovery.class) |
| .addExtension(P4_INFO_TEXT, p4InfoUrl) |
| .addExtension(TOFINO_BIN, tofinoBinUrl) |
| .addExtension(TOFINO_CONTEXT_JSON, contextJsonUrl) |
| .build(); |
| } |
| |
| private static Collection<PiPipeconf> buildAll() { |
| ImmutableList.Builder<PiPipeconf> builder = ImmutableList.builder(); |
| for (String platform : PLATFORMS) { |
| for (String appendix : APPENDICES) { |
| builder.add(buildTofinoPipeconf(platform, appendix)); |
| } |
| } |
| return builder.build(); |
| } |
| |
| private static PiPipelineModel parseP4Info(URL p4InfoUrl) { |
| try { |
| return P4InfoParser.parse(p4InfoUrl); |
| } catch (P4InfoParserException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| } |