-
Notifications
You must be signed in to change notification settings - Fork 15
/
FabricCapabilities.java
138 lines (122 loc) · 4.81 KB
/
FabricCapabilities.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2018-present Open Networking Foundation
// SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
package org.stratumproject.fabric.tna.behaviour;
import org.onosproject.net.pi.model.PiPipeconf;
import org.slf4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Optional;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.CPU_PORT_TXT;
import static org.slf4j.LoggerFactory.getLogger;
import static org.stratumproject.fabric.tna.behaviour.P4InfoConstants.FABRIC_INGRESS_SPGW_DOWNLINK_PDRS;
/**
* Representation of the capabilities of a given fabric-tna pipeconf.
*/
public class FabricCapabilities {
private static final String MAVERICKS = "mavericks";
private static final String MONTARA = "montara";
private final Logger log = getLogger(getClass());
private final PiPipeconf pipeconf;
public FabricCapabilities(PiPipeconf pipeconf) {
this.pipeconf = checkNotNull(pipeconf);
}
public int hwPipeCount() {
// FIXME: use chip type (or platform name) when Stratum will support
// reading that via gNMI. Until then, we need to rely on the
// pipeconf name (which prevents us from using chip-independent
// pipeconfs).
final var id = pipeconf.id().toString();
if (id.contains(MONTARA)) {
return 2;
} else if (id.contains(MAVERICKS)) {
return 4;
} else {
log.error("Unable to derive HW pipe count from pipeconf ID: {}", id);
return 0;
}
}
public boolean hasHashedTable() {
return pipeconf.pipelineModel()
.table(P4InfoConstants.FABRIC_INGRESS_NEXT_HASHED).isPresent();
}
public Optional<Integer> cpuPort() {
// This is probably brittle, but needed to dynamically get the CPU port
// for different platforms.
if (pipeconf.extension(CPU_PORT_TXT).isEmpty()) {
log.warn("Missing {} extension in pipeconf {}", CPU_PORT_TXT, pipeconf.id());
return Optional.empty();
}
try {
final InputStream stream = pipeconf.extension(CPU_PORT_TXT).get();
final BufferedReader buff = new BufferedReader(
new InputStreamReader(stream));
final String str = buff.readLine();
buff.close();
if (str == null) {
log.error("Empty CPU port file for {}", pipeconf.id());
return Optional.empty();
}
try {
return Optional.of(Integer.parseInt(str));
} catch (NumberFormatException e) {
log.error("Invalid CPU port for {}: {}", pipeconf.id(), str);
return Optional.empty();
}
} catch (IOException e) {
log.error("Unable to read CPU port file of {}: {}",
pipeconf.id(), e.getMessage());
return Optional.empty();
}
}
/**
* Returns true if the pipeconf supports UPF capabilities, false otherwise.
*
* @return boolean
*/
public boolean supportUpf() {
return pipeconf.pipelineModel()
.table(FABRIC_INGRESS_SPGW_DOWNLINK_PDRS)
.isPresent();
}
public boolean supportDoubleVlanTerm() {
// TODO: re-enable support for double-vlan
// FIXME: next_vlan has been moved to pre_next
// if (pipeconf.pipelineModel()
// .table(P4InfoConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN).isPresent()) {
// return pipeconf.pipelineModel().table(P4InfoConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN)
// .get().action(P4InfoConstants.FABRIC_INGRESS_NEXT_SET_DOUBLE_VLAN)
// .isPresent();
// }
return false;
}
// TODO: add fabric-bng profile
// /**
// * Returns true if the pipeconf supports BNG user plane capabilities, false
// * otherwise.
// *
// * @return boolean
// */
// public boolean supportBng() {
// return pipeconf.pipelineModel()
// .counter(P4InfoConstants.FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_C_LINE_RX)
// .isPresent();
// }
// TODO: add fabric-bng profile
// /**
// * Returns the maximum number of BNG lines supported, or 0 if this pipeconf
// * does not support BNG capabilities.
// *
// * @return maximum number of lines supported
// */
// public long bngMaxLineCount() {
// if (!supportBng()) {
// return 0;
// }
// return pipeconf.pipelineModel()
// .counter(P4InfoConstants.FABRIC_INGRESS_BNG_INGRESS_DOWNSTREAM_C_LINE_RX)
// .orElseThrow().size();
// }
}