Carmelo Cascone
Committed by Brian O'Connor

Various BMv2 bugfixes

Change-Id: Ia5a2a1c86b8a90ad68ddb92980377f6308e200d2
......@@ -64,6 +64,8 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import java.util.stream.Stream;
......@@ -87,7 +89,7 @@ public abstract class AbstractUpgradableFabricApp {
private static final int NUM_SPINES = 3;
private static final int FLOW_PRIORITY = 100;
private static final int CLEANUP_SLEEP = 1000;
private static final int CLEANUP_SLEEP = 2000;
protected final Logger log = getLogger(getClass());
......@@ -137,10 +139,11 @@ public abstract class AbstractUpgradableFabricApp {
private Set<DeviceId> spineSwitches;
private Map<DeviceId, List<FlowRule>> deviceFlowRules;
private Map<DeviceId, Bmv2DeviceContext> previousContexts;
private Map<DeviceId, Boolean> contextFlags;
private Map<DeviceId, Boolean> ruleFlags;
private ConcurrentMap<DeviceId, Boolean> deployLocks = Maps.newConcurrentMap();
private ConcurrentMap<DeviceId, Lock> deviceLocks = Maps.newConcurrentMap();
/**
* Creates a new BMv2 fabric app.
......@@ -270,7 +273,7 @@ public abstract class AbstractUpgradableFabricApp {
public abstract List<FlowRule> generateSpineRules(DeviceId deviceId, Collection<Host> dstHosts, Topology topology)
throws FlowRuleGeneratorException;
private void deployRoutine() {
private void deployAllDevices() {
if (otherAppFound && otherApp.appActive) {
log.info("Deactivating other app...");
appService.deactivate(otherApp.appId);
......@@ -297,9 +300,10 @@ public abstract class AbstractUpgradableFabricApp {
DeviceId deviceId = device.id();
// Synchronize executions over the same device.
deployLocks.putIfAbsent(deviceId, new Boolean(true));
synchronized (deployLocks.get(deviceId)) {
Lock lock = deviceLocks.computeIfAbsent(deviceId, k -> new ReentrantLock());
lock.lock();
try {
// Set context if not already done.
if (!contextFlags.getOrDefault(deviceId, false)) {
log.info("Setting context to {} for {}...", configurationName, deviceId);
......@@ -321,6 +325,8 @@ public abstract class AbstractUpgradableFabricApp {
ruleFlags.put(deviceId, true);
}
}
} finally {
lock.unlock();
}
}
......@@ -421,9 +427,9 @@ public abstract class AbstractUpgradableFabricApp {
ImmutableMap.Builder<DeviceId, List<FlowRule>> mapBuilder = ImmutableMap.builder();
concat(spines.stream(), leafs.stream())
.map(deviceId -> ImmutableList.copyOf(newFlowRules
.stream()
.filter(fr -> fr.deviceId().equals(deviceId))
.iterator()))
.stream()
.filter(fr -> fr.deviceId().equals(deviceId))
.iterator()))
.forEach(frs -> mapBuilder.put(frs.get(0).deviceId(), frs));
this.deviceFlowRules = mapBuilder.build();
......@@ -433,10 +439,9 @@ public abstract class AbstractUpgradableFabricApp {
// Avoid other executions to modify the generated flow rules.
flowRuleGenerated = true;
log.info("DONE! Generated {} flow rules for {} devices...", newFlowRules.size(), spines.size() + leafs.size());
log.info("Generated {} flow rules for {} devices", newFlowRules.size(), spines.size() + leafs.size());
// Deploy configuration.
spawnTask(this::deployRoutine);
spawnTask(this::deployAllDevices);
}
/**
......
/Users/carmelo/workspace/onos-p4-dev/p4src/build/ecmp.json
\ No newline at end of file
{
"header_types": [
{
"name": "standard_metadata_t",
"id": 0,
"fields": [
[
"ingress_port",
9
],
[
"packet_length",
32
],
[
"egress_spec",
9
],
[
"egress_port",
9
],
[
"egress_instance",
32
],
[
"instance_type",
32
],
[
"clone_spec",
32
],
[
"_padding",
5
]
],
"length_exp": null,
"max_length": null
},
{
"name": "intrinsic_metadata_t",
"id": 1,
"fields": [
[
"ingress_global_timestamp",
32
],
[
"lf_field_list",
32
],
[
"mcast_grp",
16
],
[
"egress_rid",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "ethernet_t",
"id": 2,
"fields": [
[
"dstAddr",
48
],
[
"srcAddr",
48
],
[
"etherType",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "ipv4_t",
"id": 3,
"fields": [
[
"version",
4
],
[
"ihl",
4
],
[
"diffserv",
8
],
[
"totalLen",
16
],
[
"identification",
16
],
[
"flags",
3
],
[
"fragOffset",
13
],
[
"ttl",
8
],
[
"protocol",
8
],
[
"hdrChecksum",
16
],
[
"srcAddr",
32
],
[
"dstAddr",
32
]
],
"length_exp": null,
"max_length": null
},
{
"name": "tcp_t",
"id": 4,
"fields": [
[
"srcPort",
16
],
[
"dstPort",
16
],
[
"seqNo",
32
],
[
"ackNo",
32
],
[
"dataOffset",
4
],
[
"res",
3
],
[
"ecn",
3
],
[
"ctrl",
6
],
[
"window",
16
],
[
"checksum",
16
],
[
"urgentPtr",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "udp_t",
"id": 5,
"fields": [
[
"srcPort",
16
],
[
"dstPort",
16
],
[
"length_",
16
],
[
"checksum",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "ecmp_metadata_t",
"id": 6,
"fields": [
[
"groupId",
16
],
[
"selector",
16
]
],
"length_exp": null,
"max_length": null
}
],
"headers": [
{
"name": "standard_metadata",
"id": 0,
"header_type": "standard_metadata_t",
"metadata": true
},
{
"name": "intrinsic_metadata",
"id": 1,
"header_type": "intrinsic_metadata_t",
"metadata": true
},
{
"name": "ethernet",
"id": 2,
"header_type": "ethernet_t",
"metadata": false
},
{
"name": "ipv4",
"id": 3,
"header_type": "ipv4_t",
"metadata": false
},
{
"name": "tcp",
"id": 4,
"header_type": "tcp_t",
"metadata": false
},
{
"name": "udp",
"id": 5,
"header_type": "udp_t",
"metadata": false
},
{
"name": "ecmp_metadata",
"id": 6,
"header_type": "ecmp_metadata_t",
"metadata": true
}
],
"header_stacks": [],
"parsers": [
{
"name": "parser",
"id": 0,
"init_state": "start",
"parse_states": [
{
"name": "start",
"id": 0,
"parser_ops": [],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": "parse_ethernet"
}
]
},
{
"name": "parse_ethernet",
"id": 1,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "ethernet"
}
]
}
],
"transition_key": [
{
"type": "field",
"value": [
"ethernet",
"etherType"
]
}
],
"transitions": [
{
"value": "0x0800",
"mask": null,
"next_state": "parse_ipv4"
},
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_ipv4",
"id": 2,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "ipv4"
}
]
}
],
"transition_key": [
{
"type": "field",
"value": [
"ipv4",
"fragOffset"
]
},
{
"type": "field",
"value": [
"ipv4",
"protocol"
]
}
],
"transitions": [
{
"value": "0x000006",
"mask": null,
"next_state": "parse_tcp"
},
{
"value": "0x000011",
"mask": null,
"next_state": "parse_udp"
},
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_tcp",
"id": 3,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "tcp"
}
]
}
],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_udp",
"id": 4,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "udp"
}
]
}
],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": null
}
]
}
]
}
],
"deparsers": [
{
"name": "deparser",
"id": 0,
"order": [
"ethernet",
"ipv4",
"udp",
"tcp"
]
}
],
"meter_arrays": [],
"actions": [
{
"name": "_drop",
"id": 0,
"runtime_data": [],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "hexstr",
"value": "0x1ff"
}
]
}
]
},
{
"name": "ecmp_group",
"id": 1,
"runtime_data": [
{
"name": "groupId",
"bitwidth": 16
},
{
"name": "groupSize",
"bitwidth": 16
}
],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"ecmp_metadata",
"groupId"
]
},
{
"type": "runtime_data",
"value": 0
}
]
},
{
"op": "modify_field_with_hash_based_offset",
"parameters": [
{
"type": "field",
"value": [
"ecmp_metadata",
"selector"
]
},
{
"type": "hexstr",
"value": "0x0"
},
{
"type": "calculation",
"value": "ecmp_hash"
},
{
"type": "runtime_data",
"value": 1
}
]
}
]
},
{
"name": "send_to_cpu",
"id": 2,
"runtime_data": [],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "hexstr",
"value": "0xff"
}
]
}
]
},
{
"name": "count_packet",
"id": 3,
"runtime_data": [],
"primitives": [
{
"op": "count",
"parameters": [
{
"type": "counter_array",
"value": "ingress_port_counter"
},
{
"type": "field",
"value": [
"standard_metadata",
"ingress_port"
]
}
]
},
{
"op": "count",
"parameters": [
{
"type": "counter_array",
"value": "egress_port_counter"
},
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
}
]
}
]
},
{
"name": "set_egress_port",
"id": 4,
"runtime_data": [
{
"name": "port",
"bitwidth": 9
}
],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "runtime_data",
"value": 0
}
]
}
]
}
],
"pipelines": [
{
"name": "ingress",
"id": 0,
"init_table": "table0",
"tables": [
{
"name": "port_count_table",
"id": 0,
"match_type": "exact",
"type": "simple",
"max_size": 16384,
"with_counters": false,
"direct_meters": null,
"support_timeout": false,
"key": [],
"actions": [
"count_packet"
],
"next_tables": {
"count_packet": null
},
"default_action": null,
"base_default_next": null
},
{
"name": "table0",
"id": 1,
"match_type": "ternary",
"type": "simple",
"max_size": 16384,
"with_counters": true,
"direct_meters": null,
"support_timeout": true,
"key": [
{
"match_type": "ternary",
"target": [
"standard_metadata",
"ingress_port"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"dstAddr"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"srcAddr"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"etherType"
],
"mask": null
}
],
"actions": [
"set_egress_port",
"ecmp_group",
"send_to_cpu",
"_drop"
],
"next_tables": {
"set_egress_port": "_condition_0",
"ecmp_group": "ecmp_group_table",
"send_to_cpu": "_condition_0",
"_drop": "_condition_0"
},
"default_action": null,
"base_default_next": "_condition_0"
},
{
"name": "ecmp_group_table",
"id": 2,
"match_type": "exact",
"type": "simple",
"max_size": 16384,
"with_counters": true,
"direct_meters": null,
"support_timeout": false,
"key": [
{
"match_type": "exact",
"target": [
"ecmp_metadata",
"groupId"
],
"mask": null
},
{
"match_type": "exact",
"target": [
"ecmp_metadata",
"selector"
],
"mask": null
}
],
"actions": [
"set_egress_port"
],
"next_tables": {
"set_egress_port": "_condition_0"
},
"default_action": null,
"base_default_next": "_condition_0"
}
],
"conditionals": [
{
"name": "_condition_0",
"id": 0,
"expression": {
"type": "expression",
"value": {
"op": "<",
"left": {
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
"right": {
"type": "hexstr",
"value": "0xfe"
}
}
},
"true_next": "port_count_table",
"false_next": null
}
]
},
{
"name": "egress",
"id": 1,
"init_table": null,
"tables": [],
"conditionals": []
}
],
"calculations": [
{
"name": "ecmp_hash",
"id": 0,
"input": [
{
"type": "field",
"value": [
"ipv4",
"srcAddr"
]
},
{
"type": "field",
"value": [
"ipv4",
"dstAddr"
]
},
{
"type": "field",
"value": [
"ipv4",
"protocol"
]
},
{
"type": "field",
"value": [
"tcp",
"srcPort"
]
},
{
"type": "field",
"value": [
"tcp",
"dstPort"
]
},
{
"type": "field",
"value": [
"udp",
"srcPort"
]
},
{
"type": "field",
"value": [
"udp",
"dstPort"
]
}
],
"algo": "bmv2_hash"
}
],
"checksums": [],
"learn_lists": [],
"field_lists": [],
"counter_arrays": [
{
"name": "ingress_port_counter",
"id": 0,
"is_direct": false,
"size": 254
},
{
"name": "egress_port_counter",
"id": 1,
"is_direct": false,
"size": 254
},
{
"name": "table0_counter",
"id": 2,
"is_direct": true,
"binding": "table0"
},
{
"name": "ecmp_group_table_counter",
"id": 3,
"is_direct": true,
"binding": "ecmp_group_table"
}
],
"register_arrays": [],
"force_arith": [
[
"standard_metadata",
"ingress_port"
],
[
"standard_metadata",
"packet_length"
],
[
"standard_metadata",
"egress_spec"
],
[
"standard_metadata",
"egress_port"
],
[
"standard_metadata",
"egress_instance"
],
[
"standard_metadata",
"instance_type"
],
[
"standard_metadata",
"clone_spec"
],
[
"standard_metadata",
"_padding"
],
[
"intrinsic_metadata",
"ingress_global_timestamp"
],
[
"intrinsic_metadata",
"lf_field_list"
],
[
"intrinsic_metadata",
"mcast_grp"
],
[
"intrinsic_metadata",
"egress_rid"
]
]
}
\ No newline at end of file
......@@ -105,7 +105,7 @@ public class WcmpFabricApp extends AbstractUpgradableFabricApp {
}
return true;
} catch (Bmv2RuntimeException e) {
log.error("Unable to init device {}: {}", deviceId, e.explain());
log.debug("Exception while initializing device {}: {}", deviceId, e.explain());
return false;
}
}
......
/Users/carmelo/workspace/onos-p4-dev/p4src/build/wcmp.json
\ No newline at end of file
{
"header_types": [
{
"name": "standard_metadata_t",
"id": 0,
"fields": [
[
"ingress_port",
9
],
[
"packet_length",
32
],
[
"egress_spec",
9
],
[
"egress_port",
9
],
[
"egress_instance",
32
],
[
"instance_type",
32
],
[
"clone_spec",
32
],
[
"_padding",
5
]
],
"length_exp": null,
"max_length": null
},
{
"name": "intrinsic_metadata_t",
"id": 1,
"fields": [
[
"ingress_global_timestamp",
32
],
[
"lf_field_list",
32
],
[
"mcast_grp",
16
],
[
"egress_rid",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "ethernet_t",
"id": 2,
"fields": [
[
"dstAddr",
48
],
[
"srcAddr",
48
],
[
"etherType",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "ipv4_t",
"id": 3,
"fields": [
[
"version",
4
],
[
"ihl",
4
],
[
"diffserv",
8
],
[
"totalLen",
16
],
[
"identification",
16
],
[
"flags",
3
],
[
"fragOffset",
13
],
[
"ttl",
8
],
[
"protocol",
8
],
[
"hdrChecksum",
16
],
[
"srcAddr",
32
],
[
"dstAddr",
32
]
],
"length_exp": null,
"max_length": null
},
{
"name": "tcp_t",
"id": 4,
"fields": [
[
"srcPort",
16
],
[
"dstPort",
16
],
[
"seqNo",
32
],
[
"ackNo",
32
],
[
"dataOffset",
4
],
[
"res",
3
],
[
"ecn",
3
],
[
"ctrl",
6
],
[
"window",
16
],
[
"checksum",
16
],
[
"urgentPtr",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "udp_t",
"id": 5,
"fields": [
[
"srcPort",
16
],
[
"dstPort",
16
],
[
"length_",
16
],
[
"checksum",
16
]
],
"length_exp": null,
"max_length": null
},
{
"name": "wcmp_meta_t",
"id": 6,
"fields": [
[
"groupId",
16
],
[
"numBits",
8
],
[
"selector",
64
]
],
"length_exp": null,
"max_length": null
}
],
"headers": [
{
"name": "standard_metadata",
"id": 0,
"header_type": "standard_metadata_t",
"metadata": true
},
{
"name": "intrinsic_metadata",
"id": 1,
"header_type": "intrinsic_metadata_t",
"metadata": true
},
{
"name": "ethernet",
"id": 2,
"header_type": "ethernet_t",
"metadata": false
},
{
"name": "ipv4",
"id": 3,
"header_type": "ipv4_t",
"metadata": false
},
{
"name": "tcp",
"id": 4,
"header_type": "tcp_t",
"metadata": false
},
{
"name": "udp",
"id": 5,
"header_type": "udp_t",
"metadata": false
},
{
"name": "wcmp_meta",
"id": 6,
"header_type": "wcmp_meta_t",
"metadata": true
}
],
"header_stacks": [],
"parsers": [
{
"name": "parser",
"id": 0,
"init_state": "start",
"parse_states": [
{
"name": "start",
"id": 0,
"parser_ops": [],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": "parse_ethernet"
}
]
},
{
"name": "parse_ethernet",
"id": 1,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "ethernet"
}
]
}
],
"transition_key": [
{
"type": "field",
"value": [
"ethernet",
"etherType"
]
}
],
"transitions": [
{
"value": "0x0800",
"mask": null,
"next_state": "parse_ipv4"
},
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_ipv4",
"id": 2,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "ipv4"
}
]
}
],
"transition_key": [
{
"type": "field",
"value": [
"ipv4",
"fragOffset"
]
},
{
"type": "field",
"value": [
"ipv4",
"protocol"
]
}
],
"transitions": [
{
"value": "0x000006",
"mask": null,
"next_state": "parse_tcp"
},
{
"value": "0x000011",
"mask": null,
"next_state": "parse_udp"
},
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_tcp",
"id": 3,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "tcp"
}
]
}
],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": null
}
]
},
{
"name": "parse_udp",
"id": 4,
"parser_ops": [
{
"op": "extract",
"parameters": [
{
"type": "regular",
"value": "udp"
}
]
}
],
"transition_key": [],
"transitions": [
{
"value": "default",
"mask": null,
"next_state": null
}
]
}
]
}
],
"deparsers": [
{
"name": "deparser",
"id": 0,
"order": [
"ethernet",
"ipv4",
"tcp",
"udp"
]
}
],
"meter_arrays": [],
"actions": [
{
"name": "set_egress_port",
"id": 0,
"runtime_data": [
{
"name": "port",
"bitwidth": 9
}
],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "runtime_data",
"value": 0
}
]
}
]
},
{
"name": "_drop",
"id": 1,
"runtime_data": [],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "hexstr",
"value": "0x1ff"
}
]
}
]
},
{
"name": "send_to_cpu",
"id": 2,
"runtime_data": [],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
{
"type": "hexstr",
"value": "0xff"
}
]
}
]
},
{
"name": "wcmp_group",
"id": 3,
"runtime_data": [
{
"name": "groupId",
"bitwidth": 16
}
],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"wcmp_meta",
"groupId"
]
},
{
"type": "runtime_data",
"value": 0
}
]
},
{
"op": "modify_field_with_hash_based_offset",
"parameters": [
{
"type": "field",
"value": [
"wcmp_meta",
"numBits"
]
},
{
"type": "hexstr",
"value": "0x2"
},
{
"type": "calculation",
"value": "wcmp_hash"
},
{
"type": "hexstr",
"value": "0x3e"
}
]
}
]
},
{
"name": "wcmp_set_selector",
"id": 4,
"runtime_data": [],
"primitives": [
{
"op": "modify_field",
"parameters": [
{
"type": "field",
"value": [
"wcmp_meta",
"selector"
]
},
{
"type": "expression",
"value": {
"type": "expression",
"value": {
"op": "<<",
"left": {
"type": "expression",
"value": {
"op": "-",
"left": {
"type": "expression",
"value": {
"op": "<<",
"left": {
"type": "hexstr",
"value": "0x1"
},
"right": {
"type": "field",
"value": [
"wcmp_meta",
"numBits"
]
}
}
},
"right": {
"type": "hexstr",
"value": "0x1"
}
}
},
"right": {
"type": "expression",
"value": {
"op": "-",
"left": {
"type": "hexstr",
"value": "0x40"
},
"right": {
"type": "field",
"value": [
"wcmp_meta",
"numBits"
]
}
}
}
}
}
}
]
}
]
},
{
"name": "count_packet",
"id": 5,
"runtime_data": [],
"primitives": [
{
"op": "count",
"parameters": [
{
"type": "counter_array",
"value": "ingress_port_counter"
},
{
"type": "field",
"value": [
"standard_metadata",
"ingress_port"
]
}
]
},
{
"op": "count",
"parameters": [
{
"type": "counter_array",
"value": "egress_port_counter"
},
{
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
}
]
}
]
}
],
"pipelines": [
{
"name": "ingress",
"id": 0,
"init_table": "table0",
"tables": [
{
"name": "port_count_table",
"id": 0,
"match_type": "exact",
"type": "simple",
"max_size": 16384,
"with_counters": false,
"direct_meters": null,
"support_timeout": false,
"key": [],
"actions": [
"count_packet"
],
"next_tables": {
"count_packet": null
},
"default_action": null,
"base_default_next": null
},
{
"name": "table0",
"id": 1,
"match_type": "ternary",
"type": "simple",
"max_size": 16384,
"with_counters": true,
"direct_meters": null,
"support_timeout": true,
"key": [
{
"match_type": "ternary",
"target": [
"standard_metadata",
"ingress_port"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"dstAddr"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"srcAddr"
],
"mask": null
},
{
"match_type": "ternary",
"target": [
"ethernet",
"etherType"
],
"mask": null
}
],
"actions": [
"set_egress_port",
"wcmp_group",
"send_to_cpu",
"_drop"
],
"next_tables": {
"set_egress_port": "_condition_0",
"wcmp_group": "wcmp_set_selector_table",
"send_to_cpu": "_condition_0",
"_drop": "_condition_0"
},
"default_action": null,
"base_default_next": "_condition_0"
},
{
"name": "wcmp_set_selector_table",
"id": 2,
"match_type": "exact",
"type": "simple",
"max_size": 16384,
"with_counters": false,
"direct_meters": null,
"support_timeout": false,
"key": [],
"actions": [
"wcmp_set_selector"
],
"next_tables": {
"wcmp_set_selector": "wcmp_group_table"
},
"default_action": null,
"base_default_next": "_condition_0"
},
{
"name": "wcmp_group_table",
"id": 3,
"match_type": "lpm",
"type": "simple",
"max_size": 16384,
"with_counters": true,
"direct_meters": null,
"support_timeout": false,
"key": [
{
"match_type": "exact",
"target": [
"wcmp_meta",
"groupId"
],
"mask": null
},
{
"match_type": "lpm",
"target": [
"wcmp_meta",
"selector"
],
"mask": null
}
],
"actions": [
"set_egress_port"
],
"next_tables": {
"set_egress_port": "_condition_0"
},
"default_action": null,
"base_default_next": "_condition_0"
}
],
"conditionals": [
{
"name": "_condition_0",
"id": 0,
"expression": {
"type": "expression",
"value": {
"op": "<",
"left": {
"type": "field",
"value": [
"standard_metadata",
"egress_spec"
]
},
"right": {
"type": "hexstr",
"value": "0xfe"
}
}
},
"true_next": "port_count_table",
"false_next": null
}
]
},
{
"name": "egress",
"id": 1,
"init_table": null,
"tables": [],
"conditionals": []
}
],
"calculations": [
{
"name": "wcmp_hash",
"id": 0,
"input": [
{
"type": "field",
"value": [
"ipv4",
"srcAddr"
]
},
{
"type": "field",
"value": [
"ipv4",
"dstAddr"
]
},
{
"type": "field",
"value": [
"ipv4",
"protocol"
]
},
{
"type": "field",
"value": [
"tcp",
"srcPort"
]
},
{
"type": "field",
"value": [
"tcp",
"dstPort"
]
},
{
"type": "field",
"value": [
"udp",
"srcPort"
]
},
{
"type": "field",
"value": [
"udp",
"dstPort"
]
}
],
"algo": "bmv2_hash"
}
],
"checksums": [],
"learn_lists": [],
"field_lists": [],
"counter_arrays": [
{
"name": "ingress_port_counter",
"id": 0,
"is_direct": false,
"size": 254
},
{
"name": "egress_port_counter",
"id": 1,
"is_direct": false,
"size": 254
},
{
"name": "table0_counter",
"id": 2,
"is_direct": true,
"binding": "table0"
},
{
"name": "wcmp_group_table_counter",
"id": 3,
"is_direct": true,
"binding": "wcmp_group_table"
}
],
"register_arrays": [],
"force_arith": [
[
"standard_metadata",
"ingress_port"
],
[
"standard_metadata",
"packet_length"
],
[
"standard_metadata",
"egress_spec"
],
[
"standard_metadata",
"egress_port"
],
[
"standard_metadata",
"egress_instance"
],
[
"standard_metadata",
"instance_type"
],
[
"standard_metadata",
"clone_spec"
],
[
"standard_metadata",
"_padding"
],
[
"intrinsic_metadata",
"ingress_global_timestamp"
],
[
"intrinsic_metadata",
"lf_field_list"
],
[
"intrinsic_metadata",
"mcast_grp"
],
[
"intrinsic_metadata",
"egress_rid"
]
]
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ package org.onosproject.drivers.bmv2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.onlab.osgi.ServiceNotFoundException;
import org.onlab.packet.ChassisId;
import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent;
import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
......@@ -54,12 +55,13 @@ public class Bmv2DeviceDescriptionDiscovery extends AbstractHandlerBehaviour imp
private Bmv2Controller controller;
private boolean init() {
controller = handler().get(Bmv2Controller.class);
if (controller == null) {
log.warn("Failed to get a BMv2 controller");
try {
controller = handler().get(Bmv2Controller.class);
return true;
} catch (ServiceNotFoundException e) {
log.warn(e.getMessage());
return false;
}
return true;
}
@Override
......
......@@ -19,6 +19,7 @@ package org.onosproject.drivers.bmv2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.tuple.Pair;
import org.onlab.osgi.ServiceNotFoundException;
import org.onosproject.bmv2.api.context.Bmv2Configuration;
import org.onosproject.bmv2.api.context.Bmv2DeviceContext;
import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator;
......@@ -70,22 +71,15 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour implement
private Bmv2DeviceContextService contextService;
private boolean init() {
controller = handler().get(Bmv2Controller.class);
tableEntryService = handler().get(Bmv2TableEntryService.class);
contextService = handler().get(Bmv2DeviceContextService.class);
if (controller == null) {
log.warn("Failed to get a BMv2 controller");
return false;
}
if (tableEntryService == null) {
log.warn("Failed to get a BMv2 table entry service");
return false;
}
if (contextService == null) {
log.warn("Failed to get a BMv2 device context service");
try {
controller = handler().get(Bmv2Controller.class);
tableEntryService = handler().get(Bmv2TableEntryService.class);
contextService = handler().get(Bmv2DeviceContextService.class);
return true;
} catch (ServiceNotFoundException e) {
log.warn(e.getMessage());
return false;
}
return true;
}
@Override
......@@ -140,9 +134,14 @@ public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour implement
Bmv2FlowRuleWrapper frWrapper = tableEntryService.lookup(entryRef);
if (frWrapper == null) {
log.warn("missing reference from table entry service, BUG? " +
log.debug("Missing reference from table entry service. Deleting it. BUG? " +
"deviceId={}, tableName={}, matchKey={}",
deviceId, table.name(), entryRef.matchKey());
try {
doRemove(deviceAgent, table.name(), parsedEntry.entryId(), parsedEntry.matchKey());
} catch (Bmv2RuntimeException e) {
log.warn("Unable to remove inconsistent flow rule: {}", e.explain());
}
continue; // next entry
}
......
......@@ -16,6 +16,7 @@
package org.onosproject.drivers.bmv2;
import org.onlab.osgi.ServiceNotFoundException;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent;
import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException;
......@@ -78,9 +79,11 @@ public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements
DeviceId deviceId = handler().data().deviceId();
Bmv2Controller controller = handler().get(Bmv2Controller.class);
if (controller == null) {
log.error("Failed to get BMv2 controller");
Bmv2Controller controller;
try {
controller = handler().get(Bmv2Controller.class);
} catch (ServiceNotFoundException e) {
log.warn(e.getMessage());
return;
}
......
......@@ -189,16 +189,17 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
(!Objects.equals(thisDescription, lastDescription) ||
!Objects.equals(thisDescription.annotations(), lastDescription.annotations()));
if (descriptionChanged || !deviceService.isAvailable(did)) {
if (contextService.getContext(did) == null) {
if (deviceService.getDevice(did) == null) {
// Device is a first timer.
log.info("Setting DEFAULT context for {}", did);
// It is important to do this before connecting the device so other
// services won't find a null context.
contextService.setContext(did, contextService.defaultContext());
} else {
resetDeviceState(did);
initPortCounters(did);
providerService.deviceConnected(did, thisDescription);
updatePortsAndStats(did);
}
resetDeviceState(did);
initPortCounters(did);
providerService.deviceConnected(did, thisDescription);
updatePortsAndStats(did);
}
return thisDescription;
} else {
......@@ -272,7 +273,7 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
if (deviceService.isAvailable(did)) {
providerService.deviceDisconnected(did);
}
activeDevices.put(did, null);
activeDevices.remove(did);
}
/**
......@@ -333,7 +334,7 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
}
/**
* Task that periodically trigger device probes to check for device status and update port informations.
* Task that periodically trigger device probes to check for device status and update port information.
*/
private class DevicePoller implements TimerTask {
......