blob: 565c1e4ec52f0656069908eddf40e5a9f917a5ff [file] [log] [blame]
Carmelo Casconeb7388bd2016-04-14 10:20:13 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.drivers.bmv2.translators;
18
19import com.eclipsesource.json.Json;
20import com.eclipsesource.json.JsonObject;
21import com.google.common.annotations.Beta;
22import com.google.common.collect.Maps;
23import org.onlab.util.ImmutableByteSequence;
24import org.onosproject.bmv2.api.model.Bmv2Model;
25import org.onosproject.bmv2.api.runtime.Bmv2Action;
Carmelo Casconee9121642016-04-27 17:02:38 -070026import org.onosproject.net.PortNumber;
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070027import org.onosproject.net.flow.TrafficTreatment;
28import org.onosproject.net.flow.criteria.Criterion;
29import org.onosproject.net.flow.instructions.Instruction;
30import org.onosproject.net.flow.instructions.Instructions;
31
32import java.io.BufferedReader;
33import java.io.IOException;
34import java.io.InputStream;
35import java.io.InputStreamReader;
36import java.util.Map;
37
38/**
39 * Implementation of a Bmv2 flow rule translator configuration for the
Carmelo Casconee9121642016-04-27 17:02:38 -070040 * simple.p4 model.
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070041 */
42@Beta
Carmelo Casconee9121642016-04-27 17:02:38 -070043public class Bmv2SimpleTranslatorConfig implements Bmv2FlowRuleTranslator.TranslatorConfig {
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070044
Carmelo Casconee9121642016-04-27 17:02:38 -070045 private static final String JSON_CONFIG_PATH = "/simple.json";
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070046 private final Map<String, Criterion.Type> fieldMap = Maps.newHashMap();
47 private final Bmv2Model model;
48
49 /**
50 * Creates a new simple pipeline translator configuration.
51 */
Carmelo Casconee9121642016-04-27 17:02:38 -070052 public Bmv2SimpleTranslatorConfig() {
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070053
54 this.model = getModel();
55
56 // populate fieldMap
57 fieldMap.put("standard_metadata.ingress_port", Criterion.Type.IN_PORT);
58 fieldMap.put("ethernet.dstAddr", Criterion.Type.ETH_DST);
59 fieldMap.put("ethernet.srcAddr", Criterion.Type.ETH_SRC);
60 fieldMap.put("ethernet.etherType", Criterion.Type.ETH_TYPE);
61 }
62
63 private static Bmv2Action buildDropAction() {
64 return Bmv2Action.builder()
65 .withName("_drop")
66 .build();
67 }
68
Carmelo Casconee9121642016-04-27 17:02:38 -070069 private static Bmv2Action buildPushToCpAction() {
70 return Bmv2Action.builder()
71 .withName("send_to_cpu")
72 .build();
73 }
74
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070075 private static Bmv2Action buildFwdAction(Instructions.OutputInstruction inst)
76 throws Bmv2FlowRuleTranslatorException {
77
78 Bmv2Action.Builder actionBuilder = Bmv2Action.builder();
79
80 actionBuilder.withName("fwd");
81
82 if (inst.port().isLogical()) {
Carmelo Casconee9121642016-04-27 17:02:38 -070083 if (inst.port() == PortNumber.CONTROLLER) {
84 return buildPushToCpAction();
85 } else {
86 throw new Bmv2FlowRuleTranslatorException(
87 "Output logic port number not supported: " + inst);
88 }
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070089 }
90
91 actionBuilder.addParameter(
92 ImmutableByteSequence.copyFrom((short) inst.port().toLong()));
93
94 return actionBuilder.build();
95 }
96
97 private static Bmv2Model getModel() {
Carmelo Casconee9121642016-04-27 17:02:38 -070098 InputStream inputStream = Bmv2SimpleTranslatorConfig.class
Carmelo Casconeb7388bd2016-04-14 10:20:13 -070099 .getResourceAsStream(JSON_CONFIG_PATH);
100 InputStreamReader reader = new InputStreamReader(inputStream);
101 BufferedReader bufReader = new BufferedReader(reader);
102 JsonObject json = null;
103 try {
104 json = Json.parse(bufReader).asObject();
105 } catch (IOException e) {
106 throw new RuntimeException("Unable to parse JSON file: " + e.getMessage());
107 }
108
109 return Bmv2Model.parse(json);
110 }
111
112 @Override
113 public Bmv2Model model() {
114 return this.model;
115 }
116
117 @Override
118 public Map<String, Criterion.Type> fieldToCriterionTypeMap() {
119 return fieldMap;
120 }
121
122 @Override
123 public Bmv2Action buildAction(TrafficTreatment treatment)
124 throws Bmv2FlowRuleTranslatorException {
125
126
127 if (treatment.allInstructions().size() == 0) {
128 // no instructions means drop
129 return buildDropAction();
130 } else if (treatment.allInstructions().size() > 1) {
131 // otherwise, we understand treatments with only 1 instruction
132 throw new Bmv2FlowRuleTranslatorException(
133 "Treatment not supported, more than 1 instructions found: "
134 + treatment.toString());
135 }
136
137 Instruction instruction = treatment.allInstructions().get(0);
138
139 switch (instruction.type()) {
140 case OUTPUT:
141 return buildFwdAction((Instructions.OutputInstruction) instruction);
142 case NOACTION:
143 return buildDropAction();
144 default:
145 throw new Bmv2FlowRuleTranslatorException(
146 "Instruction type not supported: "
147 + instruction.type().name());
148 }
149 }
150}