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 4d940e6c66..66ac4fcd21 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.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 spineSwitches; private Map> deviceFlowRules; + private Map previousContexts; private Map contextFlags; private Map ruleFlags; - private ConcurrentMap deployLocks = Maps.newConcurrentMap(); + private ConcurrentMap deviceLocks = Maps.newConcurrentMap(); /** * Creates a new BMv2 fabric app. @@ -270,7 +273,7 @@ public abstract class AbstractUpgradableFabricApp { public abstract List generateSpineRules(DeviceId deviceId, Collection 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> 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); } /** 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 acdff05303..0000000000 --- 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 0000000000..5bf2d4a95c --- /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 f86e5f967f..2d47afbdea 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 @@ 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; } } 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 ede290e8e7..0000000000 --- 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 0000000000..1dd6c025dc --- /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 2ed71e290c..29543bfe02 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 @@ 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 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 ce93422327..d8fed8a16a 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 @@ 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"); + 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 @@ 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 } 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 7131475dd9..e04d8757cd 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 @@ 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; } 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 2f30f06f17..fda7aadef4 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 @@ 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 {