ONOS-7251 - Initial implementation of fabric.p4 L2 broadcast feature.

Thrift client cherry-picked from the commit dd5792ac9ee38a702c3128a34224852b5c284687

Change-Id: I989f2b2074485a892195889a7c976b518510da88
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2DeviceAgent.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2DeviceAgent.java
new file mode 100644
index 0000000..ac83038
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2DeviceAgent.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api;
+
+import org.onosproject.drivers.bmv2.api.runtime.Bmv2PreGroup;
+import org.onosproject.drivers.bmv2.api.runtime.Bmv2RuntimeException;
+import org.onosproject.net.DeviceId;
+
+import java.util.List;
+
+/**
+ * An agent to control a BMv2 device.
+ */
+public interface Bmv2DeviceAgent {
+
+    /**
+     * Returns the device ID of this agent.
+     *
+     * @return a device id
+     */
+    DeviceId deviceId();
+
+    /**
+     * Creates a multicast group and related entries atomically on a BMv2 device.
+     * If successful returns modified version of the group object that is filled with BMv2 switch-specific identifiers
+     * of the created group and nodes; throws Bmv2RuntimeException otherwise.
+     *
+     * @param preGroup Bmv2PreGroup
+     * @return modified version of preGroup param.
+     * @throws Bmv2RuntimeException if any error occurs
+     */
+    Bmv2PreGroup writePreGroup(Bmv2PreGroup preGroup) throws Bmv2RuntimeException;
+
+    /**
+     * Deletes a multicast group and all associated nodes from a BMV2 device.
+     *
+     * @param preGroup Bmv2PreGroup
+     * @throws Bmv2RuntimeException if any error occurs
+     */
+    void deletePreGroup(Bmv2PreGroup preGroup) throws Bmv2RuntimeException;
+
+    /**
+     * Returns all BMv2 PRE groups.
+     *
+     * @return list of PRE groups.
+     * @throws Bmv2RuntimeException if any error occurs
+     */
+    List<Bmv2PreGroup> getPreGroups() throws Bmv2RuntimeException;
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2PreController.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2PreController.java
new file mode 100644
index 0000000..b9d3910
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/Bmv2PreController.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.onosproject.drivers.bmv2.api;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * PRE Controller for BMv2 devices.
+ */
+public interface Bmv2PreController {
+
+    /**
+     * Creates a client to communicate with the PRE layer of a BMv2 device
+     * and associates it with the given device identifier.
+     * Returns true if the client was created and the channel to the device is open.
+     * If so, a {@link Bmv2DeviceAgent} can be later obtained by invoking {@link #getPreClient(DeviceId)}.
+     * Otherwise, returns false.
+     *
+     * @param deviceId         device identifier
+     * @param thriftServerIp   Thrift server address
+     * @param thriftServerPort Thrift server port
+     * @return true if the client was created and the channel to the device is open; false otherwise
+     * @throws IllegalStateException if a client already exists for the given device identifier
+     */
+    boolean createPreClient(DeviceId deviceId, String thriftServerIp, Integer thriftServerPort);
+
+    /**
+     * Returns the PRE client associated with the given device identifier, if any.
+     *
+     * @param deviceId device identifier
+     * @return client instance if a client has already been created; null otherwise
+     */
+    Bmv2DeviceAgent getPreClient(DeviceId deviceId);
+
+    /**
+     * Removes the PRE client associated with the given device identifier.
+     *
+     * @param deviceId device identifier
+     */
+    void removePreClient(DeviceId deviceId);
+
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/package-info.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/package-info.java
new file mode 100644
index 0000000..d96ec97
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * Package for BMv2 API.
+ */
+package org.onosproject.drivers.bmv2.api;
\ No newline at end of file
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Entity.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Entity.java
new file mode 100644
index 0000000..8412763
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Entity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+
+/**
+ * Abstraction of an entity of BMv2 that can be read or write
+ * at runtime.
+ */
+public interface Bmv2Entity {
+
+    /**
+     * Returns the type of this entity.
+     *
+     * @return entity type
+     */
+    Bmv2EntityType entityType();
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2EntityType.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2EntityType.java
new file mode 100644
index 0000000..e219024
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2EntityType.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+/**
+ * Type of runtime entity of BMv2.
+ */
+public enum Bmv2EntityType {
+
+    /**
+     * Indicates a multicast group.
+     */
+    PRE_GROUP
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Handle.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Handle.java
new file mode 100644
index 0000000..373b41b
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2Handle.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+import org.onosproject.net.DeviceId;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Global identifier of an entity applied to a BMv2 device.
+ * @param <E> an object extending Bmv2Entity
+ */
+public abstract class Bmv2Handle<E extends Bmv2Entity> {
+
+    private final DeviceId deviceId;
+    private final E bmv2Entity;
+
+    protected Bmv2Handle(DeviceId deviceId, E bmv2Entity) {
+        this.deviceId = checkNotNull(deviceId);
+        this.bmv2Entity = checkNotNull(bmv2Entity);
+    }
+
+    /**
+     * Returns the device ID of this handle.
+     *
+     * @return device ID
+     */
+    public final DeviceId deviceId() {
+        return deviceId;
+    }
+
+    /**
+     * Returns the type of entity identified by this handle.
+     *
+     * @return BMv2 entity type
+     */
+    public final Bmv2EntityType entityType() {
+        return bmv2Entity.entityType();
+    }
+
+    /**
+     * The entity to which this handle is associated.
+     *
+     * @return Bmv2 entity
+     */
+    public final E bmv2Entity() {
+        return bmv2Entity;
+    }
+
+    @Override
+    public abstract int hashCode();
+
+    @Override
+    public abstract boolean equals(Object obj);
+
+    @Override
+    public abstract String toString();
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroup.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroup.java
new file mode 100644
index 0000000..c0c4b5d
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroup.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of a multicast group in BMv2 PRE.
+ */
+public class Bmv2PreGroup implements Bmv2Entity {
+
+    private final Integer groupId;
+    private final Bmv2PreNodes nodes;
+    //internal device-level identifier used by BMv2
+    private Integer nativeGroupHandle;
+
+    public Bmv2PreGroup(Integer groupId, Bmv2PreNodes nodes) {
+        this.groupId = checkNotNull(groupId, "groupId argument can not be null");
+        this.nodes = checkNotNull(nodes, "nodes argument can not be null");
+    }
+
+    /**
+     * Returns a new builder of BMv2 PRE groups.
+     *
+     * @return a BMv2 PRE group builder
+     */
+    public static Bmv2PreGroupBuilder builder() {
+        return new Bmv2PreGroupBuilder();
+    }
+
+    public Integer groupId() {
+        return groupId;
+    }
+
+    public Integer nativeGroupHandle() {
+        return nativeGroupHandle;
+    }
+
+    public Bmv2PreNodes nodes() {
+        return nodes;
+    }
+
+    public void setNativeGroupHandle(Integer nativeGroupHandle) {
+        this.nativeGroupHandle = nativeGroupHandle;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(groupId, nodes, nativeGroupHandle);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final Bmv2PreGroup other = (Bmv2PreGroup) obj;
+        return Objects.equal(this.groupId, other.groupId)
+                && Objects.equal(this.nodes, other.nodes);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("groupId", groupId)
+                .add("nativeGroupHandle", nativeGroupHandle)
+                .add("nodes", nodes)
+                .toString();
+    }
+
+    @Override
+    public Bmv2EntityType entityType() {
+        return Bmv2EntityType.PRE_GROUP;
+    }
+
+    /**
+     * Builder of BMv2 PRE groups.
+     */
+    public static final class Bmv2PreGroupBuilder {
+        private Integer groupId;
+        private Set<Bmv2PreNode> nodes = Sets.newHashSet();
+
+        private Bmv2PreGroupBuilder() {
+            //hidden constructor
+        }
+
+        /**
+         * Sets the identifier of this group.
+         *
+         * @param groupId identifier of this BMv2 PRE group.
+         * @return this
+         */
+        public Bmv2PreGroupBuilder withGroupId(Integer groupId) {
+            this.groupId = groupId;
+            return this;
+        }
+
+        /**
+         * Adds a node to this group.
+         *
+         * @param node a BMv2 PRE node.
+         * @return this
+         */
+        public Bmv2PreGroupBuilder addNode(Bmv2PreNode node) {
+            nodes.add(node);
+            return this;
+        }
+
+        /**
+         * Creates a new BMv2 PRE group.
+         *
+         * @return a new BMv2 PRE group
+         */
+        public Bmv2PreGroup build() {
+            return new Bmv2PreGroup(groupId, new Bmv2PreNodes(ImmutableSet.copyOf(nodes)));
+        }
+    }
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroupHandle.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroupHandle.java
new file mode 100644
index 0000000..7e886bc
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreGroupHandle.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Global identifier of a BMv2 PRE group applied to a device, uniquely defined
+ * by a device ID and group ID.
+ */
+public final class Bmv2PreGroupHandle extends Bmv2Handle<Bmv2PreGroup> {
+
+    private Bmv2PreGroupHandle(DeviceId deviceId, Bmv2PreGroup group) {
+        super(deviceId, group);
+    }
+
+    /**
+     * Creates a new handle for the given device ID and BMv2 PRE group.
+     *
+     * @param deviceId device ID
+     * @param group    BMv2 PRE group
+     * @return BMv2 PRE group handle
+     */
+    public static Bmv2PreGroupHandle of(DeviceId deviceId,
+                                        Bmv2PreGroup group) {
+        return new Bmv2PreGroupHandle(deviceId, group);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(deviceId(),
+                                bmv2Entity().groupId());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Bmv2PreGroupHandle that = (Bmv2PreGroupHandle) o;
+        return Objects.equal(deviceId(), that.deviceId()) &&
+                Objects.equal(bmv2Entity().groupId(), that.bmv2Entity().groupId());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("deviceId", deviceId())
+                .add("groupId", bmv2Entity().groupId())
+                .toString();
+    }
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreJsonGroups.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreJsonGroups.java
new file mode 100644
index 0000000..83a6fa2
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreJsonGroups.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Represents mc group list retrieved from BMv2 PRE.
+ */
+public final class Bmv2PreJsonGroups {
+    public final L1Handle[] l1handles;
+    public final L2Handle[] l2handles;
+    public final Lag[] lags;
+    public final Mgrp[] mgrps;
+
+    @JsonCreator
+    public Bmv2PreJsonGroups(@JsonProperty("l1_handles") L1Handle[] l1handles,
+                             @JsonProperty("l2_handles") L2Handle[] l2handles,
+                             @JsonProperty("lags") Lag[] lags,
+                             @JsonProperty("mgrps") Mgrp[] mgrps) {
+        this.l1handles = l1handles;
+        this.l2handles = l2handles;
+        this.lags = lags;
+        this.mgrps = mgrps;
+    }
+
+    public static final class L1Handle {
+        public final int handle;
+        public final int l2handle;
+        public final int rid;
+
+        @JsonCreator
+        public L1Handle(@JsonProperty("handle") int handle,
+                        @JsonProperty("l2_handle") int l2handle,
+                        @JsonProperty("rid") int rid) {
+            this.handle = handle;
+            this.l2handle = l2handle;
+            this.rid = rid;
+        }
+    }
+
+    public static final class L2Handle {
+        public final int handle;
+        public final int[] lags;
+        public final int[] ports;
+
+        @JsonCreator
+        public L2Handle(@JsonProperty("handle") int handle,
+                        @JsonProperty("lags") int[] lags,
+                        @JsonProperty("ports") int[] ports) {
+            this.handle = handle;
+            this.lags = lags;
+            this.ports = ports;
+        }
+    }
+
+    public static final class Lag {
+        //lag is not used for now
+        @JsonCreator
+        public Lag() {
+        }
+    }
+
+    public static final class Mgrp {
+        public final int id;
+        public final int[] l1handles;
+
+        @JsonCreator
+        public Mgrp(@JsonProperty("id") int id, @JsonProperty("l1_handles") int[] l1handles) {
+            this.id = id;
+            this.l1handles = l1handles;
+        }
+    }
+}
+
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNode.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNode.java
new file mode 100644
index 0000000..3d50e50
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNode.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * The class that represents a multicast node in BMv2 PRE.
+ */
+public class Bmv2PreNode {
+    //replication id
+    private final Integer rid;
+    private final String portMap;
+    private Integer l1Handle;
+
+    public Bmv2PreNode(Integer rid, String portMap) {
+        this.rid = checkNotNull(rid, "rid argument can not be null");
+        this.portMap = checkNotNull(portMap, "portMap argument can not be null");
+    }
+
+    public static Bmv2PreNodeBuilder builder() {
+        return new Bmv2PreNodeBuilder();
+    }
+
+    public Integer rid() {
+        return rid;
+    }
+
+    public String portMap() {
+        return portMap;
+    }
+
+    public Integer l1Handle() {
+        return l1Handle;
+    }
+
+    public void setL1Handle(Integer l1Handle) {
+        this.l1Handle = l1Handle;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(rid, portMap, l1Handle);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final Bmv2PreNode other = (Bmv2PreNode) obj;
+        return Objects.equal(this.rid, other.rid)
+                && Objects.equal(this.portMap, other.portMap);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("rid", rid)
+                .add("portMap", portMap)
+                .add("l1Handle", l1Handle)
+                .toString();
+    }
+
+    public static final class Bmv2PreNodeBuilder {
+        //replication id
+        private Integer rid;
+        private String portMap;
+        private Integer l1Handle;
+
+        private Bmv2PreNodeBuilder() {
+        }
+
+        public Bmv2PreNodeBuilder withRid(Integer rid) {
+            this.rid = rid;
+            return this;
+        }
+
+        public Bmv2PreNodeBuilder withPortMap(String portMap) {
+            this.portMap = portMap;
+            return this;
+        }
+
+        public Bmv2PreNodeBuilder withL1Handle(Integer l1Handle) {
+            this.l1Handle = l1Handle;
+            return this;
+        }
+
+        public Bmv2PreNode build() {
+            Bmv2PreNode bmv2PreNode = new Bmv2PreNode(rid, portMap);
+            bmv2PreNode.setL1Handle(l1Handle);
+            return bmv2PreNode;
+        }
+    }
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNodes.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNodes.java
new file mode 100644
index 0000000..31edef1
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2PreNodes.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable collection of BMv2 PRE group nodes.
+ */
+public final class Bmv2PreNodes {
+    private final ImmutableSet<Bmv2PreNode> nodes;
+
+    /**
+     * Creates a immutable list of group nodes.
+     *
+     * @param nodes list of group nodes
+     */
+    public Bmv2PreNodes(ImmutableSet<Bmv2PreNode> nodes) {
+        this.nodes = checkNotNull(nodes);
+    }
+
+    public ImmutableSet<Bmv2PreNode> nodes() {
+        return nodes;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(nodes);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Bmv2PreNodes) {
+            return (this.nodes.containsAll(((Bmv2PreNodes) obj).nodes) &&
+                    ((Bmv2PreNodes) obj).nodes.containsAll(this.nodes));
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("nodes", nodes)
+                .toString();
+    }
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2RuntimeException.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2RuntimeException.java
new file mode 100644
index 0000000..fd61bcf
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/Bmv2RuntimeException.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.onosproject.drivers.bmv2.api.runtime;
+
+/**
+ * General exception of the BMv2 runtime APIs.
+ */
+public final class Bmv2RuntimeException extends Exception {
+
+    private final Code code;
+    private String codeString;
+
+    public Bmv2RuntimeException(String message) {
+        super(message);
+        this.code = Code.OTHER;
+        this.codeString = message;
+    }
+
+    public Bmv2RuntimeException(Throwable cause) {
+        super(cause);
+        this.code = Code.OTHER;
+        this.codeString = cause.toString();
+    }
+
+    public Bmv2RuntimeException(Code code) {
+        super(code.name());
+        this.code = code;
+    }
+
+    public Code getCode() {
+        return this.code;
+    }
+
+    public String explain() {
+        return (codeString == null) ? code.name() : code.name() + " " + codeString;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " " + explain();
+    }
+
+    /**
+     * Code of BMv2 error.
+     */
+    public enum Code {
+        /**
+         * Indicates table is full.
+         */
+        TABLE_FULL,
+        INVALID_MGID,
+        /**
+         * Indicates multicast group handle is invalid.
+         */
+        INVALID_MGRP_HANDLE,
+        /**
+         * Indicates l1 handle is not associated with a node.
+         */
+        INVALID_L1_HANDLE,
+        /**
+         * Indicates a general error.
+         */
+        MC_GENERAL_ERROR,
+        /**
+         * Indicates an unknown error.
+         */
+        MC_UNKNOWN_ERROR,
+        OTHER
+    }
+}
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/package-info.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/package-info.java
new file mode 100644
index 0000000..ef19b3a
--- /dev/null
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/api/runtime/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * Classes abstracting entities of BMv2.
+ */
+package org.onosproject.drivers.bmv2.api.runtime;
\ No newline at end of file