Various BMv2 bugfixes
Change-Id: Ia5a2a1c86b8a90ad68ddb92980377f6308e200d2
diff --git a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java b/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java
index 4d940e6..66ac4fc 100644
--- a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java
+++ b/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java
@@ -64,6 +64,8 @@
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 @@
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 @@
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 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 @@
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 @@
ruleFlags.put(deviceId, true);
}
}
+ } finally {
+ lock.unlock();
}
}
@@ -421,9 +427,9 @@
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 @@
// 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);
}
/**
diff --git a/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json b/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json
deleted file mode 120000
index acdff05..0000000
--- a/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json
+++ /dev/null
@@ -1 +0,0 @@
-/Users/carmelo/workspace/onos-p4-dev/p4src/build/ecmp.json
\ No newline at end of file
diff --git a/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json b/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json
new file mode 100644
index 0000000..5bf2d4a
--- /dev/null
+++ b/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json
@@ -0,0 +1,909 @@
+{
+ "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
diff --git a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java b/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java
index f86e5f9..2d47afb 100644
--- a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java
+++ b/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java
@@ -105,7 +105,7 @@
}
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;
}
}
diff --git a/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json b/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json
deleted file mode 120000
index ede290e..0000000
--- a/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json
+++ /dev/null
@@ -1 +0,0 @@
-/Users/carmelo/workspace/onos-p4-dev/p4src/build/wcmp.json
\ No newline at end of file
diff --git a/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json b/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json
new file mode 100644
index 0000000..1dd6c02
--- /dev/null
+++ b/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json
@@ -0,0 +1,1000 @@
+{
+ "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
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java
index 2ed71e2..29543bf 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java
@@ -18,6 +18,7 @@
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 @@
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
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java
index ce93422..d8fed8a 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java
@@ -19,6 +19,7 @@
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 @@
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");
+ 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;
}
- 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");
- return false;
- }
- return true;
}
@Override
@@ -140,9 +134,14 @@
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
}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java
index 7131475..e04d875 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java
@@ -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 @@
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;
}
diff --git a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java
index 2f30f06..fda7aad 100644
--- a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java
+++ b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java
@@ -189,16 +189,17 @@
(!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 @@
if (deviceService.isAvailable(did)) {
providerService.deviceDisconnected(did);
}
- activeDevices.put(did, null);
+ activeDevices.remove(did);
}
/**
@@ -333,7 +334,7 @@
}
/**
- * 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 {