blob: 13f27e61c24cfffafd1056f6f4461bacb6dac8dc [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;
26import org.onosproject.net.flow.TrafficTreatment;
27import org.onosproject.net.flow.criteria.Criterion;
28import org.onosproject.net.flow.instructions.Instruction;
29import org.onosproject.net.flow.instructions.Instructions;
30
31import java.io.BufferedReader;
32import java.io.IOException;
33import java.io.InputStream;
34import java.io.InputStreamReader;
35import java.util.Map;
36
37/**
38 * Implementation of a Bmv2 flow rule translator configuration for the
39 * simple_pipeline.p4 model.
40 */
41@Beta
42public class Bmv2SimplePipelineTranslatorConfig implements Bmv2FlowRuleTranslator.TranslatorConfig {
43
44 private static final String JSON_CONFIG_PATH = "/simple_pipeline.json";
45 private final Map<String, Criterion.Type> fieldMap = Maps.newHashMap();
46 private final Bmv2Model model;
47
48 /**
49 * Creates a new simple pipeline translator configuration.
50 */
51 public Bmv2SimplePipelineTranslatorConfig() {
52
53 this.model = getModel();
54
55 // populate fieldMap
56 fieldMap.put("standard_metadata.ingress_port", Criterion.Type.IN_PORT);
57 fieldMap.put("ethernet.dstAddr", Criterion.Type.ETH_DST);
58 fieldMap.put("ethernet.srcAddr", Criterion.Type.ETH_SRC);
59 fieldMap.put("ethernet.etherType", Criterion.Type.ETH_TYPE);
60 }
61
62 private static Bmv2Action buildDropAction() {
63 return Bmv2Action.builder()
64 .withName("_drop")
65 .build();
66 }
67
68 private static Bmv2Action buildFwdAction(Instructions.OutputInstruction inst)
69 throws Bmv2FlowRuleTranslatorException {
70
71 Bmv2Action.Builder actionBuilder = Bmv2Action.builder();
72
73 actionBuilder.withName("fwd");
74
75 if (inst.port().isLogical()) {
76 throw new Bmv2FlowRuleTranslatorException(
77 "Output logic port numbers not supported: " + inst);
78 }
79
80 actionBuilder.addParameter(
81 ImmutableByteSequence.copyFrom((short) inst.port().toLong()));
82
83 return actionBuilder.build();
84 }
85
86 private static Bmv2Model getModel() {
87 InputStream inputStream = Bmv2SimplePipelineTranslatorConfig.class
88 .getResourceAsStream(JSON_CONFIG_PATH);
89 InputStreamReader reader = new InputStreamReader(inputStream);
90 BufferedReader bufReader = new BufferedReader(reader);
91 JsonObject json = null;
92 try {
93 json = Json.parse(bufReader).asObject();
94 } catch (IOException e) {
95 throw new RuntimeException("Unable to parse JSON file: " + e.getMessage());
96 }
97
98 return Bmv2Model.parse(json);
99 }
100
101 @Override
102 public Bmv2Model model() {
103 return this.model;
104 }
105
106 @Override
107 public Map<String, Criterion.Type> fieldToCriterionTypeMap() {
108 return fieldMap;
109 }
110
111 @Override
112 public Bmv2Action buildAction(TrafficTreatment treatment)
113 throws Bmv2FlowRuleTranslatorException {
114
115
116 if (treatment.allInstructions().size() == 0) {
117 // no instructions means drop
118 return buildDropAction();
119 } else if (treatment.allInstructions().size() > 1) {
120 // otherwise, we understand treatments with only 1 instruction
121 throw new Bmv2FlowRuleTranslatorException(
122 "Treatment not supported, more than 1 instructions found: "
123 + treatment.toString());
124 }
125
126 Instruction instruction = treatment.allInstructions().get(0);
127
128 switch (instruction.type()) {
129 case OUTPUT:
130 return buildFwdAction((Instructions.OutputInstruction) instruction);
131 case NOACTION:
132 return buildDropAction();
133 default:
134 throw new Bmv2FlowRuleTranslatorException(
135 "Instruction type not supported: "
136 + instruction.type().name());
137 }
138 }
139}