}
 
 #endif
+#ifdef HAVE_FDB_OPS
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+                           struct net_device *dev,
+                           const unsigned char *addr,
+                           u16 flags)
+#else
+static int i40e_ndo_fdb_add(struct ndmsg *ndm,
+                           struct net_device *dev,
+                           unsigned char *addr,
+                           u16 flags)
+#endif
+{
+       struct i40e_netdev_priv *np = netdev_priv(dev);
+       struct i40e_pf *pf = np->vsi->back;
+       int err = 0;
+
+       if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED))
+               return -EOPNOTSUPP;
+
+       /* Hardware does not support aging addresses so if a
+        * ndm_state is given only allow permanent addresses
+        */
+       if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
+               netdev_info(dev, "FDB only supports static addresses\n");
+               return -EINVAL;
+       }
+
+       if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
+               err = dev_uc_add_excl(dev, addr);
+       else if (is_multicast_ether_addr(addr))
+               err = dev_mc_add_excl(dev, addr);
+       else
+               err = -EINVAL;
+
+       /* Only return duplicate errors if NLM_F_EXCL is set */
+       if (err == -EEXIST && !(flags & NLM_F_EXCL))
+               err = 0;
+
+       return err;
+}
+
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+                           struct net_device *dev,
+                           const unsigned char *addr)
+#else
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+                           struct net_device *dev,
+                           unsigned char *addr)
+#endif
+{
+       struct i40e_netdev_priv *np = netdev_priv(dev);
+       struct i40e_pf *pf = np->vsi->back;
+       int err = -EOPNOTSUPP;
+
+       if (ndm->ndm_state & NUD_PERMANENT) {
+               netdev_info(dev, "FDB only supports static addresses\n");
+               return -EINVAL;
+       }
+
+       if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
+               if (is_unicast_ether_addr(addr))
+                       err = dev_uc_del(dev, addr);
+               else if (is_multicast_ether_addr(addr))
+                       err = dev_mc_del(dev, addr);
+               else
+                       err = -EINVAL;
+       }
+
+       return err;
+}
+
+static int i40e_ndo_fdb_dump(struct sk_buff *skb,
+                            struct netlink_callback *cb,
+                            struct net_device *dev,
+                            int idx)
+{
+       struct i40e_netdev_priv *np = netdev_priv(dev);
+       struct i40e_pf *pf = np->vsi->back;
+
+       if (pf->flags & I40E_FLAG_SRIOV_ENABLED)
+               idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+
+       return idx;
+}
+
+#endif /* USE_DEFAULT_FDB_DEL_DUMP */
+#endif /* HAVE_FDB_OPS */
 static const struct net_device_ops i40e_netdev_ops = {
        .ndo_open               = i40e_open,
        .ndo_stop               = i40e_close,
        .ndo_add_vxlan_port     = i40e_add_vxlan_port,
        .ndo_del_vxlan_port     = i40e_del_vxlan_port,
 #endif
+#ifdef HAVE_FDB_OPS
+       .ndo_fdb_add            = i40e_ndo_fdb_add,
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+       .ndo_fdb_del            = i40e_ndo_fdb_del,
+       .ndo_fdb_dump           = i40e_ndo_fdb_dump,
+#endif
+#endif
 };
 
 /**