16 package org.openkilda.floodlight.switchmanager.web;
20 import com.google.common.collect.ImmutableList;
25 import org.projectfloodlight.openflow.protocol.OFActionType;
26 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
27 import org.projectfloodlight.openflow.protocol.OFInstructionType;
28 import org.projectfloodlight.openflow.protocol.action.OFAction;
29 import org.projectfloodlight.openflow.protocol.action.OFActionMeter;
30 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
31 import org.projectfloodlight.openflow.protocol.action.OFActionPushVlan;
32 import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
33 import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
34 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
35 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionMeter;
36 import org.projectfloodlight.openflow.protocol.match.Match;
37 import org.projectfloodlight.openflow.protocol.match.MatchField;
38 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
39 import org.projectfloodlight.openflow.types.DatapathId;
40 import org.projectfloodlight.openflow.types.OFValueType;
41 import org.restlet.resource.Get;
42 import org.restlet.resource.ServerResource;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 import java.util.HashMap;
47 import java.util.List;
49 import java.util.Objects;
50 import java.util.Optional;
53 private static final Logger LOGGER = LoggerFactory.getLogger(
FlowsResource.class);
55 private static final List<MatchField<? extends OFValueType>> KNOWN_MATCHES = ImmutableList.of(
56 MatchField.ETH_SRC, MatchField.ETH_DST, MatchField.IN_PORT, MatchField.VLAN_VID,
60 private Map<String, Object> buildFlowMatch(
final Match match) {
61 final Map<String, Object>
data =
new HashMap<>();
63 for (MatchField<? extends OFValueType> field : KNOWN_MATCHES) {
64 OFValueType
value = match.get(field);
65 if (Objects.nonNull(
value)) {
66 data.put(field.getName(),
value.toString());
72 private Map<String, Object> buildFlowInstructions(
final List<OFInstruction> instructions) {
73 Map<String, Object>
data =
new HashMap<>();
74 for (OFInstruction instruction : instructions) {
75 Map<String, Object> iData =
new HashMap<>();
76 OFInstructionType instructionType = instruction.getType();
77 switch (instructionType) {
79 for (OFAction action : ((OFInstructionApplyActions) instruction).getActions()) {
80 OFActionType actionType = action.getType();
83 iData.put(actionType.toString(), ((OFActionMeter) action).getMeterId());
86 Optional.ofNullable(((OFActionOutput) action).getPort())
87 .ifPresent(
port -> iData.put(actionType.toString(),
port.toString()));
90 iData.put(actionType.toString(), null);
93 Optional.ofNullable(((OFActionPushVlan) action).getEthertype())
94 .ifPresent(ethType -> iData.put(actionType.toString(), ethType.toString()));
97 OFOxm<?> setFieldAction = ((OFActionSetField) action).getField();
98 iData.put(actionType.toString(), String.format(
"%s->%s",
99 setFieldAction.getValue(), setFieldAction.getMatchField().getName()));
102 iData.put(actionType.toString(),
"could not parse");
108 OFInstructionMeter action = ((OFInstructionMeter) instruction);
109 iData.put(instructionType.toString(), action.getMeterId());
112 iData.put(instructionType.toString(),
"could not parse");
115 data.put(instruction.getType().name(), iData);
120 private Map<String, Object> buildFlowStat(
final OFFlowStatsEntry entry) {
121 Map<String, Object>
data =
new HashMap<>();
122 data.put(
"version", entry.getVersion());
123 data.put(
"duration-nsec", entry.getDurationNsec());
124 data.put(
"duration-sec", entry.getDurationSec());
125 data.put(
"hard-timeout", entry.getHardTimeout());
126 data.put(
"idle-timeout", entry.getIdleTimeout());
127 data.put(
"priority", entry.getPriority());
128 data.put(
"byte-count", entry.getByteCount().getValue());
129 data.put(
"packet-count", entry.getPacketCount().getValue());
130 data.put(
"flags", entry.getFlags());
131 data.put(
"cookie", Long.toHexString(entry.getCookie().getValue()));
132 data.put(
"table-id", entry.getTableId().getValue());
133 data.put(
"match", buildFlowMatch(entry.getMatch()));
134 data.put(
"instructions", buildFlowInstructions(entry.getInstructions()));
139 @SuppressWarnings(
"unchecked")
141 Map<String, Object> response =
new HashMap<>();
142 String switchId = (String) this.getRequestAttributes().get(
"switch_id");
143 LOGGER.debug(
"Get flows for switch: {}", switchId);
148 List<OFFlowStatsEntry> flowEntries = switchManager.
dumpFlowTable(DatapathId.of(switchId));
149 LOGGER.debug(
"OF_STATS: {}", flowEntries);
151 if (flowEntries != null) {
152 for (OFFlowStatsEntry entry : flowEntries) {
153 String key = String.format(
"flow-0x%s",
154 Long.toHexString(entry.getCookie().getValue()).toUpperCase());
155 response.put(key, buildFlowStat(entry));
158 }
catch (IllegalArgumentException exception) {
159 String messageString =
"No such switch";
160 LOGGER.error(
"{}: {}", messageString, switchId, exception);
163 response.putAll(MAPPER.convertValue(responseMessage, Map.class));
static final ObjectMapper MAPPER
List< OFFlowStatsEntry > dumpFlowTable(final DatapathId dpid)
Map< String, Object > getFlows()