diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java
new file mode 100644
index 0000000..ee94628
--- /dev/null
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/Interface.java
@@ -0,0 +1,1024 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.ovsdb.rfc.table;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.tableservice.AbstractOvsdbTableService;
+import org.onosproject.ovsdb.rfc.tableservice.ColumnDescription;
+
+/**
+ * This class provides operations of Interface Table.
+ */
+public class Interface extends AbstractOvsdbTableService {
+
+    /**
+     * Interface table column name.
+     */
+    public enum InterfaceColumn {
+        NAME("name"), TYPE("type"), OPTIONS("options"),
+        INGRESSPOLICINGRATE("ingress_policing_rate"),
+        INGRESSPOLICINGBURST("ingress_policing_burst"), MACINUSE("mac_in_use"),
+        MAC("mac"), IFINDEX("ifindex"), EXTERNALIDS("external_ids"),
+        OFPORT("ofport"), OFPORTREQUEST("ofport_request"), BFD("bfd"),
+        BFDSTATUS("bfd_status"), MONITOR("monitor"), CFMMPID("cfm_mpid"),
+        CFMREMOTEMPID("cfm_remote_mpid"), CFMREMOTEMPIDS("cfm_remote_mpids"),
+        CFMFLAPCOUNT("cfm_flap_count"), CFMFAULT("cfm_fault"),
+        CFMFAULTSTATUS("cfm_fault_status"),
+        CFMREMOTEOPSTATE("cfm_remote_opstate"), CFMHEALTH("cfm_health"),
+        LACPCURRENT("lacp_current"), OTHERCONFIG("other_config"),
+        STATISTICS("statistics"), STATUS("status"), ADMINSTATE("admin_state"),
+        LINKSTATE("link_state"), LINKRESETS("link_resets"),
+        LINKSPEED("link_speed"), DUPLEX("duplex"), MTU("mtu"), ERROR("error");
+
+        private final String columnName;
+
+        private InterfaceColumn(String columnName) {
+            this.columnName = columnName;
+        }
+
+        /**
+         * Returns the table column name for InterfaceColumn.
+         * @return the table column name
+         */
+        public String columnName() {
+            return columnName;
+        }
+    }
+
+    /**
+     * Constructs a Interface object. Generate Interface Table Description.
+     * @param dbSchema DatabaseSchema
+     * @param row Row
+     */
+    public Interface(DatabaseSchema dbSchema, Row row) {
+        super(dbSchema, row, OvsdbTable.INTERFACE, VersionNum.VERSION100);
+    }
+
+    /**
+     * Get the Column entity which column name is "name" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "name"
+     */
+    public Column getNameColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "getNameColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "name" to the Row entity of
+     * attributes.
+     * @param name the column data which column name is "name"
+     */
+    public void setName(String name) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "setName",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, name);
+    }
+
+    /**
+     * Get the column data which column name is "name" from the Row entity of
+     * attributes.
+     * @return the column data which column name is "name"
+     */
+    public String getName() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.NAME
+                                                                     .columnName(),
+                                                             "getName",
+                                                             VersionNum.VERSION100);
+        return (String) super.getDataHandler(columndesc);
+    }
+
+    /**
+     * Get the Column entity which column name is "type" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "type"
+     */
+    public Column getTypeColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.TYPE
+                                                                     .columnName(),
+                                                             "getTypeColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "type" to the Row entity of
+     * attributes.
+     * @param type the column data which column name is "type"
+     */
+    public void setType(String type) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.TYPE
+                                                                     .columnName(),
+                                                             "setType",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, type);
+    }
+
+    /**
+     * Get the Column entity which column name is "options" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "options"
+     */
+    public Column getOptionsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OPTIONS
+                                                                     .columnName(),
+                                                             "getOptionsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "options" to the Row entity of
+     * attributes.
+     * @param options the column data which column name is "options"
+     */
+    public void setOptions(Map<String, String> options) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OPTIONS
+                                                                     .columnName(),
+                                                             "setOptions",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, options);
+    }
+
+    /**
+     * Get the Column entity which column name is "ingress_policing_rate" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "ingress_policing_rate"
+     */
+    public Column getIngressPolicingRateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGRATE
+                                                                     .columnName(),
+                                                             "getIngressPolicingRateColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ingress_policing_rate" to the
+     * Row entity of attributes.
+     * @param ingressPolicingRate the column data which column name is
+     *            "ingress_policing_rate"
+     */
+    public void setIngressPolicingRate(Set<Long> ingressPolicingRate) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGRATE
+                                                                     .columnName(),
+                                                             "setIngressPolicingRate",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ingressPolicingRate);
+    }
+
+    /**
+     * Get the Column entity which column name is "ingress_policing_burst" from
+     * the Row entity of attributes.
+     * @return the Column entity which column name is "ingress_policing_burst"
+     */
+    public Column getIngressPolicingBurstColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGBURST
+                                                                     .columnName(),
+                                                             "getIngressPolicingBurstColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ingress_policing_burst" to the
+     * Row entity of attributes.
+     * @param ingressPolicingBurst the column data which column name is
+     *            "ingress_policing_burst"
+     */
+    public void setIngressPolicingBurst(Set<Long> ingressPolicingBurst) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.INGRESSPOLICINGBURST
+                                                                     .columnName(),
+                                                             "setIngressPolicingBurst",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, ingressPolicingBurst);
+    }
+
+    /**
+     * Get the Column entity which column name is "mac_in_use" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "mac_in_use"
+     */
+    public Column getMacInUseColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MACINUSE
+                                                                     .columnName(),
+                                                             "getMacInUseColumn",
+                                                             VersionNum.VERSION710);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mac_in_use" to the Row entity
+     * of attributes.
+     * @param macInUse the column data which column name is "mac_in_use"
+     */
+    public void setMacInUse(Set<String> macInUse) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MACINUSE
+                                                                     .columnName(),
+                                                             "setMacInUse",
+                                                             VersionNum.VERSION710);
+        super.setDataHandler(columndesc, macInUse);
+    }
+
+    /**
+     * Get the Column entity which column name is "mac" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "mac"
+     */
+    public Column getMacColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MAC
+                                                                     .columnName(),
+                                                             "getMacColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mac" to the Row entity of
+     * attributes.
+     * @param mac the column data which column name is "mac"
+     */
+    public void setMac(Set<String> mac) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MAC
+                                                                     .columnName(),
+                                                             "setMac",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, mac);
+    }
+
+    /**
+     * Get the Column entity which column name is "ifindex" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "ifindex"
+     */
+    public Column getIfIndexColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.IFINDEX
+                                                                     .columnName(),
+                                                             "getIfIndexColumn",
+                                                             VersionNum.VERSION721);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ifindex" to the Row entity of
+     * attributes.
+     * @param ifIndex the column data which column name is "ifindex"
+     */
+    public void setIfIndex(Long ifIndex) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.IFINDEX
+                                                                     .columnName(),
+                                                             "setIfIndex",
+                                                             VersionNum.VERSION721);
+        super.setDataHandler(columndesc, ifIndex);
+    }
+
+    /**
+     * Get the Column entity which column name is "external_ids" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "external_ids"
+     */
+    public Column getExternalIdsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "getExternalIdsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "external_ids" to the Row entity
+     * of attributes.
+     * @param externalIds the column data which column name is "external_ids"
+     */
+    public void setExternalIds(Map<String, String> externalIds) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.EXTERNALIDS
+                                                                     .columnName(),
+                                                             "setExternalIds",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, externalIds);
+    }
+
+    /**
+     * Get the Column entity which column name is "ofport" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "ofport"
+     */
+    public Column getOpenFlowPortColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORT
+                                                                     .columnName(),
+                                                             "getOpenFlowPortColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ofport" to the Row entity of
+     * attributes.
+     * @param openFlowPort the column data which column name is "ofport"
+     */
+    public void setOpenFlowPort(Set<Long> openFlowPort) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORT
+                                                                     .columnName(),
+                                                             "setOpenFlowPort",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, openFlowPort);
+    }
+
+    /**
+     * Get the Column entity which column name is "ofport_request" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "ofport_request"
+     */
+    public Column getOpenFlowPortRequestColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORTREQUEST
+                                                                     .columnName(),
+                                                             "getOpenFlowPortRequestColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "ofport_request" to the Row
+     * entity of attributes.
+     * @param openFlowPortRequest the column data which column name is
+     *            "ofport_request"
+     */
+    public void setOpenFlowPortRequest(String openFlowPortRequest) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OFPORTREQUEST
+                                                                     .columnName(),
+                                                             "setOpenFlowPortRequest",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, openFlowPortRequest);
+    }
+
+    /**
+     * Get the Column entity which column name is "bfd" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "bfd"
+     */
+    public Column getBfdColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFD
+                                                                     .columnName(),
+                                                             "getBfdColumn",
+                                                             VersionNum.VERSION720);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bfd" to the Row entity of
+     * attributes.
+     * @param bfd the column data which column name is "bfd"
+     */
+    public void setBfd(Map<String, String> bfd) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFD
+                                                                     .columnName(),
+                                                             "setBfd",
+                                                             VersionNum.VERSION720);
+        super.setDataHandler(columndesc, bfd);
+    }
+
+    /**
+     * Get the Column entity which column name is "bfd_status" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "bfd_status"
+     */
+    public Column getBfdStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFDSTATUS
+                                                                     .columnName(),
+                                                             "getBfdStatusColumn",
+                                                             VersionNum.VERSION720);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "bfd_status" to the Row entity
+     * of attributes.
+     * @param bfdStatus the column data which column name is "bfd_status"
+     */
+    public void setBfdStatus(Map<String, String> bfdStatus) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.BFDSTATUS
+                                                                     .columnName(),
+                                                             "setBfdStatus",
+                                                             VersionNum.VERSION720);
+        super.setDataHandler(columndesc, bfdStatus);
+    }
+
+    /**
+     * Get the Column entity which column name is "monitor" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "monitor"
+     */
+    public Column getMonitorColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MONITOR
+                                                                     .columnName(),
+                                                             "getMonitorColumn",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION350);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "monitor" to the Row entity of
+     * attributes.
+     * @param monitor the column data which column name is "monitor"
+     */
+    public void setMonitor(String monitor) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MONITOR
+                                                                     .columnName(),
+                                                             "setMonitor",
+                                                             VersionNum.VERSION100,
+                                                             VersionNum.VERSION350);
+        super.setDataHandler(columndesc, monitor);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_mpid" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "cfm_mpid"
+     */
+    public Column getCfmMpidColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMMPID
+                                                                     .columnName(),
+                                                             "getCfmMpidColumn",
+                                                             VersionNum.VERSION400);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_mpid" to the Row entity of
+     * attributes.
+     * @param cfmMpid the column data which column name is "cfm_mpid"
+     */
+    public void setCfmMpid(Set<Long> cfmMpid) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMMPID
+                                                                     .columnName(),
+                                                             "setCfmMpid",
+                                                             VersionNum.VERSION400);
+        super.setDataHandler(columndesc, cfmMpid);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_mpid" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_mpid"
+     */
+    public Column getCfmRemoteMpidColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPID
+                                                                     .columnName(),
+                                                             "getCfmRemoteMpidColumn",
+                                                             VersionNum.VERSION400,
+                                                             VersionNum.VERSION520);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_mpid" to the Row
+     * entity of attributes.
+     * @param cfmRemoteMpid the column data which column name is
+     *            "cfm_remote_mpid"
+     */
+    public void setCfmRemoteMpid(Set<Long> cfmRemoteMpid) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPID
+                                                                     .columnName(),
+                                                             "setCfmRemoteMpid",
+                                                             VersionNum.VERSION400,
+                                                             VersionNum.VERSION520);
+        super.setDataHandler(columndesc, cfmRemoteMpid);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_mpids" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_mpids"
+     */
+    public Column getCfmRemoteMpidsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPIDS
+                                                                     .columnName(),
+                                                             "getCfmRemoteMpidsColumn",
+                                                             VersionNum.VERSION600);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_mpids" to the Row
+     * entity of attributes.
+     * @param cfmRemoteMpids the column data which column name is
+     *            "cfm_remote_mpids"
+     */
+    public void setCfmRemoteMpids(Set<Long> cfmRemoteMpids) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEMPIDS
+                                                                     .columnName(),
+                                                             "setCfmRemoteMpids",
+                                                             VersionNum.VERSION600);
+        super.setDataHandler(columndesc, cfmRemoteMpids);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_flap_count" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_flap_count"
+     */
+    public Column getCfmFlapCountColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFLAPCOUNT
+                                                                     .columnName(),
+                                                             "getCfmFlapCountColumn",
+                                                             VersionNum.VERSION730);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_flap_count" to the Row
+     * entity of attributes.
+     * @param cfmFlapCount the column data which column name is "cfm_flap_count"
+     */
+    public void setCfmFlapCount(Set<Long> cfmFlapCount) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFLAPCOUNT
+                                                                     .columnName(),
+                                                             "setCfmFlapCount",
+                                                             VersionNum.VERSION730);
+        super.setDataHandler(columndesc, cfmFlapCount);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_fault" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_fault"
+     */
+    public Column getCfmFaultColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULT
+                                                                     .columnName(),
+                                                             "getCfmFaultColumn",
+                                                             VersionNum.VERSION400);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_fault" to the Row entity of
+     * attributes.
+     * @param cfmFault the column data which column name is "cfm_fault"
+     */
+    public void setCfmFault(Set<Boolean> cfmFault) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULT
+                                                                     .columnName(),
+                                                             "setCfmFault",
+                                                             VersionNum.VERSION400);
+        super.setDataHandler(columndesc, cfmFault);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_fault_status" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_fault_status"
+     */
+    public Column getCfmFaultStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULTSTATUS
+                                                                     .columnName(),
+                                                             "getCfmFaultStatusColumn",
+                                                             VersionNum.VERSION660);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_fault_status" to the Row
+     * entity of attributes.
+     * @param cfmFaultStatus the column data which column name is
+     *            "cfm_fault_status"
+     */
+    public void setCfmFaultStatus(Set<String> cfmFaultStatus) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMFAULTSTATUS
+                                                                     .columnName(),
+                                                             "setCfmFaultStatus",
+                                                             VersionNum.VERSION660);
+        super.setDataHandler(columndesc, cfmFaultStatus);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_remote_opstate" from the
+     * Row entity of attributes.
+     * @return the Column entity which column name is "cfm_remote_opstate"
+     */
+    public Column getCfmRemoteOpStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEOPSTATE
+                                                                     .columnName(),
+                                                             "getCfmRemoteOpStateColumn",
+                                                             VersionNum.VERSION6100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_remote_opstate" to the Row
+     * entity of attributes.
+     * @param cfmRemoteOpState the column data which column name is
+     *            "cfm_remote_opstate"
+     */
+    public void setCfmRemoteOpState(Set<String> cfmRemoteOpState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMREMOTEOPSTATE
+                                                                     .columnName(),
+                                                             "setCfmRemoteOpState",
+                                                             VersionNum.VERSION6100);
+        super.setDataHandler(columndesc, cfmRemoteOpState);
+    }
+
+    /**
+     * Get the Column entity which column name is "cfm_health" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "cfm_health"
+     */
+    public Column getCfmHealthColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMHEALTH
+                                                                     .columnName(),
+                                                             "getCfmHealthColumn",
+                                                             VersionNum.VERSION690);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "cfm_health" to the Row entity
+     * of attributes.
+     * @param cfmHealth the column data which column name is "cfm_health"
+     */
+    public void setCfmHealth(Set<Long> cfmHealth) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.CFMHEALTH
+                                                                     .columnName(),
+                                                             "setCfmHealth",
+                                                             VersionNum.VERSION690);
+        super.setDataHandler(columndesc, cfmHealth);
+    }
+
+    /**
+     * Get the Column entity which column name is "lacp_current" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "lacp_current"
+     */
+    public Column getLacpCurrentColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LACPCURRENT
+                                                                     .columnName(),
+                                                             "getLacpCurrentColumn",
+                                                             VersionNum.VERSION330);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "lacp_current" to the Row entity
+     * of attributes.
+     * @param lacpCurrent the column data which column name is "lacp_current"
+     */
+    public void setLacpCurrent(Set<Boolean> lacpCurrent) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LACPCURRENT
+                                                                     .columnName(),
+                                                             "setLacpCurrent",
+                                                             VersionNum.VERSION330);
+        super.setDataHandler(columndesc, lacpCurrent);
+    }
+
+    /**
+     * Get the Column entity which column name is "other_config" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "other_config"
+     */
+    public Column getOtherConfigColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "getOtherConfigColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "other_config" to the Row entity
+     * of attributes.
+     * @param otherConfig the column data which column name is "other_config"
+     */
+    public void setOtherConfig(Map<String, String> otherConfig) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.OTHERCONFIG
+                                                                     .columnName(),
+                                                             "setOtherConfig",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, otherConfig);
+    }
+
+    /**
+     * Get the Column entity which column name is "statistics" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "statistics"
+     */
+    public Column getStatisticsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "getStatisticsColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "statistics" to the Row entity
+     * of attributes.
+     * @param statistics the column data which column name is "statistics"
+     */
+    public void setStatistics(Map<String, Long> statistics) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATISTICS
+                                                                     .columnName(),
+                                                             "setStatistics",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, statistics);
+    }
+
+    /**
+     * Get the Column entity which column name is "status" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "status"
+     */
+    public Column getStatusColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATUS
+                                                                     .columnName(),
+                                                             "getStatusColumn",
+                                                             VersionNum.VERSION100);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "status" to the Row entity of
+     * attributes.
+     * @param status the column data which column name is "status"
+     */
+    public void setStatus(Map<String, String> status) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.STATUS
+                                                                     .columnName(),
+                                                             "setStatus",
+                                                             VersionNum.VERSION100);
+        super.setDataHandler(columndesc, status);
+    }
+
+    /**
+     * Get the Column entity which column name is "admin_state" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "admin_state"
+     */
+    public Column getAdminStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ADMINSTATE
+                                                                     .columnName(),
+                                                             "getAdminStateColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "admin_state" to the Row entity
+     * of attributes.
+     * @param adminState the column data which column name is "admin_state"
+     */
+    public void setAdminState(Set<String> adminState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ADMINSTATE
+                                                                     .columnName(),
+                                                             "setAdminState",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, adminState);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_state" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_state"
+     */
+    public Column getLinkStateColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSTATE
+                                                                     .columnName(),
+                                                             "getLinkStateColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_state" to the Row entity
+     * of attributes.
+     * @param linkState the column data which column name is "link_state"
+     */
+    public void setLinkState(Map<String, String> linkState) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSTATE
+                                                                     .columnName(),
+                                                             "setLinkState",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, linkState);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_resets" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_resets"
+     */
+    public Column getLinkResetsColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKRESETS
+                                                                     .columnName(),
+                                                             "getLinkResetsColumn",
+                                                             VersionNum.VERSION620);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_resets" to the Row entity
+     * of attributes.
+     * @param linkResets the column data which column name is "link_resets"
+     */
+    public void setLinkResets(Set<String> linkResets) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKRESETS
+                                                                     .columnName(),
+                                                             "setLinkResets",
+                                                             VersionNum.VERSION620);
+        super.setDataHandler(columndesc, linkResets);
+    }
+
+    /**
+     * Get the Column entity which column name is "link_speed" from the Row
+     * entity of attributes.
+     * @return the Column entity which column name is "link_speed"
+     */
+    public Column getLinkSpeedColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSPEED
+                                                                     .columnName(),
+                                                             "getLinkSpeedColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "link_speed" to the Row entity
+     * of attributes.
+     * @param linkSpeed the column data which column name is "link_speed"
+     */
+    public void setLinkSpeed(Set<Long> linkSpeed) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.LINKSPEED
+                                                                     .columnName(),
+                                                             "setLinkSpeed",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, linkSpeed);
+    }
+
+    /**
+     * Get the Column entity which column name is "duplex" from the Row entity
+     * of attributes.
+     * @return the Column entity which column name is "duplex"
+     */
+    public Column getDuplexColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.DUPLEX
+                                                                     .columnName(),
+                                                             "getDuplexColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "duplex" to the Row entity of
+     * attributes.
+     * @param duplex the column data which column name is "duplex"
+     */
+    public void setDuplex(Set<Long> duplex) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.DUPLEX
+                                                                     .columnName(),
+                                                             "setDuplex",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, duplex);
+    }
+
+    /**
+     * Get the Column entity which column name is "mtu" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "mtu"
+     */
+    public Column getMtuColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MTU
+                                                                     .columnName(),
+                                                             "getMtuColumn",
+                                                             VersionNum.VERSION106);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "mtu" to the Row entity of
+     * attributes.
+     * @param mtu the column data which column name is "mtu"
+     */
+    public void setMtu(Set<Long> mtu) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.MTU
+                                                                     .columnName(),
+                                                             "setMtu",
+                                                             VersionNum.VERSION106);
+        super.setDataHandler(columndesc, mtu);
+    }
+
+    /**
+     * Get the Column entity which column name is "error" from the Row entity of
+     * attributes.
+     * @return the Column entity which column name is "error"
+     */
+    public Column getErrorColumn() {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ERROR
+                                                                     .columnName(),
+                                                             "getErrorColumn",
+                                                             VersionNum.VERSION770);
+        return (Column) super.getColumnHandler(columndesc);
+    }
+
+    /**
+     * Add a Column entity which column name is "error" to the Row entity of
+     * attributes.
+     * @param error the column data which column name is "error"
+     */
+    public void setError(Set<String> error) {
+        ColumnDescription columndesc = new ColumnDescription(
+                                                             InterfaceColumn.ERROR
+                                                                     .columnName(),
+                                                             "setError",
+                                                             VersionNum.VERSION770);
+        super.setDataHandler(columndesc, error);
+    }
+
+}
